Практическое использование интерфейса USB в контроллерах PIC производства Microchip

Интерфейс USB приобретает все большую популярность как интерфейс связи периферийных устройств с ПК и современные компьютеры зачастую не имеют привычного интерфейса RS-232. Популярность USB обусловлена многими причинами, вот основные из них:

• высокая скорость обмена, высокая помехозащищенность
• управление потоком данных, контроль целостности и исправление ошибок
• возможность разветвления через хабы и подключения большого количества устройств.
• возможность получения питания от шины
• универсальность шины – возможность подключения разноплановых устройств (клавиатура, принтер, модем)
• автоматическая идентификация и конфигурирование системы, Plug and Play
Однако существуют (зачастую необоснованные) факторы, сдерживающие массовое использование USB разработчиками микроконтроллерных приборов:
• необходимость программирования драйверов для Windows
• сравнительно малая распространенность микроконтроллеров со встроенным интерфейсом USB

Этот цикл статей призван показать, что преодолеть эти трудности довольно легко и каждый может провести "апгрейд" своего устройства с привычного RS-232 на USB или создать новое устройство с USB интерфейсом.

В качестве микроконтроллера в примерах будет рассматриваться микроконтроллер производства компании Microchip PIC18F4550 с интерфейсом USB 2.0 (поддерживает Low Speed и Full Speed).

Урок #1. USB без программирования Windows, виртуальный COM порт

Одна из задач, возникающих при разработке USB устройств, это переход с интерфейса RS-232 на USB, при этом, если производится модификация "старого" прибора или устройство должно быть совместимо с существующими протоколами и программным обеспечением ПК, то желательно избавиться от любой модификации программного обеспечения на компьютере. Одним из решений данной задачи является использование интерфейса USB в качестве виртуального COM-порта. Применение данного метода исключает необходимость модификации ПО компьютера, т.к. USB соединение видится персональным компьютером как дополнительный COM-порт. Другое важное преимущество заключается в том, что используются стандартные драйвера Windows и не требуется создание какого-либо своего драйвера.
Спецификация USB описывает класс коммуникационных устройств (Communication Device Class – CDC), который определяет множество режимов соединений для телекоммуникационных (модемы, терминалы, телефоны) и сетевых устройств (Ethernet адаптеры и хабы, ADSL модемы), включая эмуляцию последовательного порта.

Возьмем в качестве примера устройство, которое через RS-232 передает данные о напряжении с потенциометра и температуре с цифрового датчика TC77, а так же принимает команды для включения/выключения двух светодиодов (данный пример для простоты реализуем на плате PICDEM™ FS USB DEMONSTRATION BOARD, но можно собрать и более простую схему – см.ниже).

Отладочная плата PICDEM FS-USB предназначена для разработок и демонстрации устройств на микроконтроллере PIC18F4550 с шиной USB2.0. На плате установлен контроллер PIC18F4550 в корпусе TQFP44, имеющий следующие особенности:
• Максимальная частота работы – 48 МГц (12 MIPS);
• 32 Кб Flash памяти программ (технология Enhanced Flash);
• 2 Кб памяти данных (из них 1 Кб двухпортового ОЗУ);
• 256 байт памяти данных
EEPROM;
• Интерфейс FS USB2.0 с поддержкой скорости работы 12 Мбит/с, со встроенным приемопередатчиком и стабилизатором напряжения.

На плате установлены:
• Кварц 20 МГц;
• Интерфейс
RS-232 для демонстрации возможности перехода с USART на USB;
• Разъем для внутрисхемного программирования и отладки
• Стабилизатор питающего напряжения с возможностью переключения на питание от шины
USB;
• Разъем расширения PICtail™;
• Температурный датчик TC77, подключенный по I2C;
• Переменный резистор, подключенный ко входу АЦП;
• Светодиоды, кнопки.

Фрагмент программы подготовки и передачи данных:

ReadPOT();   // Чтение данных с АЦП
output_buffer[0] = ADRESH;
output_buffer[1] = ADRESL;       
AcquireTemperature(); // Чтение температуры из сенсора
output_buffer[2] = MSB(temperature);
output_buffer[3] = LSB(temperature);
User_ProcessUSART(); // передача данных по RS-232

Прием данных и управление светодиодами:

if(PIR1bits.RCIF) {
PIR1bits.RCIF = 0;
input_buffer[1] = RCREG;
switch (input_buffer[1]) {
    case '1' : mLED_3_On(); break;
    case '2' : mLED_3_Off(); break;
    case '3' : mLED_4_On(); break;
    case '4' : mLED_4_Off(); break;
    default   : break;
}   
}

Для данного устройства есть программа для ПК для управления устройством и индикации значений напряжения и температуры. Итак, мы можем подключить устройство к RS-232, выбрать доступный в системе COM-порт и  установить скорость обмена с нашим устройством, число бит данных, количество стоповых бит, а так же параметры битов четности и управления потоком в соответствии с программой микроконтроллера (для этого мы должны знать параметры инициализации нашего контроллера)

Приступим к подключению нашего устройства к USB.
Компания Microchip Technology Inc. Предлагает готовый пример применения AN956, в котором реализована поддержка USB CDC для микроконтроллера PIC18F2550, PIC18F2455, PIC18F4455, PIC18F4550. Программа построена по модульному принципу, что позволяет легкую модернизацию и интегрированию в готовые проекты.
После начальной инициализации контроллера программа может общаться с ПК через интерфейс USB посредством нескольких готовых функций:

Функция

Описание

putrsUSBUSART

запись стринга заканчивающегося на ноль из памяти программ в USB

putsUSBUSART

запись стринга заканчивающегося на ноль из памяти данных в USB

mUSBUSARTTxRom

запись стринга известной длины из памяти программ в USB

mUSBUSARTTxRam

запись стринга известной длины из памяти данных в USB

mUSBUSARTIsTxTrfReady

проверка готовности драйвера принять данные для записи в USB

getsUSBUSART

чтение стринга из USB

mCDCGetRxLength

чтение длинны последнего пакета принятого из USB

Модифицируем нашу программу для передачи и приема данных через USB.

Фрагмент программы подготовки и передачи данных:

ReadPOT();   // Чтение данных с АЦП
output_buffer[0] = ADRESH;
output_buffer[1] = ADRESL;       
AcquireTemperature(); // Чтение температуры из сенсора
output_buffer[2] = MSB(temperature);
output_buffer[3] = LSB(temperature);
if(mUSBUSARTIsTxTrfReady()) { // Если USB свободен, то передать данные
     mUSBUSARTTxRam((byte*)output_buffer,4);
}

Прием данных:

if(getsUSBUSART(input_buffer,1)) {
  switch (input_buffer[0]) {
    case '1' : mLED_3_On(); break;
    case '2' : mLED_3_Off(); break;
    case '3' : mLED_4_On(); break;
    case '4' : mLED_4_Off(); break;
    default   : break;
  }    
}

После подключения устройства к USB система опознает новое устройство

И устанавливает новое оборудование

Выбираем установку с указанного места и указываем путь расположения файла mcpusb.inf из комплекта исходных кодов программы к AN956. После этого производится установка нового устройства в систему.

Итак, новое устройство готово к работе. В системе появился новый виртуальный COM порт.

Теперь в нашей программе мы можем выбрать появившийся виртуальный COM порт для общения с устройством …

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

Окно программы PICDEM CDC

При использовании микроконтроллеров PIC18Fxx5x со встроенным модулем USB 2.0 виртуальный COM порт может обеспечить скорость передачи данных до 80Кбайт в секунду (640Кбит/сек), что существенно превышает возможную скорость передачи через RS-232, при этом, как мы видим, переделки ПО для компьютера не потребовалось!

