Содержание
Урок 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Наступила очередь рассказать о довольно интересной теме — о том, как подключить AVR микроконтроллер к компьютеру. Для этого, у микроконтроллеров есть приемопередатчик. У некоторых их, даже два. 

Update:10.02.17
Использовать будем UART наиболее простой и распространенный интерфейс. Чтобы понять как он работает, представьте себе что уарт это водопроводный кран, из которого течет вода — байты. Каждая новая капля, «затирает» старую, поэтому главная задача нашей программы успевать забирать данные до того, как придут новые.

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

Данные приходят последовательно один байт за другим, поэтому часто UART называют последовательным портом. Если ваша программа достаточно простая, то можно принять/передать один байт и на основании этого выполнить какое то действие. Например если приняли байт 100, то включили светодиод.

if(byte == 100)
{
   PORTB.1 = 1;
}

Только не стоит путать ASCII символ и байт, например i = ‘1’ i = 1 не одно и тоже. В чем разница можно почитать тут

Если ваша программа подразумевает, нечто более сложное, т.е. прием нескольких байт, то в прерывании по приходу данных складываем их в массив, далее в основном цикле разбираем массив. Стоит понимать, что поток не имеет ни начала, ни конца, он просто льется постоянно, поэтому нужно самому придумать какие то условности которые бы говорили о том, что сейчас пришел первый байт, а сейчас последний. Типовое решение, это использование спецсимволов, либо таймаутов. Пример можно посмотреть тут

Теперь перейдем к железу. У Atmega8 всего один приемопередатчик, PD0 — Rx, receiver (приемник) и PD1 — Tx, transmitter (передатчик).

Usart2

Аналогичные ножки есть на нашем переходнике FT232. Соединяем микроконтроллер и переходник между собой. В протеусе это будет выглядеть так:

Usart3

Напишем программу, которая по сигналу от компьютера будет включать светодиод и выключать. В CodeVision создаем новый проект, микроконтроллер atmega8, частота 8МГц (тактирование от кварца), на закладке  USART включаем приемник и передатчик.

usart4

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

#include <mega8.h>
#include <stdio.h>
 
void main(void)
{
char data;
 
PORTB=0x00;
DDRB=0xFF;
 
PORTD=0x00;
DDRD=0x00;
 
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x10;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
 
while (1)
      {
      data=getchar();
 
      if(data=='1')
      {
      PORTB=0xFF;
      }
      if(data=='0')
      {
      PORTB=0x00;
      }
 
      };
}

В текущем алгоритме используется простой способ функция getchar() постоянно проверяет не появились ли новые данные. После того как данные пришли — записываем их в переменную data; если пришла единичка, зажигаем светодиод; если 0, то выключаем его. Еще раз обратите внимание ‘1’ означает ASCII символ 1, реально байт будет равен 0x31. Сделано так, потому что большинство терминалов при нажатии кнопки на клавиатуре, отправляет именно символы.

Собираем схемку и прошиваем. Подключаем к компьютеру. Запускаем программу KeTerm или другой терминал. Подсоединяемся к нужному com порту. Шлем единичку — светодиод включается, шлем 0 светодиод выключается.

Урок был бы неполным, если не применить наши знания по C#.

Создадим проект, нарисуем 2 кнопки и последовательный порт
vusb21

В свойствах последовательного порта не забудьте настроить PortName, он должен соответствовать номеру порта переходника FT232. Добавим события: по клику на 1 кнопку — отсылаем 1, по клику на 2 кнопку — отсылаем 0, при загрузке формы — открытие порта, при выходе из формы — закрытие порта.

 private void button1_Click(object sender, EventArgs e)
  {
    serialPort1.WriteLine("1");
  }
 
  private void button2_Click(object sender, EventArgs e)
  {
     serialPort1.WriteLine("0");
  }
 
  private void Form1_Load(object sender, EventArgs e)
  {
     serialPort1.Open();
  }
 
  private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  {
     serialPort1.Close();
  }

И напоследок, видео работы всего этого безобразия)

Update: По просьбе Евгения программа немного изменена, теперь при запуске программа автоматически проверяет все ком порты, если есть активные, то они заносятся в comboBox1.

1
2
3
4
5
6
private void Form1_Load(object sender, EventArgs e)
 {
  string[] myPort; //создаем массив строк
  myPort = System.IO.Ports.SerialPort.GetPortNames(); // в массив помещаем доступные порты
  comboBox1.Items.AddRange(myPort); //теперь этот массив заносим в список(comboBox) 
 }

vusb3

Исходники программы

133 комментария: Урок 8. Передача данных через UART в AVR микроконтроллерах

  • Для выделения памяти 2 элементов в массиве использовал конструкцию:

    byte[] buf = new byte[2];

    Если вдуг кому нибудь понадопбиться.

  • Делаете успехи :mrgreen:

  • Спасибо, стараемся.. ) Тот кто ищет всегда найдет )

  • Добрый день. Скомпилировал Вашу прошивку и залил в контроллер. Программой для пк воспользовался тоже Вашей. Но, увы, ничего не заработало. С чем это может быть связано? usb-uart преобразователь CP2102.

  • с чем угодно, не правильно подсоединено, не правильные скорости и т.п. земли мк и переходника обязательно соединять

  • Подскажите, как с Вами можно связаться — Вконтакте и т.д. Буду очень признателен.

  • у меня вопрос.через UART можно передавать а также принимать с компьютера .Одно временно нельзя.А если мне нужно со схемы в комп принять информацию а потом передать что я должен сделать?

  • Заранее говорю спасибо.

  • Если у вас полный дуплекс, то линии Rx,Tx независимые, поэтому прием никак не зависит от передачи.

  • System.IO.Ports.SerialPort.GetPortNames(); — А это в каком фреймвёрке эта функцияия есть?

  • Спасибо за статью, с терминалами обменяться данными получилось.
    Можно ли сделать так, чтобы программа (для компьютера) отправляла не ASCII код, а просто числа?

  • можно

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

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