Avr і usb

У даній статті мова піде про такий досить популярному інтерфейсі як USB, точніше як використовувати цей інтерфейс USB на мікроконтролерах сімейства AVR. В інтернеті на цю тему багато інформації але більшість з неї представлено окремими фрагментами і не дає повну картину про те як використовувати цей інтерфейс на мікроконтролерах AVR.

Такі інтерфейси як COM, MIDI, LPT широко використовувалися свого часу, але зараз вони морально застаріли і все рідше і рідше зустрічаються в сучасних комп'ютерах в основному в комп'ютерах для промислового і вузькоспеціалізованого обладнання. Для зв'язку зібраного пристрою з комп'ютером можна використовувати всілякі перехідники конвертери і емулятори, але як показує практика вони породжують безліч проблем.

Для того щоб використовувати подружити USB і AVR можна піти 3-ма шляхами:

Використовувати апаратну поддрежки USB інтерфейсу, наприклад мікроконтролера AT90USB *. Для того щоб його використовувати потрібно написати для нього особливу прошивку. І якщо вашу збори пристрій не стандартного класу USB то доведеться для комп'ютера писати драйвер, який пояснить ПК з яким пристроєм маємо справу.

Використовувати конвертори USB в який-небудь інший інтерфейст (наприклад USB-UART на мікросхемі FTDI FT232RL). В якості інших інтерфейсів може виступати RS232, I2C або інші. При такому підході нам не потрібно замарачіваться і знати як працює інтерфейс USB, також потреба в драйвері для комп'ютера теж відпадає, так як драйвера для таких конверторів вже написані виробником.

Можна зробити все хитрішими взяти мікроконтролер AVR і написати для нього програму яка буде емулювати роботу USB. При такому підході виникають труднощі в реалізації великій швидкості передачі даних. Інтерфейс USB працює на великій швидкості яка може бути: LowSpeed ​​- 1,5 Mbit / s, FullSpeed ​​- 12 Mbit / s, HighSpeed ​​- 480 Mbit / s, а у інтерфейсу USB 3.0 швидкість може бути ще вище. Тому на мікроконтролерах AVR можна зробити пристрій тільки зі швидкістю LowSpeed. Для більшості саморобних пристроїв такої швидкості цілком достатньо.

Ми будемо використовувати способо програмної емуляції. В даний час вже є три готових проекту під мікроконтролери AVR для емуляції інтерфейсу USB.
  • USBtiny;
  • V-USB;
  • Igor Cesko.

Igor Cesko перший хто зробив такий проект, він був написаний на мові assembler.

Після з'явився проект V-USB який написаний на мові C з використанням ассемблерного коду Використовуючи V-USB був зроблений проект ІК приймача для комп'ютера.

USBtiny в свою чергу є проізволним від ранньої версії проекту V-USB. По можливості він поступається V-USB але зате гараздо простіше теоретично і відносно легкий в освоєнні.

Ми будемо використовувати проект V-USB

Avr і usb

У своїх USB експериментах, прошивку для мікроконтролерів писав на мові C в середовищі AVR-Studio 4 + WinAVR, програма для ПК була розроблена за допомогою середовища Borland C ++ Builder як найпростіший і хустрий варіант. Тому все наступні приклади будуть такими ж. Від правильного вибору інструментів залежить кількість головного болю на наступних кроках. З приводу того що краще C або Assembler можна говорити багато. Як на мене то потрібно володіти всіма інструментами, якимось більшою мірою якимось меншою і використовувати той або інший залежно від конкретної поставленої задачі.

Давайте спробуємо зібрати свій перший USB HID пристрій на мікроконтролері Atmega8 і навчимо його спілкуватися з комп'ютером за допомогою інтерфейсу USB. Може виникнути питання "чому саме HID пристрій". Відповідь самий простий-бо ми не хочемо замарачіваться, виносити собі мозок і писати всякі там драйвера під Windows. А коли ми подключаетм HID пристрій то операційна система сама вибирає і включає необхідний драйвер. Наша програма під комп'ютер не потребуватиме установки і настройки чого або вона відразу буде використовувати готовий алгоритм для роботи з HID пристроєм.

Для роботи нам знадобляться наступні програми:
  • Borland C ++ Builder 6 -середовище для розробки додаток під Windows на мові програмування C ++;
  • V-USB - програма під мікроконтролери AVR реалізує роботу low-speed USB 1.1, скачатьvusb.tar.gz;
  • WinAVR - набір для розробників AVR, сдесь нам потрібен буде GNU GCC компілятор, який автоматично інтегрується в студію;
  • AVR Studio - відмінне середовище для Разрабока програм під мікроконтролери AVR.

Схема підключення AVR до USB

Avr і usb

