STM32例程之USB HID双向数据传输

发布者:量子心跳最新更新时间:2018-09-20 来源: eefocus关键字:STM32  USB  HID  双向数据传输 手机看文章 扫描二维码
随时随地手机看文章

程序功能

  • 将STM32的USB枚举为HID设备。

  • STM32使用3个端点,端点0用于枚举用,端点1和2用于数据的发送和接收。

  • 端点长度为64,也就是单次最多可以传输64个字节数据。

  • STM32获取上位机下发的数据并将该数据通过USB原样返回,同时将数据打印输出。

  • 上位机程序通过调用windows的API实现对HID设备的读写控制。

USB接口原理图: 
USB.jpg
HID枚举成功: 
1.jpg
程序效果图 
1.jpg
图一 上位机程序运行图 
2.jpg
图二  STM32串口打印输出 
3.jpg
图三 Bus Hound抓取的数据 
程序部分代码 

STM32的报告描述符:

const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =

{

        0x05, 0x8c, /* USAGE_PAGE (ST Page) */

        0x09, 0x01, /* USAGE (Demo Kit) */

        0xa1, 0x01, /* COLLECTION (Application) */

        // The Input report

        0x09,0x03, // USAGE ID - Vendor defined

        0x15,0x00, // LOGICAL_MINIMUM (0)

        0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)

        0x75,0x08, // REPORT_SIZE (8bit)

        0x95,0x40, // REPORT_COUNT (64Byte)

        0x81,0x02, // INPUT (Data,Var,Abs)

        // The Output report

        0x09,0x04, // USAGE ID - Vendor defined

        0x15,0x00, // LOGICAL_MINIMUM (0)

        0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)

        0x75,0x08, // REPORT_SIZE (8bit)

        0x95,0x40, // REPORT_COUNT (64Byte)

        0x91,0x02, // OUTPUT (Data,Var,Abs)

        0xc0 /* END_COLLECTION */

}; /* CustomHID_ReportDescriptor */



上位机测试程序


/**

  * @brief  发送数据后读取数据

  * @param  None

  * @retval None

  */

void HIDSampleFunc(void)  

