Программирование AVR: работа с USB Простой пример управления портами P1..P22 платы AVR-USB-MEGA16 (portctrl) Sun, February 26 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Простой пример управления портами P1..P22 платы AVR-USB-MEGA16 (portctrl) Печать
Добавил(а) microsin   

Устройство, которое может зажигать светодиоды, подключенные к портам P1..P22 макетной платы AVR-USB-MEGA16 [1].

Взял за основу пример hid-data. Для проверки запаял только 8 светодиодов к портам P1..P8. Можно управлять платой, тупо посылая туда 5 байт с помощью программы hidtool.exe (взял готовую из того же примера hid-data, просто перекомпилил её для нового значения usbconfig.h\USB_CFG_DEVICE_NAME). Структура данных такая - первые 3 байта содержат 22 бита, которые надо поменять, а 5-й байт содержит 0 или 1. Если 0, то нужно сбросить указанные биты, а если 1, то установить. Команда чтения должна вернуть в 3 байтах состояние светодиодов.
portctrl_IMG_8319sm.jpg

Светодиоды зажигаются/гаснут по команде с консольной программы, а также можно считать состояние светодиодов. Примеры:

1. Зажечь светодиод на порте P1 (выдать туда +5 вольт). На состояние остальных светодиодов команда не влияет. Последний, пятый байт в командной строке определяет, нужно зажечь (если он ==1) или погасить (если он ==0) светодиоды на портах, указанных в байтах с 1-го по 3-й (четвертый байт лишний, а также не используются биты 7 и 6 третьего байта):
hidtool write 0x01 0x00 0x00 0x00 0x01

2. Погасить светодиод на порте P1 (на состояние остальных светодиодов команда не влияет):
hidtool write 0x01 0x00 0x00 0x00 0x00

3. Установить лог. 1 на порте P10 (на состояние остальных портов и светодиодов команда не влияет):
hidtool write 0x00 0x02 0x00 0x00 0x01

4. Установить лог. 0 на порте P10 (на состояние остальных портов команда не влияет):
hidtool write 0x00 0x02 0x00 0x00 0x00

5. Записать во все порты P1..P22 лог. 0:
hidtool write 0xFF 0xFF 0x3F 0x00 0x00

6. Записать во все порты P1..P22 лог. 1:
hidtool write 0xFF 0xFF 0x3F 0x00 0x01

7. Прочитать статус портов:
hidtool read
0xff 0xff 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Статус портов P1..P22 находится в первых трех байтах (0xff 0xff 0x3f, то есть все порты в состоянии лог. 1).

Байты перемычек (fuse bits) ATmega16 должны быть 0xFF (low) и 0x09 (high). 

[Ссылки]

1. Макетная плата AVR-USB-MEGA16.
2. Firmware Сергея Кухтецкого, которое позволяет управлять ресурсами микроконтроллера (писать/читать регистры, порты и проч.) с помощью класса Visual C#. Весь алгоритм работы устройства USB можно перенести в ПО хоста, что упрощает программирование.
3. CDC-IO - управление ресурсами микроконтроллера через виртуальный COM-порт и простую консоль, т. е. не нужно не только писать firmware, но даже писать ПО хоста. Берете готовую любимую терминальную программу (SecureCRT, HyperTerminal, TerraTerm и проч.) - и управляете ножками (регистрами, таймерами, чем угодно) микроконтроллера.
3. Работа с USB для чайников на примере AVR-USB-MEGA16 site:vanoid.ru - программа на Delphi - управление портами макетной платы AVR-USB-MEGA16 (в макетную плату прошито firmware класса-обертки Сергея Кухтецкого).
4. 140120portctrl.zip - исходный код проекта portctrl и готовые скомпилированные прошивки на разные частоты кварца (см. папку hex внутри архива).

 

Комментарии  

 
0 #14 vs145 30.09.2010 12:57
lalinux, microsin, не могли бы Вы ещё раз выложить куда-нибудь "обернутую libusb в delphi". А если бы ещё проектик - то вообще бы было бы замечательно!

