.NET 4.x Подключение устройства через USB - C#

Узнай цену своей работы

Формулировка задачи:

Всем доброго времени суток. Имеется задачка: к ПК подключается устройство по USB, сказали что комп будет видеть это устройство как Virtual Port. Мне это честно говоря ни о чем не говорит, поэтому подскажите пожалуйста где и что почитать или может есть какие то готовые решения: нужно будет отправлять команды на это устройство, а так же получать некоторые данные (в режиме реального времени постоянно будут идти какие-то данные), которые потом я уже буду отображать на форме. Заранее спасибо.

Решение задачи: «.NET 4.x Подключение устройства через USB»

textual
Листинг программы
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <util/delay.h>
  4. #include <avr/pgmspace.h>   /* нужно для usbdrv.h */
  5. #include "usbdrv.h"
  6.  
  7.  
  8. struct dataexchange_t       // Описание структуры для передачи данных
  9. {
  10.    uchar b1;        // Я решил для примера написать структуру на 3 байта.
  11.    uchar b2;        // На каждый байт подцепим ногу из PORTB. Конечно это
  12.    uchar b3;        // не рационально (всего то 3 бита нужно).
  13. };                  // Но в целях демонстрации в самый раз.
  14.                     // Для наглядности прикрутить по светодиоду и созерцать :)
  15.  
  16.  
  17. struct dataexchange_t pdata = {0, 0, 0};
  18.  
  19.  
  20. PROGMEM char usbHidReportDescriptor[22] = { // USB report descriptor         // Дескриптор описывает структуру пакета данных для обмена
  21.     0x06, 0x00, 0xff,                       // USAGE_PAGE (Generic Desktop)
  22.     0x09, 0x01,                             // USAGE (Vendor Usage 1)
  23.     0xa1, 0x01,                             // COLLECTION (Application)
  24.     0x15, 0x00,                             //    LOGICAL_MINIMUM (0)        // min. значение для данных
  25.     0x26, 0xff, 0x00,                       //    LOGICAL_MAXIMUM (255)      // max. значение для данных, 255 тут не случайно, а чтобы уложиться в 1 байт
  26.     0x75, 0x08,                             //    REPORT_SIZE (8)            // информация передается порциями, это размер одного "репорта" 8 бит
  27.     0x95, sizeof(struct dataexchange_t),    //    REPORT_COUNT               // количество порций (у нашем примере = 3, описанная выше структура передастся за три репорта)
  28.     0x09, 0x00,                             //    USAGE (Undefined)
  29.     0xb2, 0x02, 0x01,                       //    FEATURE (Data,Var,Abs,Buf)
  30.     0xc0                                    // END_COLLECTION
  31. };
  32. /* Здесь мы описали только один report, из-за чего не нужно использовать report-ID (он должен быть первым байтом).
  33.  * С его помощью передадим 3 байта данных (размер одного REPORT_SIZE = 8 бит = 1 байт, их количество REPORT_COUNT = 3).
  34.  */
  35.  
  36.  
  37. /* Эти переменные хранят статус текущей передачи */
  38. static uchar    currentAddress;
  39. static uchar    bytesRemaining;
  40.  
  41.  
  42. /* usbFunctionRead() вызывается когда хост запрашивает порцию данных от устройства
  43.  * Для дополнительной информации см. документацию в usbdrv.h
  44.  */
  45. uchar   usbFunctionRead(uchar *data, uchar len)
  46. {
  47.     if(len > bytesRemaining)
  48.         len = bytesRemaining;
  49.  
  50.     uchar *buffer = (uchar*)&pdata;
  51.  
  52.     if(!currentAddress)        // Ни один кусок данных еще не прочитан.
  53.     {                          // Заполним структуру для передачи
  54.         if ( PINB & _BV(1) )
  55.             pdata.b1 = 1;
  56.         else
  57.             pdata.b1 = 0;
  58.  
  59.  
  60.         if ( PINB & _BV(2) )
  61.             pdata.b2 = 1;
  62.         else
  63.             pdata.b2 = 0;
  64.  
  65.  
  66.         if ( PINB & _BV(3) )
  67.             pdata.b3 = 1;
  68.         else
  69.             pdata.b3 = 0;
  70.     }
  71.  
  72.     uchar j;
  73.     for(j=0; j<len; j++)
  74.         data[j] = buffer[j+currentAddress];
  75.  
  76.     currentAddress += len;
  77.     bytesRemaining -= len;
  78.     return len;
  79. }
  80.  
  81.  
  82. /* usbFunctionWrite() вызывается когда хост отправляет порцию данных к устройству
  83.  * Для дополнительной информации см. документацию в usbdrv.h
  84.  */
  85. uchar   usbFunctionWrite(uchar *data, uchar len)
  86. {
  87.     if(bytesRemaining == 0)
  88.         return 1;               /* конец передачи */
  89.  
  90.     if(len > bytesRemaining)
  91.         len = bytesRemaining;
  92.  
  93.     uchar *buffer = (uchar*)&pdata;
  94.    
  95.     uchar j;
  96.     for(j=0; j<len; j++)
  97.         buffer[j+currentAddress] = data[j];
  98.  
  99.     currentAddress += len;
  100.     bytesRemaining -= len;
  101.  
  102.     if(bytesRemaining == 0)     // Все данные получены
  103.     {                           // Выставим значения на PORTB
  104.         if ( pdata.b1 )
  105.             PORTB |= _BV(1);
  106.         else
  107.             PORTB &= ~_BV(1);
  108.  
  109.  
  110.         if ( pdata.b2 )
  111.             PORTB |= _BV(2);
  112.         else
  113.             PORTB &= ~_BV(2);
  114.  
  115.  
  116.         if ( pdata.b3 )
  117.             PORTB |= _BV(3);
  118.         else
  119.             PORTB &= ~_BV(3);
  120.     }
  121.  
  122.     return bytesRemaining == 0; /* 0 означает, что есть еще данные */
  123. }
  124.  
  125. /* ------------------------------------------------------------------------- */
  126.  
  127. usbMsgLen_t usbFunctionSetup(uchar data[8])
  128. {
  129. usbRequest_t    *rq = (void *)data;
  130.  
  131.     if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* HID устройство */
  132.         if(rq->bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */
  133.             // у нас только одна разновидность репорта, можем игнорировать report-ID
  134.             bytesRemaining = sizeof(struct dataexchange_t);
  135.             currentAddress = 0;
  136.             return USB_NO_MSG;  // используем usbFunctionRead() для отправки данных хосту
  137.         }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
  138.             // у нас только одна разновидность репорта, можем игнорировать report-ID
  139.             bytesRemaining = sizeof(struct dataexchange_t);
  140.             currentAddress = 0;
  141.             return USB_NO_MSG;  // используем usbFunctionWrite() для получения данных от хоста
  142.         }
  143.     }else{
  144.         /* остальные запросы мы просто игнорируем */
  145.     }
  146.     return 0;
  147. }
  148. /* ------------------------------------------------------------------------- */
  149.  
  150. int main(void)
  151. {
  152.     DDRB = 0b00001110;      // PB1,PB2,PB3 - выход
  153.  
  154.     usbInit();
  155.     usbDeviceDisconnect();  // принудительно отключаемся от хоста, так делать можно только при выключенных прерываниях!
  156.    
  157.     uchar i = 0;
  158.     while(--i){             // пауза > 250 ms
  159.         _delay_ms(1);
  160.     }
  161.    
  162.     usbDeviceConnect();     // подключаемся
  163.  
  164.     sei();                  // разрешаем прерывания
  165.  
  166.     for(;;){                // главный цикл программы
  167.         usbPoll();          // эту функцию надо регулярно вызывать с главного цикла, максимальная задержка между вызовами - 50 ms
  168.     }
  169.     return 0;
  170. }
  171. /* ------------------------------------------------------------------------- */

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы