LIB USBТы спросишь: а придется ли писать драйвер для операционной системы компьютера, чтобы подключить USB — устройство? Если использовать libusb, то можно обойтись без реализации полноценного модуля ядра. Libusb —это open source библиотека, которая позволяет быстро запрограммировать, во-первых, поиск устройства на шине, а во-вторых —обмен данными с ним.

Под Linux библиотеку и необходимые заголовочные файлы можно получить из исходных кодов. А лучше воспользоваться стандартным репозиторием твоего дистрибутива. Для Deblan/ Ubuntu, например, так:

$ sudo apt — get install libusb — dev

Существует также порт libusb под Windows —Iibusb — win32. Вопреки названию проекта, также поддерживаются 64 — битные ОС от Microsoft (начиная с версии 1.2.0.0).

Но libusb —это отдельная тема разговора. Думаю, с программированием для ПК ты знаком и сможешь в этом разобраться сам. Поэтому буду краток. Создаем файл usbtest.c и начинаем наполнять его контентом. Сначала необходимые заголовочные файлы и определения:

Sinclude <stdio.h>

//Для компьютера смысл команд обратный, //но обозначения остаются те же ftdefine DATAJXJT 1 ftdefine DATA

IN 2

Функция usbOpenDevice для инициализации устройства:

usb_init();.//. Инициализировать USB usb_find_busses(); // Найти шины usb_find_devices(); // Найти устройства // Перебрать все шины

