.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; } /* ------------------------------------------------------------------------- */
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д