Мікроконтролер ATmega8 підключається за класичною 5-ти вольтової схемі живлення. Інші схеми можна подивитися в архіві V-USB в каталозі cirtuits. В інтерфейсі USB на лініях D + і D- рівень сигналу становить 3,3 В, а вся наша схема працює від напруги в 5 В. Тому потрібно узгодити рівні USB з нашої схемою, для цього встановлюються стабілітрони D1 і D2, які знижують сигнал з мікроконтролера на гасять резисторах R3 і R4 до необхідного рівня в 3,3 в необхідного стандарту. Для визначення версії протоколу використовується дільник напруги на резисторах R1 і R2 який створює на лінії D- рівень в 3,4 В в режимі холостого ходу. Якщо використовувати інший номінал резистора 1,5 кОм замість зазначеного R1 2,2 кОм, або якщо не встановити резистор R2 зовсім те замість 3,4 В вийде 3,7 У що призведе до відкривання стабілітрона D1 який зменшить його до напруги відкривання 3,4 В - 3,5 В. В результаті у нас вийде перекіс по току на холостому ходу (стабілітрон D2 вийде не навантажений зовсім, а по D1 вже буде текти струм) і це буде відбиватися на довгих проводах USB. Значення опорів R3 і R4 опреляются по току, в даній USB AVR схемою вони дорівнюють значенню в 68 Ом.

Ассесмблерная частина V-USB написана з підтримкою наступного ряду частот: 12 МГц, 12,8 МГц, 15 МГц, 16 МГц, 16.5 МГц, 18 МГц, 20 МГц. Інші частоти не підтримуються. Дана частота вручну ніде не прописується, вона визначається в конфігурації проект AVR Studio. Proget> Configuration Options> General (вкладка)> Frequency (поле). Частота вказується в Герцах, якщо не правильно виставити частоту то при компіляції спливе купа попереджень і програма так і не буде скомпелірованна. У студії Сществует змінна F_CPU яку використовує компілятор і вона доступна всім проектом, V-USB також використовує його. Для правильної роботи кварцу необхідно правильно виставити FUSE біти мікроконтролера.

Avr і usb

12 Мгц - частоіспользуемих частота для V-USB, вона є мінімальною частотою при якій можлива емуляція всіх необхідних таймингов специфікації USB;

15 МГц - близька до 12 МГц, місцями виставлені NOP-и. Використання такої частоти робить код дещо менше, це пов'язано з тим що велика частота дозволяє чаші використовувати цикли;

16 МГц - ця частота була додана для користувачів Arduino і інших плат які мають кварцовий резонатор на 16 МГц. Асемблерна реалізація даної частоти була напісна з деякими тонкощами які застосовують цикли уповільнення. Це відбувається тому що 16 МГц неможливо розділити без остачі на USB low speed bit clock;

12.8 МГц і 16,5 МГц - дані частоти призначені для тактирования від внутрішнього RC генератора, точність становить 1%.

18 МГц - така частота найбільш близька до стандартів USB. Використання такої частоти дозволяє проводити перевірку вхідних пакетів CRC прямо на льоту. Якщо пакети мають не вірну контрольну суму то вони отклоняются.ТАкже існує опція перевірки даних на цілісність на рівні програми.

20 МГц - для тих хто любить великі швидкості. Так як 20 МГц не ділиться без остачі на USB speed bit clock 1,5 Мгц. Те застосовуються цикли уповільнення як і при частоті 16 МГц.

Створення проекту в середовищі AVR Studio

Створюємо проект AVR GCC, назвемо його наприклад Hid_example_firmware. І почнемо писати нашу прошивку.

Avr і usb

Далі нам необхідно скопіювати всі файли з раніше скачав архіваvusb.tar.gz в каталог проекту. Далі додаємо в проект такі файли:
  • usbdrv.c;
  • oddebug.c;
  • usbdrvasm.s.

Для того щоб додати файлу потрібно вибрати в контекстному меню "Add existing Source File (s)"

Avr і usb

алгоритм роботи

Перед тим як почати писати програму для МК, необхідно розібратися з базовими принципами роботи. HID пристрій обмінюється з хотом даними, дані надходять блоками фіксованого розміру - або репорт. Їх структура описана в дискриптор HID, це дискриптор надає хосту при підключенні. Інізіалізацію прийому і передачу даних здійснює хост прогамма на комп'ютері. У разі якщо хост хоче послати дані пристрою то він спочатку посилає команду HID_SET_REPORT, при цьому V-USB викликає функцію usbFunctionRead ().

Лінія даних D + підключається до переривання INT0 так як це переривання з найвищим пріоритетом. В процесі обміну даних по USB, мікроконтролер постійно йде на обробку INT0, на якому якраз і підключений V-USB. І тільки після цього управління буде передано основній програмі. Якщо вам у вашому пристрої потрібно ще й обробляти свої переривання, то потрібно виставити глобальний прапор переривання використовуючи команду sei (), для того щоб змогло спрацювати INT0 з метою належного функціонування V-USB.

