For two Days a tried to run a RS232 communication with 57600 Baud on my Arduino Mega2560r3.
According to the Atmel Datasheet of the ATmega2560 page 230, I use UBRR0 = 34 and set the U2X0 bit.
So the communication have an error of only -0.8%. This should be OK.
Sending data from Arduino to a terminal program works without any problems, but the arduino recieved only bullshit.
The solution is to change the UBRR0 register to 16 and unset the U2X0 bit.
So the error is with 2.1% much bigger, but now the communication is working fine.
I guess the reason ist, that the ATmegaU on the Arduino use the same "wrong/high error" setup with 2.1%. So the errors will compensate!
The same way as the normal arduino programming way.
You have the USB Port on the Arduino Mega2560. It is connected to the Atmega16U2 and provides a virtual com port under windows. The USART0 of the Atmega2560 is connected via RS232 to the Atmega16U2. Thats it.
I configure USART0 of the Atmega2560 to communicate via the virtual com port witch is provided by the Atmega16U2.
I don't use the arduino IDE and set USART0 config registers manually.
So I looked in the Atmega2560 datasheet and choose following setup for USART0:
57600 baud,
8 bits,
1 stop bit,
no parity
So UBRR0 = 34 and U2X0 is set, correspondent to the datasheet page 230. The Error is small enough with -0.8%.
Now only transmitting from arduino to my windows pc (hterm terminal program) was possible. When I try to send some data from the pc to the arduino, the data is corrupted.
The problem is this:
/* Special case 57600 baud for compatibility with the ATmega328 bootloader. */
UBRR1 = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600)
? SERIAL_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)
: SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
UCSR1C = ConfigMask;
UCSR1A = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600) ? 0 : (1 << U2X1);
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
Found in Arduino-usbserial.h
So the Atmega16U2 don't use the U2X bit and produce a high baudrate error of +2.1%.
Together with the error of the Atmega2560 2.9% are to high!
My workaround is to config the Atmega2560 to UBRR0 = 16 and U2X0 = 0 too. So the errors are the same and compensate each other.
It's not OK that the Atmega16U2 choose such a wrong datarate and it isn't documented outside the source code! This issue is very hard to find.