Кодирование Arduino UNO UART на чистом языке C

Ниже представлен простой код USART для ARDUINO, написанный на чистом C. Но по неизвестным (мне) причинам код не обеспечивает желаемого результата.

Может ли кто-нибудь указать на ошибку в коде? Я не могу использовать встроенную в Arduino функцию Serial.begin, так как мне нужно использовать USART для приема прерываний.

#include <avr/io.h>
#define F_CPU 16000000
#define BAUD 9600 
#include<util/setbaud.h>

void UART_Init();

void setup() 
{
    UART_Init();
}

void loop()
{
    UART_Transmit('c');
}

void UART_Init()
{
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE; 
   UCSR0B = (1<<RXEN0) | (1<<TXEN0);
   UCSR0C = (3<<UCSZ00);
}

void UART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1<<UDRE0)));
    UDR0 = data;
}

, 👍-1

Обсуждение

Скомпилированный как скетч Arduino, ваш код отлично работает на моем Uno. Как вы его скомпилировали?, @Edgar Bonet

@EdgarBonet Я скомпилировал его в Arduino IDE. В коде не было ошибок. Но после загрузки на плату полученный выход не соответствует ожидаемому., @Sreez..

Какой вывод вы ожидали? Я вижу длинный поток "cccccccccccccccccccccc...", и это то, чего я ожидаю от прочтения кода., @Edgar Bonet

@EdgarBonet Я тоже ожидаю только этого. Но не получаю. В моем последовательном мониторе я получаю только квадратные коробки, @Sreez..

При скорости 115200 бод получается правильный вывод. Но при 9600 вывод представляет собой квадратные блоки., @Sreez..

Это настоящий Uno с тактовой частотой 16 МГц? Не могли бы вы где-нибудь выложить сгенерированного эльфа?, @Edgar Bonet

@EdgarBonet Я использую клон Arduino с тактовой частотой 16 МГц. elf-файл: [ссылка](https://www.dropbox.com/s/iixou908mjdcapk/chk041.ino.elf?dl=0), @Sreez..

Я не могу скачать это, не открыв аккаунт Dropbox, чего я делать не буду., @Edgar Bonet

Предложите хорошую альтернативу, пожалуйста., @Sreez..

@EdgarBonet [файл эльфа](https://ufile.io/j1qcd), @Sreez..

Я застрял с той же проблемой...не могу использовать последовательные функции Arduino.....при использовании прерывания приема UART..... у вас есть решение?, @kishan


2 ответа


Лучший ответ:

0

Наконец-то я понял.

Расчет UBRR0 был ошибкой

Чтобы код работал на скорости передачи данных 9600 бод, нам нужно задать уравнение следующим образом:

UBRR0 = (F_CPU / 4 / бод - 1) / 2;

а также удвоить скорость USART, установив:

UCSR0A = (1<< U2X0)

Надеюсь, эта информация окажется кому-то полезной.

,

0

UBRR0 = (F_CPU / 4 / бод - 1) / 2;

Возможно, вам стоит проверить спецификацию.

Один из способов кодирования — изменить его на основе бита U2X, например так:

UxBRR=F_UART / ((UxCSRA & (1<<U2X0))?8:16) / baud - 1;          //генерация регистра скорости передачи данных

Таким образом, пользователь может свободно изменять бит U2X, а программное обеспечение позаботится об этом.

есть один набор процедур опроса UART и управления прерываниями, которые я использую: https://github.com/dannyf00/My-MCU-Library/tree/master/UART/UARTISR/ATMega328p

Они имеют одинаковый пользовательский интерфейс, поэтому их можно свободно заменять.

,