基于STM32CubeMX的USB鼠标例程

大家好,我是mcu起航。
最近在玩stm32cube的usb功能,用起来还是挺方便的。只要配置一下,设备描述符、配置描述符、接口描述符什么的,都能给你自动生成,其中还包括比较复杂的报告描述符。
这次给大家演示一下如何用stm32cube的配置,自动生成一个usb鼠标的过程。这里多说一句,usb是一套比较复杂的协议,单靠一两个例程是不可能完全理解的。至少要找本书,再配着usb官网的各种协议啃几天,才算入门。
所以这个例子起到的是一个抛砖引玉的过程,如果你真的感兴趣,就去找相关资料学习。stm32cubemx的便利,在很多方面都给了我们很大的帮助!当然,如果有感兴趣的想继续学的,可以留言,我会试着写一些这方面的文章。
首先,软件版本我用的是stm32cubemx的5.3.0,并不是最新版。为什么没用最新的?最新版有个很恶心的bug,好像是打不开工程,记不清了。
打开stm32cube,选择一个芯片。这里我选的是stm32f103c8t6。
其次,rcc这里外部高速时钟,外部默认都接8mhz。
第三,sys这里,调试接口选择serial wire。我个人习惯用sw接口,你们随意。
第四,gpio这里,我把pa15设置为推挽输出,默认高电平。这是和我的硬件电路相关的。首先要明确的一点是,stm32f103c8的这个片子,只支持usb的fs模式,也就是全速(full speed)模式。
usb主机(也就是电脑)如何知道usb设备支持全速模式?只要在usb设备的d+数据线上接一个1.5k的上拉电阻即可。而我这里这个上拉电阻的电源端是接到了stm32的pa15上面。如图:
所以,如果你的板子上,上拉电阻默认接到vcc,这一步就不用管了。没有的话,自己想办法~~~
第五,connectivity选项里,选择usb,然后右侧device(fs)前面打勾,下面不用管。
第六,中间件(middleware)这里,选择usb。右侧上面选择human interface device class,也就是俗称的hid。
下面要注意几个地方!
vid和pid分别代表厂商(vender)编号和产品(pid)编号,vid不能随便用,要花钱向usb协会申请,所以这里仅供学习使用。pid还好,由厂商自己定义。
manufacturer_string是厂商字符串,product_string是产品字符串,configuration_string是配置字符串,interface_string是接口字符串,这四个是可以手动修改的。放心改,不要钱。我随便改了两个。
还有一个langid_string,它表示usb设备支持什么语言。我这里没有动,默认选择英语。
7、修改时钟。usb那里需要48m的时钟,别的无所谓。照着改吧!
8、生成工程。工程名称和路径,不用说了,那个是基本的。主要是框住的这两个位置,根据你的代码习惯和编译器(keil还是iar)来进行选择。
9、修改代码。打开工程,找到main.c,添加一些代码。
/* private includes ----------------------------------------------------------*/
/* user code begin includes */
#include usbd_hid.h
/* user code end includes */
/* private typedef -----------------------------------------------------------*/
/* user code begin ptd */
uint8_t mousedata01[4] = {0,0,0,0};
extern usbd_handletypedef husbdevicefs;
/* user code end ptd */
主函数里:
while (1)
{
/* user code end while */
/* user code begin 3 */
mousedata01[0] = 0x01;
usbd_hid_sendreport(&husbdevicefs,(uint8_t*)&mousedata01,sizeof(mousedata01));
hal_delay(1000);
mousedata01[0] = 0x00;
usbd_hid_sendreport(&husbdevicefs,(uint8_t*)&mousedata01,sizeof(mousedata01));
hal_delay(1000);
}
好了,保存、编译、下载、上电。你会发现,板子上电的时候电脑右下角弹出一个“发现新设备”的提示框。
然后你的屏幕上的光标位置,每隔1秒,自动点一下鼠标左键。
很多人到这里,其实是蒙的!!!
为什么?
自始至终,stm32cubemx里,和主函数里没出现鼠标相关的函数(除了我们自定义的一个带鼠标字符的数组),怎么就出来一个鼠标?
为什么不是键盘?
为什么不是优盘? 这个我可以回答,因为你选的是hid,而不是存储类设备。
为什么不是游戏手柄?
其实,你可以理解为,这是官方提供给我们的一个鼠标例程。这里简单说下usb设备上电的过程:
1、设备插入后,usb主机自动对设备进行复位,使设备地址为零。
2、usb主机对地址为零的设备提问:你是个什么东西?
3、usb设备说:我的pid是xx,vid是xx,usb协议是2.0等等。
4、usb主机再次对设备进行复位,然后给复位后的设备分配一个地址。
5、usb主机向新地址提问:你是个什么东西? usb设备回答:…
6、两次回答一样,说明usb设备的地址分配成功。usb主机继续提问,获取其它描述符。
7、usb设备,在向主机回复配置集合的时候,表明自己的身份:你好,我是个鼠标!
也就是说,在配置集合中,有信息说明这个设备是鼠标,我们看下。在usb_hid.c文件中,有一个数组:usbd_hid_cfgfsdesc,其中一行:
单是这个还不够,还要结合报告描述符。也在这个文件内,名字是hid_mouse_reportdesc。内容如下:
__align_beginstaticuint8_thid_mouse_reportdesc[hid_mouse_report_desc_size]__align_end= { 0x05,0x01, 0x09,0x02, 0xa1,0x01, 0x09,0x01, 0xa1,0x00, 0x05,0x09, 0x19,0x01, 0x29,0x03, 0x15,0x00, 0x25,0x01, 0x95,0x03, 0x75,0x01, 0x81,0x02, 0x95,0x01, 0x75,0x05, 0x81,0x01, 0x05,0x01, 0x09,0x30, 0x09,0x31, 0x09,0x38, 0x15,0x81, 0x25,0x7f, 0x75,0x08, 0x95,0x03, 0x81,0x06, 0xc0,0x09, 0x3c,0x05, 0xff,0x09, 0x01,0x15, 0x00,0x25, 0x01,0x75, 0x01,0x95, 0x02,0xb1, 0x22,0x75, 0x06,0x95, 0x01,0xb1, 0x01,0xc0 }; 是不是很懵逼?这都是啥?怎么没有注释?
别问我,我也不知道。可能是研发人员懒,也可能是他们忘了。
无论是配置集合,还是报告描述符,这里都不做解释,因为一两篇文章根本说不完。这里只说一点,由于报告描述符的规定,鼠标设备向电脑发送数据的时候,一般是发送4个字节的数据。
字节1:无符号字符型,低三位分别表示鼠标的左、右、中键是否被按下,1按下,0抬起。
字节2:有符号字符型,表示鼠标在x方向的移动。
字节3:有符号字符型,表示鼠标在y方向的移动。
字节4:有符号字符型,表示鼠标滚轮的移动。
所以,我在上面的代码中循环将第一个字节的值设为0和1,就能看到屏幕上的光标每隔一秒,触发一下鼠标左键。
好了,不知不觉说的有点多。还好大部分都是图片,看起来不难理解。总结起来,就是个发送数据的过程。
还是那句话,usb协议比较复杂,只靠一两篇文章是学不会的。完整例程我放到了公众号后台(单片机爱好者),回复关键词:usb鼠标例程,即可获取下载链接。

日常出行公交金龙汽车将面临巨额罚款 只因新能源汽车申报骗取补贴
什么牌子的学习机好,自主学习推荐优学派U80!
大疆回应:严格遵守,反对用于任何军事或战争用途
简洁的前级分频功放电路图
沟通触摸器噪声大的原因
基于STM32CubeMX的USB鼠标例程
Parker直线电机应用-龙门双驱单双工位自动点胶平台
有哪些荣耀机型可直接升级到鸿蒙系统
在电容式传感器应用中提供优势
智慧灯杆网关与云平台共同助力智慧城市智能照明
霍尔元件工作原理视频
视联网的实现路径及发展的三大要素解析
CSIP发布09中国集成电路设计业发展报告
人工智能python是什么
2023北京安博会倒计时1天,英码邀您共享盛会
国产霍尔IC低成本线性输出霍尔芯片-SC4001介绍
中国AI云服务市场厂商百度阿里腾讯位居前列
用于下一代安全传感器和筛选系统的设计解决方案
雷曼智慧教室教育显示系统为师生提供更多样、更灵活的课堂协作方式
无线路由器的工作频段