Задача
Связать микроконтроллер с компьютером. Микроконтроллер должен принимать по USART`у символ, отображать его на LCD и отвечать компьютеру “Ok”.
Аппаратная часть
Микроконтроллер ATmega8535 имеет в своем составе модуль универсального синхронно/асинхронного приемопередатчика - USART. С его помощью между компьютером и микроконтроллером можно организовать обмен данными по последовательному каналу. Раньше в компьютерах для этих целей использовались COM порты, однако на современных машинах они уже большая редкость. Если на вашем компьютере все-таки есть такой порт, то для подключения микроконтроллера, понадобится преобразователь уровней ТТЛ – RS232. Его можно собрать на микросхеме
MAX232AEPE.
Если COM порта нет, будем подключаться к USB. Для облегчения работы с этим интерфейсом и для поддержки старых устройств, использовавших RS232, производители микросхем выпускают специальные USB-UART преобразователи. Один из вариантов подобного преобразователя представлен на схеме ниже (микросхема
FT232BM). При подключении его к компьютеру, система попросит драйвера. Их можно скачать на сайте производителя.
Схема для нашего примера (без переходника)
Программная часть
Для работы с USART`ом нам нам понадобятся 4 функции. Три пользовательские, которые мы сможем вызывать:
Функция инициализации
Функция отправки символа
Функция чтения приемного буфера
И одна для обработки прерывания USART`а:
Обработчик прерывания по завершению приема
Функция инициализации
Как и любой другой периферийный модуль, USART перед использованием нужно настроить. Для этого в микроконтроллере ATmega8535 есть 5 регистров – UBRRH, UBRRL, UCSRA, UCSRB, UCSRC.
//инициализация usart`avoid USART_Init(
void)
{
UBRRH = 0;
UBRRL = 51;
//скорость обмена 9600 бод //разр. прерыв при приеме, разр приема, разр передачи. UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
//обращаемся к регистру UCSRS, размер слова – 8 бит UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
UCSRB
Принятый символ USART модуль сохраняет в регистре данных UDR. Оттуда мы его потом переписываем в буфер. Выполняется это в прерывании, а для этого оно должно быть разрешено. Устанавливаем бит – RXCIE – разрешение прерывания по завершению приема в единицу.
Биты TXCIE и UDRIE – разрешают прерывания по завершению передачи и прерывания при очистке регистра данных соответственно. Эти прерывания мы сейчас использовать не будем.
Модуль USART состоит из трех основных частей – блока тактирования, блока передатчика и блока приемника. Для разрешения работы приемника и передатчика нужно установить в единицу биты RXEN и TXEN соответственно.
Размер слова данных передаваемых/принимаемых модулем USART может варьироваться от 5 до 9 разрядов и определяется битами UCSZ2..UCSZ0. В регистре UCSRB находится только бит UCSZ2. Остальные биты находятся в регистре UCSRC. Мы будем использовать 8-ми разрядные слова, а значит эти три бита должны быть установлены так - 011.
Биты RXB8 и TXB8 – это 8-ой разряд принимаемых/передаваемых данных соответсвенно. Они используются, если размер слова данных – 9 бит.
//разр. прерывания при приеме, разр. приема, разр. передачиUCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
UCSRC
У микроконтроллера ATmega8535 регистр UCSRC размещен по тому же адресу что и регистр UBRRH (это тоже регистр модуля USART, вместе с регистром UBRRL он определяет скорость обмена), поэтому при обращении к ним нужно выполнять ряд дополнительных действий для выбора конкретного регистра. За это отвечает бит URSEL. Если он установлен в 1 обращение производится к UCSRC. Устанавливаем его.
UMSEL – определяет режим работы модуля USART – синхронный, асинхронный. У нас режим работы асинхронный, разряд должен быть сброшен.
UPM1, UPM0 – определяют режимы работы схем контроля и формирования четности. Используются для повышения надежности передачи данных. В нашем случае контроль четности выключен – биты должны быть сброшены.
USBS – количество стоп битов. Для нашего случай бит сброшен.
UCSZ1, UCSZ0 – формат посылок. О них мы уже говорили выше. Для 8-ми разрядного слова эти биты должны быть установлены в единицы.
UCPOL – полярность тактового сигнала. Пропускаем мимо, потому что разряд используется только при работе в синхронном режиме.
//обращаемся к регистру UCSRS, размер слова – 8 битUCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UBRR – UBRRH:UBRRL
Скорость обмена данными определяется содержимым регистра UBRR. Это 12 разрядный регистр и он физически размещается в двух регистрах ввода/вывода - UBRRH:UBRRL. Скорость обмена выбирается из ряда стандартных значений, в нашем примере она равна 9600 бод. Значение UBRR для обычного асинхронного режима (есть еще асинхронный режим с удвоенной скоростью обмена) вычисляется по формуле:
UBRR = (Fck/(16*BAUD)) – 1
где Fck – тактовая частота микроконтроллера, BAUD скорость обмена в бодах
Для нашего случая UBRR = 8000000/(16*9600) – 1 = 51. Это округленное значение, поэтому реальная скорость обмена будет отличаться от 9600. Рекомендуется использовать такие значение регистра UBRR, при которых получаемая скорость передачи отличается от требуемой на величину < 0.5%. Большая ошибка будет снижать помехозащищенность линии передачи.
UBRRH = 0;
UBRRL = 51;
//скорость обмена 9600 бодUCSRA
Этот регистр в основном содержит флаги устанавливаемые самим модулем USART. Единственный флаг который нам понадобится в программе – UDRE – флаг опустошения регистра данных. Он устанавливается в 1 при пустом буфере передатчика. Установленный флаг означает, что в регистр данных можно загружать новое значение.
Функция посылающая символ
//отправка символа по usart`у
void USART_SendChar(unsigned char sym)
{
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}
Передача данных USART`ом инициируется записью данных в буферный регистр передатчика – регистр данных UDR. (Работа передатчика естественно должна быть разрешена). Но перед тем как записать данные, нужно убедиться что передатчик освободился и готов к получению нового слова данных. Для этого в цикле while мы проверяем бит UDRE регистра UCSRA.
Обработчик прерывания по завершению приема
//прием символа по usart`у в буфер
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void)
{
usartRxBuf = UDR;
}
Когда модуль USART принял данные, вызывается соответствующее прерывание. В прерывании мы переписываем содержимое регистра UDR в буфер usartRxBuf. Старое значение буфера при этом затрется, но так как мы используем медленный посимвольный обмен, потерь данных не будет
Функция чтения приемного буфера
//чтение буфера
unsigned char USART_GetChar(void)
{
unsigned char tmp = usartRxBuf;
usartRxBuf = 0;
return tmp;
}
Копируем значение буфера в локальную переменную, очищаем его. Локальную переменную возвращаем.
Необходимый минимум готов. Оформляем его в виде программного модуля.
usart.h
usart.c
Основная программа
Основная программа будет выглядеть так. Надеюсь дополнительных комментариев она не требует.
//*****************************************
// Author(s)...: Pashgan http://ChipEnable.Ru
// Target(s)...: ATMega8535
// Compiler....: IAR EWA 5.11A
// Description.: UART/USART. Получение первых результатов
//******************************************
#include <ioavr.h>
#include "lcd_lib.h"
#include "usart.h"
int main( void )
{
unsigned char sym;
USART_Init();
LCD_Init();
__enable_interrupt();
LCD_SendString("uart:");
while(1){
sym = USART_GetChar(); //читаем буфер
if (sym){ //если что-то приняли, то
LCD_Goto(6,0);
LCD_WriteData(sym); //отображаем на lcd принятый символ
USART_SendChar('O'); //отвечаем компу "Ok "
USART_SendChar('k');
USART_SendChar(' ');
}
}
return 0;
}
Для проверки результатов работы микроконтроллера потребуется программа - терминал. Вы можете скачать ее в разделе
полезный софт. Если лень собирать схему и возиться с реальным железом, можно проверить программу в Proteus`e.
Файлы
[code] [/code]