{      

        HANDLE       hDev;      

        BYTE         recvDataBuf[1024],reportBuf[1024];;                  

        DWORD        bytes;      

        hDev = OpenMyHIDDevice(0); // 打开设备,不使用重叠(异步)方式 ;     

        if (hDev == INVALID_HANDLE_VALUE){          

                printf("INVALID_HANDLE_VALUE\n");

                return; 

        }

        reportBuf[0] = 0; // 输出报告的报告 ID 是 0     

        for(int i=0;i

                reportBuf[i+1]=i+1;//将数据存放在数据缓冲区

        }

        printf("开始写数据到设备...\n");

        // 写入数据到设备,注意,第三个参数值必须为REPORT_COUNT+1,否则会返回1784错误

        if (!WriteFile(hDev, reportBuf, REPORT_COUNT+1, &bytes, NULL)){          

                printf("write data error! %d\n",GetLastError());

                return;   

        }else{

                printf("成功向设备写出%d个数据... \n",bytes);

        }

        printf("开始从设备读取数据...\n");

        // 从设备读取数据,注意,第三个参数值必须大于等于REPORT_COUNT+1,否则会返回1784错误

        if(!ReadFile(hDev, recvDataBuf, REPORT_COUNT+1, &bytes, NULL)){ // 读取设备发给主机的数据 

                printf("read data error! %d\n",GetLastError());

                return;   

        }else{

                printf("成功向设备读出%d个数据... \n",bytes);

        }

        printf("设备返回的数据为:\n");

        //显示读取回来的数据

        for(int i=0;i

                printf("0x%02X ",recvDataBuf[i+1]);

        }

        printf("\n\r");


关键字:STM32  USB  HID  双向数据传输 引用地址:STM32例程之USB HID双向数据传输

上一篇:STM32学习笔记之USB数据接收和发送流程分析
下一篇:stm32usb库bug及解决办法

推荐阅读最新更新时间:2024-03-16 16:14

STM32如何移植uCGUI,看这里!
第一部分:在UCGUI移植之前 在移植之前,首先要了解在网上下的UCGUI 3.98源码的文件结构是。 UCGUI 3.98源码中有三个文件夹: 1)“tool文件夹”是用来使用一些uCgui的上位机程序,基本都是字体和模板查看之类的. 2)“sample文件夹”下面是已经别人帮你写好了很多有用的东西,像跟操作系统有关的GUI_X或者一些模板(后面我们会用到的自己定义的Demo),或者是gui配置.后面再一一详细叙说这个文件夹的功能. 3)“Start文件夹”里面,这是我们最主要的文件夹.里面就包含了uCGUI的源代码,uCGUI的作者把源代码放进vc里面进行编译了(当然,这是用标准C语言写的程序,所以我们可以
[单片机]
STM32 IIC OLED中英文显示
简介 ; II2C OLED 中英文显示 ADC数据采集实时显示 八路ADC 一 先上代码 #include oled.h #include sys.h #include delay.h #include oledfont.h #include delay.h #include bmp.h #include gbk.h #define uint unsigned int #define uchar unsigned char //OLED显存 u8 OLED_GRAM ; // 开始信号:SCLK为高电平 SDA由高电平跳变为低电平 开始传输数据 // 结束信号:SCLK为高电平 SDA由低电平跳变为高
[单片机]
<font color='red'>STM32</font> IIC OLED中英文显示
STM32时钟配置方法详解
一、在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。 二、在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理: ①对于
[单片机]
STM32在低功耗状态时IO引脚常规的配置内容分享
做有低功耗产品设计经验的朋友都应该知道,一个产品的功耗不光是硬件功耗的事,其实软件也是影响整个产品功耗的一个关键因素。 今天就为大家分享一点关于STM32在低功耗状态时,IO引脚常规的配置内容。 1 将未使用的GPIO输入配置为模拟输入GPIO始终有一个输入通道,可以是数字或模拟通道。如果不需要读取GPIO数据,则优先配置为模拟输入。这节省了输入施密特触发器的消耗。在STM32CubeMX配置中都有这么一个选项:将不用引脚配置为模拟状态。 2 调节GPIO速度上升时间,下降时间和最大频率可使用GPIOx_OSPEEDR配置寄存器进行配置。这种调整对EMI(电磁干扰)和SSO(同时开关输出)有影响,因为开关电流峰值较高。
[单片机]
<font color='red'>STM32</font>在低功耗状态时IO引脚常规的配置内容分享
STM32学习笔记之对PWM频率和占空比都可调测试
基于战舰开发板 修改的可以对频率和占空比同时调节的一个简单程序。 span style= font-size:18px; void TIM3_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //ʹÄܶ¨Ê±Æ÷3
[单片机]
stm32中“拔掉jlink”程序无法正确运行
Q:在调试stm32程序时,从电脑USB口拔掉jlink后开发板上程序为什么无法正确运行?断点复位后也不行。 A:首先,要拔了jlink与开发板的连接(而不仅仅是其与PC的连接),因为jlink本省内部也有电路,对开发板上的程序运行有所影响; 其次,检查stm32的boot 的配置,将BOOT0配置为0才能从复位后Flash启动。BOOT的具体配置如下: BOOT1 BOOT0 启动模式 说明 X 0 Flash 复位后选择主闪存启动 0 1
[单片机]
STM32模拟IIC读写AT24CXX
以前只用51做过AT24C02,后来才接触到容量更大的型号,发现了很多和以前的不一致的东西,现总结如下。 在上一篇博客中已经写好了STM32用IO口模拟IIC的基本驱动代码,下面结合数据手册用上一篇博客提到的函数编写AT24CXX全系列通用的驱动代码。 我们先来看AT24CXX的中文手册。 这是写操作的步骤。 而上面提到的从器件的地址信息由下图所示。 不同的容量的AT24CXX的从器件地址位是不同的。这在后面的基本的读写函数的关于器件的不同就有所体现。 下面先初始化AT24CXX: void AT24CXX_Init() { IIC_Init(); } 这里只需要初始化IIC总线即可。 下面写出AT24CXX基本
[单片机]
<font color='red'>STM32</font>模拟IIC读写AT24CXX
如何在STM32中收发float数据?
实际应用中,我们可能需要两个设备通过串口传输浮点数据: 本篇笔记为了方便演示,使用串口助手模拟其中一个设备,本篇笔记内容如下: 我们创建一个用于管理float类型数据的共用体: union float_data { float f_data; uint8_t by te [4]; }; 数据的流向如: 本次使用串口助手模拟发送设备,省略了第一步,主要看第②、③步。 创建两个共用体变量,用于发送与接收: union float_data rx_float_data, tx_float_data; 收发相关代码: // 公众号: 嵌入式 大杂烩 if(HAL_ UART _Receive(&huart3, rx_float
[单片机]
如何在<font color='red'>STM32</font>中收发float数据?
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved