Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problem with 16f877a UART.

Status
Not open for further replies.

mohsin_ee08

Newbie level 6
Joined
Jan 31, 2012
Messages
14
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,372
Hi all!

I am using 16f877a UART. But the problem is that it doesn't receive multiple characters. Whenever it receives data, it reads only the first character again and again... for example: when I send 9876, every subsequent read operation produces 9. Can anyone suggest a solution??


Waiting for response.

Mohsin Ali
 

show the receiving part of code
 

Actually, I would suggest posting your code in its entirety, however please use CODE Tags when posting your code.


BigDog
 

Thanks for replying... I am new to edaboard; so i don't know where the CODE tag is...

The relevant part of code is:

Code:
k=0;
if (UART1_Data_Ready()) {     // If data is received,
                   uart_input[k] = UART1_Read();     //   read the received data,
                   UART1_Write(uart_input[k]);
                   if(uart_input[k]=='1'){
                         uart_input[k]='0';
                         delay_ms(200);                         
                         Lcd_Out(2,1, "receiving price");
                         uart_in=UART1_Read();
                         while(k<4){
                                 Lcd_Chr(2,1, uart_in);
                                 uart_input[k]=uart_in;
                                 k++;
                                 uart_in=UART1_Read();
                         }
                         price=atoi(uart_input);
                         Lcd_Cmd(_LCD_CLEAR);
                         Lcd_Out(2,1, uart_input);
                   }
      }
 
Last edited by a moderator:

the # sign on top is the code tag,also post the whole code here for better understanding.
 

what about those functions
Code:
UART1_Read()
etc are they from a library or you have written them
if you wrote that put them also
 

The full code is:

Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
sbit test1 at RB6_bit;
sbit test2 at RB7_bit;

 char txt3[]="W";
 char txt4[7];
char uart_input[5];
char uart_output[5];
char uart_in;
float peaki, nowi, nowv, peakv, peakw;
int i=0, j, k, Flag = 0;
float price=5, cost;
int secs = 0, secs_prev=0;
int mins = 0;
int hrs = 0;
char out_sec[7];
char out_min[7];
char out_hr[7];
char out_row_1[17]="                ";
char out_row_2[17]="                ";
int test=0;
//
// TMR0 timer interrupt service routine. The program jumps to the ISR at
// every 5ms.
//
void interrupt (){

     TMR0 = 0x00; // Re-load TMR0
     T0IF_bit = 0;
     Flag =  Flag+1; // Toggle Flag
     if(Flag > 7400){    //oroginal value is 7813
        Flag=0;
        secs++;
     }
}

void main(){
     //ANSEL=0x03;
     TRISA=0xFF;                                                 //portA as input
     //ANSELH=0;
     ADCON1 = 0x00;                                      // Select Verf and Right Justify
     ADCON1 = 0xC9;                                // Select Analog1 RC_Mode and ADON
     CMCON  |= 7;                    // Disable comparators
     UART1_Init(9600);
     Delay_ms(100);                  // Wait for UART 1module to


     PORTB=0;
     TRISB=0;                                                 //output

     PORTD=0;
     TRISD=0;                                                 //output

     Lcd_Init();                                              // Initialize LCD

     Lcd_Cmd(_LCD_CLEAR);                          // Clear display
     Lcd_Cmd(_LCD_CURSOR_OFF);             // Cursor off
     IntToStr(hrs, out_hr);
      j=0;
      if(hrs<10){
           out_hr[0]='0';
            j++;                        //converting output to proper format
      }
      for(i = j; i<7; i++){
              if(out_hr[i]!=' '){
                  out_hr[j]=out_hr[i];
                  j++;
              }
      }
      Lcd_Out(1, 12, out_hr);
      Lcd_Chr(1, 14, ':');
      IntToStr(mins, out_min);
      j=0;
      if(mins<10){
           out_min[0]='0';
            j++;
      }
      for(i = j; i<7; i++){
              if(out_min[i]!=' '){
                  out_min[j]=out_min[i];
                  j++;
              }
      }
      Lcd_Out(1, 15, out_min);
      IntToStr(secs, out_sec);

       //
     // Configure TMR0 timer interrupt
     //
     OPTION_REG = 0x08; // no prescalar
     TMR0 = 0x00; // Load TMR0L with 00
     INTCON = 0xA0; // Enable TMR0 interrupt
     UART1_Write_Text("Start");
  
     Start:
     peaki=0;
     peakv=0;
     nowi=0;
     nowv=0;
     i=0;
     secs_prev=secs;
     while (secs_prev==secs) {
     ADCON0=0x05;
     ADRESH=0x00;
     ADRESL=0x00;
                             //for using channel 0
     nowi=ADC_Read(0);
     nowi=nowi*5/1024;
     nowi=nowi-2.4948;

     if(nowi<0.01)
        nowi=0;
     if(nowi>=peaki)
        peaki=nowi;

        ADCON0=0x0D;
        ADRESH=0x00;
        ADRESL=0x00;
                        //for using channel1
        nowv=ADC_Read(1);
        nowv=nowv*5/1024;
        nowv=nowv-2.4948;

        if(nowv<0.01)
           nowv=0;
        if(nowv>=peakv)
           peakv=nowv;
     }

    if(secs==60){
          secs=0;
           mins++;
          if(mins==60){
              mins=0;
              hrs++;
              if(hrs==24){
                     hrs=0;
               }
         }
    }
    Lcd_Cmd(_LCD_CLEAR);

   IntToStr(secs, out_sec);
   IntToStr(mins, out_min);
   IntToStr(hrs, out_hr);

   j=0;
      if(mins<10){
            out_min[0]='0';
            j++;
       }
       for(i = j; i<7; i++){
            if(out_min[i]!=' '){
                  out_min[j]=out_min[i];
                   j++;
            }
       }
       j=0;
       if(hrs<10){
            out_hr[0]='0';
            j++;
       }
       for(i = j; i<7; i++){
            if(out_hr[i]!=' '){
                 out_hr[j]=out_hr[i];
                 j++;
            }
        }

        if(secs%2==0){
              //out_row_2[13]=':';
              Lcd_Chr(1, 14, ':');
        }
        else{
               //out_row_2[13]=' ';
               Lcd_Chr(1, 14, ' ');
        }
        Lcd_Out(1, 12, out_hr);
        Lcd_Out(1, 15, out_min);

        peakw=peaki*peakv;
        peakw=peakw/2;
        cost=peakw*price;
        FloatToStr(cost, txt4);
        
        Lcd_Out(1, 1, txt4);
        Lcd_Out(1,9, txt3);
        k=0;
        if (UART1_Data_Ready()) {     // If data is received,
                   uart_input[k] = UART1_Read();     //   read the received data,
                   UART1_Write(uart_input[k]);

                   Lcd_Out(2,1, "a");
                   if(uart_input[k]=='1'){
                         uart_input[k]='0';
                         delay_ms(200);
                         
                         Lcd_Out(2,1, "receiving price");
                         uart_in=UART1_Read();
                         while(k<4){
                                 Lcd_Chr(2,1, uart_in);
                                 uart_input[k]=uart_in;
                                 k++;
                                 uart_in=UART1_Read();
                         }
                         price=atoi(uart_input);
                         Lcd_Cmd(_LCD_CLEAR);
                         Lcd_Out(2,1, uart_input);
                   }
                   else if(uart_input[k]=='2'){
                         Lcd_Out(2,1, "sending reading");
                         FloatToStr(peakw, uart_output);
                         Lcd_Out(2,1, uart_output);
                         UART1_Write_Text(uart_output);
                         //UART1_Write('a');
                   }
                   else if(uart_input[k]=='3'){
                         Lcd_Out(2,1, "receiving time");
                   }
                   else{
                         Lcd_Out(2,1, "unknown input");
                   }
                   ++k;
                   //else
                   //    break;
           //}
            //Lcd_Out(2,1, uart_input);
           //UART1_Write_Text(uart_rd);
        }
        goto Start;
}

- - - Updated - - -

I am using MikroC for this project... Any suggestions about overcoming this problem??
 

Could you try replacing the bit of code you mentioned with this:

Code:
k = 0;
while(1)
        {
          if (UART1_Data_Ready()) {     // If data is received,
                     uart_input[k] = UART1_Read();     //   read the received data,
                     UART1_Write(uart_input[k]);
          }
        }

It should return all the characters you send over uart back to you.
 

try to check with the following changes, and the character value get reflected to the window and same time it will incremented, so it is possible to read the next character.....

Code:
unsigned char ch;            // Global Variable
if (UART1_Data_Ready()) {     // If data is received,
                   k = UART1_Read();     //   read the received data,
                   UART1_Write(k);
                   uart_input[ch] = k;
                   ch++;
   }
 

it works fine when this code runs alone; but when it is integrated with other parts, it gives the problem stated above...

Can you suggest a solution?
 

it works fine when this code runs alone; but when it is integrated with other parts, it gives the problem stated above...

One solution is to implement an Interrupt Service Routine (ISR), which handles the transmission or reception of characters through the UART.


BigDog
 

Isn't there some way to refresh or reset the input UART register when we want??? so that we may send and receive one character after the other (using polling)...

My point is: we receive and store a character, send its acknowledgement, reset the register and then receive and store the next character and so on...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top