17 Окт., 2021, 16:55

Знание -- столь драгоценная вещь, что его не зазорно добывать из любого источника.

Абу-ль-Фарадж бин Харун


UART в AVR

Автор Shaman, 23 Июнь, 2021, 17:56

« предыдущая - следующая »

Shaman

В общем дело с фонарём из темы со скрипом, но движется.

На блок фонаря с моргалкой код почти написан. Добрался до UART части для связи с блоком управления. Есть несколько вопросов по работе UART  в атмеге 328. Если не сложно помогите разобраться.
Вот так выглядит немного переделанный под свои нужды пример из даташита по включению UART
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define F_CPU 1000000UL // Clock Speed
// настраиваем скорость прердачи UART
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#define SIZE_STATUS 3                    //размер алфавита
unsigned char status [SIZE_STATUS] =
{
      0b10000011,   /*Состояние эффекта начиная с младшего бита по порядку:
                        Правый поворот
                        Левый поворот
                        Стоп
                        Моргалка */
      1,            // Шаг эффекта поворот
      1,            // Шаг Эффекта моргалка
};
//Обработка прерывания по вектору USART_RX
ISR (USART_RX_vect)
{status[0]=UDR0;}

void USART_Init( unsigned int ubrr);
void main(void)
{
sei();                      //разрешаем глобальные прерывания
USART_Init(MYUBRR);

};
void USART_Init( unsigned int ubrr)
{
/*установка битрейта */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;

UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // Установка параметров: включение портов ввода и вывода, разрешение прерывание по окончанию приёма
UCSR0C = (1<<USBS0)|(3<<UCSZ00);            // Установка формата фрейма: 8data, 2stop bit
}
[свернуть]
1. судя по даташиту
даташиту
The USART Transmit Data Buffer Register and USART Receive Data Buffer Registers share the
same I/O address referred to as USART Data Register or UDRn. The Transmit Data Buffer Reg-
ister (TXB) will be the destination for data written to the UDRn Register location. Reading the
UDRn Register location will return the contents of the Receive Data Buffer Register (RXB).
For 5-, 6-, or 7-bit characters the upper unused bits will be ignored by the Transmitter and set to
zero by the Receiver.
The transmit buffer can only be written when the UDREn Flag in the UCSRnA Register is set.
Data written to UDRn when the UDREn Flag is not set, will be ignored by the USART Transmit-
ter. When data is written to the transmit buffer, and the Transmitter is enabled, the Transmitter
will load the data into the Transmit Shift Register when the Shift Register is empty. Then the
data will be serially transmitted on the TxDn pin.
The receive buffer consists of a two level FIFO. The FIFO will change its state whenever the
receive buffer is accessed. Due to this behavior of the receive buffer, do not use Read-Modify-
Write instructions (SBI and CBI) on this location. Be careful when using bit test instructions
(SBIC and SBIS), since these also will change the state of the FIFO.
[свернуть]
всё что попадает в регистр UDRn начинает передаваться или приниматься в зависимости от того включен передатчик или приемник, а если включены оба как в примере?
2. Во всех примера где нужно передать не один бит, несколко их просто по очереди записывают в UDRn
Пример
int readSerial(char* str)
{
i=0;
do {
while(!(UCSRA&(1<<RXC))) {};
str[i]=UDR;
i++;
} while (str[i-1] != ':' && i <MAX_STRING);

return 0;
}
[свернуть]
Что происходит с UARTтом после того как данные записаны в регистр переданы, а новых ёще не поступило?
В даташите не нашел.
Мои варианты:
а). Регистр обнуляется и ждёт новых данных
б). Продолжает передавать свое содержимое повторно

3. В примере выше никак не проверяется прошли ли передача предидущего фрейма, а если она не успела пройти данные в UDRn будут перезаписаны новыми и на вход придёт мусор?
4. Какое состояние для UDRn это отсутсвие данных, дабы передача прекратилась и как он обнуляется автоматически, после каждого переданного фрейма, или вручную?

Shaman

Нашел статью на тему, разбираюсь дальше.

Slabovik

1. Всё, что записываешь в data-буфер попадает только в передатчик. Всё, что читаешь из dada-буфера, принято приёмником. Физически сигналом выборки того или другого dada-буфера служит строб чтения или строб записи. Одновременная работа приёмника и передатчика при этом вполне прозрачна.

2. Буфер не обнуляется, но аппаратура передатчика будет в режиме "стоп" до тех пор, пока в data-буфер не будет записан очередной байт. Процесс записи поставит внутренний триггер "передача" в состояние "run", после чего передатчик запустится, передаст стартовый бит, биты данных, стоповый, после чего, скинув триггер, снова замрёт в положении "стоп".
зы: я не помню, как у AVR, но у хардверного порта скидывание триггера в положение "стоп" происходит сразу, как передатчик "забирает" данные из data-буфера, таким образом, разрешая запись нового значения (ведь триггер этот работает ещё и арбитром для пользователя, его состояние может считываться через порт управления), что позволяет не терять скорости на паузах между байтами. Собственно, это вполне себе однобайтный FIFO (в серьёзых микросхемах FIFO 16-байтовое).
Собственно, это, наверное, ответ и на п.4
3. не понял, что ты называешь фреймом. Байт передаётся от начала до конца, это обеспечивается аппаратно. Скорость "запихивания" байт синхронизируется while(!(UCSRA&(1<<RXC))). За программную организацию передачи последовательности байт отвечает программист.
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

Slabovik

Щас подумал... а можно же спокойно снифферить всё, что там на приеме и передаче болтается. Нужна только MAX232 и комп в качестве терминала  ;)
Общением на форуме подпитываю свою эгоистичную, склонную к самолюбованию сущность.

Shaman

В принципе да, только писать чем? Там в общем то много вариантов, можно ардуино приспособить с его средой, можно анализатор спектра. Но в моём случае можно и осциллографом прочитать информации немного. Но за подсказку благодарю.