0
\$\begingroup\$

Hello i m writng a program for UART receive interrupt for PIC24FJ64GA306

i m receiving a data which is in format of 0xAAXXXXXXXX, where data after AA can be anything... the data transmityted through host and received by pic doesnt match

Also i observed a strange issue: when i transmit for ist time the data is not fully received, only 2 bytes of data is received, where in when i transmit 2nd time i get a OVER run error.

The code is as follows:

static void uart1_DebugSerial_init(void)
{
  /*Setting the RPINRbits to map the peripheral port pins*/
   RPINR18bits.U1RXR = 26;   /*Selects RP26 as UART1 RX pin*/
   /*Setting the RPORbits to map the peripheral port pins to UART TX pin*/    
   RPOR10bits.RP21R = 3;   /*Assign U1TX to RP21*/  

   U1MODEbits.STSEL = 0; // 1-Stop bit
   U1MODEbits.PDSEL = 0; // No Parity, 8-Data bits
   U1MODEbits.ABAUD = 0; // Auto-Baud disabled
   U1MODEbits.BRGH = 0; // Standard-Speed mode
   U1BRG = BRGVAL; // Baud Rate setting for 9600

   //   U1STAbits.UTXISEL0 = 0;        // Interrupt after one TX character     is transmitted
  //    U1STAbits.UTXISEL1 = 0;
  IEC0bits.U1TXIE = 0;           // Disable UART TX interrupt
    IEC0bits.U1RXIE = 1;            // Enable the UART RX interrupt
  U1STAbits.URXISEL = 0;         // Interrupt after one RX character is   received

  U1MODEbits.UARTEN = 1; // Enable UART
  U1STAbits.UTXEN = 1; // Enable UART TX

  /* Wait at least 105 microseconds (1/9600) before sending first char */
  DELAY_105uS
  //U1TXREG = 'a'; // Transmit one character
  }

Uart transmitt code:

int uart1_DebugSerial_send(char *buf)
 {
    int len, buf_length;

   buf_length = strlen(buf);
   len = buf_length;

   while(buf_length--)
   {
       while(!(U1STAbits.TRMT));   //stay here until the UXTSR register is empty
       U1TXREG = *buf++;
    }

   return len;

}

UART Receive ISR

void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
 {
   static char str[50];
  unsigned char RxChar;
  static uint8_t uart_header_rcvd_flag = false;
  static uint8_t i = 0;

  IFS0bits.U1RXIF = 0;    /*Clear the Rx interrupt flag*/
  /* Check for receive errors */
  if(U1STAbits.FERR == 1)
   {

//          continue;
  }
  /* Must clear the overrun error to keep UART receiving */
  if(U1STAbits.OERR == 1)
  {

    U1STAbits.OERR = 0;
  //        continue;
}
/* Get the data */
if(U1STAbits.URXDA == 1)
{

    RxChar = U1RXREG;

}
/*If the Received char is 0xAA and Header received flag is false, then
 start receiving the packet*/

if (RxChar == 0xAA && uart_header_rcvd_flag == false)
{

    uart_header_rcvd_flag = true;
    i = 0;
}
/*If the Packet reception is already commenced, then check for the PKT_SIZE
 to stop populating the host_rx_buf
 */
if (uart_header_rcvd_flag == true)
{

    host_rx_buf[i++] = RxChar;

    if (i == HOST_PKT_SIZE)
    {

        host_pkt_rcvd_flag = true;
        uart_header_rcvd_flag = false;
    }
}    
 }

Please help me, where i m going wrong

Thanks in advance

