打印
[研电赛技术支持]

USB HID和CDC数据收发样例程序测试

[复制链接]
189|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
drer|  楼主 | 2023-12-21 10:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
HID例程

GD固件库自定义HID样例程序是收发两个字节控制按键和LED,这里以GD32F10x系列 USB例程讲解怎么实现100字节的数据接收和发送。

例程路径:



测试上位机软件:



例程和测试软件可以到GD官网下载,或找GD代理商和原厂FAE提供。

打开custom_hid工程,修改几个地方:

先修改报告描述符,在custom_hid_core.c文件里面
const uint8_t customhid_report_descriptor[DESC_LEN_REPORT] =                    
{
    0x06, 0x00, 0xFF,  /* USAGE_PAGE (Vendor Defined: 0xFF00) */
    0x09, 0x00,        /* USAGE (Custom Device)               */
    0xa1, 0x01,        /* COLLECTION (Application)            */
    0x09,0x00,
    0x15,0x00,          /* LOGICAL_MINIMUM (0)       */   
    0x26,0xff,0x00,       /* LOGICAL_MAXIMUM (255)       */
    0x75,0x08,        /* REPORT_SIZE (8)           */
    0x95,0x64,        /* REPORT_COUNT (100)       */
    0x81,0x06,         /* INPUT (Data,Var,Abs,Vol) */
    0x09,0x00,
    0x15,0x00,
    0x26,0xff,0x00,
    0x75, 0x08,     /* REPORT_SIZE (8)           */
    0x95, 0x64,     /* REPORT_COUNT (100)       */
    0x91, 0x06,     /* OUTPUT (Data,Var,Abs,Vol) */
    0xc0            /* END_COLLECTION        REPORT    */
}

修改报告描述符长度DESC_LEN_REPORT为34,在custom_hid_core.h文件里
#define DESC_LEN_REPORT            34
    3. 修改端点IN和OUT数据包长度,改为最大值64,在usbd_conf.h文件里面  

#define CUSTOMHID_IN_PACKET              64
#define CUSTOMHID_OUT_PACKET             64
    4. 把custom_hid_init()里面的usbd_ep_recev()函数的接收数据长度的参数改为100

usbd_ep_recev (udev, CUSTOMHID_OUT_EP, hid_handler.data, 100U);
     5.  修改结构体custom_hid_handler中的数组元素data[100],在custom_hid_core.h文件里面

typedef struct {
    uint8_t data[100];                 
    uint8_t reportID;
    uint8_t idlestate;
    uint8_t protocol;
} custom_hid_handler;
     6.  修改custom_hid_data_out(),在custom_hid_core.c文件里面

static uint8_t custom_hid_data_out (usb_dev *udev, uint8_t ep_num)
{
custom_hid_handler *hid =(custom_hid_handler*)udev>dev.class_data[CUSTOM_HID_INTERFACE];
    switch (hid->data[0]){
    case 0x11U:
        if (RESET != hid->data[1]) {
            gd_eval_led_on(LED5);
        } else {
            gd_eval_led_off(LED5);
        }
        break;
    case 0x12U:
        if (RESET != hid->data[1]) {
            gd_eval_led_on(LED2);
        } else {
            gd_eval_led_off(LED2);
        }
        break;
    case 0x13U:
        if (RESET != hid->data[1]) {
            gd_eval_led_on(LED3);
        } else {
            gd_eval_led_off(LED3);
        }
        break;

    case 0x14U:
        if (RESET != hid->data[1]) {
            gd_eval_led_on(LED4);
        } else {
            gd_eval_led_off(LED4);
        }
        break;
    default:
        break;
    }
    usbd_ep_recev (udev, CUSTOMHID_IN_EP, hid->data, 100U);
        custom_hid_report_send (&custom_hid, hid->data, 100U);       
    return USBD_OK;
}

      7. 编译下载测试



     发送和接收的第一个字节是报告符ID,默认是00,所以发送和接收的字节数是101.

虚拟串口CDC

例程路径:



例程是通过串口向DEMO板发送多少数据,然后DEMO板通过串口返回多少数据。



把例程改为向上位机发送1K字节数据

修改app.c文件
#include "drv_usb_hw.h"
#include "cdc_acm_core.h"
#include "systick.h"
#include <string.h>

usb_core_driver cdc_acm;
void my_cdc_acm_data_send (usb_dev *udev, uint8_t* addr, uint32_t len);
/*!
    \brief      main routine will construct a USB virtual ComPort device
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    uint8_t arr1k[1024];
    uint16_t i;
    for(i=0;i<1024;i++){
        arr1k = '0'+i%10;
    }
        char buf1[] = {"\r\n*********************\r\n"};
    systick_config();
    usb_rcu_config();
    usb_timer_init();
    usbd_init (&cdc_acm, USB_CORE_ENUM_FS, &cdc_desc, &cdc_class);   
    usb_intr_config();
    /* main loop */
    while (1) {
        if (USBD_CONFIGURED == cdc_acm.dev.cur_status) {
                                        delay_1ms(2000);
                                        my_cdc_acm_data_send (&cdc_acm,  arr1k, 1024);
                                        my_cdc_acm_data_send (&cdc_acm,  (uint8_t*)buf1, strlen(buf1));
        }
    }
}

void my_cdc_acm_data_send (usb_dev *udev, uint8_t* addr, uint32_t len)
{
    usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];

    cdc->packet_sent = 0U;

    usbd_ep_send (udev, CDC_DATA_IN_EP, addr, len);
}

     2. 添加systick.c和systick.h文件的同时,要在中断函数SysTick_Handler()中添加 delay_decrement(),不然延时不起作用。

void SysTick_Handler(void)
{
         delay_decrement();
}
     3.  编译下载,串口调试显示如下:


————————————————
版权声明:本文为CSDN博主「frank_1a」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/frank_1a/article/details/134710439

使用特权

评论回复
沙发
tpgf| | 2024-1-17 19:07 | 只看该作者
HID是一种USB通信协议,无需安装驱动就能进行交互

使用特权

评论回复
板凳
wowu| | 2024-1-17 19:44 | 只看该作者
当插入USB设备后,主机会向设备请求各种描述符来识别设备

使用特权

评论回复
地板
xiaoqizi| | 2024-1-18 08:00 | 只看该作者
描述符,是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的

使用特权

评论回复
5
木木guainv| | 2024-1-18 09:01 | 只看该作者
USB有5种标准描述符:设备描述符 、配置描述符、字符描述符、接口描述符、端点描述符

使用特权

评论回复
6
磨砂| | 2024-1-18 09:43 | 只看该作者
描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符

使用特权

评论回复
7
晓伍| | 2024-1-18 20:08 | 只看该作者
USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

3309

帖子

4

粉丝