.NET 4.x Подключение устройства через USB - C#
Формулировка задачи:
Всем доброго времени суток.
Имеется задачка: к ПК подключается устройство по USB, сказали что комп будет видеть это устройство как Virtual Port.
Мне это честно говоря ни о чем не говорит, поэтому подскажите пожалуйста где и что почитать или может есть какие то готовые решения: нужно будет отправлять команды на это устройство, а так же получать некоторые данные (в режиме реального времени постоянно будут идти какие-то данные), которые потом я уже буду отображать на форме.
Заранее спасибо.
Решение задачи: «.NET 4.x Подключение устройства через USB»
textual
Листинг программы
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include <avr/pgmspace.h> /* нужно для usbdrv.h */
- #include "usbdrv.h"
- struct dataexchange_t // Описание структуры для передачи данных
- {
- uchar b1; // Я решил для примера написать структуру на 3 байта.
- uchar b2; // На каждый байт подцепим ногу из PORTB. Конечно это
- uchar b3; // не рационально (всего то 3 бита нужно).
- }; // Но в целях демонстрации в самый раз.
- // Для наглядности прикрутить по светодиоду и созерцать :)
- struct dataexchange_t pdata = {0, 0, 0};
- PROGMEM char usbHidReportDescriptor[22] = { // USB report descriptor // Дескриптор описывает структуру пакета данных для обмена
- 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x01, // USAGE (Vendor Usage 1)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x15, 0x00, // LOGICAL_MINIMUM (0) // min. значение для данных
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) // max. значение для данных, 255 тут не случайно, а чтобы уложиться в 1 байт
- 0x75, 0x08, // REPORT_SIZE (8) // информация передается порциями, это размер одного "репорта" 8 бит
- 0x95, sizeof(struct dataexchange_t), // REPORT_COUNT // количество порций (у нашем примере = 3, описанная выше структура передастся за три репорта)
- 0x09, 0x00, // USAGE (Undefined)
- 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
- 0xc0 // END_COLLECTION
- };
- /* Здесь мы описали только один report, из-за чего не нужно использовать report-ID (он должен быть первым байтом).
- * С его помощью передадим 3 байта данных (размер одного REPORT_SIZE = 8 бит = 1 байт, их количество REPORT_COUNT = 3).
- */
- /* Эти переменные хранят статус текущей передачи */
- static uchar currentAddress;
- static uchar bytesRemaining;
- /* usbFunctionRead() вызывается когда хост запрашивает порцию данных от устройства
- * Для дополнительной информации см. документацию в usbdrv.h
- */
- uchar usbFunctionRead(uchar *data, uchar len)
- {
- if(len > bytesRemaining)
- len = bytesRemaining;
- uchar *buffer = (uchar*)&pdata;
- if(!currentAddress) // Ни один кусок данных еще не прочитан.
- { // Заполним структуру для передачи
- if ( PINB & _BV(1) )
- pdata.b1 = 1;
- else
- pdata.b1 = 0;
- if ( PINB & _BV(2) )
- pdata.b2 = 1;
- else
- pdata.b2 = 0;
- if ( PINB & _BV(3) )
- pdata.b3 = 1;
- else
- pdata.b3 = 0;
- }
- uchar j;
- for(j=0; j<len; j++)
- data[j] = buffer[j+currentAddress];
- currentAddress += len;
- bytesRemaining -= len;
- return len;
- }
- /* usbFunctionWrite() вызывается когда хост отправляет порцию данных к устройству
- * Для дополнительной информации см. документацию в usbdrv.h
- */
- uchar usbFunctionWrite(uchar *data, uchar len)
- {
- if(bytesRemaining == 0)
- return 1; /* конец передачи */
- if(len > bytesRemaining)
- len = bytesRemaining;
- uchar *buffer = (uchar*)&pdata;
- uchar j;
- for(j=0; j<len; j++)
- buffer[j+currentAddress] = data[j];
- currentAddress += len;
- bytesRemaining -= len;
- if(bytesRemaining == 0) // Все данные получены
- { // Выставим значения на PORTB
- if ( pdata.b1 )
- PORTB |= _BV(1);
- else
- PORTB &= ~_BV(1);
- if ( pdata.b2 )
- PORTB |= _BV(2);
- else
- PORTB &= ~_BV(2);
- if ( pdata.b3 )
- PORTB |= _BV(3);
- else
- PORTB &= ~_BV(3);
- }
- return bytesRemaining == 0; /* 0 означает, что есть еще данные */
- }
- /* ------------------------------------------------------------------------- */
- usbMsgLen_t usbFunctionSetup(uchar data[8])
- {
- usbRequest_t *rq = (void *)data;
- if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID устройство */
- if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
- // у нас только одна разновидность репорта, можем игнорировать report-ID
- bytesRemaining = sizeof(struct dataexchange_t);
- currentAddress = 0;
- return USB_NO_MSG; // используем usbFunctionRead() для отправки данных хосту
- }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
- // у нас только одна разновидность репорта, можем игнорировать report-ID
- bytesRemaining = sizeof(struct dataexchange_t);
- currentAddress = 0;
- return USB_NO_MSG; // используем usbFunctionWrite() для получения данных от хоста
- }
- }else{
- /* остальные запросы мы просто игнорируем */
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
- int main(void)
- {
- DDRB = 0b00001110; // PB1,PB2,PB3 - выход
- usbInit();
- usbDeviceDisconnect(); // принудительно отключаемся от хоста, так делать можно только при выключенных прерываниях!
- uchar i = 0;
- while(--i){ // пауза > 250 ms
- _delay_ms(1);
- }
- usbDeviceConnect(); // подключаемся
- sei(); // разрешаем прерывания
- for(;;){ // главный цикл программы
- usbPoll(); // эту функцию надо регулярно вызывать с главного цикла, максимальная задержка между вызовами - 50 ms
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д