У меня есть Arduino Uno, управляемая ATmega328P. И я хотел отойти от его библиотек и сделать все на более низком уровне для учебных целей. Однако я не могу заставить uart работать правильно, теперь он работает только при отправке на устройство. Получение возвращает странный мусор, который терминал не может распечатать.
#define BAUDRATE (((F_CPU / (BAUD * 16UL))) - 1)
void init_uart()
{
UBRR0H = BAUDRATE >> 8; // set high baud
UBRR0L = BAUDRATE; //set low baud
UCSR0B = _BV(TXEN0) | _BV(RXEN0); //enable duplex
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01) | _BV(USBS0); //8-N-1
}
void putchar_uart(char c, FILE* stream)
{
loop_until_bit_is_set(UCSR0A, UDRE0); //wait till prev char is read
UDR0 = c;
}
char getchar_uart(FILE* stream)
{
loop_until_bit_is_set(UCSR0A, RXC0); //wait if there is data
return UDR0;
}
//^ actually is in a seperate file which gets linked
int main()
{
DDRD |= PIN_LED;
PORTD |= PIN_LED;
stdout = &mystdout;
stdin = &mystdin;
char buf[0xFF];
init_uart();
while (1)
{
char c = getchar_uart(NULL);
if (c == 'a')
{
PIND = PIN_LED;
printf("%s\n", "Hallo");
}
}
}
Я использую Ubuntu 14.04 LTS и использую minicom для связи. Который настроен как: 115200 8N1 (конечно, с правильным последовательным устройством).
Он компилируется как:
avr-gcc -Wall -Os -mmcu=atmega328p -DF_CPU=16000000UL -DBAUD=115200 -std=c99 -L/home/joel/avr-libs/lib -I/home/joel/avr-libs/inc -o firmware.o main.c -luart
Итак, как я узнаю, что один из способов работает? Из-за того, что светодиод переключается только при вводе «а». Но ответ - недопустимые символы. В шестнадцатеричном формате:
c8 e1 ec ec ef 8a