На этом уроке мы с Вами разберём вариант аппаратной реализации протокола обмена на основе модуля универсального асинхронного приёмопередатчика УАПП (Universal Asynchronous Receiver-Transmitter, UART) микроконтроллера AVR.
В те далёкие, давние времена, когда начинали появляться первые микроконтроллеры аппаратные модули интерфейсов обмена отсутствовали. Все интерфейсы связи организовывались программно (на подобие того, чем мы занимались на предыдущих уроках). В наши дни, когда практически каждый микроконтроллер буквально напичкан аппаратными модулями UART, I2C, SPI, CAN и т.п, программную реализацию практически не используют.
Аппаратная реализация интерфейса позволяет освободить машинное время за счёт автономности модулей и использования прерываний. На сегодняшний день почти каждый микроконтроллер имеет на борту универсальный последовательный интерфейс UART. AVR поддерживает этот протокол полностью.
!! В связи с фиксированным расположением выводов модуля UART клавиши управления пришлось перенести. Обратите на это внимание.
Перед использованием настроим UART. Нам нужно задать скорость обмена и формат передаваемых данных.
Для того, чтобы установить скорость обмена необходимо записать в регистр генератора скорости UBRR связи константу вычисленную по формуле приведённой в документации. Но есть более простой путь – выбрать константу из таблицы стандартных скоростей.
Я выбираю скорость 9600 бит/сек…
UBRRH = 0;
UBRRL = 103; //Скорость 9600 бод
По поводу формата передаваемых данных…
В начале передаётся один стартовый бит. Затем передается байт данных. В завершении передаётся стоповый бит, говорящий о том, что передача этого байта завершена.
В конце байта данных, перед стоповым битом, может находится бит четности.
Также, для надежности, может использоваться два стоповых бита.
Я собираюсь использовать самый популярный формат: 8 бит, один стартовый и один стоповый бит, без бита четности…
UCSRC = (0 << UMSEL)| // Bit 6 – USART Mode Select
(0 << UPM0)| // Bit 5 – Parity Mode
(0 << UPM1)| // Bit 4 – Parity Mode
(0 << USBS)| // Bit 3 – Stop Bit Select
(1 << UCSZ1)| // Bit 2 – Character Size
(1 << UCSZ0)| // Bit 1 – Character Size
(0 << UCPOL); // Bit 0 – Clock Polarity
Включаем передатчик…
UCSRB = (0 << RXCIE)| // Bit 7 – RX Complete Interrupt Enable
(0 << TXCIE)| // Bit 6 – TX Complete Interrupt Enable
(0 << UDRIE)| // Bit 5 – USART Data Register Empty Interrupt Enable
(0 << RXEN)| // Bit 4 – Receiver Enable
(1 << TXEN)| // Bit 3 – Transmitter Enable
(0 << UCSZ2); // Bit 2 – Character Size
Для того, чтобы начать передачу необходимо загрузить байт данных в регистр ввода/вывода данных UDR. Передача данных происходит автономно и не занимает машинного времени.
UDR = <байт данных>;
Ну и конечно же, прежде чем отправлять следующий байт необходимо дождаться окончания передачи предыдущего. Для этого используем флаг освобождения регистра данных UDRE…
while(!(UCSRA & (1 << UDRE)));
Для передачи данных я использую две функции: передача байта…
USART_TransmitByte(unsigned char txData) {
UDR = txData;
while(!(UCSRA & (1 << UDRE)));
}
…и передача строки…
USART_TransmitString(unsigned char txData[]) {
for (int i=0; i < strlen(txData);) {
USART_TransmitByte(txData[i]);
i++;
}
}
Ну а далее… опрашиваем ручку газа, клавиши пульта управления и передаём…
//Передача стартовых байт
USART_TransmitString(START_SEQUENCE);
//Передача байта мощности
USART_TransmitByte(ADCH);
//Передача байта commandBuffer
USART_TransmitByte(commandBuffer);
//Передача стоповых байт
USART_TransmitString(STOP_SEQUENCE);
Несколько слов в завершении. В следующем видео мы напишем программу приёмника на основе аппаратного модуля UART, МК AVR.
ПРОЕКТ С ИСХОДНЫМ КОДОМ И СИМУЛЯЦИЯ В PROTEUS во вложении.
Прикрепленные файлы:
- transmitter_uart_crr.rar (43 Кб)