bidirectional interconnection of 2 16F877A microprocessor via uart problem

Discussion in 'Embedded Systems and Microcontrollers' started by NioBium, May 25, 2010.

  1. NioBium

    Thread Starter New Member

    May 5, 2010
    6
    0
    Dear friends,

    Please help me with my project. I need to maintain a reliable communication between two microprocessors using UART (asynchronous). The program is as follows. Master 16F877A sends a frame of 11 bytes every 75ms. On reception of a properly formatted packet (using header and the trailer), Slave declares the link to be established and sends a similar acknowledgement packet to the Master shortly after. On reception of the ack packet Master declares link to be established and starts sending non-zero data. If a packet is not received on any of the microprocessors in 260ms, it declares the link to be broken (thus losses for up to 2 packets are tolerated). I have connected rx to tx and tx to rx directly, also the grounds of the microprocessors are the same. unfortunately what I see is rapid blinking of the link-status led, which indicates that connection is established and broken many times per second. using some led outputs which are not present in the attached code for the sake of simplicity, I observe moderate amount of framing errors, no overrun errors and a vast majority of the errors in the formatting of the data frame. Another weird thing is that when there is no physical connection between the RX and TX terminals of a master microprocessor with anything whatsoever, RCIF is constantly flagged, indicating that transmission bytes somehow imprint themselves on the RX terminals of the same microprocessor, though there is no short connection between them (checked with multimeter several times). 20MHz oscillators are in use. Does anyone have any idea about the possible causes and the solution?

    Thank you.

    master code:
    Code ( (Unknown Language)):
    1. #define CONST_TIMING_TRANSMISSION_LONG 11  // interval between individual transmissions
    2. #define CONST_TIMING_TIMEOUT_LONG 40 // maximum time between reception of two frames until the link is declared broken (tolerates up to 2 packet losses if rf module is used
    3. #define CONST_TIMING_TIMEOUT_SHORT 2 // maximum time between reception of individual bytes of a frame
    4.  
    5.  
    6. unsigned int rf_timeout_counter = CONST_TIMING_TIMEOUT_LONG;
    7. unsigned short rf_uart_transmission_queue[11] = {0x0A, 0x0D, 0x44, 0x4E, 0x45, 0x80, 0x80, 0x44, 0x46, 0x52, 0x24};
    8.  
    9. //backwards
    10. signed short rf_uart_transmission_queue_length;
    11. unsigned short rf_byte_order, rf_rx_data, rf_temp_data, rf_link_status;
    12. signed int timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
    13.  
    14.  
    15. void rf_init()
    16. {
    17.     TRISC|=0xC0;
    18.     SPBRG = 129;
    19.        
    20.     TXSTA = 0b00100100;
    21.     RCSTA = 0b10010000;
    22.     PIE1 |= 0b00110000;
    23.     TXREG=RCREG;
    24.  
    25.     rf_uart_transmission_queue_length=0;
    26.     timing_transmission_ready=0;
    27.     timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
    28.     rf_byte_order=0;
    29.     rf_link_status=0;
    30.     rf_timeout_counter=CONST_TIMING_TIMEOUT_LONG;
    31.     INTCON |= 0b01000000;   //peie
    32. }
    33.  
    34. void timing_init()
    35. {
    36.     INTCON.T0IE=1;
    37.     OPTION_REG.T0CS=0;                       //Set Timer0 to instruction clock
    38.     OPTION_REG.PSA=0;                        //Assign pre-scaler to Timer0
    39.     OPTION_REG.PS2=1;                      //Set first digit of pre-scale value
    40.     OPTION_REG.PS1=1;                      //Set second digit of pre-scale value
    41.     OPTION_REG.PS0=0;                      //Set third digit of pre-scale value     000 - 10ms 100, 101 - 10 ms 3
    42.     INTCON.T0IF=0;
    43.     INTCON.GIE=1;
    44. }
    45.  
    46. void rf_link_lost_action()
    47. {
    48.     rf_timeout_counter=-1;
    49.     rf_link_status=0;
    50.     rf_byte_order=0;
    51.     PORTD.F4=0; // link disrupt
    52. }
    53.  
    54. void rf_uart_byte_ready_action()
    55. {
    56.         if (rf_byte_order==0)
    57.         {
    58.             if (rf_rx_data==0x24)
    59.             {
    60.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    61.                 rf_byte_order=1;
    62.             }
    63.             else
    64.                 rf_link_lost_action();
    65.         }
    66.         else if (rf_byte_order==1)
    67.         {
    68.             if (rf_rx_data==0x52)
    69.             {
    70.                 rf_byte_order=2;
    71.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    72.             }
    73.             else
    74.                 rf_link_lost_action();
    75.         }
    76.         else if (rf_byte_order==2)
    77.         {
    78.             if (rf_rx_data==0x46)
    79.             {
    80.                 rf_byte_order=3;
    81.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    82.             }
    83.             else
    84.                 rf_link_lost_action();
    85.         }
    86.         else if (rf_byte_order==3)
    87.         {
    88.             if (rf_rx_data==0x41)
    89.             {
    90.                 rf_byte_order=4;
    91.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    92.             }
    93.             else
    94.                 rf_link_lost_action();
    95.         }
    96.         else if (rf_byte_order==4)
    97.         {
    98.             rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    99.             rf_temp_data = rf_rx_data;
    100.             rf_byte_order = 5;
    101.         }
    102.         else if (rf_byte_order==5)
    103.         {
    104.             rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    105.             rf_byte_order=6;
    106.         }
    107.         else if (rf_byte_order==6) //e
    108.         {
    109.             if (rf_rx_data==0x45)
    110.             {
    111.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    112.                 rf_byte_order=7;
    113.             }
    114.             else
    115.                 rf_link_lost_action();
    116.         }
    117.         else if (rf_byte_order==7) //n
    118.         {
    119.             if (rf_rx_data==0x4E)
    120.             {
    121.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    122.                 rf_byte_order=8;
    123.             }
    124.             else
    125.                 rf_link_lost_action();
    126.         }
    127.         else if (rf_byte_order==8) //d
    128.         {
    129.             if (rf_rx_data==0x44)
    130.             {
    131.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    132.                 rf_byte_order=9;
    133.             }
    134.             else
    135.                 rf_link_lost_action();
    136.         }
    137.         else if (rf_byte_order==9) //13
    138.         {
    139.             if (rf_rx_data==0x0D)
    140.             {
    141.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    142.                 rf_byte_order=10;
    143.             }
    144.             else
    145.                 rf_link_lost_action();
    146.         }
    147.         else if (rf_byte_order==10) //10
    148.         {
    149.             if (rf_rx_data==0x0A)
    150.             {
    151.                 rf_byte_order=0;
    152.                 rf_timeout_counter=CONST_TIMING_TIMEOUT_LONG;    //200ms
    153.                 rf_link_status=1; // link up
    154.                 PORTD.F4=1;
    155.             }
    156.             else
    157.                 rf_link_lost_action();
    158.  
    159.         }
    160.   //      if (rf_timeout_counter==-1)
    161.   //          PORTD.F5=1;
    162. }
    163.  
    164. void rf_transmit_data()
    165. {
    166.     timing_transmission_ready=0;
    167.     timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
    168.     if (rf_link_status)
    169.     {
    170.         rf_uart_transmission_queue[6] = (unsigned short)((signed int)control_slave_left_speed+128);
    171.         rf_uart_transmission_queue[5] = (unsigned short)((signed int)control_slave_right_speed+128);
    172.     }
    173.     else
    174.     {
    175.         rf_uart_transmission_queue[6] = 128;
    176.         rf_uart_transmission_queue[5] = 128;
    177.     }
    178.     rf_uart_transmission_queue_length=10;
    179.     TXREG=rf_uart_transmission_queue[rf_uart_transmission_queue_length];
    180. }
    181.  
    182. void interrupt(void)
    183. {
    184.     INTCON.GIE=0;
    185.     if (PIR1.RCIF)
    186.     {
    187.         rf_rx_data = RCREG;
    188.         rf_uart_byte_ready_action();
    189.     }
    190.     if (INTCON.T0IF)
    191.     {
    192.        if (RCSTA.OERR)
    193.        {
    194.            RCSTA = 0b10000000;
    195.            RCSTA = 0b10010000;
    196.        }
    197.        if (timing_transmission_counter>=0)
    198.        {
    199.            timing_transmission_counter--;
    200.            if (timing_transmission_counter==0)
    201.            {
    202.                rf_transmit_data();
    203.            }
    204.        }
    205.        if (rf_timeout_counter>=0)
    206.        {
    207.            rf_timeout_counter--;
    208.            if (rf_timeout_counter==0)
    209.            {
    210.                rf_link_lost_action();
    211.            }
    212.        }
    213.        INTCON.T0IF=0;
    214.     }
    215.  
    216.     if (PIR1.TXIF)
    217.      {
    218.          if (rf_uart_transmission_queue_length>0)
    219.           {
    220.              rf_uart_transmission_queue_length--;
    221.              TXREG = rf_uart_transmission_queue[rf_uart_transmission_queue_length];
    222.           }
    223.     }
    224.     INTCON.GIE=1;
    225. }
    226.  
    227.  
    228. void main() {
    229.      leds_init();
    230.      rf_init();
    231.      delay_ms(250);
    232.      timing_init();
    233.  
    234.      while (1);
    235. }
     
  2. NioBium

    Thread Starter New Member

    May 5, 2010
    6
    0
    slave code:
    Code ( (Unknown Language)):
    1. #define CONST_TIMING_ACKNOWLEDGEMENT 1 //delay before sending an acknowledgement
    2. #define CONST_TIMING_TIMEOUT_LONG 40
    3. #define CONST_TIMING_TIMEOUT_SHORT 2
    4.  
    5. unsigned short rf_uart_transmission_queue[11] = {0x0A, 0x0D, 0x44, 0x4E, 0x45, 0x00, 0x00, 0x41, 0x46, 0x52, 0x24};
    6.  
    7. //backwards
    8. signed short rf_uart_transmission_queue_length;
    9. unsigned short rf_byte_order, rf_rx_data, rf_temp_data, rf_link_status;
    10. signed int timing_recepetion_timeout_counter;
    11. signed int timing_acknowledgement_counter=CONST_TIMING_ACKNOWLEDGEMENT;
    12.  
    13.  
    14.  
    15. void rf_init()
    16. {
    17.     TRISC|=0xC0;
    18.     SPBRG = 129;
    19.     TXSTA = 0b00100100;
    20.     RCSTA = 0b10010000;
    21.     PIE1 |= 0b00110000;
    22.     TXREG=RCREG;
    23.     rf_uart_transmission_queue_length=0;
    24.     rf_link_status=0;
    25.     timing_acknowledgement_counter=CONST_TIMING_TIMEOUT_LONG;
    26.     rf_byte_order=0;
    27.     timing_recepetion_timeout_counter = -1;
    28. }
    29.  
    30. void timing_init()
    31. {
    32.     INTCON.T0IE=1;
    33.     OPTION_REG.T0CS=0;                       //Set Timer0 to instruction clock
    34.     OPTION_REG.PSA=0;                        //Assign pre-scaler to Timer0
    35.     OPTION_REG.PS2=1;                      //Set first digit of pre-scale value
    36.     OPTION_REG.PS1=1;                      //Set second digit of pre-scale value
    37.     OPTION_REG.PS0=0;                      //Set third digit of pre-scale value
    38.     INTCON.T0IF=0;
    39.     INTCON|= 0b01000000;   //peie
    40.     timing_acknowledgement_counter=-1;
    41.     INTCON.GIE=1;
    42. }
    43.  
    44.  
    45. void rf_link_lost_action()
    46. {
    47.     rf_link_status=0;
    48.     rf_byte_order=0;
    49.     timing_recepetion_timeout_counter=-1;
    50.     PORTD.F4=0; //link disrupt  
    51. }
    52.  
    53. void rf_uart_byte_ready_action()
    54. {
    55.       rf_rx_data=RCREG;
    56.         if (rf_byte_order==0)
    57.         {
    58.             if (rf_rx_data==0x24)
    59.             {
    60.                 rf_byte_order=1;
    61.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    62.             }
    63.             else
    64.                 rf_link_lost_action();
    65.         }
    66.         else if (rf_byte_order==1)
    67.         {
    68.             if (rf_rx_data==0x52)
    69.             {
    70.                 rf_byte_order=2;
    71.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    72.             }
    73.             else
    74.                 rf_link_lost_action();
    75.         }
    76.         else if (rf_byte_order==2)
    77.         {
    78.             if (rf_rx_data==0x46)
    79.             {
    80.                 rf_byte_order=3;
    81.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    82.             }
    83.             else
    84.                 rf_link_lost_action();
    85.         }
    86.         else if (rf_byte_order==3)
    87.         {
    88.             if (rf_rx_data==0x44)
    89.             {
    90.                 rf_byte_order=4;
    91.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    92.             }
    93.             else
    94.                 rf_link_lost_action();
    95.         }
    96.         else if (rf_byte_order==4)
    97.         {
    98.             rf_temp_data = rf_rx_data;
    99.  
    100.                 rf_byte_order=5;
    101.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    102.  
    103.         }
    104.         else if (rf_byte_order==5)
    105.         {
    106.             motors_set_left((signed int)rf_temp_data-128);
    107.             motors_set_right((signed int)rf_rx_data-128);
    108.  
    109.             rf_byte_order=6;
    110.             timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    111.  
    112.         }
    113.         else if (rf_byte_order==6) //e
    114.         {
    115.             if (rf_rx_data==0x45)
    116.             {
    117.                 rf_byte_order=7;
    118.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    119.             }
    120.             else
    121.                 rf_link_lost_action();
    122.         }
    123.         else if (rf_byte_order==7) //n
    124.         {
    125.             if (rf_rx_data==0x4E)
    126.             {
    127.                 rf_byte_order=8;
    128.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    129.             }
    130.             else
    131.                 rf_link_lost_action();
    132.         }
    133.         else if (rf_byte_order==8) //d
    134.         {
    135.             if (rf_rx_data==0x44)
    136.             {
    137.                 rf_byte_order=9;
    138.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    139.             }
    140.             else
    141.                 rf_link_lost_action();
    142.         }
    143.         else if (rf_byte_order==9) //13
    144.         {
    145.             if (rf_rx_data==0x0D)
    146.             {
    147.                 rf_byte_order=10;
    148.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
    149.             }
    150.             else
    151.                 rf_link_lost_action();
    152.         }
    153.         else if (rf_byte_order==10) //10
    154.         {
    155.             if (rf_rx_data==0x0A)
    156.             {
    157.                 rf_byte_order=0;
    158.                 timing_recepetion_timeout_counter=CONST_TIMING_TIMEOUT_LONG;
    159.                 timing_acknowledgement_counter=CONST_TIMING_ACKNOWLEDGEMENT;
    160.                 rf_link_status=1;
    161.                 PORTD.F4=1;     //link is established
    162.             }
    163.             else
    164.                 rf_link_lost_action();
    165.  
    166.         }
    167.         #ifndef RF_LEDS_BLINKING_MAD
    168.         if (timing_recepetion_timeout_counter<0) PORTD.F5=1;
    169.         #endif
    170. }
    171.  
    172. void rf_acknowledge()
    173. {
    174.     rf_uart_transmission_queue[6] = 0x00;
    175.     rf_uart_transmission_queue[5] = 0x00;
    176.     rf_uart_transmission_queue_length=10;
    177.     TXREG=rf_uart_transmission_queue[rf_uart_transmission_queue_length];
    178. }
    179.  
    180. void interrupt(void)
    181. {
    182.     INTCON.GIE=0;
    183.     if (PIR1.RCIF)
    184.     {
    185.         #ifdef RF_LEDS_BLINKING_MAD
    186.         PORTD.F5=!PORTD.F5;
    187.         #endif
    188.         rf_uart_byte_ready_action();
    189.  
    190.     }
    191.     if (INTCON.T0IF)
    192.     {
    193.          if (RCSTA.OERR)
    194.          {
    195.              RCSTA = 0b10000000;
    196.              RCSTA = 0b10010000;
    197.          }
    198.  
    199.        if (timing_acknowledgement_counter>=0)
    200.        {
    201.            timing_acknowledgement_counter--;
    202.            if (timing_acknowledgement_counter==0)
    203.            {
    204.               rf_acknowledge();
    205.            }
    206.        }
    207.        if (timing_recepetion_timeout_counter>=0)
    208.        {
    209.            timing_recepetion_timeout_counter--;
    210.            if (timing_recepetion_timeout_counter==0)
    211.            {
    212.                rf_link_lost_action();
    213.                #ifndef LEDS_FOR_US
    214.                #ifndef RF_LEDS_BLINKING_MAD
    215.                PORTD.F5=0;
    216.                #endif
    217.                #endif
    218. //             PORTB = 0xF0;
    219.            }
    220.        }
    221.        INTCON.T0IF=0;
    222.     }
    223.  
    224.     if (PIR1.TXIF)
    225.      {
    226.          if (rf_uart_transmission_queue_length>0)
    227.           {
    228.              rf_uart_transmission_queue_length--;
    229.              TXREG = rf_uart_transmission_queue[rf_uart_transmission_queue_length];
    230.           }
    231.     }
    232.     INTCON.GIE=1;
    233. }
    234.  
    235.  
    236.  
    237.  
    238. void main()
    239. {
    240.     leds_init(); // trisd assignment
    241.     rf_init();
    242.     delay_ms(250);
    243.     timing_init();
    244.     while (1) ;
    245. }
    246.  
     
  3. beenthere

    Retired Moderator

    Apr 20, 2004
    15,815
    282
  4. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    plus adding some comments to your code would help in deciphering it to give any advice....

    and also try running them synchronous instead of asynchronous, especially since you are doing a slave and master......

    B. Morse
     
Loading...