Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

8-logoПо просьбам трудящихся, было решено продолжить урок по передаче данных через UART. Основной проблемой, на мой взгляд, при общении двух микроконтроллеров является прием данных.

В качестве примера возьмем две Atmega8. Задача первого микроконтроллера переслать массив символов, задача второго принять их и вывести на экран LCD дисплея. Схема будет выглядеть так:

uart821

Код передающего микроконтроллера будет выглядеть так:

#include <mega8.h>
#include <stdio.h>
 
void main(void)
{
 
char massiv[5]={'h','e','l','l','o'};
bit on=0;
int i=0;
 
PORTC=0x01;
DDRC=0x00;
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
 
while (1)
{
  if(PINC.0==0 && on==0)
  {
    UDR=massiv[i];
    i++;
    if(i>4)
    {
      i=0;
    }
    on=1;
  }
  if(PINC.0!=0)
  {
    on=0;
  }
 
};
}

При нажатии на кнопку передается 1 элемент массива символов, при повторном нажатии — следующий символ и т.д. В результате должен передаться массив «hello». Переменная on нужна для исключения дребезга кнопки (для передачи следующего символа нужно отпустить кнопку и затем нажать).

Второй микроконтроллер принимает данные в прерывании. Код прерывания, CodeWizard создает автоматически. Обработка достаточно большая, пугаться не стоит. Отдельно посмотреть данный код можно выставив галочки как показано на рисунке и щелкнуть File — Program Preview.

uart822

Разберемся с нашим алгоритмом, для нас самое главное это само прерывание:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
 
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
  rx_buffer[rx_wr_index]=data;
  if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
  if (++rx_counter == RX_BUFFER_SIZE)
  {
  rx_counter=0;
  rx_buffer_overflow=1;
  };
};
 
//здесь мы помещаем приходящие данные в массив, заранее известно количество 
//принимаемых символов = 5
uart_data[i]=data;
i++;
if(i>4)
{
  i=0;
}
 
}

Прием производится в прерывании, т.е. как только символ пришел срабатывает прерывание — символ записывается в первый элемент массива, инкрементируется счетчик. В следующее прерывание приходит следующий символ и т.д. Сразу оговорюсь, что количество приходящих символов заранее известно.

Теперь осталось только вывести результат на экран, для этого в цикле выводятся все символы на экран.

1
2
3
4
5
6
7
8
while(j<5) // цикл пока все 5 символов не будут выведены на экран
{
  lcd_gotoxy(j,0); //выбираем место куда будет выводиться символ
  sprintf(lcd_buffer,"%c",uart_data[j]); //преобразовываем символ в понятный для дисплея вид
  lcd_puts(lcd_buffer);  //выводим на экран
  j++;  //увеличить счетчик
}
j=0; // обнулить счетчик

uart823
Схема и прошивка доступны тут

90 комментариев: Урок 8.2. Передача данных через UART в AVR микроконтроллерах. Продолжение

  • Добрый день! Взял передающй микроконтроллер и подключил его к Bluetooth модулю hc05 приконектился с комютера через USB Bluetooth модуль на модуль HC05. Rx микроконтроллера соединил с Tx BT модуля и Tx с Rx. Подал и питание.
    Попробовал с терминала Tera Term на компе конектится на порт где висит Bluetooth. Конектится все ок. Но никак не принимаю данные. Пробовал менять скорость на терминале. Как правильно настроить передачу и синхронизироваться??
    В протеус все отлично работает. Получаю “Hello” на терминале .

  • попробуйте отдельно проверить bt и отдельно мк, универсального рецепта нет, может быть проблема с драйверами в винде, может скорости разные может земли не соединены и тп

  • А как можно проверить передается ли вообще сигнал с Rxd и Txd?
    И еще один вопрос UART Atmega8 настроен на скорости 9600. И частота тактирования 8 Mhz
    они же тоже должны играть роль в синхорнизации ? Может надо фюзами поиграть ?

  • и фьюзы и частота и предделители — все играет роль. проверить можно если замкнуть их между собой, должны увидеть эхо

  • Добрый вечер! Передаю температуру в терминал с 2 датчиков ds18b20 через микроконтроллер.
    Скажите пожалуйста, а как бороться с помехами и ошибками?
    У меня фюзы прошиты на 8 MHz регистры устанавливал так:

    UCSRA=0x00;
    UCSRB=0x48;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x33;

    Проволоки вроде короткие и земли соединенны. Выводит на терминал вот эти значения

    23 151 23 151 23 23 151 23 151 151 151 23
    151 23 23 151 23 151 23 23 23 23 151 151
    151 151 151 23 151 151 151 151 151 23 151 23
    23 23 23 151 151 151 23 151 23 151 151 23
    Правильная температура вроде 23 а другие ошибки…

  • сложно сказать, может вы датчик часто опрашиваете

  • Датчики опрашиваются каждые 500ms. При таких настроек регистров все исправилось и ошибок больше нет.
    UBRRH=0x00;
    UBRRL=0x34;

  • Добрый день.Прошу помощи по UART.
    Пищу так :
    if (PINB.0==0){delay_ms(2); sec|=1<<0; }else{sec&= ~(1 << 0);}

    if (PINB.1==0){delay_ms(2); sec|=1<<1; }else{sec&= ~(1 << 1);}

    if (PINB.2==0){delay_ms(2); sec|=1<<2; }else{sec&= ~(1 << 2);}

    if (PINB.3==0){delay_ms(2); sec|=1<<3; }else{sec&= ~(1 << 3);}

    UDR=sec;
    В протеусе все нормально а вот в живую ошибка . 01 03 0F
    0F всегда выскакивает когда любую третью кнопку нажимаю????

    В чем может быть проблема????

  • Уважаемый Админ! Объясните, пожалуйста, почему на микроконтроллере ATMega64a UART0 «заводится» без проблем, а UART1 — нужны «танцы с бубнами»? Пользуюсь CVAVR версия 3.12.
    Я честно пытался несколько дней настроить UART1 на прием и до сих пор не могу сообразить, как это сделать. Не реагирует, зараза… CVAVR выдает кучу настроек.
    Плюнул. Решил сделать на UART0 — всё отлично пошло с первого пинка.

  • Сложно сказать, нужно читать даташит что именно не так с уартом1. Я помню что в старших мегах были приколы с уартом, но за давностью времени уже все забылось.

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

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

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика