Управление микроконтроллером ATmega32 через интерфейс USB
Прежде всего LabVIEW - среда программирования, но отличается она от большинства других принципом написания кода программы. Программа в этой среде является графическим представлением взаимосвязанных блоков, выполняющих определённые функции. Такой подход значительно упрощает написание приложений, т. к. нет необходимости вникать в тонкости синтаксиса текстовых языков программирования. По основным функциональным возможностям (работа с файлами, реестром, получением, обработкой данных, передачей их по сети и т.д.) LabVIEW не уступает другим языкам.
Также среда разработки LabVIEW очень удобна для радиоинженеров и научных работников, потому что имеет в своем составе множество готовых инструментов (для создания ПИД-регуляторов, обработки звука, изображений и множества других приложений), да и в целом работа в LabVIEW для людей, не посвящённых в тонкости программирования, намного проще, чем в том же Delphi или Visual Studio.
Изучая управление микроконтроллерами по шине USB на основе библиотек V-USB и LibUSB, у меня возник вопрос – как управлять разрабатываемым USB-устройством из LabVIEW, и возможно ли это вообще?
Выяснилось, что в LabVIEW можно просмотреть все доступные функции libusb0.dll (основная DLL библиотеки LibUSB). Чтобы начать использовать функции библиотеки libusb, нужно научиться работать с типом данных handle в LabVIEW. Довольно простое решение нашлось на одном англоязычном форуме – оно заключалось в преобразовании handle в числовой тип, см. [1]. Читая статью [2] об управлении макетной платой из программы на Delphi, я подумал, что наверно можно сделать такую dll-ку в Delphi, которую потом использовать в LabVIEW для управления устройством USB. Эта DLL (назовем её V-USB-LabVIEW.dll) будет обращаться к libusb0.dll и управлять микроконтроллером ATmega32 по протоколу USB. Все манипуляции с handl-ами, PID, VID, адресами, байтами и т. д. будут происходить внутри V-USB-LabVIEW.dll. Получается следующая схема взаимодействия:
За основу для создания V-USB-LabVIEW.dll взял почти без изменений пример программы useport от Vanoid-а [2], и готовую прошивку для контроллера от Сергея Кухтецкого [3]. Скомпилированную DLL, её исходный код и пример программы LabVIEW можно скачать по ссылке [4]. Теперь коротко о содержимом исходного кода DLL. Работу программ испытывал на макетной плате AVR-USB-MEGA16, на которой установлен микроконтроллер ATmega32A (в память микроконтроллера через USB-бутлоадер была залита прошивка Сергея Кухтецкого).
В начале кода V-USB-LabVIEW.dll объявлены используемые константы, функции и процедуры из проекта useport: usbGetStringAscii, usbOpenDevice, SendUSBControlMessage. Они нужны, чтобы обратиться к нужному устройству USB. В процедуре SendUSBControlMessage объявлены также PID и VID устройства USB в виде строковых констант. Я добавил функцию PortX_Write, которая будет вызываться в LabVIEW. На примере обращения к порту PB0, к которому подключен светодиод на макетной плате AVR-USB-MEGA16, эта дополнительная функция в проекте DLL на Delphi выглядит так:
function PortX_Write (Address:integer;on_off:integer): integer; stdcall;
var data: array [0..2] of char; //AVR отправляет обратно max 3 байта
bit: byte;
begin
//Порт PB0 со светодиодом
if Address = 0 then
begin
//Читаем состояние ножек порта В
SendUSBControlMessage(USB2PC,RQ_IO_READ, 0, aPORTB, 0, data);
bit := bit0;
if on_off = 1 then
data[0]:=char(byte(data[0]) or bit)
else
data[0]:=char(byte(data[0]) and ($FF-bit));
SendUSBControlMessage(PC2USB, RQ_IO_WRITE,
byte(data[0]), aPORTB, 0, data);
end;
result := 1;
end;
…
// Далее идет экспорт функций dll для последующего
// использования в LabVIEW
exports PortX_Write;
…
Функция PortX_Write имеет два аргумента: первый Address – определяет порт, которым нужно управлять. Светодиод на макетной плате подключен к порту PB0, и для него используется адрес 0. Для всех остальных портов P1..P22 макетной платы (которые подключены к разрядам портов A, B, C, D микроконтроллера ATmega32) используются значения от 1 до 22 соответствуют портам макетки P1..P22). Второй аргумент on_off – состояние, в которое порт нужно перевести. Например, чтобы подать питание на светодиод (зажечь его), в параметре on_off нужно передать 1, и чтобы погасить светодиод, надо передать 0. В параметре Address соответственно должен быть 0 (адрес порта светодиода).
V-USB-LabVIEW.dll можно использовать в среде LabVIEW. Далее приведена последовательность создания программы в LabVIEW 2010 с пояснительными скриншотами. Сначала нужно создать новый виртуальный прибор (VI):
Перейдите в меню блок-диаграммы:
Здесь уже появились наши элементы Numeric (поле ввода адреса) и Boolean (положение тумблера):
Разместите узел для вызова функций dll. Для этого сделайте правый клик в пустом месте окна блок диаграммы => Connectivity=>Libraries & Executables => Call Library Function Node:
Двойным кликом по нему вызовите окно настроек вызова функций из dll. Сначала укажите путь к dll (таким же образом можно просмотреть все доступные функции libusb0.dll), выберите нужную нам функцию PortX_Write, параметр Calling convention установите в stdcall (WINAPI):
В этом же окне перейдите на вкладку Parameters:
Теперь, чтобы программа работала в зацикленном режиме, нужно ещё раз «обернуть» все наши блоки, но уже структурой While Loop:
Примерно так:
Кстати, это не единственный вариант USB-обмена с макеткой AVR-USB-MEGA16 в среде LabVIEW. Можно также записать в память чипа ATmega32A программу виртуального последовательного порта (класс USB CDC, virtual COM-port, см. [5]), с которым организовать обмен данными в среде LabVIEW довольно просто.
В будущем планирую добавить работу с АЦП и ШИМ, т. е. сделать более-менее универсальную dll для LabVIEW, которая позволит использовать все возможности очень удобной прошивки С. Кухтецкого [3]. Надеюсь, пользователям LabVIEW статья поможет с организацией подключения к системе собственных USB-устройств.
Все программы разрабатывались и тестировались в WinXP, Delphi 7, LabVIEW 2010.
Эксперименты с VISA
Разработчик LabVIEW, компания National Instruments для коммуникаций с «железом» предлагает специальную архитектуру VISA, см. [7]. VISA является стандартным программным интерфейсом приложения (API), осуществляющего ввод/вывод, и применяется для управления контрольно-измерительным оборудованием. VISA может управлять многими типами приборов (через интерфейсы VXI, GPIB, PXI, USB или COM-порты), вызывая соответствующие драйверы, которые зависят от типа используемого прибора.
Я пробовал применить VISA для управления портами микроконтроллера ATmega32A, установленного на макетной млате AVR-USB-MEGA16, однако пока не смог сделать firmware для микроконтроллера, которое в полной мере поддерживало бы стандарт VISA. Подсистема VISA после установки своих драйверов видит контроллер и даже получает с него информацию. Рассмотрим подробнее.
Если хотите попробовать обратиться к контроллеру через VISA, то необходимо, прежде всего, установить саму подсистему VISA. Если вы уже работали с AVR-USB-MEGA16 через libusb, то нужно в Диспетчере Устройств удалить имеющееся устройство USB. После экспериментов всё легко возвращается в исходное состояние. У меня устройство USB макетной платы AVR-USB-MEGA16 опознавалось как устройство USBasp, находящееся в ветке lib-usb-win32 devices:
Укажите интерфейс USB:
Выбирите наш контроллер по PID и VID. Напомню, что USB-устройство на прошивке Сергея Кухтецкого имеет VID 0x16C0 и PID 0x05DC (это бесплатные VID и PID, которые предоставляет библиотека V-USB в свободное использование):
Ссылка: http://youtu.be/3x9E_U9ZA-0
[Словарик]
V-USB популярная библиотека (с открытым исходным кодом) для микроконтроллеров AVR, которая позволяет организовать обмен данными по шине USB для микроконтроллеров, которые не имеют встроенного контроллера USB. Эта библиотека используется в firmware Сергея Кухтецкого для микроконтроллера ATmega32, см. [3].
LibUSB другая популярная библиотека (с открытым исходным кодом, кроссплатформенная), которая упрощает написание ПО хоста на компьютере. Часто используется для управления устройствами USB.
LabVIEW (Laboratory Virtual Instrument Engineering Workbench - среда разработки лабораторных виртуальных приборов) представляет собой многоплатформенную (Windows, MacOS, Linux, Solaris, HP-UX) среду графического программирования, которая широко используется в промышленности, образовании и научно-исследовательских лабораториях в качестве стандартного инструмента для сбора данных и управления приборами.
VISA стандартный программный интерфейс приложений (API), осуществляющий ввод/вывод в системе LabVIEW. Используется для программирования контрольно-измерительного оборудования, которое используется совместно с LabVIEW. VISA может управлять многими типами приборов (через интерфейсы VXI, GPIB, PXI, USB или COM-порты), вызывая соответствующие драйверы, которые зависят от типа используемого прибора.
LabVIEW Run-Time Engine бесплатный компонент, позволяющий запускать программы, созданные в среде LabVIEW, не устанавливая саму систему LabVIEW.
VI Virtual Instrument – виртуальный прибор. В терминологии LabVIEW это означает просто программу, которая выполняет какие-то функции.
[Ссылки]
1. LibUSB - passing device handle as integer - http://libusb.6.n5.nabble.com/Passing-device-handle-as-integer-td3218678.html
2. Работа с USB для чайников на Delphi http://www.vanoid.ru/avr/.
3. AVR-USB-MEGA16: быстрая разработка USB приложений на C# при помощи класса-обертки (автор Сергей Кухтецкий) http://microsin.ru/content/view/812/44/
4. V-USB-LabVIEW.dll, её исходный код, пример программы LabVIEW и другая документация http://depositfiles.com/files/8wzqaabgf .
5. USB консоль для управления радиолюбительскими приборами http://microsin.ru/content/view/1178/44/ .
6. Создание исполняемого exe файла из проекта LabVIEW http://zone.ni.com/reference/en-XX/help/371361G-01/lvhowto/building_a_stand_alone_app/
7. NI VISA http://sine.ni.com/psp/app/doc/p/id/psp-411/lang/en .
Автор Никишин В.