for(bus=usb_get_busses(); bus; bus=bus ->next) (

//..Перебрать.все устройства на шине

for(dev=bus ->devices; dev; dev=dev ->next) (

…..// Если идентификаторы вендора и продукта.

……//..не совпадают.

if (dev — descriptor. idVendor ! = vendor 11 dev ->descriptor.idProduct != product)

……… continue; //…пропустить.эту…итерацию..

// Попробовать получить дескриптор устройства

…..if(!(handle = usb_open(dev))) (

fprintf(stderr, «%s\n», usb_strerror());

continue: __ _

)

return handle; // Вернуть дескриптор

// Устройство не найдено return NULL:

Как видно, параметрами usbOpenDevice выступают числовые идентификаторы производителя и устройства. В случае если устройство присутствует на шине, возвращается его дескриптор. Если устройств на V — USB будет несколько —придется дописать проверку символьных имен вендора и продукта.

И функция main консольной утилиты usbtest:

int main(.i.nt argc, char argv) ( // Дескриптор устройства usb_dev_handle handle = NULL;

…..int nBytes = 0;

char buffer[256];

// Ищем устройство

handle = usbOpenDevice(0xl6C0_

if(handle == NULL) (

0X05DC);

fprintf (stderrj «Could not find USB device! \n»); exit(l);

// Аргумент out — получить данные от чипа if(strcmp(argv[l], «out») == 0) (

nBytes = usb_control_msg(handle, ______……

USB_TYPE_VEND0R | USB_RECIPJ3EVICE |

PROTEUS ОТДЫХАЕТ

Всенародно любимый симулятор электрических схем Proteus ISIS бесполезен при разработке устройств с программной реализацией USB. Его эмулятор USB по дде рж и ва ет тол ько чипы с аппаратной поддержкой универсальной последовательной шины (например, AT90USB646 или АТ90 и ЗВ1286).

……USB_ENDPOINT_IN>……………………..___________________________

…..РАТА_ОиТл <д, 8, (char )buffer,…___

_______sizeof(buffer)л 5000)i

printf(«Got %d bytes: %5\л»л nBytes. buffer);

// Аргумент in — отправить строку _______

// ( с л еду]щи й___а р_ гу ме нт ) ____ ) else if(strcmptargvtlL 2) (____………._______………________

nBytes = usb_control_msg(handle,

USB_TYPE_VENDOR | USB_RECIP_DEVICE

USB ENDPOINT OUT.

«in»)

0 && argc >

X

DATA_IN, 0, 0, argv[2], strlen(argv[2])+l,….. 5000);……….._______

if (nBytes < 9) fprintf (stderr. «%s\n»,-> usb_strerror())j……

usb_close(handle); // Закрыть дескриптор

. return.3.1___________,________.—,.________, ____

Здесь правит бал функция usb_control_msg, которая объявлена во включаемом файле usb.h. Она имеет кучу параметров и собственно создает те управляющие сообщения, обработка которых реализована в прошивке микроконтроллера.

СОБИРАЕМ, ПРОШИВАЕМ, ТЕСТИРУЕМ

Ниже приведен небольшой, но очень полезный Makefile, с помощью которого командой make из main.с и usbtest.c легко получить прошивку для чипа —main.hex и бинарник утилиты usbtest:

СС..=.. avr — gcc…………………_________…………….._________________

OBJCOPY.= ayr — objcopy

CFLAGS = — Wall — Os — Iusbdrv — mmcu=attiny2313…..____________

OBJFLAGS = — j.text — j.data — 0 ihex

OBJECTS = usbdrv/usbdrv.o usbdrv/oddebug.o>__

usbdrv/usbdrvasm.o main.o……_______………………_____________________________

CMDLINE = usbtest

Цель: собрать, все____________

all: main.hex $(CMDLINE)

Сборка утилиты для компьютера__________________

$(CMDLINE): usbtest.c

…..gec — I./libusb/include — L./libusb/lib/gcc

— 0 — Wall usbtest.co usbtest — lusb

Очистить проект от бинарного кода

clean: _____., _______

$(RM).о.hex.elf usbdry/,.o.

Получение файла прошивки из elf — файла %.hex: %.elf

$(0BJC0PY) $(0BHFLACS) $< $@

.. С боpкa_elf — файл a……

main.elf: $(0BDECTS)

net@netty — $ sudo avrdude — p т.2313 — с usbtiny — U lfuse:w:Oxef :m

avrdude: AVR device initialized and ready to accept instructions

Reading ] | 100% 0.01s

avrdude: Device signature = 0xle910a avrdude: reading input file «Oxef» avrdude: writing Ifuse (1 bytes):

Writing I I 100% 0.00s

avrdude: 1 bytes of Ifuse written avrdude: verifying Ifuse memory against Oxef: avrdude: load data Ifuse data from input file Oxef: avrdude: input file Oxef contains 1 bytes avrdude: reading on — chip Ifuse data:

Reading | | 100% 0.00s

avrdude: verifying…

avrdude: 1 bytes of Ifuse verified

avrdude: safemode: Fuses OK

avrdude done. Thank you.

В avrdude фьюзы задаются не слишком наглядно, но их можно легко рассчитать в одном из online — калькуляторов.

Подключаем устройство к компьютеру и проверяем, как оно работает (usbtest с параметром out считывает строку, in —записывает указанную строку в буфер чипа):

sudo./usbtest in all_ok sudo./usbtest out

ЛОЖКА ДЕГТЯ

Софтовый USB не есть панацея. Программные

реализации обычно имеют ряд упрощений, таких как отсутствие проверки контрольной суммы и симметричности канала,что отрицательно сказывается на помехозащищенности. Также обычно софтовые библиотеки используют низкоскоростные режимы работы USB. Да и код USB — библиотеки «кушает» и без того небольшую память чипа.

ПОДГЛЯДЫВАЕМ…

На уровне логики протокол USB —это, по сути, многоуровневая пакетная передача данных. В этом нетрудно убедиться (а заодно узнать много интересного про USB), воспользовавшись анализатором сетевых протоколов Wireshark. Предварительно необходимо загрузить драйвер USB — монитора:

$ sudo modprobe usbmon

Теперь в списке интерфейсов Wireshark можно выбирать шины USB. Посмотреть номер шины устройства можно, например, в логах.

ЗАКЛЮЧЕНИЕ

Надеюсь, после того, как ты научился пересылать данные между компьютером и микроконтроллером AVR, твоя страсть к электронике разгорится с новой силой, породив немало оригинальных и полезных устройств. Остается лишь пожелать тебе успехов на этом сложном, но интересном поприще.