|
如有转载请注明来自http://blog.csdn.net/cy757
大家可以使用紧缩包中的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/5117 610.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,custom usb, /* 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_de sc] =
{
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/200 7/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,解释发送停止。 |
|