.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;
}
/* ------------------------------------------------------------------------- */

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


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

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

12   голосов , оценка 4 из 5
Похожие ответы