Hot!Uart Receive data error

Author
ajitnayak87
Starting Member
  • Total Posts : 50
  • Reward points : 0
  • Joined: 2017/06/20 03:53:02
  • Location: 0
  • Status: offline
2017/11/15 00:28:34 (permalink)
0

Uart Receive data error

Dear all,
 
I am using MPlab X IDE v3.61 on PIC18F24k40 . I am trying to send and receive data from UART function. with below Peice of code i could able to send data in byte or string successfully. Now I am trying to read External data input and send back same. I have attached output printed for receive data .
 

#include "mcc_generated_files/mcc.h"
#define EUSART_TX_BUFFER_SIZE 8
#define EUSART_RX_BUFFER_SIZE 8
/**
Section: Global Variables
*/
volatile uint8_t eusartTxHead = 0;
volatile uint8_t eusartTxTail = 0;
volatile uint8_t eusartTxBuffer[EUSART_TX_BUFFER_SIZE];
volatile uint8_t eusartTxBufferRemaining;
volatile uint8_t eusartRxHead = 0;
volatile uint8_t eusartRxTail = 0;
volatile uint8_t eusartRxBuffer[EUSART_RX_BUFFER_SIZE];
volatile uint8_t eusartRxCount;

#define LED_RX RC7 // Pin assigned RX LED
#define LED_TX RC6 // Pin assigned TX LED
#define LED RC2 // Pin assigned for LED
#define DE RC5
char i;
unsigned int count=0;
char data;
static int DEVICE_ID=1;
char rxbuf[50]=" ";
unsigned char Function_code=0X03;
static int index=0;
static int rec_flag = 0;
static int check_flag = 1;

unsigned char buff[10];
char data1[10];
unsigned char buf[20]; //array to hold twenty bytes
 
 
 
void main(void)

{
    SYSTEM_Initialize();
    //EUSART_Initialize();
   
    while (1) {
        for (j=0;j<=8;j++)
         {
             rxbuf[j++] = Serial_Receive_byte();
             Serial_1_Send_byte(rxbuf[j]);
                      
         }
        //ser_data[0]=14;
        //Serial_1_Send_byte(ser_data[0]);
         //Send_string_uart1("Welcome back");
        __delay_ms(2000);


    }
}



void Serial_1_Send_byte(uint8_t trbuf1) {
    TX1REG = trbuf1;
    while (0 == TX1STAbits.TRMT);
}

void Send_string_uart1(const unsigned char *string) {
    unsigned char i = 0;

    do {
        TX1REG = string[i++];
        while (0 == TX1STAbits.TRMT);
    } while (string[i] != '\0');
}

char Serial_Receive_byte()
{
   
   while(0==PIR3bits.RCIF);
    return RC1REG;
    
}


void EUSART_Initialize(void)
{
    // disable interrupts before changing states
    PIE3bits.RCIE = 0;
    PIE3bits.TXIE = 0;

    // Set the EUSART module to the options selected in the user interface.

    // ABDOVF no_overflow; SCKP Non-Inverted; BRG16 16bit_generator; WUE disabled; ABDEN enabled;
    BAUD1CON = 0x09;

    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled;
    RC1STA = 0x90;

    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave;
    TX1STA = 0x24;

    // Baud Rate = 9600; SP1BRGL 207;
    SP1BRGL = 0xCF;

    // Baud Rate = 9600; SP1BRGH 0;
    SP1BRGH = 0x00;


    // initializing the driver state
    eusartTxHead = 0;
    eusartTxTail = 0;
    eusartTxBufferRemaining = sizeof(eusartTxBuffer);

    eusartRxHead = 0;
    eusartRxTail = 0;
    eusartRxCount = 0;

    // enable receive interrupt
    PIE3bits.RCIE = 1;
}



 
 
 
post edited by ajitnayak87 - 2017/11/15 00:32:20
#1

