Связь AVR ATmega8 и Arduino Uno через универсальный асинхронный приемопередатчик (UART)

В этой статье мы рассмотрим процесс взаимодействия микроконтроллера ATmega8 (семейство AVR) и платформой Arduino Uno через последовательный порт. Взаимодействие будет осуществляться через универсальный асинхронный приемопередатчик (UART — Universal Asynchronous Receiver Transmitter) – это последовательный порт связи. Подобное взаимодействие часто бывает востребовано в различных системах на основе микроконтроллеров.

Подключение AVR ATmega8 к Arduino Uno через универсальный асинхронный приемопередатчик

В этой статье мы рассмотрим общие принципы связи двух микроконтроллеров через универсальный асинхронный приемопередатчик (последовательный порт) и рассмотрим принцип действия программы, реализующей данное взаимодействие. Также данный вопрос рассмотрен в статье про взаимодействие двух AVR ATmega8 через UART.

В рассматриваемом проекте микроконтроллер ATmega8 используется в качестве передатчика, а Arduino Uno – в качестве приемника данных. При последовательной передаче мы будем последовательно передавать один бит за другим до тех пока весь байт данных не будет принят полностью. При рассматриваемом способе можно передавать до 10 бит за один раз, но мы в целях упрощения ограничимся передачей 8 бит.

Необходимые компоненты

Аппаратное обеспечение

Микроконтроллер ATmega8
Arduino Uno
Источник питания с напряжением 5 Вольт
Программатор AVR-ISP, USBASP или другой подобный
Конденсатор 100 мкФ (соединенный по питанию)
Светодиод
Резистор 1 кОм (2 шт.)
Кнопка

Программное обеспечение

Atmel Studio версии 6.1 (или выше)
Progisp или flash magic (необязательно)
ARDUINO NIGHTLY

Работа схемы

Схема устройства приведена на следующем рисунке.

Схема подключения AVR ATmega8 к Arduino Uno через универсальный асинхронный приемопередатчик (UART)

Прежде чем рассматривать работу схемы остановимся на принципах последовательной связи между микроконтроллерами. ATmega8 будет передавать данные, а Arduino Uno – принимать их.

Передачу данных между ATmega8 и Arduino Uno можно организовать и другими способами: через коммуникацию MASTER SLAVE, коммуникацию через JTAG, но в данной статье мы рассмотрим их коммуникацию через последовательный порт RS232. Для этого мы соединим контакт TXD (Transmitter) микроконтроллера ATmega8 с контактом RXD (Receiver) Arduino Uno.

Для осуществления успешного взаимодействия между ними необходимо установить следующие параметры последовательного порта:

  1. Восемь бит данных.
  2. Два стоповых бита.
  3. Нет бита проверки на четность.
  4. Бодовая скорость 9600 бод/с (поскольку двоичная связь, то можно измерять в бит/с).
  5. Асинхронный режим связи (часы (таймеры) обоих устройств не синхронизированы).

Таким образом, мы должны установить соответствующие значения регистров последовательного порта для микроконтроллера ATmega8. Эти значения следующие:

  1. Контакт TXD микроконтроллера должен быть задействован в качестве передатчика.
  2. Поскольку связь последовательная, то мы должны знать когда мы примем весь байт целиком. Поэтому мы не должны останавливать прием данных до тех пока не примем весь байт. Остановка приема данных после приема всего байта производится с помощью соответствующего прерывания.
  3. Данные передаются и принимаются в 8 битном режиме. Поэтому два символа должны пересылаться единовременно.
  4. Битов проверки на четность нет, в конце данных передается один стоповый бит.

Для осуществления всех этих функций соответствующим образом должны быть установлены регистры, отвечающие за работу последовательного порта. Рассмотрим этот вопрос более подробно. Состав этих регистров приведен на следующем рисунке.

Регистры последовательного порта микроконтроллера AVR ATmega8

DARK GREY (темно-серый, UDRE): (сторона передатчика) Этот бит не устанавливается в самом начале, но он используется во время работы последовательного порта чтобы проверить готов ли передатчик к передаче или нет. Более подробно использование этого бита рассмотрено в программе, приведенной ниже.

LIGHT GREY (светло-серый, RXC): (сторона приемника) Этот бит не устанавливается в самом начале, но он используется во время работы последовательного порта чтобы проверить готов ли приемник к приему данных или нет. Более подробно использование этого бита рассмотрено в программе.

VOILET (фиолетовый, TXEN): (сторона передатчика) Этот бит устанавливается чтобы разрешить передачу данных по последовательному порту на стороне передатчика.

RED (красный, RXEN): (сторона приемника) Устанавливается чтобы разрешить прием данных на контакте RXD микроконтроллера.

BROWN (коричневый, RXCIE): Этот бит должен быть установлен для того, чтобы после успешного приема данных генерировалось прерывание. При помощи установки этого бита мы будем знать что очередные 8 бит приняты правильно.

PINK (розовый, URSEL): Этот бит должен быть установлен перед тем как устанавливать другие биты в регистре UCSRC. Но после того как мы установим все необходимые биты UCSRC, бит URSEL должен быть сброшен.

YELLOW(желтый, UCSZ0,UCSZ1,UCSZ2): (сторона приемника и сторона передатчика). Эти три бита используются для выбора числа бит, которые мы будем передавать/принимать за одну попытку (передачи).

Установка битов UCSZ для последовательного порта микроконтроллера AVR

