Компьютерные книги
Главное меню
Главная Поиск по сайту Добавить материал О нас Карта книг Карта сайта
Реклама
computersbooks.net -> Добавить материал -> Аппаратное обеспечение -> Агуров П.В. -> "Интерфейсы USB. Практика использования и программирования" -> 122

Интерфейсы USB. Практика использования и программирования - Агуров П.В.

Агуров П.В. Интерфейсы USB. Практика использования и программирования — БВХ-Петербург, 2004. — 576 c.
ISBN 5-94157-202-6
Скачать (прямая ссылка): interfeysusbpraktikaispolzovaniya2004.djvu
Предыдущая << 1 .. 116 117 118 119 120 121 < 122 > 123 124 125 126 127 128 .. 168 >> Следующая

производиться при получении запроса от хоста. Для
382
Часть IV. Создание USB-устройств
HID-устройств важно заполнить FIFO-буфер данными, соответствующими
структуре, декларированной в дескрипторе репорта (в дескрипторе конечной
точки описывается максимальное число байт передачи, а в дескрипторе
репорта - структура самих данных).
Листинг 13.
void main ()
{
/* основной цикл програыш */ for Iff) i
Fill EP1 FIFO();
/* обнаружено прерывание от конечной точки */ if
(Usb_endpoint_interrupt())
{
/* переключиться на 1 конечную точку */ Usbjselectjep(l); if
(Usb_tx_complete ()) {
Usb_clear_tx_complete() ; end_pointl_ready - FALSE;
)
)
)
} /* end for ;; */
void Fill_EPl_FIFO()
/* устройство не готово к передаче данных */ if ((usb_configuration_nb -
О) II (Usb_suspend())) return;
if (!end_j>ointl_ready) /* предыдущий пакет отправлен */ {
Usb_select_ep(l);
|
ередача данных через конечную точку
f.
Глава 13. HID-устройство на основе Atmel АТ89С5131
383
Usb_write_byte(0x01);
Usb_write_byte(0x02);
Usb_write_byte(pointljstate);
Usb_write_byte(0x04);
Usb_write_byte(0x05);
Usb_wri te_byte(0x06);
Usb_write_byte(0x07);
Usb_set_tx_ready();
pointl_state++; endjpointl_ready - TRUE; return;
)
)
Флаг end pointl ready позволяет заполнять буфер новыми данными только
после передачи предыдущего пакета. Переменная pointi_state является
простым счетчиком отправленных пакетов, введенная исключительно для того,
чтобы данные не были статическими и хоть немного менялись.
Важно понимать еще одну тонкость работы HID-устройства в случае
использования INPUT-репортов. Добавим в функцию передачи данных
переключение светодиодного индикатора, подключенного к контакту РЗ.З:
Usb_select_ep(1); if (Usb_tx_complete()){
Dsb_clear_tx_complete(); end_pointl_ready = FALSE;
P3.3-p_test; p_test=!p_test;
)
Подключив устройство, мы увидим, что обмен данными происходит постоянно,
хотя мы со стороны Windows никакие данные не запрашивали! Запустим USB
Monitor. Легко увидеть, что HID-драйвер Windows читает данные с
устройства каждый раз, когда устройство сообщает о появлении нового
пакета данных, т. е. каждый цикл программы. Что же произойдет, если
данных не будет? Добавим еще одну строку, позволяющую управлять
появлением новых пакетов: void Fill_EPl_FIFO()
I
/* устройство не готово х передаче данных */
384
Часть IV. Создание USB-устройств
if ((usb_configuration_nb - 0) И (Usb_suspend())) return; if (P3.2 - 0)
return;
}
Теперь, нажимая кнопку, соответствующую контакту Р3.2, мы будем прерывать
генерацию новых пакетов. Разумеется, при отсутствии новых пакетов HID-
драйвер не производит чтения данных с устройства, однако, как мы покажем
в следующем разделе, функция чтения данных ReadFile "зависает" до тех
пор, пока не сможет получить требуемый пакет.
Таким образом, при использовании INPUT-репортов предпочтительнее
генерировать пакеты данных всегда (еще лучше делать это не в цикле
программы, а по прерыванию), а при отсутствии новых данных либо посылать
предыдущие, либо специальным флагом отмечать, что данные отсутствуют (в
Windows ХР можно использовать другой механизм чтения данных, см. разд.
13.7).
Оптимальный вариант - выделение чтения данных в отдельный поток и
использование асинхронных функций (листинг 13.38)1.
шшшшшшшшттшшжятшшштжштт/тт/ттшшшштжтшжжшшшмжшж щистинг 13.38.
Использование асинКРбйного чтения
ReadOL : ТOverLapped; {структура для асинхронного чтения}
ReadFlag : Boolean;
HidHandle:= CreateFiie(PChar(0HidName[1]),
GENERIC_READ or GENERICJWRITE,
FILE_SHARE_READ or FILEJSHAREJWRITE, nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, // открыть для асинхронного доступа 0
);
// инициализация буфера
FillChar(InputReport, SizeOf(InputReport), #0);
1 Более подробно о создании потоков асинхронного чтения можно прочитать в
[1].
Глава 13. HID-устройство на основе Atmel АТ89С5131
385
II создание события для асинхронного чтения FillChar(ReadOL,
SizeOf(ReadOL), 0);
ReadOL.hEvent:= CreateEvent(nil, True, True, nil);
ReadFlag:= False;
// если не удалось прочитать сразу - операция еще длится,
// или произошла ошибка
If not ReadFile(HidHandle, InputReport,
Capabilities.InputReportByteLength, BytesRead, 0ReadOL) then begin //
если операция еще длится, то ждем If GetLastError() = ERROR_IO_PENDING
then begin // идем 2 сех, если не получилось, выходим
If WaitForSingleObject(ReadOL.hEvent, 2000) = WAIT_OBJECT_0 then
ReadFlag:= True;
End else begin lbLog.Items.Add(' Ошибка ReadFile');
End;
End else begin ReadFlag:" True; // прочитали данные сразу End;
// если данные прочитаны...
If ReadFlag then begin
End;
// Освободить дескрипторы CloseHandle(ReadOL.hEvent);
CloseHandle(HidHandle);
Программу чтения данных мы будем разбирать в разд. 13.6.
Использование FEATURE-репортов
Второй способ передачи данных, который мы рассмотрим, заключается в
использовании репортов типа feature. Репорты этого типа удобно
использовать, когда важно время доставки данных.
Предыдущая << 1 .. 116 117 118 119 120 121 < 122 > 123 124 125 126 127 128 .. 168 >> Следующая
Книги
Web-программирован-
ие
Аппаратное обеспечение Графика Руководство по П.О. Самоучитель Теория программирования Фотошоп Языки программирования
Новые книги
Вирт Н. "Систематическое программирование " (Теория программирования)

Эком "Microsoft Excel 2000 шаг за шагом Русская версия самоучитель " (Самоучитель)

Поляков А.Ю. "Методы и алгоритмы компьютерной графики в примерах Vizual C++" (Графика)

Баяковский Ю.М. "Графическая библиотека Open GL " (Графика)

Валиков А. "Технология " (Языки программирования)
Авторские права © 2013 ComputersBooks. Все права защищены.