18 Replies Related Threads

    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/15 00:31:13 (permalink)
    0
    I have attached code Output Here. I have checked 
    Below function Working fine.
    Serial_1_Send_byte(uint8_t trbuf1)
    Send_string_uart1

    For Below function i used to print 00 00
    Serial_Receive_byte()

     
     
    I have also Tried Modified ,Receiving data as string and read value

    unsigned char* str;

    void main(void)

    {
       
        while (1) {
            for (j=0;j<=8;j++)
             {
                 rxbuf[j] = usart_RxString();
                 Serial_1_Send_byte( rxbuf[j]);
                 j++;
                          
             }
           // ser_data[0]=15;
           // Serial_1_Send_byte(ser_data[0]);
            // Send_string_uart1("Welcome back");
            __delay_ms(500);


        }
    }


    char usart_RxString()
    {

       while(*str !='\0')
       { // while not end of string
          while(0==PIR3bits.RCIF);
           RCREG = *str; // read next character
           str++; // increment pointer to next character
       }
           return RC1REG; // return the contents of uart
    }

     
    Data2 Represent for above code. Where I see data but not printed properly. 
     
     
     
     
    post edited by ajitnayak87 - 2017/11/15 01:33:56

    Attachment(s)

    Attachments are not available: Download requirements not met
    #2
    qhb
    Superb Member
    • Total Posts : 6255
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Uart Receive data error 2017/11/15 02:29:33 (permalink)
    0
    This code
    rxbuf[j++] = Serial_Receive_byte();
    Serial_1_Send_byte(rxbuf[j]);

    will not work because you increment j AFTER writing to the receive buffer, so you are sending the NEXT value from the buffer, which has not yet been written to.
     
    Your second version would have worked if you had not changed to function to receive a byte into a different function which tries to receive a string, but is full of nonsense code.
     
     
    #3
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/15 03:27:58 (permalink)
    0
    I have change the code. I have Initially Tested same. I am getting same result.
     
    void main(void) {
        // Initialize the device
        SYSTEM_Initialize();
        
        while (1) {
            for (j=0;j<=8;j++)
             {
                 rxbuf[j] = Serial_Receive_byte();
                 Serial_1_Send_byte( rxbuf[j]);
                 j++;
                          
             }
           // ser_data[0]=15;
           // Serial_1_Send_byte(ser_data[0]);
            // Send_string_uart1("Welcome back");
            __delay_ms(100);


        }
    }

    Attachment(s)

    Attachments are not available: Download requirements not met
    #4
    DarioG
    leaving this planet
    • Total Posts : 53071
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: porcodioland
    • Status: offline
    Re: Uart Receive data error 2017/11/15 03:31:29 (permalink)

    Dario Greggio
    --
    how does it feel, never having been loved? as life fades away, day after day, on this planet made of s h i t...

    #5
    qhb
    Superb Member
    • Total Posts : 6255
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Uart Receive data error 2017/11/15 03:40:24 (permalink)
    0
    I think your code is just too slow, waiting far too long in the send byte code.
    For starters, change this
    void Serial_1_Send_byte(uint8_t trbuf1) {
    TX1REG = trbuf1;
    while (0 == TX1STAbits.TRMT);
    }

    to
    void Serial_1_Send_byte(uint8_t trbuf1) {
    TX1REG = trbuf1;
    while (0 == PIR3bits.TX1IF);
    }

    #6
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/15 21:03:58 (permalink)
    0
    I have made code changes as per suggestion. These are thing i observed.
     When I go through datasheet PIR3 section shows TXIF bit represented as TX1IF similarly RXIF presented as RX1IF. If i am using this in code it shows Error.
     
    I am using Internal oscillator 8Mhz with 16bit timer0 Interrupt for code.
    Is use of Internal Oscillator making difference in code. Please give guideline for below.
     
     
    case 1: Send data 01030000000ACDC5 Format   Data read and transmitted 0000
     
    Case 2: Send data in Byte 01 every 2Sec Data read and transmitted 01
     
    Case 3  : Send data in Byte 01 every 2Sec
     Send data in Byte 03 every 3Sec
    Data read and transmitted 01    
     
     
     
     
    void Serial_1_Send_byte(uint8_t trbuf1) 
    {
     TX1REG = trbuf1;
     
    while (0 == PIR3bits.TXIF);
     //while (!TX1IF);
     
    }

    But As per Datasheet PIR3bits.TX1IF but i dont why it take TXIF function.


    void main(void)
    {
        // Initialize the device
        SYSTEM_Initialize();
        while (1)
    {
            for (j=0;j<=8;j++)
             {
                 rxbuf[j] = Serial_Receive_byte();
                 Serial_1_Send_byte(rxbuf[j]);
                 j++;
                          
             }
           // ser_data[0]=15;
           // Serial_1_Send_byte(ser_data[0]);
            // Send_string_uart1("Welcome back");
            __delay_ms(100);


        }
    }

    Attachment(s)

    Attachments are not available: Download requirements not met
    #7
    qhb
    Superb Member
    • Total Posts : 6255
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Uart Receive data error 2017/11/15 21:55:24 (permalink)
    +1 (1)
    ajitnayak87
    ...
     When I go through datasheet PIR3 section shows TXIF bit represented as TX1IF similarly RXIF presented as RX1IF. If i am using this in code it shows Error.

    Which version of the compiler are you using?
    Here is the complete definition of PIR3bits from pic18f24k40.h in v1.43 of XC8, so yoU can see that both versions are defined.
    // bitfield definitions
    typedef union {
        struct {
            unsigned SSPIF :1;
            unsigned BCLIF :1;
            unsigned :2;
            unsigned TXIF :1;
            unsigned RCIF :1;
        };
        struct {
            unsigned SSP1IF :1;
            unsigned BCL1IF :1;
            unsigned :2;
            unsigned TX1IF :1;
            unsigned RC1IF :1;
        };
        struct {
            unsigned :1;
            unsigned RXBNIF :1;
            unsigned :2;
            unsigned TXBNIF :1;
        };
    } PIR3bits_t;
    extern volatile PIR3bits_t PIR3bits @ 0xECD;

     
    #8
    NorthGuy
    Super Member
    • Total Posts : 4525
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Uart Receive data error 2017/11/15 22:33:27 (permalink)
    +2 (2)
    First, since you use K40, you may be affected by NVM errata.
     
    Then, you're doing too much at a time. You do send and receive together. Therefore there's no way for you to tell whether you cannot receive right or you cannot send right. You need to guess and it makes the whole thing much more difficult than it is.
     
    Start first by checking transmissions. Write a program which sends something every 1 sec or so and observe what you receive on the other end, such as:
     
    char c = 0;
    while (1) {
      Serial_1_Send_byte(c++);
      __delay_ms(500);
    }

     
    When you make this working, you'll know that you can transmit Ok and then you can use the transmission line to debug your receptions.
     
    #9
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/15 23:23:26 (permalink)
    0
    I have tested below cases in while loop and attached relevant output file.
    Data4: represent output for case 1
    data5: represent output for case 4
    data6: represent output for case 5
    I am sending data for every 1s in byte format.I found data Intruppted mismatch. I am thinking is totally about timing. If i am sending data in 01030000000AC5CD it wont work. if send data one byte in interval work,but due to sending data on same time.whatever last data read will be transmitted in output.
     
     /* 
      CASE1:
      Serial_1_Send_byte(c);
               c++;
                 __delay_ms(500);
     */


     /*
      CASE2:
      ser_data[0]=15;
      Serial_1_Send_byte(ser_data[0]);
     */


     /*
      CASE3:
      Send_string_uart1("Welcome back");
     */

    /*
     CASE4:
     for (j=0;j<=8;j++)
             {
                 rxbuf[j] = Serial_Receive_byte();
                 Serial_1_Send_byte(rxbuf[j]);
                 j++;
                          
             }
     
     */



    /*
     * Case5:
     if((PIE3bits.RCIE==1)&&(PIR3bits.RCIF=1))
                {
                    PIR3bits.RCIF=0;
                   rxbuf[index] = Serial_Receive_byte();
                   Serial_1_Send_byte(rxbuf[index]);
                           
                     __delay_ms(2);

                          index++;
                    
                     if(index>20)
                   {
                       index=0;
                       Send_string_uart1("Index flag reseted");
                   }
                    
                    if(index>8)
                       {
                           rec_flag = 1;
                          // Send_string_uart1("Receive flag trigger");
                       }
                   }
     
     
     */

    Attachment(s)

    Attachments are not available: Download requirements not met
    #10
    NorthGuy
    Super Member
    • Total Posts : 4525
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Uart Receive data error 2017/11/16 08:07:25 (permalink)
    0
    So, you can send, but you cannot receive. Now we need to test the reception. Remove all the complications, and do a very simple case:
     
    char c;
    while (1) {
      c = Serial_Receive_byte();
      Serial_1_Send_byte(c);
    }

     
    Then send something in at a slow pace.
     
    Does it work?
    #11
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/16 09:00:58 (permalink)
    0
    As said in my prvious thread its working fine.
    But when i used as complete code. I wont receive.
     
    if((PIE3bits.RCIE==1)&&(PIR3bits.RCIF=1)) 
                {
                    PIR3bits.RCIF=0;
                   rxbuf[index] = Serial_Receive_byte();
                   Serial_1_Send_byte(rxbuf[index]);
                           
                     __delay_ms(2);

                          index++;
                    
                     if(index>20)
                   {
                       index=0;
                       Send_string_uart1("Index flag reseted");
                   }
                    
                    if(index>8)
                       {
                           rec_flag = 1;
                          // Send_string_uart1("Receive flag trigger");
                       }
                   }
     

    #12
    KTrenholm
    Super Member
    • Total Posts : 257
    • Reward points : 0
    • Joined: 2012/08/08 14:04:23
    • Location: Connecticut, USA
    • Status: offline
    Re: Uart Receive data error 2017/11/16 09:30:56 (permalink)
    +1 (1)
    If I'm not missing something, isn't your Serial_Receive_byte() function incorrect?
    RCIF is read only. It remains set (1) until all characters are read from the FIFO.  You appear to be only reading the FIFO when RCIF is clear, which will never happen in your code because you're trying to set RCIF to 0 manually. 
     
    RCIF is read-only (see pg 393 of the datasheet).  You can only clear it by removing all characters from the FIFO.  It will clear automatically when the FIFO is empty.
     
    You would want this:

    /*while there are characters to be read from the FIFO, read them out to rxbuf*/
    while (PIR3bits.RCIF){
    rxbuf[index++] = RCREG;
    }

     
    If you know you're only ever going to get transmissions that are 8 bytes:

    /*while there are characters to be read from the FIFO, read them out to rxbuf*/
    while (PIR3bits.RCIF){
    rxbuf[index++] = RCREG;
    }
     
    if (index >=8){
    /*We have a complete transmission, reset the index*/
    /*You could also set a bool flag here to denote the transmission is finished and service it outside the ISR*/
    index = 0;
    }

     
     
    post edited by KTrenholm - 2017/11/16 10:54:58
    #13
    NorthGuy
    Super Member
    • Total Posts : 4525
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Uart Receive data error 2017/11/16 12:09:37 (permalink)
    +1 (1)
    ajitnayak87
    As said in my prvious thread its working fine.
    But when i used as complete code. I wont receive.



    Receiving is exactly what I suggested in my post #11. Your Data5.jpg doesn't seem to be working because you miss most of the bytes. Get rid of all the complications and only send and receive. You know that the sending part is working. Time to find out if the problem is with receiving or with your buffer-mangling.
    #14
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/16 21:08:32 (permalink)
    0
    I have done below test and i am sharing my main code with out put
     
    Case 1: Send Byte of data . Its working fine , Refer case 1 jpg 
    void Serial_1_Send_byte(uint8_t trbuf1) 
    {
     TX1REG = trbuf1;
     
    while (0 == PIR3bits.TXIF);
     //while (!TX1IF);
     
    }

    But As per Datasheet PIR3bits.TX1IF but i dont why it take TXIF function.


    void main(void)
    {
         unsigned char c=0;
        while (1)
       {
            Serial_1_Send_byte(c);
            c++;
            __delay_ms(50);

        }
    }

    case 2: Testing data receive as byte and send as byte
    Refer case2 and case2-jpeg . I am receiving data but receive update is slow.
     
    void Serial_1_Send_byte(uint8_t trbuf1) 
    {
     TX1REG = trbuf1;
     
    while (0 == PIR3bits.TXIF);
     //while (!TX1IF);
     
    }


    char Serial_Receive_byte()
    {
       
       while(0==PIR3bits.RCIF);
        return RC1REG;
        
    }



    void main(void)
    {
        while (1)
        
        
        {
        
                 rxbuf[0] = Serial_Receive_byte();
                 Serial_1_Send_byte(rxbuf[0]);
                  __delay_ms(10);
                          
           


        }



    }

     
     
    case 3: My main code. i am sending data 0103 expected to print 0103 in buffer.
    When data received get updated in relevant rxbuf. The rxbuf data being used for RS485 modbus computation. So before i add up other programs i want to make ensure 
    if datasend 01030000000Ac5cd  that 8 byte of data received properly.

    char rxbuf[50];
    void main(void)
    {
       
    unsigned char c=0;
     while (1)


    {
    while (1)
           
     {
         
     if((PIE3bits.RCIE==1)&&(PIR3bits.RCIF=1))
     {
         while (PIR3bits.RCIF==1)
          {
           rxbuf[index++] = RCREG;
           while(0==PIR3bits.RCIF);
         }
     if(index>=20)index=0;
     if(index>=8)
    {
     rec_flag = 1;
    }

     if(1==RCSTA1bits.FERR)
    {
     RCSTA1bits.SPEN=0;
    RCSTA1bits.SPEN=1;
     }
     if(1==RCSTA1bits.OERR)
     {
       RCSTA1bits.CREN=0;
     RCSTA1bits.CREN=1;
     }
    for(c=0;c<8;c++);
    Serial_1_Send_byte(rxbuf[c]);
    __delay_ms(50);

     }
                    
            
     }
             
    }

     
     

    Attachment(s)

    Attachments are not available: Download requirements not met
    #15
    qhb
    Superb Member
    • Total Posts : 6255
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Uart Receive data error 2017/11/16 21:24:51 (permalink)
    +1 (1)
    How can any of those programs you just showed work at all, when none of them set the baud rate or enable the serial peripheral?
    Just another thought, we've never seen your CONFIG bits. Are you disabling the Watchdog Timer? You should.
     
    #16
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/16 23:01:34 (permalink)
    0
    Dear all,
     
    Here i am putting only part of code. Since MCC generated file . It include lot of files to ad up here. If it really necessary then i will add it  soon.




    void main(void)

     {
        unsigned char c=0;

        
       while (1)
           
     {
      
           rxbuf[index++] = Serial_Receive_byte();
           if(index>=20)
           {
               index=0;
           }
     if(index>=8)
    {
     rec_flag = 1;
    }

     if(1==RCSTA1bits.FERR)
    {
     RCSTA1bits.SPEN=0;
    RCSTA1bits.SPEN=1;
     }
     if(1==RCSTA1bits.OERR)
     {
       RCSTA1bits.CREN=0;
     RCSTA1bits.CREN=1;
     }
    //for(c=0;c<8;c++);
    Serial_1_Send_byte(rxbuf[0]);
    Serial_1_Send_byte(rxbuf[1]);

    Serial_1_Send_byte(rxbuf[2]);
    Serial_1_Send_byte(rxbuf[3]);

    Serial_1_Send_byte(rxbuf[4]);
    Serial_1_Send_byte(rxbuf[5]);

    Serial_1_Send_byte(rxbuf[6]);
    Serial_1_Send_byte(rxbuf[7]);

    Serial_1_Send_byte(rxbuf[8]);



    __delay_ms(250);

     }



    char Serial_Receive_byte()
    {
       
       while(0==PIR3bits.RCIF);
        return RC1REG;
        
    }

     
    post edited by ajitnayak87 - 2017/11/16 23:04:55

    Attachment(s)

    Attachments are not available: Download requirements not met
    #17
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/16 23:07:41 (permalink)
    0
    I have attached config data relevant to mCC below.
     
    I have Set my PIC18F24k40 with internal oscillator 8Mhz with Timer0 16bit Interrupt with 3ms delay. I am pasting main and relevant function called during execution in above threads

    Attachment(s)

    Attachments are not available: Download requirements not met
    #18
    ajitnayak87
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Uart Receive data error 2017/11/17 01:08:06 (permalink)
    0
    If i am using dummy values It printing properly. and Further modbus code also working fine. 
    If i am trying to receive data externally and try to do computation its not working.
     
    Below code with dummy value for first 10 byte of data
    void main(void)

     {
       
       while (1)
           
     {
      
          
           /*Working for 10byte of dummy data*/
           rxbuf[0]=01; rxbuf[1]=03; rxbuf[2]=00; rxbuf[3]=00;
           rxbuf[4]=00; rxbuf[5]=10; rxbuf[6]=197; rxbuf[7]=205;
           
           
           if(index>=20)
           {
               index=0;
           }
     if(index>=8)
    {
     rec_flag = 1;
    }

     if(1==RCSTA1bits.FERR)
    {
     RCSTA1bits.SPEN=0;
    RCSTA1bits.SPEN=1;
     }
     if(1==RCSTA1bits.OERR)
     {
       RCSTA1bits.CREN=0;
     RCSTA1bits.CREN=1;
     }

    Serial_1_Send_byte(rxbuf[0]);
    Serial_1_Send_byte(rxbuf[1]);

    Serial_1_Send_byte(rxbuf[2]);
    Serial_1_Send_byte(rxbuf[3]);

    Serial_1_Send_byte(rxbuf[4]);
    Serial_1_Send_byte(rxbuf[5]);

    Serial_1_Send_byte(rxbuf[6]);
    Serial_1_Send_byte(rxbuf[7]);
    __delay_ms(100);

     }
          
     //}
        
    }

    #19
    Jump to:
    © 2017 APG vNext Commercial Version 4.5