Mega2560 R3 USB Serial Baud - Bare Metal

I am having some difficulty getting the proper data through the 16U2 USB interface on a mega2560 R3 clone to my PC terminal program. I am coding in bare metal C using AVR Studio 6.1 and programming using an Atmel mkII ISP.

For a sanity check I set up the microcontroller to spit data out on USART0 through the 16U2. I was getting gibberish on the PC end so I suspected improper baud rate. I discovered the PC baud rate wants to be set to HALF the baud rate the microcontroller is programmed to. The microcontroller registers are set (and I've verified by reading back) as follows:

UCSR0A: 0x40 UCSR0B: 0x98 UCSR0C: 0x07 UBRR0: 0x019 (25 dec)

Which should set up a 38400 baud at 8N1 format. With a 16 MHz rock, the UBRR setting matches table 22-12 in the ATmega2560 datasheet for 38400. I've also used the USART code at least 6-8 times in other projects (NOT Arduino related) without any issue whatsoever.

In order to get the proper data on the PC, the PC baud rate must be set to 19200. I've tried other microcontroller baud rates and the PC end ALWAYS wants to be half of what the microcontroller is set to. On the PC side I have tried two terminal programs (Putty and RealTerm) as well as two different mega R3 clones from different manufacturers/sources.

I suspect the 16U2 may be halving the data rate and that the Arduino software code for Serial.begin() actually masks the issue. Can anyone point out if I'm doing something wrong or shed some insight here?

-Thanks-

GeekDadLI: I am having some difficulty getting the proper data through the 16U2 USB interface on a mega2560 R3 clone to my PC terminal program. I am coding in bare metal C using AVR Studio 6.1 and programming using an Atmel mkII ISP.

For a sanity check I set up the microcontroller to spit data out on USART0 through the 16U2. I was getting gibberish on the PC end so I suspected improper baud rate. I discovered the PC baud rate wants to be set to HALF the baud rate the microcontroller is programmed to. The microcontroller registers are set (and I've verified by reading back) as follows:

UCSR0A: 0x40 UCSR0B: 0x98 UCSR0C: 0x07 UBRR0: 0x019 (25 dec)

Which should set up a 38400 baud at 8N1 format. With a 16 MHz rock, the UBRR setting matches table 22-12 in the ATmega2560 datasheet for 38400. I've also used the USART code at least 6-8 times in other projects (NOT Arduino related) without any issue whatsoever.

-Thanks-

UCSR0C? bit 0 states: |500x177

I would change UCSR0C = 0x06;

That is the only problem I can find. The 16u2's data rate is set by the pc's Serial emulation(USB) code. It has nothing to do with the Serial.begin() coding.

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

Chucktodd- Thanks for the reply. That bit is for synchronous mode only. The USB serial mode is asynchronous.

I am not using the Arduino Serial.begin() and just referenced it - I am programming in AVR Studio 6.1 using raw C. The 16U2's baud rate is set by the PC but I believe the uC baud rate must match that of the 16U2 as well.

My bad, UCSR0C s/b 0x06...

GeekDadLI: My bad, UCSR0C s/b 0x06...

Did changing USCR0C fix the problem?

Chuck

GeekDadLI: Chucktodd-

I am not using the Arduino Serial.begin() and just referenced it - I am programming in AVR Studio 6.1 using raw C. The 16U2's baud rate is set by the PC but I believe the uC baud rate must match that of the 16U2 as well.

GeekDadLI, You are correct, they both must match to communicate. I interpreted your statement as meaning the 16u2 was changing its behavior base on the Serial.begin() coding. (monitoring the uploaded data stream to configure its baud rate.)

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

Chucktodd- Thanks for following up - same result though. I suspect an issue with the 16U2 coding. Looking through the code for the USBserial on Github, there is a specialized case for 57600 baud which indicates the double speed setting. I wonder if something went awry in the logic and the Serial.begin() function compensates for it. I was able to follow through some of it, but I'm not at the level of that coding.

Maybe the question should be how many users code the Arduino bare metal and use the USB port for serial communication?