The behavior of the TX complete flag is baffling me. I would really appreciate it if someone could shed some light on this behavior.
All the code does is set up the UART and then bounce back any data that is received. Initially the code didn't work until I added the 16 us delay. In order to try to figure out why, I toggled PD3 and then probed it with the oscilliscope.
#include#include #include #define F_CPU 12000000 #define TX0_EMPTY (UCSR0A & (1<<UDRE0)) #define RX0_COMPLETE (UCSR0A & (1<<RXC0)) #define TX0_COMPLETE (UCSR0A & (1<<TXC0)) int main(void) { //UART0 SETUP #define baud 500000 #define UBRR ((uint16_t)(F_CPU/(8.0*baud) - 1 + 0.5)) UBRR0H = (uint8_t)(UBRR>>8); UBRR0L = (uint8_t)(UBRR); UCSR0A = (1<<U2X0); // DOUBLE SPEED MODE (BAUD = XTAL/(8*(UBRR+1))) UCSR0B = (1<<TXEN0)|(1<<RXEN0); //ENABLE UART UCSR0C = (3<<UCSZ00); //8-BIT RS232, 1 STOP BIT, NO PARITY DDRD |= (1<<PD6); //PD6 controls the half-duplex direction on the RS-485 driver chip #define TX_MODE PORTD |= (1<<PD6); #define RX_MODE PORTD &= ~(1<<PD6); RX_MODE DDRD |= (1<<PD3); PORTD &= ~(1<<PD3); _delay_loop_2(64000); PORTD |= 1<<PD3; while(1) { if(RX0_COMPLETE) { _delay_loop_2(4); //~1.2 us delay TX_MODE UDR0 = UDR0; PORTD ^= 1<<PD3; while(!TX0_COMPLETE) ; PORTD ^= 1<<PD3; _delay_loop_2(50); //16.2 us delay measured PORTD ^= 1<<PD3; RX_MODE } _delay_loop_2(64000); _delay_loop_2(64000); _delay_loop_2(64000); } }
Below you can see the oscilliscope probes. I cant figure out why the while(!TX0_COMPLETE) last much shorter than the frame duration.
Any thoughts?