microsin: у меня, к сожалению, ничего для Delphi нет.
Цитировать
 
 
0 #13 lrstein 02.06.2010 23:06
Недавно вернулся к этому проекту (тензодатчик-АЦП -> ПК). Почитав примеры выбрал за основу прошивку и класс Сергея Кухтецкого, принял во внимание рекомендации по прерываниям.
Прошивку изменил, добавил прерывания по таймеру с усреднением данных в микроконтроллер е - частота дискретизации составила 1562 Гц, данные усредняются по 78 10-битных чисел и помещаются в буфер, который читает компьютер 20 раз в секунду. Компьютер радостно принимает данные и отображает их на графике. Помимо АЦП, используется также несколько выходов микроконтроллер а - один для запуска двигателя, второй для счетчика оборотов.

Напаял быстренько схемку USB на атмеге16, после отладки все заработало, система увидела устройство.
В общем, устройство работает как надо. ;-)
Спасибо большое вашему сайту и Сергею за информацию, без ваших пояснений и примеров ничего бы не получилось. :-)

microsin: интересная конструкция у Вас получилась. Было бы неплохо, если у себя на сайте или в блоге (а если нет таких, то хотя бы на Хабре) Вы опубликовали бы описание разработки.
Цитировать
 
 
0 #12 Hausauer 14.04.2010 14:20
Здравствуйте! наконец то решил собрать данную схему, и при проверке наткнулся на такую проблему: выход порта РВ0 (там где светодиод) никак не управляется, хотя остальные работают отлично. Возможно ли это связано с прошивкой контроллера, которая не дает возможность управлять ногой РВ0, или здесь другая проблема? И ещё, если в fuse деактивировать JTAG, возможно ли к управляемым портам подсоединить к управлению порты РС2-РС5, без изменения прошивки?

microsin: возможность управления портом PB0, как и любым другим (в том числе и портами PC2..PC5, задействованным и под JTAG) зависит только от программы firmware, прошитой в микроконтроллер . Смотрите в исходниках той программы, которую прошиваете - как настраиваются интересующие Вас порты, и управляйте состоянием портов соответственно Вашим нуждам.

Если Вы оставите фьюз JTAGEN незапрограммиро ванным, то ножки PC2..PC5 микроконтроллер а ATmega16 можете использовать как обычные порты ввода-вывода.
Цитировать
 
 
0 #11 lalinux 13.04.2010 07:34
вот обернул usblib в delphi если кому надо смотрите здесь:
http://depositfiles.com/files/r62i2babf

microsin: респект! Однако полностью Delphi-проект со всеми файлами не помешал бы.
Цитировать
 
 
0 #10 lstein 03.03.2010 15:37
Спасибо. Теперь все понятно. :-)

microsin: рад стараться! Надеюсь, что это не последний Ваш вопрос.
Цитировать
 
 
0 #9 lstein 03.03.2010 14:47
Спасибо за ответ.
Точная привязка по времени не нужна, главное чтобы данные шли на порт. Получается надо организовать прием потока байтов, заранее записанных в озу микроконтроллер а из АЦП(например 10-20 раз в секунду). Или средствами микроконтроллер а усреднять данные с АЦП, передавая потом только результат усреднения в ПК в таком же интервале. Последний вопрос - есть ли команды которые позволяют передавать данные сразу массивами или непрерывным потоком?

microsin: тогда Вы точно уложитесь. А команд никаких нет. Есть библиотека V-USB (для firmware), и есть библиотека libusb (для ПО хоста). В библиотеке V-USB есть примеры firmware, которые могут передавать данные в двух направлениях, и есть примеры ПО хоста, которые используют функции библиотеки libusb. Все просто - берете готовый пример, и организуете "поток данных" из буфера АЦП (можно кольцевого, например) путем передачи блоков фиксированного размера. В примерах есть передача за раз по 4 байта (см. пример avr-usb-russianexamples hid-custom-rq) и по 128 байт (см. пример avr-usb-russianexamples hid-data).
Цитировать
 
 
0 #8 lstein 03.03.2010 01:45
Необходимо сделать устройство для измерения усилия на тензодатчике. Процесс довольно быстрый и необходимо делать 500 - 1000 измерений в секунду. Встроенный в атмегу16 ацп позволяет работать на такой скорости. Но как я понял интерфейс не сможет передавать на такой скорости информацию в ПК?

