I am sending ADC results from an ATmega16 controller to a PC through CP2102. Baudrate: 0.5Mb/s, 8 data-bits, 1 stop bit, no parity. I've written a software to visualize received data. Here is an example of ADC results from sampling a sine wave signal:
At some point my PC was under heavy load and this is the result that I had:
In my previous question I assumed that these spikes were caused by the ADC itself. However it is clearly seen now that these spikes are caused by transmission errors.
As far as I understand this problem occurs due to the overflow of CP210 TX buffer. Is my assumption correct? And if so, what can be done to prevent this?
Besides these spikes I've also found another problem. I am sending two bytes consecutively (ADCL and ADCH). What I've noticed is that sometimes the received bytes are swapped (i.e. ADCH is received before ADCL).
I've dumped some data where the spikes occur (first byte is ADCH, second is ADCL and the number is the resulting integer value)
Example 1:
821 : 00000011, 00110101
803 : 00000011, 00100011
783 : 00000011, 00001111
1018 : 00000011, 11111010
740 : 00000010, 11100100
718 : 00000010, 11001110
694 : 00000010, 10110110
Example 2:
229 : 00000000, 11100101
237 : 00000000, 11101101
246 : 00000000, 11110110
255 : 00000000, 11111111
10 : 00000000, 00001010
276 : 00000001, 00010100
289 : 00000001, 00100001
Update: added usart initialization routine
#define F_CPU 16000000UL
#define USART_BAUDRATE 500000
#define BAUD_PRESCALE ((F_CPU / (USART_BAUDRATE * 16UL)) - 1)
void USARTInit() {
UBRRH &= ~(1 << URSEL);
UBRRH = (unsigned char) (BAUD_PRESCALE >> 8);
UBRRL = (unsigned char) BAUD_PRESCALE;
UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // 1 stop bit, 8-bit data length
}
Update: added a simple test for usart
I've disabled ADC and replaced my main routine with a simple loop:
for (uint16_t i = 0; i < 1023; i++) {
USARTSendByte(uint8_t(i));
USARTSendByte(uint8_t(i >> 8));
}
When I start the terminal on my computer and put the system under heavy load (lots of background processes) I sometimes receive results like this:
...
252 : 00000000, 11111100
253 : 00000000, 11111101
254 : 00000000, 11111110
255 : 00000000, 11111111
0 : 00000000, 00000000
257 : 00000001, 00000001
513 : 00000001, 00000010
769 : 00000001, 00000011
260 : 00000001, 00000100
261 : 00000001, 00000101
...
11111010
, left most bit is transmitted last. Are you sure the baud rate is accurate? \$\endgroup\$