STM32作为主机识别鼠标键盘
STM32作为Host接收鼠标键盘数据
- 引言
- 移植
- 测试
引言
有一天在调试麦轮小车时,尝试使用串口发送命令控制小车的移动,使用的是无线串口,类似蓝牙,确实可以
然后又想,能不能用键盘来控制小车的移动,也就是遥控小车,然后发现XCOM可以读取键盘的值,只不过只能读取数字键值,不过也够了
结果还真行
然后又想了想,这还要连一个无线串口模块,也就是说键盘和小车之间需要一台主机才能进行通信控制,能不能直接将键盘连到单片机进行通信呢,USB好像可以实现,键盘与电脑连接时,电脑作为主机Host,键盘作为从机Slave,那单片机能不能作为主机,键盘作为从机呢,刚好板子上又引出了单片机的USB口,于是就去看了一下USB相关的内容,简单了解了一下
移植
USB 鼠标键盘属于 USB HID 设备。USB HID 即:Human Interface Device(人机交互设备)的缩写,键盘、鼠标与游戏杆等都属于此类设备。不过 HID 设备并不一定要有人机接口,只要符合 HID 类别规范的设备都是 HID 设备。
对于STM32,ST官方有专门的USB例程,根据自己的需要进行移植就行
然后直接开始移植正点原子的例程(F407标准库例程(实验54 USB鼠标键盘(Host)实验)),需要用到这些文件
添加头文件路径
刚移植完编译会报错,内容大概如下,这个弹窗的意思是:IDE(如 Keil、IAR 或 STM32CubeIDE)在尝试跳转或查看源文件时,找不到相关的源文件路径信息
要在C/C++选项卡中定义全局宏,这时候再编译,基本就没什么报错了,如果还有的话跳转去错误的地方看看是什么问题
如果用的是正点原子的学习板基本直接用就行,但是我是用星火一号,所以要把LCD相关的代码删掉,基本上要改的地方就只有usbh_usr.c
文件,还有其他有出现LCD相关函数的地方,因为我需要读取键盘值,所以我定义了一个无符号整型变量keyboard用来接收键盘的键值数据,然后用这个数据进行判断
正点原子的历程把USB连接的函数放在主函数了,我这里进行了封装
USB.c
#include "usb.h"
#include "usbh_usr.h" #include "delay.h"#include "string.h"USBH_HOST USB_Host;
USB_OTG_CORE_HANDLE USB_OTG_Core_dev;
extern HID_Machine_TypeDef HID_Machine; //HID重新连接
void USBH_HID_Reconnect(void)
{//关闭之前的连接USBH_DeInit(&USB_OTG_Core_dev,&USB_Host); //复位USB HOSTUSB_OTG_StopHost(&USB_OTG_Core_dev); //停止USBhostif(USB_Host.usr_cb->DeviceDisconnected) //存在,才禁止{USB_Host.usr_cb->DeviceDisconnected(); //关闭USB连接USBH_DeInit(&USB_OTG_Core_dev, &USB_Host);USB_Host.usr_cb->DeInit();USB_Host.class_cb->DeInit(&USB_OTG_Core_dev,&USB_Host.device_prop);}USB_OTG_DisableGlobalInt(&USB_OTG_Core_dev);//关闭所有中断//重新复位USBRCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS,ENABLE);//USB OTG FS 复位delay_ms(5);RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS,DISABLE); //复位结束 memset(&USB_OTG_Core_dev,0,sizeof(USB_OTG_CORE_HANDLE));memset(&USB_Host,0,sizeof(USB_Host));//重新连接USB HID设备USBH_Init(&USB_OTG_Core_dev,USB_OTG_FS_CORE_ID,&USB_Host,&HID_cb,&USR_Callbacks); }void USB_Connect(void)
{USBH_Process(&USB_OTG_Core_dev, &USB_Host);if(bDeviceState==1)//连接建立了{ if(USBH_Check_HIDCommDead(&USB_OTG_Core_dev,&HID_Machine))//检测USB HID通信,是否还正常? { USBH_HID_Reconnect();//重连} }else //连接未建立的时候,检测{if(USBH_Check_EnumeDead(&USB_Host)) //检测USB HOST 枚举是否死机了?死机了,则重新初始化 { USBH_HID_Reconnect();//重连} }}
USB.h
#ifndef __USB_H
#define __USB_H
#include "stm32f4xx_conf.h"
#include "sys.h" void USBH_HID_Reconnect(void);
void USB_Connect(void);#endif
最后在主函数调用USBH_Init()
设备初始化函数和USB_Connect()
函数就可以了
extern USBH_HOST USB_Host;
extern USB_OTG_CORE_HANDLE USB_OTG_Core_dev;
extern HID_Machine_TypeDef HID_Machine; int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168); //延时初始化uart_init(115200);USBH_Init(&USB_OTG_Core_dev,USB_OTG_FS_CORE_ID,&USB_Host,&HID_cb,&USR_Callbacks); while(1){ USB_Connect();}
}
测试
效果如下,我的键盘是VGN N75,插上后单片机识别出来了,打印出了正确的信息,然后按下按键后也能正确打印键值,说明USB通信没有问题,接着就可以对数据进行处理,来控制小车的移动
最后的效果如下