STM32 USB-HID通信移植步骤
大家可以使用压缩包中的UsbApp.exe调试本软件idVendor为:0483 idProduct为5750。
今天太晚了,明天还要上半天班,上位机软件找个时间在写一篇文章。请关注我的博客。压缩包中附带了几个编译软件典型的上位机源代码,大家可以参考下。
本文中源程序的下载网址为:http://download.csdn.net/source/2918553
很久没写过文章了,趁今晚有空出来露一下。最近发现很多人对STM32的USB通信很感兴趣。要将USB的通信协议搞懂确实是一个比较漫长的过程。但是USB的HID通信无论是上位机的设计还是STM32程序的编程都非常的简单。只是我想很多人都不知道而已。这篇文章的目的是让大家以最短的时间将USB加到你的设备中。如果想学得更深就靠大家。
HID只是适合低速传输,其理论上可以达到64KB/S,但多由于windows系统和硬件的关系一般达不到这个传输数度。但这个速度对于一般系统的控制和数据传输都已经足够了,而且是免驱,省去了很多麻烦。如果您需要高速传输可参考我的另外一篇文章《STM32的USB例程修改步骤》文章在http://blog.csdn.net/cy757/archive/2010/01/01/5117610.aspx
一、安装完MDK后请打开C:/Keil/ARM/Examples/ST/STM32F10xUSBLib/Demos路径,将Custom_HID在同一个目录下复制一份,如果你要放到其他路径你需要在MDK Options for target的C/C++中添加USB的头文件路径(MDK下的/INC/ST/STM32F10x/USB)。
二、打开usb_desc.c文件,该文件主要包含的端点描述符、设备描述符、配置描述符和字符描述符等。具体请大家参考其他资料了,这里主要说几个常用。
u8 DeviceDescriptor[SIZ_DEVICE_DESC]为USB设备描述符。当中的
0x83, /*idVendor (0x0483)*/
0x04,
0x50, /*idProduct = 0x5750*/
0x57,
//idVender字段。厂商ID号,我们这里取0x0483,仅供实验用。
//实际产品不能随便使用厂商ID号,必须跟USB协会申请厂商ID号。
//注意小端模式,低字节在先。
//idProduct字段。产品ID号,我们这里取0x5750。
//注意小端模式,低字节应该在前。
const u8 ConfigDescriptor[SIZ_CONFIG_DESC]是配置描述符,注意如下
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x81, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
0x02, /* wMaxPacketSize: 2 Bytes max */
0x00,
0x20, /* bInterval: Polling Interval (32 ms) */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
0x01, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
0x02, /* wMaxPacketSize: 2 Bytes max */
0x00,
0x20, /* bInterval: Polling Interval (20 ms) */
上面包含了“输入端点描述符”和“输出端点描述符”。
//wMaxPacketSize字段。该端点的最大包长。
//bInterval字段。端点查询的时间,
为了实现更高速的通信我们修改如下:
/******************** Descriptor of endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x81, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x40, /*wMaxPacketSize: 64 Byte max */
0x00,
0x0A, /*bInterval: Polling Interval (10 ms)*/
/* 34 */
/******************** Descriptor of endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x01, /*bEndpointAddress: Endpoint Address (OUT)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x40, /*wMaxPacketSize: 64 Byte max */
0x00,
0x0A, /*bInterval: Polling Interval (10 ms)*/
const u8 ReportDescriptor[SIZ_REPORT_DESC]为HID专用的报告描述符,具体的大家就参考资料了,这里可以直接复制了。
const u8 CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
0x05, 0xFF, // USAGE_PAGE(User define)
0x09, 0xFF, // USAGE(User define)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x01, // USAGE_PAGE(1)
0x19, 0x00, // USAGE_MINIMUM(0)
0x29, 0xFF, // USAGE_MAXIMUM(255)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x40, // REPORT_COUNT (64)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x02, // USAGE_PAGE(2)
0x19, 0x00, // USAGE_MINIMUM (0)
0x29, 0xFF, // USAGE_MAXIMUM (255)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x40, // REPORT_SIZE (64)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
}; /* ReportDescriptor */
const u8 CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR]
const u8 StringProduct[SIZ_STRING_PRODUCT]
const u8 StringSerial[SIZ_STRING_SERIAL]
分别是“厂商字符”、“产品字符”、“产品序列号”,这些将在USB HID设备加载的时候显示。但是这需要这些字符要求为Unicode编码,你需要将你要显示的字符先转为Unicode编码。你可以到http://computer00.21ic.org/user1/2198/archives/2007/42769.html转换。最好大家还要根据各个数组的长度修改如下定义。
#define CUSTOMHID_SIZ_REPORT_DESC 39
#define CUSTOMHID_SIZ_STRING_VENDOR 64
#define CUSTOMHID_SIZ_STRING_PRODUCT 28
#define CUSTOMHID_SIZ_STRING_SERIAL 26
三、打开hw_config.c文件,将那些没有的函数删除,只保留如下函数
a) Set_System(void)
b) void Set_USBClock(void)
c) void USB_Interrupts_Config(void)
d) void USB_Cable_Config (FunctionalState NewState)
特别要注意最后一个函数,其主要作用是控制USB的上拉电阻,让电脑检测USB设备是否连接的。
四、打开stm32f10x_it.c文件,把EXTI15_10_IRQHandler等中断内的代码删除。
打开usb_prop.c文件,修改如下:
void CustomHID_Reset(void)
{
/* Set Joystick_DEVICE as not configured */
pInformation->Current_Configuration = 0;
pInformation->Current_Interface = 0;/*the default Interface*/
SetBTABLE(BTABLE_ADDRESS);
/* Initialize Endpoint 0 */
SetEPType(ENDP0, EP_CONTROL);
SetEPTxStatus(ENDP0, EP_TX_STALL);
SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPTxAddr(ENDP0, ENDP0_TXADDR);
Clear_Status_Out(ENDP0);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPRxValid(ENDP0);
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_INTERRUPT);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxCount(ENDP1, 64);
SetEPRxStatus(ENDP1, EP_RX_DIS);
SetEPTxStatus(ENDP1, EP_TX_NAK);
/* Initialize Endpoint 1 */
// SetEPType(ENDP1, EP_INTERRUPT);
SetEPRxAddr(ENDP1, ENDP1_RXADDR);
SetEPRxCount(ENDP1, 64);
// SetEPTxStatus(ENDP1, EP_TX_DIS);
SetEPRxStatus(ENDP1, EP_RX_VALID);
/* Set this device to response on default address */
SetDeviceAddress(0);
}
五、usb_endp.c文件
void EP1_OUT_Callback(void)
{
这些写接收代码
}
六、数据发送和接收,举例说明
1、数据接收
u8 DataLen;
DataLen = GetEPRxCount(ENDP1);
PMAToUserBufferCopy(TX1_buffer, ENDP1_RXADDR, DataLen);
SetEPRxValid(ENDP1);
USART1_Send(DataLen);
count_out = 1;
2、数据发送
UserToPMABufferCopy(InBuffer, GetEPTxAddr(ENDP1), 64);
SetEPTxCount(ENDP1, 64);
SetEPTxValid(ENDP1);
如果你发送数据较为频繁,每次发送前应使用GetEPTxStatus(ENDP1)检测上次发送是否完成。如果端点状态处于EP_TX_VALID,说明发送未结束,如果端点状态处于EP_TX_NAK,说明发送结束。
STM32 USB-HID通信移植步骤的更多相关文章
- 史上最全USB HID开发资料
史上最全USB HID开发资料 史上最全USB HID开发资料,悉心整理一个月,亲自测试. 涉及STM32 C51 8051F例子都有源码,VC上位机例子以及源码,USB协议,HID协议,USB抓包工 ...
- STM32 USB开发(三) 基于F105RBT6核心板开发的自定义HID收发(FS)
硬件设计 该核心板的USB插口有两个,一个是用于USB Slave的,可以用来做HID设备,把模拟STM32模拟为U盘等:另一个是USB Host设备,可以对插上的U盘的数据进行读写. 图中J2是Mi ...
- C#与USB HID间的通信
原文:C#与USB HID间的通信 C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API.其原理编者尚未全部理清,以下提供简单的USBHID通讯流程. ...
- android usb Host模式下与usb Hid 设备的通信
做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...
- Windows与自定义USB HID设备通信说明.
1 . 所使用的典型 Windows API CreateFile ReadFile WriteFile 以下函数是 DDK 的内容: HidD_SetFeature HidD_GetFeatur ...
- STM32 USB 问题汇总(转)
源:STM32 USB 问题汇总 汇总1:STM32的USB例程修改步骤,来自http://blog.csdn.net/cy757/archive/2010/01/01/5117610.aspx 以下 ...
- PIC32MZ 通过USB在线升级 -- USB HID bootloader
了解 bootloader 的实现, 请加QQ: 1273623966(验证填bootloader); 欢迎咨询或定制bootloader; 我的博客主页 www.cnblogs.com/geekyg ...
- USB HID介绍【转】
本文转载自:http://blog.csdn.net/leo_wonty/article/details/6721214 HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复 ...
- USB HID 协议入门
转载请注明来源:cuixiaolei的技术博客 USB HID设备类的应用场合 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互操作的设备,用于控制计算机 ...
随机推荐
- embed标签遮住div层
依然是上次的那个返工友情项目,当时帮忙用jquery ui写了一个漂浮的投票箱,就是类似点击一个项目然后就收藏到了投票箱中的效果.. 虽然不是很复杂,但是由于页面上有大面积的由kindeditor上传 ...
- 在 Windows 8 或 8.1 上安装 .NET Framework 3.5 安装错误:0x800f0906、0x800F081F
昨天给一天新装Windows 8.1的PC装.NET Framework 3.5 发现联网速度很慢,并且在长久等待过后直接报错了:0x800f0906 经过Bing,发现了解决方案: 如果根据需要安装 ...
- hdu 4726
贪心 不是很难 各种细节注意 #include <cstdio> #include <cstring> #include <algorithm> using na ...
- 发现一个可以在线运行JS代码的网站
平时可以在这里玩 http://jsbin.com/
- hibernate annotation注解 columnDefinition用法
column注解中的columnDefinition属性用于覆盖数据库DDL中的语句:(MySql) @Column(columnDefinition = "int(11) DEFAULT ...
- codeforces #309 div1 B
题目啰里啰嗦说了一大堆(耐心读完题目就可以秒题了) 首先我们考虑当前置换的开头的循环节的开头 1.如果是1 1->1形成循环节 问题变成i-1的子问题 2.如果是2 1->2->1形 ...
- 思科模拟器软件教程---教你如何划分Vlan
方法/步骤 1.打开Cisco Packet Tracer,点击[交换机],选择第三个图标2960交换机,按住鼠标左键拖动到工作区.这里有很多类型的交换机,但是我们比较常用的是这个. 2.我们选择[终 ...
- HeadFirst设计模式之RMI介绍
一.使用步骤 1.generate stubs and skeletons:Run rmic on the remote implementation class 如:D:\Workspaces\My ...
- DX 绘制位图
简单地学习了四个API: HRESULT CreateOffscreenPlainSurface( [in] UINT Width, // 宽度 [in] UINT Height, // 高度 [in ...
- python脚本工具 - 3 目录遍历
遍历系统中某一目录下的所有文件名 #! /usr/bin/python # coding:utf-8 import os def dirList(path): filelist = os.listdi ...