microsin: все зависит от того, какой объем данных Вам нужно передавать. Библиотека V-USB может предоставить скорость low speed, что составляет 1.5 мегабит/сек. Если Вы забуферизируете данные с АЦП, или, что еще лучше - сделаете над ними статистическую обработку (свертку, чтобы уменьшить объем данных), то сможете уложиться в полосу. Простой расчет показывает - даже без свертки 1000 выборок/сек = 10битАЦП * 1000 = 0.01 мегабит/сек. С такой скоростью справится обычный low speed USB HID, т. е. V-USB подойдет. Проблема может возникнуть, если Вам нужно сделать ТОЧНУЮ привязку выборок к абсолютному времени - тут уже обработка протокола USB будет мешать (она работает по прерываниям с максимальным приоритетом). В этом случае присмотритесь к чипам с аппаратной поддержкой интерфейса USB, см. макетную плату AVR-USB162.
Цитировать
 
 
0 #7 Hausauer 25.02.2010 01:39
Ок. Только сейчас работы много, диплом писать нужно, а так в свободное время буду начинать макетную плату собирать и компонент писать.
Цитировать
 
 
0 #6 Hausauer 25.02.2010 00:43
Спасибо за информацию, а особенно за статью http://microsin.ru/content/view/812/44/!
P.S. Наверное буду писать компонент для Delphi, чтобы можно было легко обращаться и управлять контроллером.

microsin: очень интересная тема - буду рад, если поделитесь компонентом и примером программы с его использованием.
Цитировать
 
 
0 #5 Hausauer 24.02.2010 18:52
Вопрос такой:
1) Беру я, к примеру, тот же ATmega640 в файле pins.h я должен определить дополнительные переменные LED* которые будут соответствовать определенным битам порта контроллера, а также задать маску для других регистров. В файле portctrl.c также прописываем дополнительные регистры и в строке 233 изменяем переменную ledstate до требуемого количество битов (выходных светодиодов).
--> Поэтому если я задействую, к примеру, 10 полноценных регистров контроллера то посылать я должен уже не 4 байт, а 10 + 1 байт который бы определял режим работы светодиода? Поэтому не могли бы Вы сказать в каком месте кода, нужно сделать так чтобы теперь 11-й байт, посылаемый на контроллер, определял режим работы светодиодов (вкл или выкл)?
2) Возможно ли так сделать, чтобы ДИНАМИЧЕСКИ можно было назначать определённые порты как на выход, так и на вход (например, пересылкой управляющей команды hidtool setget), а затем уже считывать состояние портов (hidtool read)?

microsin:
1) наверное, Вы все правильно поняли. Конечно, нужно задать макроопределени я для всех используемых в программе портов микроконтроллер а (LEDxx) и маски для управления ими. Кроме того, нужно переписать процедуру LedControl в том виде, чтобы она была удобна для управления всеми Вашими портами. Сколько конкретно передавать байт данных - зависит только от метода кодирования в них информации о состояниях портов, это не имеет принципиально никакого значения. Делайте так, как Вам удобно. Можно даже выделить под один светодиод целый байт - кто нам мешает, если память это позволяет?
2) очень даже запросто. Все давно украдено до нас =). Почитайте статью Сергея Кухтецкого вот тут - http://microsin.net/programming/avr-working-with-usb/avr-usb-mega16-and-csharp-class.html (если коротко - прошивка позволяет напрямую управлять ресурсами - портами, регистрами - из программы на Visual C#), а также еще вот эту статью - http://microsin.net/programming/avr-working-with-usb/avr-cdc.html (см. CDC-IO - это примерно тоже самое, что и делает прошивка Сергея Кухтецкого, только управление ресурсами осуществляется через виртуальный COM-порт). Выбирайте, что Вам по вкусу - можно взять все готовенькое, а можно на основе этих примеров сделать что-то свое.
Цитировать
 

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


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

Top of Page