Устройство, которое может зажигать светодиоды, подключенные к портам 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 байтах состояние светодиодов.
Светодиоды зажигаются/гаснут по команде с консольной программы, а также можно считать состояние светодиодов. Примеры:
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 внутри архива). |
Комментарии
microsin: у меня, к сожалению, ничего для Delphi нет.
Прошивку изменил, добавил прерывания по таймеру с усреднением данных в микроконтроллер е - частота дискретизации составила 1562 Гц, данные усредняются по 78 10-битных чисел и помещаются в буфер, который читает компьютер 20 раз в секунду. Компьютер радостно принимает данные и отображает их на графике. Помимо АЦП, используется также несколько выходов микроконтроллер а - один для запуска двигателя, второй для счетчика оборотов.
Напаял быстренько схемку USB на атмеге16, после отладки все заработало, система увидела устройство.
В общем, устройство работает как надо.
Спасибо большое вашему сайту и Сергею за информацию, без ваших пояснений и примеров ничего бы не получилось.
microsin: интересная конструкция у Вас получилась. Было бы неплохо, если у себя на сайте или в блоге (а если нет таких, то хотя бы на Хабре) Вы опубликовали бы описание разработки.
microsin: возможность управления портом PB0, как и любым другим (в том числе и портами PC2..PC5, задействованным и под JTAG) зависит только от программы firmware, прошитой в микроконтроллер . Смотрите в исходниках той программы, которую прошиваете - как настраиваются интересующие Вас порты, и управляйте состоянием портов соответственно Вашим нуждам.
Если Вы оставите фьюз JTAGEN незапрограммиро ванным, то ножки PC2..PC5 микроконтроллер а ATmega16 можете использовать как обычные порты ввода-вывода.
http://depositfiles.com/files/r62i2babf
microsin: респект! Однако полностью Delphi-проект со всеми файлами не помешал бы.
Точная привязка по времени не нужна, главное чтобы данные шли на порт. Получается надо организовать прием потока байтов, заранее записанных в озу микроконтроллер а из АЦП(например 10-20 раз в секунду). Или средствами микроконтроллер а усреднять данные с АЦП, передавая потом только результат усреднения в ПК в таком же интервале. Последний вопрос - есть ли команды которые позволяют передавать данные сразу массивами или непрерывным потоком?
microsin: тогда Вы точно уложитесь. А команд никаких нет. Есть библиотека V-USB (для firmware), и есть библиотека libusb (для ПО хоста). В библиотеке V-USB есть примеры firmware, которые могут передавать данные в двух направлениях, и есть примеры ПО хоста, которые используют функции библиотеки libusb. Все просто - берете готовый пример, и организуете "поток данных" из буфера АЦП (можно кольцевого, например) путем передачи блоков фиксированного размера. В примерах есть передача за раз по 4 байта (см. пример avr-usb-russianexamples hid-custom-rq) и по 128 байт (см. пример avr-usb-russianexamples hid-data).
microsin: все зависит от того, какой объем данных Вам нужно передавать. Библиотека V-USB может предоставить скорость low speed, что составляет 1.5 мегабит/сек. Если Вы забуферизируете данные с АЦП, или, что еще лучше - сделаете над ними статистическую обработку (свертку, чтобы уменьшить объем данных), то сможете уложиться в полосу. Простой расчет показывает - даже без свертки 1000 выборок/сек = 10битАЦП * 1000 = 0.01 мегабит/сек. С такой скоростью справится обычный low speed USB HID, т. е. V-USB подойдет. Проблема может возникнуть, если Вам нужно сделать ТОЧНУЮ привязку выборок к абсолютному времени - тут уже обработка протокола USB будет мешать (она работает по прерываниям с максимальным приоритетом). В этом случае присмотритесь к чипам с аппаратной поддержкой интерфейса USB, см. макетную плату AVR-USB162.
P.S. Наверное буду писать компонент для Delphi, чтобы можно было легко обращаться и управлять контроллером.
microsin: очень интересная тема - буду рад, если поделитесь компонентом и примером программы с его использованием.
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-порт). Выбирайте, что Вам по вкусу - можно взять все готовенькое, а можно на основе этих примеров сделать что-то свое.
microsin: да, можете.
RSS лента комментариев этой записи