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:
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:
Rich (BB code):
#define CONST_TIMING_TRANSMISSION_LONG 11 // interval between individual transmissions
#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
#define CONST_TIMING_TIMEOUT_SHORT 2 // maximum time between reception of individual bytes of a frame
unsigned int rf_timeout_counter = CONST_TIMING_TIMEOUT_LONG;
unsigned short rf_uart_transmission_queue[11] = {0x0A, 0x0D, 0x44, 0x4E, 0x45, 0x80, 0x80, 0x44, 0x46, 0x52, 0x24};
//backwards
signed short rf_uart_transmission_queue_length;
unsigned short rf_byte_order, rf_rx_data, rf_temp_data, rf_link_status;
signed int timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
void rf_init()
{
TRISC|=0xC0;
SPBRG = 129;
TXSTA = 0b00100100;
RCSTA = 0b10010000;
PIE1 |= 0b00110000;
TXREG=RCREG;
rf_uart_transmission_queue_length=0;
timing_transmission_ready=0;
timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
rf_byte_order=0;
rf_link_status=0;
rf_timeout_counter=CONST_TIMING_TIMEOUT_LONG;
INTCON |= 0b01000000; //peie
}
void timing_init()
{
INTCON.T0IE=1;
OPTION_REG.T0CS=0; //Set Timer0 to instruction clock
OPTION_REG.PSA=0; //Assign pre-scaler to Timer0
OPTION_REG.PS2=1; //Set first digit of pre-scale value
OPTION_REG.PS1=1; //Set second digit of pre-scale value
OPTION_REG.PS0=0; //Set third digit of pre-scale value 000 - 10ms 100, 101 - 10 ms 3
INTCON.T0IF=0;
INTCON.GIE=1;
}
void rf_link_lost_action()
{
rf_timeout_counter=-1;
rf_link_status=0;
rf_byte_order=0;
PORTD.F4=0; // link disrupt
}
void rf_uart_byte_ready_action()
{
if (rf_byte_order==0)
{
if (rf_rx_data==0x24)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=1;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==1)
{
if (rf_rx_data==0x52)
{
rf_byte_order=2;
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==2)
{
if (rf_rx_data==0x46)
{
rf_byte_order=3;
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==3)
{
if (rf_rx_data==0x41)
{
rf_byte_order=4;
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==4)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_temp_data = rf_rx_data;
rf_byte_order = 5;
}
else if (rf_byte_order==5)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=6;
}
else if (rf_byte_order==6) //e
{
if (rf_rx_data==0x45)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=7;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==7) //n
{
if (rf_rx_data==0x4E)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=8;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==8) //d
{
if (rf_rx_data==0x44)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=9;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==9) //13
{
if (rf_rx_data==0x0D)
{
rf_timeout_counter=CONST_TIMING_TIMEOUT_SHORT;
rf_byte_order=10;
}
else
rf_link_lost_action();
}
else if (rf_byte_order==10) //10
{
if (rf_rx_data==0x0A)
{
rf_byte_order=0;
rf_timeout_counter=CONST_TIMING_TIMEOUT_LONG; //200ms
rf_link_status=1; // link up
PORTD.F4=1;
}
else
rf_link_lost_action();
}
// if (rf_timeout_counter==-1)
// PORTD.F5=1;
}
void rf_transmit_data()
{
timing_transmission_ready=0;
timing_transmission_counter=CONST_TIMING_TRANSMISSION_LONG;
if (rf_link_status)
{
rf_uart_transmission_queue[6] = (unsigned short)((signed int)control_slave_left_speed+128);
rf_uart_transmission_queue[5] = (unsigned short)((signed int)control_slave_right_speed+128);
}
else
{
rf_uart_transmission_queue[6] = 128;
rf_uart_transmission_queue[5] = 128;
}
rf_uart_transmission_queue_length=10;
TXREG=rf_uart_transmission_queue[rf_uart_transmission_queue_length];
}
void interrupt(void)
{
INTCON.GIE=0;
if (PIR1.RCIF)
{
rf_rx_data = RCREG;
rf_uart_byte_ready_action();
}
if (INTCON.T0IF)
{
if (RCSTA.OERR)
{
RCSTA = 0b10000000;
RCSTA = 0b10010000;
}
if (timing_transmission_counter>=0)
{
timing_transmission_counter--;
if (timing_transmission_counter==0)
{
rf_transmit_data();
}
}
if (rf_timeout_counter>=0)
{
rf_timeout_counter--;
if (rf_timeout_counter==0)
{
rf_link_lost_action();
}
}
INTCON.T0IF=0;
}
if (PIR1.TXIF)
{
if (rf_uart_transmission_queue_length>0)
{
rf_uart_transmission_queue_length--;
TXREG = rf_uart_transmission_queue[rf_uart_transmission_queue_length];
}
}
INTCON.GIE=1;
}
void main() {
leds_init();
rf_init();
delay_ms(250);
timing_init();
while (1);
}