\$\endgroup\$
  • \$\begingroup\$ You might try receiving all 5 characters and building your buffer in the isr. You could use a tight loop and include a timeout to get you out if you have a partial string. What is your processor speed? \$\endgroup\$ – John Birckhead May 23 '16 at 17:43
  • 1
    \$\begingroup\$ One other possible solution: make sure the receive buffer is empty in your transmit routine by reading it until it is empty. \$\endgroup\$ – John Birckhead May 23 '16 at 17:44
  • \$\begingroup\$ One more: if you specified Tx and Rx pins in your compiler, you may be running a software UART. This is processor intensive, as setting the buffer in the compiler setup. Make sure you are using the hardware Uart and maybe don't use a compiler buffer but catch the characters one at a time. \$\endgroup\$ – John Birckhead May 23 '16 at 17:49
1
\$\begingroup\$

the data transmityted through host and received by pic doesnt match

Check to make sure if both the baud rates for Transmitter and receiver are the same.

Also i observed a strange issue: when i transmit for ist time the data is not fully received, only 2 bytes of data is received, where in when i transmit 2nd time i get a OVER run error.

As the type of error indicates. Your Buffer is overflowing. Which means your not reading out of the buffer faster than new data arrives.Check the receiver buffer size and use hardware or software flow control appropriately. Looking at your ISR,reduce the number of operations performed in ISR to avoid overflow and it must surely work. Do all processing checks in main().

\$\endgroup\$
  • \$\begingroup\$ thanks for reply Vector9. The baudrates are same for receiver and trasmitter.. as in, while transmitting from Terminal i set the same parameters. \$\endgroup\$ – Pradeep Dayama May 23 '16 at 16:08
  • \$\begingroup\$ i just need 5 bytes and using buffer of same size.. how do i reduce that overflow error.... many a times, only 1st 2 bytes are getting read.. can see my code and let me know where i m going wrong \$\endgroup\$ – Pradeep Dayama May 23 '16 at 16:10
  • \$\begingroup\$ if u dont want to change your code entirely and keep it simple,after every byte u send,introduce a delay of 1.2 millisecond or more. This should give the receiver enough time to read the data out of the buffer. This is however not the right way to do it. \$\endgroup\$ – AlphaGoku May 24 '16 at 4:23
  • \$\begingroup\$ The right way to do it is, since it looks lik u have a Rx buffer size of 2, for every 2 bytes the master sends to the slave, wait for the slave to send back an ACK before the master sends the next 2 bytes. Or use hardware flow control(RTS,CTS etc). \$\endgroup\$ – AlphaGoku May 24 '16 at 4:25
  • \$\begingroup\$ Everyone thanks for reply, with all your help i figured it out that in my code, i m waiting for UART interrupt and also making use of ADC, i.e to read the analog pin. when i integrate my adc code and uart code, i found that uart stops working, where as when i ruun uart alone, it works... can someone pls help me with this \$\endgroup\$ – Pradeep Dayama May 30 '16 at 9:07
0
\$\begingroup\$

Hello here is the code snippet

uart ISR

void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)
{

   Receive_flag = 1;

   receive_buffer[buffer_wr_address] = U1RXREG;
   buffer_wr_address++;

   IFS0bits.U1RXIF = 0;    /*Clear the Rx interrupt flag*/ 

}

Uart source code

void uart_receive(void)
{
    while ( buffer_rd_address != buffer_wr_address )
    {
        switch (uart_state)
        {
            case RECEIVE_HEADER :        
            if (receive_buffer[buffer_rd_address] == HEADER_BYTE)
            {
                uart_state = RECEIVE_COMMAND;
            }
            break;

        case RECEIVE_COMMAND :            
            uart_state = RECEIVE_DATA_1;
            break;

        case RECEIVE_DATA_1 :           
            uart_state = RECEIVE_DATA_2;
            break;

        case RECEIVE_DATA_2 :          
            uart_state = RECEIVE_DATA_3;
            break;

        case RECEIVE_DATA_3 :            
           /*enter the code to process the data received*/


            buffer_rd_address = 0;
            buffer_wr_address = 0;
            uart_state = RECEIVE_HEADER;
            Receive_flag = 0;
            return;

        default :
            uart_state = RECEIVE_HEADER;
            break;
    }
    buffer_rd_address++;
}

Receive_flag = 0;

}

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.