Взаимодействие двух микроконтроллеров AVR ATmega8 через UART

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

Взаимодействие двух микроконтроллеров AVR ATmega8 через UART: внешний вид

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

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

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

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

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

Работа схемы

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

Схема взаимодействия двух микроконтроллеров AVR ATmega8 через UART

В данной схеме мы будем рассматривать взаимодействие двух ATmega8 через последовательный порт с интерфейсом RS232 – это один из самых простых видов взаимодействий между микроконтроллерами AVR. Для этой цели у микроконтроллеров на схеме соединены контакты TXD и RXD их последовательных портов.

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

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

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

  1. Контакт TXD первого микроконтроллера должен быть задействован в качестве передатчика, а контакт RXD второго микроконтроллера должен быть задействован в качестве приемника.
  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

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

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

На представленной схеме на передающем конце мы видим кнопку. При нажатии этой кнопки 8 бит данных передаются передатчиком и принимаются приемником. Об успешном завершении приема данных свидетельствует включение светодиода на приемной стороне.

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

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

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

#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 = 25;// установка бодовой скорости
//записываем это значение в верхнюю часть регистра (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);
}

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

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>
int main(void)
{
DDRD |= (1 << PIND0);//устанавливаем контакт 0 PORTD на ввод данных
DDRC=0xFF;//устанавливаем PORTC на вывод данных

int UBRR_Value = 25; // скорость 2400 бод/с
UBRRH = (unsigned char) (UBRR_Value >> 8);
UBRRL = (unsigned char) UBRR_Value;
UCSRB = (1 << RXEN) | (1 << TXEN);
UCSRC = (1 << USBS) | (3 << UCSZ0);

unsigned char receiveData;
while (1)
{
while (! (UCSRA & (1 << RXC)) );
receiveData = UDR;

if (receiveData == 0b11110000)
{
PORTC ^= (1 << PINC0);
_delay_ms(220);
}
}
}

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

(1 голосов, оценка: 5,00 из 5)
Загрузка...
60 просмотров


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

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