Примеры программ, документация и схема, использованные в уроке #1.
1. Программа PICDEM CDC + исходные коды для Delphi скачать
2. Компонент Delphi для работы с COM портом скачать  
3. AN956 + оригинальные исходные коды (3.6 Mb)
4. Файл user_uart.c (все изменения оригинальной программы из AN956 производились только в этом файле. Для запуска примера к урок #1, необходимо скопировать этот файл в каталог C:\MCHPFSUSB\fw\Cdc\user\, заменить в проекте файл user.c на user_uart.c,  скомпилировать проект и прошить микроконтроллер)
5. Упрощенная схема USB устройства

Примечание: в оригинальной схеме платы PICDEM FS USB используется автоматическое определение источника питания платы (внешний источник или USB). Поэтому при использовании упрощенной схемы необходимо закоментарить строку #define USE_USB_BUSSENSE_IO в файле usbcfg.h

Урок #2. Создание USB 2.0 совместимого HID-устройства типа джойстик.

Наиболее распространенными USB устройствами являются устройства интерфейса с человеком (HID – Human Interface Devices). Типичными представителями этого класса являются USB- клавиатуры, мыши, джойстики, панели настройки мониторов, считыватели штрих-кодов, карт-ридеры и т.п. Преимуществами HID устройств является:
- простота реализации;
- компактный код;
- поддержка Windows (не нужны дополнительные драйвера).

На сайте компании Microchip есть пример реализации HID манипулятора мышь. Рассмотрим реализацию простейшего игрового манипулятора на основе этого примера. Для этого проекта будем использовать демонстрационную плату PICDEM FS-USB (DM163025). Отладочная плата PICDEM FS-USB имеет один переменный резистор и 2 кнопки, поэтому разрабатываемый джойстик будет иметь минимум элементов управления (2 кнопки и, например, регулятор газа).

В первую очередь нам нужно переписать дескриптор устройства под создаваемый джойстик. Для упрощения задачи можно воспользоваться программой HID Descriptor Tool, которую можно скачать с сайта www.usb.org
В комплекте с программой предоставляются примеры конфигураций некоторых HID-устройств, которые можно корректировать под свою задачу или создавать собственное HID устройство.

Итак, в нашем случае будут использоваться несколько типов данных – это симуляция органа управления – Simulation Controls, а конкретно это ручка (педаль) газа (Throttle) и кнопки управления (Button). Для того чтобы операционная система «знала» как обращаться с этими типами данных, необходимо описать максимальные и минимальные значения и размер данных. В нашем случае «газ» это одно 8-и битное значение (report_size = 8, report_count = 1), а состояние кнопок определяется как поле однобитных значений. В примере используется только 2 кнопки, но необходимо выровнять поле до байтовой величины (report_size = 1, report_count = 8). Итого микроконтроллер при запросе данных от компьютера должен передать 2 байта – уровень газа и состояние кнопок в соответствии с сформированным дескриптором устройства (подробное описание возможных дескрипторов см. в спецификации на устройства HID www.usb.org). Созданное описание дескриптора устройства можно сохранить в разных форматах, в том числе и как заголовочный файл .h

Дополнительно нужно скорректировать в описании HID Class-Specific Descriptor размер полученного дескриптора устройства и в дескрипторе конечной точки изменить размер данных, передаваемых через конечную точку (в нашем случае передаем 2 байта, поэтому размер HID_INT_IN_EP_SIZE=2).

Перечисленных изменений хватит для того чтобы Windows опознала подключенное устройство как джойстик. Теперь можем скорректировать строковые данные, чтобы устройство имело то название, какое мы хотим (например «PIC18F4550 Joystick»). Для того чтобы присвоить устройству имя на русском языке необходимо прописывать строковый дескриптор в кодировке UNICODE.

На этом описание джойстика заканчивается и нужно подготовить данные для передачи в PC.

ReadPOT(); // запуск измерения напряжения потенциометра
buffer[0] = ADRESH;
// обработка состояний кнопок
if(sw2==0) buffer[1] |= 0x01;
else buffer[1] &= ~0x01;
if(sw3==0) buffer[1] |= 0x02;
else buffer[1] &= ~0x02;
// передача данных
Emulate_Joystick();

После компиляции проекта и программирования микроконтроллера можно подключить устройство к USB-порту. Плата определяется как HID игровое устройство, инсталлируется в систему и готово к работе.

Через панель управления в Windows мы можем открыть доступные игровые устройства, выбрать наш джойстик, откалибровать его и проверить функциональность.

При изменении конфигурации устройства – добавлении органов управления или кнопок, необходимо не только изменить описание дескриптора устройства, но и передавать данные строго в соответствии с созданным дескриптором. Так изменив в описании дескриптора устройства USAGE_MAXIMUM (BUTTON 2) максимальное число кнопок с 2 на 8, получим джойстик на 8 кнопок.

При усложнении дескриптора можем получить и более полную реализацию джойстика, при этом нужно не забыть изменять следующие параметры: размер дескриптора, размер конечной точки и необходимо оправлять столько информационных данных, сколько объявлено в дескрипторе.

 

Примеры программ, документация и схема, использованные в уроке #2.
1. Оригинальные исходные коды реализации HID-мыши.
2. Исходные коды реализации HID-джойстика.

Опыты с программатором PICkit2.

 

Компания Microchip Technology Inc. выпускает недорогой программатор разработчика PICkit2, который в первую очередь используется для программирования Flash-контроллеров. Отличительной особенностью этого программатора является доступность полной документации и исходных кодов прошивки для микроконтроллера, и программы оболочки для компьютера.

PICkit2 получает питание от USB, формирует регулируемые напряжения программирования и питания, а так же имеет 3 линии входа-выхода для подключения к программируемому устройству. Для возможности обновления прошивки программатора в PICkit2 реализована программа бутлоадер.

 

Используя все эти особенности, на основе программатора PICkit2 возможно создание и отладка своего USB-устройства с возможностью в любой момент откатиться назад к его функциям программатора. С помощью бутлоадера, который прошит в программатор, в PICkit2 можно прошить другие программы, например, программу поддержки виртуального COM-порта. Для этого берем пример CDC, переименовываем проект и делаем следующее

1. в файле main.c меняем адрес расположения прошивки (бутлоадер PICkit2 передает управление пользовательской программе на адрес 0х002000.

#pragma code _RESET_INTERRUPT_VECTOR = 0x002000

2. в io_cfg.h убираем все про порт D (можно задать мигание светодиода на PORTC0).

Так как PICKIT2 всегда питается от USB, то задаем

#define usb_bus_sense 1 // device is always plugged in

#define self_power 0 // device is powered from USB

3. в usbcfg.h ставим комментарии на 2 строки

//#define USE_SELF_POWER_SENSE_IO //#define USE_USB_BUS_SENSE_IO

4. В файле user.c выводим в USB нужные нам данные

5. подключаем файл линкера pickit2.lkr

После этого можно откомпилировать проект и через оболочку PICkit2 загрузить новую прошивку.

После перепрограммирования PICkit2, РС определяет появление нового COM-порта, и через гипертерминал можем увидеть что PICkit2 отсылает данные через виртуальный COM-порт.

Для обратного восстановления PICkit2 как программатора нужно отключить PICkit2 от USB и при нажатой кнопке снова подключить USB, после чего выбрать загрузку штатной прошивки программатора.

Исходные коды данного примера доступны по ссылке.

На основе данного примера и используя внешние выводы программатора PICkit2 можно получать данные с внешних устройств и передавать в компьютер через USB. Таким образом, используя PICkit2 можно сделать вывод данных на COG ЖК-индикаторы, считыватели I2C, SPI и 1-wire устройств, например датчиков температуры и др. устройств.

 

Радио HID клавиатура на основе PICkit2.

Рассмотрим еще один пример «нецелевого» использования программатора PICkit2 – эмулятор клавиатуры с радиоинтерфейсом. Такое устройство может использоваться, например, для проведения презентаций – для перелистывания слайдов вдали от компьютера.

Для реализации такого устройства нам понадобятся:

- PICkit2

- демо-плата из комплекта PICkit2 (DV164120)

- радиоприемник (rfRXD0420) и радиопередатчик (rfPIC12F675) из комплекта rfPICkit

К демо-плате подключаем радиоприемник. Микроконтроллер на плате будет принимать данные с приемника, обрабатывать их и, при определении нажатия одной из двух кнопок на радиобрелке, выставлять уровень лог.1 на одном из 2-х выводов подключенных к PICkit2.

PICkit2 будет выполнять следующие функции:

- при подключении к компьютеру через USB определяться как HID-клавиатура

- формировать напряжение питания +5В для демо-платы с приемником

- опрашивать 2 внешних вывода контроллера приемника и при наличии лог. 1 отсылать в компьютер коды нажатия кнопок PageUp или PageDown.

 

 

Два виртуальнык COM-порта (Эмуляция микросхемы FTDI2232) на базе PICKit2. Этот пример предназначен только для изучения работы USB. Изучите требование лицензии на драйвер FTDI перед использованием! 

Пример показывает как на базе микроконтроллера с USB портом сделать 2 виртуальных COM-порта.Для начало нужно установить драйвера для микросхемы FTDI2232. Затем для загрузки в PICkit2 нужно в оболочке PICkit2 выбрать пункт обновления прошивки и указать на файл TestVCP2.hex из архива. После перепрограммирования PICkit2 у вас в системе появятся 2 независимых последовательных COM порта.
Пример взят с сайта http://forum.microchip.com/tm.aspx?m=261649
Для обратного восстановления PICkit2 как программатора нужно отключить PICkit2 от USB и при нажатой кнопке снова подключить кабель USB, после чего выбрать загрузку штатной прошивки программатора.

 

 Все приведенные выше примеры основаны на MCHPFSUSB Framework v1.3. С появлением контроллеров PIC24 и PIC32 с USB OTG, компания Microchip выпустила новую версию стека - USB stack v. 2.х.
В новой версии USB stack v. 2.3, помимо стеков USB device, реализующего функциональность USB-клиента, USB Embedded host, реализующего функциональность хоста, также добывлен стек USB dual role, реализующий функции и хоста, и клиента; и USB OTG, поддерживающий протокол согласования роли хоста (HNP), протокол запроса сеанса (SRP), и полностью соответствующий спецификации USB OTG. В примерах применения реализовано: 
Embedded Host 
- Printer Class host – поддержка ESC/POS, PostScript® и PCL5 принтеров
- CDC Class host – поддержка устройств ACM (abstract control model)
- HID Клавиатура 
Device
- HID bootloader – добавлена поддержка семейств PIC32MX460F512L и PIC18F14K50
- HID клавиатура, мышка 
- MSD internal flash demo – использование внутренней flash для хранения файлов
- MSD + HID composite example - пример составного устройства MSD и HID 
- CDC - эмуляция COM-порта 
- поддержка семейства PIC32MX460F512L для всех демонстрационных проектов 
ПК 
- примеры HID, MCHPUSB и WinUSB теперь поддерживают функцию Microsoft Plug-and-Play (PnP) для автоопределения. 
Документация
- полное описание всех API расположено в папке “<установочная директория>\Microchip\Help”

Microchip бесплатно предоставляет драйвера наиболее востребованных USB-классов: 
1 Интерфейс пользователя (HID). Этот режим обмена используется практически во всех клавиатурах, «мышках» и прочих устройствах ввода/вывода 
2. Коммуникационное устройство (CDC). Этот режим наиболее простой для перехода с последовательного интерфейса RS-232 на USB. На компьютерах с WinXP/2K производиться создание и эмуляция виртуального COM-порта при подключении микроконтроллера. Программы, работающие с портами COM1.. 4 будут работать без изменений и с виртуальным портом, но с большей скоростью (порядка 1 Мбит/с) 
3. Устройства массового хранения (MSD). Это устройства, работающие как накопители информации - флешки, SD/MMC-карты, диски и прочее 
4. Устройства класса «принтер» (Printer Class). Этот режим создан для использования USB-принтеров, что позволяет конечному устройству на PIC-микроконтроллере с модулем USB выводить необходимую информацию непосредственно на USB-принтер 
5. Резидентный загрузчик Microchip. Простейший режим, который используется только для обновления по USB программного обеспечения микроконтроллера. Со стороны ПК устанавливается небольшая программа, аналог драйвера 
6. Собственный драйвер (Custom). Наиболее полное использование ресурсов USB2.0 для продвинутых пользователей: возможность выбора режимов работы шины (изохронный, по прерываниям, объемный, управления), высокая скорость передачи. Требует глубоких знаний работы шины и навыки разработки ПО под Windows

Бутлоадер с USB Flash Drive. Обновление прошивки с обычного флэш диска.

Для обновления прошивки микроконтроллера с модулем USB-OTG (PIC24F или PIC32) не обязательно использовать специальное программное обеспечение. Наличие Host-режима позволяет подключать к микроконтроллеру обычные USB-накопители данных (Flash Drive). На сайте Microchip опубликован пример (бета версия), позволяющий обновить программное обеспечение микроконтроллера из подключенного USB-диска.
Для запуска примера вам нужно загрузить прошивку бутлоадера в плату PIC32 USB Board или Explorer 16 (c установленным процессорным модулем PIM PIC32 USB и дочерней платой USB PICtail Plus Daughter Board). Если подать питание на плату при нажатой кнопке, то контроллер перейдет в режим обновления прошивки. Если теперь подключить Flash накопитель с записанным файлом обновления прошивки, то микроконтроллер считает этот файл и перепишет в свою память программ.

 

 

Продолжение следует …