历史上的今天
今天是:2025年03月24日(星期一)
2019年03月24日 | STM32高级教程之USB HID双向数据传输
2019-03-24 来源:eefocus
程序功能:
1,将STM32的USB枚举为HID设备。
2,STM32使用3个端点,端点0用于枚举用,端点1和2用于数据的发送和接收。
3,端点长度为64,也就是单次最多可以传输64个字节数据。
4,STM32获取上位机下发的数据并将该数据通过USB原样返回,同时将数据打印输出。
5,上位机程序通过调用windows的API实现对HID设备的读写控制。
原理图:
说明:实际测试的时候不用这么复杂的电路,接好PA11和PA12即可,当然在PA12引脚上需要一个上拉电阻,其他电路都可以省略。
HID枚举成功:
说明:枚举成功后会自动安装HID驱动,无需单独安装。
上位机程序运行效果图:
说明:上位机程序是在VS2010环境下写的,不过可以根据自己需求移植到其他环境中。
单片机运行输出:
说明:单片机端采用超级终端输出相关信息,使用的USART1串口,也就是PA9和PA10两个引脚。
Bus Hound抓取数据截图:
说明:Bus Hound是一个很不错的数据抓包工具,调试USB程序相当有用。
部分程序源码:
STM32的报告描述符:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | constuint8_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 */ |
上位机测试程序:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** * @brief 发送数据后读取数据 * @param None * @retval None */ voidHIDSampleFunc(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(inti=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(inti=0;i printf("0x%02X ",recvDataBuf[i+1]); } printf("\n\r"); } |
史海拾趣
|
本文来自于HELLODSP交流网 作者:huttu 近来有很多朋友问及MAP文件,下面我就对MAP文件的一点理解和大家分享。 MAP文件是CCS软件编译后产生的有关DSP用到所有程序、数据及IO空间的一种映射文件。 一、生成方法 MAP文件主要有两种 ...… 查看全部问答> |
|
1.交谈 尽可能多地跟其他软件开发者交谈;培养个人关系;跟意见与你相左的人交流;跟经验更丰富的人交流;跟阅历丰富的人交流。多到Groups 中去,尤其是交谈自由随意的Groups——不约束主题,不约束交谈内容。 2. 选择更好的环境&nb ...… 查看全部问答> |
|
为什么Run-time image can be larger than 32MB(IMGRAM64=1)选中后还会出现如下信息,nk.bin生成不了 Pass 1... Warning: Unable to do imports from ppp.dll to RSAENH.dll - will late bind Warning: Unable to do imports from schannel.dll ...… 查看全部问答> |
|
User command #1: C:WAVE6000\\BIN\\wave.exe /k ---Error:User Command terminated, Exit-Code = 1 \"Web51\" - 1 Error(s), 0 Warning(s). 这个错误很常见吧 哥哥姐姐请指教 … 查看全部问答> |




