Учебный курс. UART/USART. Получение первых результатов. Сопрягаем микроконтроллер с компьютером

Задача

   Связать микроконтроллер с компьютером. Микроконтроллер должен принимать по USART`у символ, отображать его на LCD и отвечать компьютеру “Ok”.

Аппаратная часть

   Микроконтроллер ATmega8535 имеет в своем составе модуль универсального синхронно/асинхронного приемопередатчика -  USART. С его помощью между компьютером и микроконтроллером можно организовать обмен данными по последовательному каналу. Раньше в компьютерах для этих целей использовались COM порты, однако на современных машинах они уже большая редкость. Если на вашем компьютере все-таки есть такой порт, то для подключения микроконтроллера, понадобится преобразователь уровней ТТЛ – RS232. Его можно собрать на микросхеме MAX232AEPE
схема преобразователя TTL-RS232
  Если COM порта нет, будем подключаться к USB. Для облегчения работы с этим интерфейсом и для поддержки старых устройств, использовавших RS232, производители микросхем выпускают специальные USB-UART преобразователи. Один из вариантов подобного преобразователя представлен на схеме ниже (микросхема FT232BM). При подключении его к компьютеру, система попросит драйвера. Их можно скачать на сайте производителя. 
схема USB-UART преобразователя
Схема для нашего примера (без переходника)
схема для нашего примера 

Программная часть

   Для работы с  USART`ом нам нам понадобятся 4 функции. Три пользовательские, которые мы сможем вызывать:

Функция инициализации
Функция отправки символа
Функция чтения приемного буфера

   И одна для обработки прерывания USART`а:

Обработчик прерывания по завершению приема

Функция инициализации

  Как и любой другой периферийный модуль, USART перед использованием нужно настроить. Для этого в микроконтроллере ATmega8535 есть 5 регистров – UBRRH, UBRRL, UCSRA, UCSRB, UCSRC.

//инициализация usart`a
void 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
регистр 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
регистр 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

  Скорость обмена данными определяется содержимым регистра 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
регистр 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]. Иначе он будет отображаться некорректно.


Защитный код
Обновить