Така функція як usbPoll () повідомляє хосту що підключений пристрій ще знаходиться в живому стані і готове до роботи, цю функцію потрібно викликати не рідше ніж 50 ms. Якщо не виконувати цю умову то операційна система Windows напише наступне "Підключено невідомий пристрій"

Інтервал в 50ms - це USB timeout for accepting a Setup message- являє собою спеціальну команду хоста в нашому прикладі HID_SET_REPORT і HID_GET_REPORT.

Функція usbFunctionSetup () займається setup повідомленнями, тут відбувається обробка керуючих команд USB, далі відбувається запуск функції usbFunctionRead () або функції usbFunctionWrite ().

USB HID report description

Пояснюючи більш зрозумілими словами то це константи зібрані в масив і зашиті в Flash пам'ять пристрою, які необхідні і описують структуру пакетів даних (HID репортів). У ньому міститься інфорамація про кількість пакетів яке підтримує пристрій. Кожен біт і кожен байт в пакеті має своє призначення. Після того як пристрій підключається до комп'ютера, дескриптор повідомляє всі свої параметри, в свою чергу операційна система комп'ютера зрозуміє як слід спілкуватися з таким пристроєм, наприклад знатиме які біти відповідальністю за натискання тих чи інших кнопок джостика.

Змінюючи дескриптор можна представитися конкретним HID пристроєм, наприклад клавіатурою або чомусь ще. Цікаві приклади на цю тему: Маленька USB капость іThe Haunted USB Cable !. Багато інтресних прикладів знаходиться на сайті V-USB.

Як відбувається процес передачі даних

З метою передачі даних зробимо структуру, її використання зробить код зручніше і гнучкіше до переробок ніж просте використання масиву. Якщо потрібен масив то в його можна додати і використовувати всередині структури. У нашому дескрипторі є один вид репорт який має розмір 8 біт - REPORT_SIZE, його кількість дорівнює розміру переданої структури - REPORT_COUNT. Виходить що дані передаються порціями по 8 біт. За замовчуванням V-USB підтримує передачу і прийом розміром по 254 байта. Якщо нам потрібен розмір по більше тогла нам нужено в файлі usbconfig.h виставітьUSB_CFG_LONG_TRANSFERS в значення 1, тільки в цьому випадку збільшиться розмір самого драйвера.

Обробку вхідних і переданих даних всередині мікроконтролера беруть на себе дві функції:
  • usbFunctionRead (uncachar * data, unchar len);
  • usbFinctionWrite (uncachar * data, unchar len).

Для простоти структура даних заповнюється внтурі цих функцій, але так робити не обов'язково, заповнити їх можна в інших ділянках коду, в цьому випадку їх необхідно оголосити як volatile.

Такий парамет як * data є покажчик на буфер V-USB де проісхоід читання і запис даних які мають розмір len. Такий буффер даних має максимальний розмір в 1 байт типу uchar і дане значення дорівнює розміру нашого репорт. А розмір нашої структури имее рамер більше ніж 1 байт, саме з цієї причини процес передачі даних відбувається по частинах. Для цього існують змінні currentAddress і bytesRemaining в яких зберігається інформація про поточну передачу.

Виходить що ми оголосили покажчик з ім'ям uchar * buffer на певне місце в пам'яті де знаходиться (зберігається) наша структура. Передача здійснюється шматками uchar.

Avr і usb

Програма для мікроконтролера

Далі нам необхідно відкомпілювати програму і записати її в мікроконтролер. Якщо все налаштовано і зроблено правильно то після підключення мікроконтролера до USB, комп'ютер повинен визначити ваше прилади як HID.

Avr і usb

Avr і usb

Написання програми для комп'ютера

Avr і usb

Надається зручний і простий інтерфейс для роботи з HID. Корисний стати "спілкування з контролером по USB". На настройку проекту і передачу даних пішло досить багато часу, поки не натрапив на цю бібліотеку.

У коді нічого складного немає, є функція connect () вона необхідна для підключення пристрою, також обробники подій для відправки даних і для прийняття даних. Використовуючи ці кнопочки можна тепер блимати світлодіодами, включати і вимикати навантаження. Дані передаються за допомогою структури dataexchange_t, для мікроконтролера описана точно така ж структура.

Для того щоб написана нами прогрмма робота і на інших компбютерах де не встановлена ​​програма Borland C ++, нам потрібно перейти настройки проекту і там вимкнути використання динамічних бібліотек. Для цього потрібно виконати наступне: Project> Options. У вкладках Linker і Packages зняти галочки навпроти "Use dynamic RTL" і "Build with runtime packages.

Avr і usb