Can I code default serial port in Arduino Mega (USART0, I assume) in pure C? I mean to set up it and configure directly by ATmega's registers?
I'm asking because I'm trying to do it and I have a problem. Below is code which I use and Arduino doesn't transfer anything...
#include <avr/io.h>
#define F_CPU 16000000
#define BAUD_RATE 9600
#define MY_UBRR (F_CPU+BAUD_RATE*8UL)/(16UL*BAUD_RATE)-1
void setup() {
UART_Init(MY_UBRR);
}
void loop() {
UART_Transmit('a');
}
void UART_Init(unsigned char ubrr)
{
UBRR0H = (unsigned char)(ubrr >> 8);
UBRR0L = (unsigned char)ubrr;
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
UCSR0C = (1<<USBS0) | (1<<UCSZ00);
}
void UART_Transmit(unsigned char data)
{
while(!(UCSR0A & (1<<UDRE0)))
UDR0 = data;
}
That code I created following the datasheet for ATmega 2560. It has been compiled and programmed but doesn't work at all...
Please give me any advice. It's important for me use just C code in that case.
2 Answers 2
I suggest to use existing code and copy that or use that.
This is the Arduino HardwareSerial : HardwareSerial.cpp
You can find more code at avrfreaks.net. Click on "Projects", search for "uart" and "usart" and try to find code that is compatible with the ATmega2560. Some projects have buffers and many functions, others are very simple.
The result might not be compatible with other Arduino code (for example with interrupts). Why do you not want to use the Arduino Serial library ?
I tried your program on an Uno, and it worked as expected once I fixed three problems:
- Removed
#define F_CPU 16000000
. This is not a big issue, but it fixes a warning about that constant being already defined by the Arduino environment. - Added the
UCSZ01
bit toUCSR0C
in order to work in 8-bit mode instead of the uncommon 6-bit mode. - Added the semicolon after
while(!(UCSR0A & (1<<UDRE0)))
.
Note also that there is no point in loading UBRR0
in two steps. You
can just UBRR0 = ubrr
and trust the compiler to do the right thing.
while(!(UCSR0A & (1<<UDRE0)))
.