Как следует из приведенной таблицы для задействования 8 битного режима связи биты UCSZ0 и UCSZ1 необходимо установить в 1, а бит UCSZ2 – в 0. Мы должны сделать этот как на приемной, так и на передающей стороне.

ORANGE (оранжевый, UMSEL): (сторона приемника и сторона передатчика). Используется для выбора режима связи: синхронный или асинхронный.

Установка битов UMSEL для последовательного порта микроконтроллера AVR

Поскольку оба микроконтроллера используют свои собственные внутренние часы (таймеры) и никоим образом не синхронизируют их между собой, то мы должны в соответствии с приведенной таблицей установить бит UMSEL в 0 на обоих микроконтроллерах.

GREEN (зеленый, UPM1, UPM0): (сторона приемника и сторона передатчика). Эти два бита устанавливаются в зависимости от того каким образом мы хотим использовать проверку на четность.

Установка битов UPM для последовательного порта микроконтроллера AVR

Микроконтроллеры ATMEGA программируются таким образом, чтобы не использовать проверку на четность поскольку длительность передачи данных (8 бит) очень мала, поэтому можно предположить что и вероятность искажения данных (вероятность ошибки) будет очень мала. Поэтому мы должны в соответствии с приведенной таблицей установить биты UPM1 и UPM0 в 0 либо не трогать их вообще, потому что по умолчанию при инициализации микроконтроллера они сброшены.

BLUE (синий, USBS): (сторона приемника и сторона передатчика) Этот бит используется для выбора числа стоповых бит в процессе передачи.

Установка битов USBS для последовательного порта микроконтроллера AVR

Поскольку мы выбрали асинхронный режим связи, то для более точной (надежной) передачи и приема данных необходимо использовать 2 стоповых бита. Поэтому устанавливаем бит USBS в 1.

Бодовая скорость последовательного порта устанавливается с помощью соответствующего значения в регистре UBRRH. Это значение необходимо определять в зависимости от требуемой бодовой скорости и тактовой частоты микроконтроллера.

Регистры для установки бодовой скорости в микроконтроллере AVR

Для выбранных нами параметров (скорость 9600 бод/с, тактовая частота 1 МГц) в регистре UBRR необходимо установить значение 6.

Таблица для установки бодовой скорости в микроконтроллере AVR

Теперь рассмотрим приемную сторону. Для осуществления последовательной связи в Arduino Uno необходимо выполнить следующие две простые команды:

  1. Serial.begin(9600);
  2. receiveddata = Serial.read();

Команда ”Serial.begin(9600);” устанавливает бодовую скорость передачи для последовательного порта Arduino Uno, равную 9600 бод/с – это изменяемый параметр.

Теперь нам необходимо запрограммировать прием данных, в Arduino Uno это делается с помощью команды — “receiveddata = Serial.read();”. С помощью этой команды Arduino Uno принимает через последовательный порт число типа integer (целое).

Кнопка на схеме включена на передающей стороне, поэтому когда мы ее нажимаем, то 8 бит данных передаются передатчиком (ATmega8) и принимаются приемником (Arduino Uno). По окончании успешного приема данных Arduino Uno включает светодиод, подключенный к его контакту PD7.

Исходный код программы на языке C (Си) с пояснениями

Программа для рассматриваемой схемы взаимодействия ATmega8 и Arduino Uno через UART представлена следующим фрагментом кода на языке С (Си). Комментарии к коду программу поясняют принцип работы отдельных команд.

Программа на передающей стороне

#include <avr/io.h>
//заголовок чтобы разрешить контроль данных на контактах
#define F_CPU 1000000UL
//задание тактовой частоты микроконтроллера
#include <util/delay.h>
//заголовок чтобы задействовать функции задержки в программе

int main(void)
{
DDRD |= 1 << PIND1;//контакт 1 portD устанавливаем на вывод данных
DDRD &= ~(1 << PIND0);//контакт 0 portD устанавливаем на ввод данных
PORTD |= 1 << PIND0;
int UBBRValue = 6;// установка бодовой скорости 9600 бод/с

//записываем это значение в верхнюю часть регистра (8 бит из 11)
UBRRH = (unsigned char) (UBBRValue >> 8);

// записываем оставшуюся часть регистра
UBRRL = (unsigned char) UBBRValue;

// задействуем передатчик и приемник
UCSRB = (1 << RXEN) | (1 << TXEN);

//устанавливаем 2 стоповых бита и 8-битную длину передаваемого символа UCSRC = (1 << USBS) | (3 << UCSZ0);

while (1)
{
if (bit_is_clear(PINC,0))// если кнопка нажата
{

while (! (UCSRA & (1 << UDRE)) );
{
UDR = 0b11110000;//когда передатчик готов посылаем 8 бит данных
}
_delay_ms(220);
}

Программа на приемной стороне

int receiveddata =0;
void setup()
{
Serial.begin(9600);// устанавливаем скорость для последовательного порта 9600 бод/с
pinMode(0,INPUT);// контакт RXD устанавливается на ввод данных
pinMode(1,OUTPUT);
pinMode(7,OUTPUT);// контакты PIN1,PIN7 устанавливаются на вывод данных
}
void loop()
{
if (Serial.available() > 0) // если прием данных доступен
{
receiveddata = Serial.read();//считываем данные из последовательного порта
if (receiveddata == 0) //операция сравнения принятых данных
{
PORTD^=(1<<7); //включаем светодиод
}
}
}

Видео, демонстрирующее работу схемы



Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *