记录stm32F4discovery板利用stm32cubemx实现串口的usart_IAP功能全过程

chenlmm 回复了问题 • 27 人关注 • 21 个回复 • 12143 次浏览 • 2019-05-17 13:59 • 来自相关话题

鉴于好多人问,分享个24C64的HAL库文件和使用操作(利用硬件库iic)

ncyaoyi 回复了问题 • 14 人关注 • 11 个回复 • 8839 次浏览 • 2019-04-19 13:11 • 来自相关话题

终于利用stm32cube生成了usb虚拟串口程序并初步调试通过,分享代码和配置先!!

jreeyssss 回复了问题 • 87 人关注 • 34 个回复 • 60483 次浏览 • 2019-03-05 19:09 • 来自相关话题

hal库uc1701液晶LCD12864驱动程序移植

广州贺工 回复了问题 • 9 人关注 • 8 个回复 • 7182 次浏览 • 2018-09-10 12:37 • 来自相关话题

CubeMX配置stm32 F103RCT6实现USB bulk传输

乌龟也会飞 发表了文章 • 22 个评论 • 7832 次浏览 • 2018-09-07 14:47 • 来自相关话题

友情提示请全屏查看(By荒野大嫖客)ST官方虽然提供很多关于USB固件库集成的(像什么VCP HID等等),但是吧在我们实际的项目开发中VCP(虚拟串口基本不用吧)另外官方提供的驱动程序都是ST厂商标志的,这对于我们来说给客户产品的时候驱动商标是别人公司好像挺不好的,故此鉴于项目的实际开发所需我们一般都是实现一个自定义的USB协议而非什么VCP 大容量的U盘之类的来通信(当然有这个需要的除外).于是就想ST把USB底层的协议都已经搞定了那么修修改改就应该能实现我所需要的了,在这过程中由于对USB协议不必熟悉弄起来不容易,其余的论坛上下载动不动就是要金币或者去买他的开发板才给你源码,或者动不动就是什么VCP来冒充根本就不是我所需要的 本文为cubeMX实现bulk批量传输,实现过程借鉴了网上最小量修改实现HID双向通信http://www.stm32cube.com/article/138 在此致谢Digital_Chip 由于HID的通信速率相对来说不是很高,如果要进行大数据量高速度传输就有可能不太满足条件,故此使用bulk传输是一个不错的选择,好了废话就说这么多了,我把过程发出来一是作为自己弄这个的一个总结将来需要时自己好看一下,二是给其余所需要的人提供点思路,完全免费的啊,不想他们动不动就是你买我开发板我给你源码 (火大)   荒野大嫖客太穷了(呜呜)历时两天才搞定,资质较差如果看官觉得有用给个赞吧一 条件cubeMX4.26.1 MDK5 F1的固件库 芯片stm32F103RCT6(F1系列根据自己的板子来选,我手边没有F4的固定可能有些函数不一样,不过也可以作为一种参考来实现F4)1,开启外部晶振 开启debug功能(我是SWD,如果板载是SWD接口不开启此功能的话第二次下载程序就会下载不进去 需要在复位状态下下载)  开启USB外设 在中间件上选择CDC(虚拟串口,需要用它来改)二:配置系统时钟72MHz(根据自己需要) USB为48MHz(必须)三:更改USB的中间件(可以不更改 自己做实验的话) 如果项目的话更改(比如PID VID更改为自己公司的去掉ST公司的字符串等)我做如下更改1024纪念程序员 鲁班大师(我的最爱,虽然比较坑都一年多了还在钻石 呜呜)四:初始化生成代码五:修改描述符 将usbd_des.c中的USBD_FS_DeviceDesc[USB_LEN_DEV_DESC]数组修改为如下六修改配置描述符 接口描述符等七:将下面的__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] 和__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 数组中的内容修改成和上面的一样就不贴图了八将USB_CDC_CONFIG_DESC_SIZ   修改为32九:定义两个变量 用于缓存数据 (全局的啊,其他.c文件可以访问的 我放在main.c中定义的 申明在头文件 其余所使用的地方包含该头文件) 并修改USBD_CDC_Init入下第二张图片十 :修改USBD_CDC_DataOut如下十一:在main.c的头文件中加载如下头文件 并修改main.c中的while(1)循环如下实现bulk通信回环好到此所有的bulk更改部分已经完成了,下面是见证奇迹的石头,编译程序下载程序不贴图了(由于我之前就做成功了,PID 和VID就是1024所以下完程序后插上USB就自动加载驱动了为了更好的展示效果我将本次的工程的PID和VID更改为如下,展示目前不能加载驱动)下载程序后重新插上USB在电脑的设备管理器中看到了我们的鲁班大师 智商250标志但是是黄色的因为没有驱动嘛右键属性看PID和VID是我们后设置的 可以使用电脑的计算机程序员模式转换至此USB bulk传输过程设备已经完成了验证,下面为试验可以进行通信我是用的是VISA来做驱动的打开NI_VISA Driver Wizard 进入如下界面选择USB 电机next 选中我们的设备 ranh然后一路狂点next知道finish最后驱动制作完成然后重新打开设备管理器查看我们的设备 驱动加载正常 没有了黄色图标以上为驱动制作加载完成,这只是证明了能够识别了,但是能不能通信呢请看下面 还是VISA 目前制作简单测试啊没有写专门的上位机 打开VISA Interactive ctrol 双击我们的设备双击后进入以下界面 可以看到我们设备的一些信息选择input/output界面在发送兰中写入要发送的数据,随便发目前只做了回环没有定义什么命令之类的发送什么,那么就应该回什么点击write变成如下情况点击Read后变成了如下界面通过以上两张图片对比发现我们实现了回环测试发送什么就接受到什么 以上证明了我们的设计是符合要求的,用于项目的话还需要进行相关的数据进行协议组织,同时增加方式提高传输速度等                                                                    以上整理提供by荒野大嫖客     如果有幸你读到这篇文章给个赞吧 查看全部

友情提示请全屏查看(By荒野大嫖客)

ST官方虽然提供很多关于USB固件库集成的(像什么VCP HID等等),但是吧在我们实际的项目开发中VCP(虚拟串口基本不用吧)另外官方提供的驱动程序都是ST厂商标志的,这对于我们来说给客户产品的时候驱动商标是别人公司好像挺不好的,故此鉴于项目的实际开发所需我们一般都是实现一个自定义的USB协议而非什么VCP 大容量的U盘之类的来通信(当然有这个需要的除外).于是就想ST把USB底层的协议都已经搞定了那么修修改改就应该能实现我所需要的了,在这过程中由于对USB协议不必熟悉弄起来不容易,其余的论坛上下载动不动就是要金币或者去买他的开发板才给你源码,或者动不动就是什么VCP来冒充根本就不是我所需要的 本文为cubeMX实现bulk批量传输,实现过程借鉴了网上最小量修改实现HID双向通信http://www.stm32cube.com/article/138 在此致谢Digital_Chip 

由于HID的通信速率相对来说不是很高,如果要进行大数据量高速度传输就有可能不太满足条件,故此使用bulk传输是一个不错的选择,好了废话就说这么多了,我把过程发出来一是作为自己弄这个的一个总结将来需要时自己好看一下,二是给其余所需要的人提供点思路,完全免费的啊,不想他们动不动就是你买我开发板我给你源码 (火大)   荒野大嫖客太穷了(呜呜)历时两天才搞定,资质较差如果看官觉得有用给个赞吧

一 条件cubeMX4.26.1 MDK5 F1的固件库 芯片stm32F103RCT6(F1系列根据自己的板子来选,我手边没有F4的固定可能有些函数不一样,不过也可以作为一种参考来实现F4)

1,开启外部晶振 开启debug功能(我是SWD,如果板载是SWD接口不开启此功能的话第二次下载程序就会下载不进去 需要在复位状态下下载)  开启USB外设 在中间件上选择CDC(虚拟串口,需要用它来改)

image.png

二:配置系统时钟72MHz(根据自己需要) USB为48MHz(必须)

image.png

三:更改USB的中间件(可以不更改 自己做实验的话) 如果项目的话更改(比如PID VID更改为自己公司的去掉ST公司的字符串等)我做如下更改1024纪念程序员 鲁班大师(我的最爱,虽然比较坑都一年多了还在钻石 呜呜)

image.png

四:初始化生成代码

image.png

五:修改描述符 将usbd_des.c中的USBD_FS_DeviceDesc[USB_LEN_DEV_DESC]数组修改为如下

image.png六修改配置描述符 接口描述符等
image.png

七:将下面的__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] 和__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 数组中的内容修改成和上面的一样就不贴图了

八将USB_CDC_CONFIG_DESC_SIZ   修改为32

image.png

九:定义两个变量 用于缓存数据 (全局的啊,其他.c文件可以访问的 我放在main.c中定义的 申明在头文件 其余所使用的地方包含该头文件) 并修改USBD_CDC_Init入下第二张图片


image.png

image.png



十 :修改USBD_CDC_DataOut如下

image.png


十一:在main.c的头文件中加载如下头文件 并修改main.c中的while(1)循环如下实现bulk通信回环

image.png

image.png

好到此所有的bulk更改部分已经完成了,下面是见证奇迹的石头,编译程序下载程序不贴图了(由于我之前就做成功了,PID 和VID就是1024所以下完程序后插上USB就自动加载驱动了为了更好的展示效果我将本次的工程的PID和VID更改为如下,展示目前不能加载驱动)

image.png


下载程序后重新插上USB在电脑的设备管理器中看到了我们的鲁班大师 智商250标志但是是黄色的因为没有驱动嘛

image.png

右键属性看PID和VID是我们后设置的 可以使用电脑的计算机程序员模式转换

image.png


至此USB bulk传输过程设备已经完成了验证,下面为试验可以进行通信我是用的是VISA来做驱动的

打开NI_VISA Driver Wizard 

image.png


进入如下界面


image.png


选择USB 电机next 

image.png

选中我们的设备 ranh然后一路狂点next知道finish最后驱动制作完成

然后重新打开设备管理器查看我们的设备 驱动加载正常 没有了黄色图标

image.png

image.png

以上为驱动制作加载完成,这只是证明了能够识别了,但是能不能通信呢请看下面 还是VISA 目前制作简单测试啊没有写专门的上位机 打开VISA Interactive ctrol 双击我们的设备

image.png

双击后进入以下界面 可以看到我们设备的一些信息

image.png

选择input/output界面

image.png

在发送兰中写入要发送的数据,随便发目前只做了回环没有定义什么命令之类的发送什么,那么就应该回什么

点击write变成如下情况

image.png

点击Read后变成了如下界面

image.png

通过以上两张图片对比发现我们实现了回环测试发送什么就接受到什么 以上证明了我们的设计是符合要求的,用于项目的话还需要进行相关的数据进行协议组织,同时增加方式提高传输速度等

                                                                    以上整理提供by荒野大嫖客     如果有幸你读到这篇文章给个赞吧



多路扫描AD转换,用DMA传输的例子(用STM32CUBEMX)

心中有个梦 回复了问题 • 57 人关注 • 32 个回复 • 29667 次浏览 • 2018-09-03 15:46 • 来自相关话题

分享一个由串口uart接收命令,来动态调整tim定时器pwm模式脉冲宽度的小实验

想飞的四轴 回复了问题 • 45 人关注 • 19 个回复 • 14072 次浏览 • 2018-08-17 12:20 • 来自相关话题

(转)基于STM32Cube库的Timer捕获应用

admin 发表了文章 • 0 个评论 • 2111 次浏览 • 2018-06-14 09:19 • 来自相关话题

当使用Timer做捕获输入时,有时候需要将捕获得到的数据通过DMA方式写到定义好的数据或数组中,本文将详细介绍使用CubeMX配置PWM捕获功能,用户可以直接得到输入的PWM信号的频率以及占空比,Cube库可以很方便配置。实验过程中,当配置超过两个以上的Timer通道DMA时会遇到一些问题,本文也对其进行了说明并给出了解决方案。Timer2的PWM信号捕获功能√使用Timer的IC1,IC2两个捕获输入通道,两个通道的外部管脚输入配置为相同TI1通道;√两个通道的捕获输入极性,一个为Active,另外一个为Inactive;√其中一个TI1FP1作为触发输入,从模式配置为复位模式;√这样CCR1为PWM输入的频率值,CCR2为占空比值(正/负)。使用STM32CubeMX对外设进行初始化配置:Step1: TIM1的输出PWM波作为捕获输入的被测信号,输出管脚为PA8Step2: TIM2的输入管脚为PA5(CH1)Step3: 配置TIM2的输入捕获参数Step4: 捕获数据直接通过DMA方式保存到RAM变量Update_Value1和Update_Value2。Step5: 测试读取到的CCR1、CCR2的数据与Update_Value1、Update_Value2对应,PWM波的频率和占空比都可以捕获得到。实验过程要点提示在stm32f3xx_hal_tim.c库文件中的HAL_TIM_IC_Start_DMA函数中会将状态置忙。但在函数结尾配置完毕后没有将该状态位复位,如果客户在其用户程序中使用了这个函数,这会导致该状态位始终为忙,后续任何对该状态的判断配置都将无法执行:因此需要在函数的最后将状态复位:本文小结本文重点介绍利用STM32CubeMX初始化配置工具和STM32Cube库如何通过TIMER的捕获功能完成对频率、占空比的测试,同时我们对如何解决实验过程中遇到的一些问题,做了特别提示。我们知道STM32Cube库非常庞大,虽难尽善尽美,但一定会越来越强大、越来越完善。本文转自:https://mp.weixin.qq.com/s/e2M22gpqFmOKee36MFe9oQ感谢ST人的分享和付出! 查看全部

当使用Timer做捕获输入时,有时候需要将捕获得到的数据通过DMA方式写到定义好的数据或数组中,本文将详细介绍使用CubeMX配置PWM捕获功能,用户可以直接得到输入的PWM信号的频率以及占空比,Cube库可以很方便配置。

实验过程中,当配置超过两个以上的Timer通道DMA时会遇到一些问题,本文也对其进行了说明并给出了解决方案。

Timer2的PWM信号捕获功能


使用Timer的IC1,IC2两个捕获输入通道,两个通道的外部管脚输入配置为相同TI1通道;

两个通道的捕获输入极性,一个为Active,另外一个为Inactive;

其中一个TI1FP1作为触发输入,从模式配置为复位模式;

这样CCR1为PWM输入的频率值,CCR2为占空比值(正/负)。

webwxgetmsgimg.jpg


使用STM32CubeMX对外设进行初始化配置:


Step1: TIM1的输出PWM波作为捕获输入的被测信号,输出管脚为PA8

Step2: TIM2的输入管脚为PA5(CH1)

webwxgetmsgimg (1).jpg

Step3: 配置TIM2的输入捕获参数

webwxgetmsgimg (2).jpg

Step4: 捕获数据直接通过DMA方式保存到RAM变量Update_Value1和Update_Value2。

webwxgetmsgimg (3).jpg

Step5: 测试读取到的CCR1、CCR2的数据与Update_Value1、Update_Value2对应,PWM波的频率和占空比都可以捕获得到。


webwxgetmsgimg (4).jpg


实验过程要点提示


在stm32f3xx_hal_tim.c

库文件中的HAL_TIM_IC_Start_DMA函数中会将状态置忙。

webwxgetmsgimg (5).jpg

但在函数结尾配置完毕后没有将该状态位复位,如果客户在其用户程序中使用了这个函数,这会导致该状态位始终为忙,后续任何对该状态的判断配置都将无法执行:

webwxgetmsgimg (6).jpg

因此需要在函数的最后将状态复位:

webwxgetmsgimg (7).jpg

本文小结

本文重点介绍利用STM32CubeMX初始化配置工具和STM32Cube库如何通过TIMER的捕获功能完成对频率、占空比的测试,同时我们对如何解决实验过程中遇到的一些问题,做了特别提示。我们知道STM32Cube库非常庞大,虽难尽善尽美,但一定会越来越强大、越来越完善。



本文转自:https://mp.weixin.qq.com/s/e2M22gpqFmOKee36MFe9oQ


感谢ST人的分享和付出!

CAN的Loopback模式例程的设置及程序分析

虎扑最大的吊 回复了问题 • 6 人关注 • 7 个回复 • 6219 次浏览 • 2018-06-10 19:56 • 来自相关话题

抛砖引玉:一步一步Hal库学习usb虚拟串口功能CDC或者叫VCP

星期五 回复了问题 • 49 人关注 • 22 个回复 • 37326 次浏览 • 2018-03-03 19:05 • 来自相关话题

一步步实现stm32F103RBT6的DFU实验记录

Playnetics 回复了问题 • 9 人关注 • 6 个回复 • 11405 次浏览 • 2018-01-07 21:16 • 来自相关话题

分享:利用stm32cube的Hal库以四线方式操作LCD1602的方法和操作示例

红烧鱼 回复了问题 • 7 人关注 • 9 个回复 • 6285 次浏览 • 2017-07-19 23:41 • 来自相关话题

Encoder模式的分析方法和使用技巧(利用Tim1定时器encoder接口)

admin 发表了文章 • 5 个评论 • 6124 次浏览 • 2017-06-09 11:24 • 来自相关话题

测试工具:keil5 , stm32cubemx , stm32F407discovery板卡, 广数凯恩帝数控CNC电子手轮(5V六端子100脉冲)应为discovery板并没有内置手轮的差分式外部电路,所以手轮我只用到了vcc ,gnd ,A+,B+这四个端子分别接到了5V,0V,PE11,PE9这几个引脚上面,硬件未滤波,只是提供演示参考.以下是cubemx中的配置信息1,选中tim1的encoder模式2,根据discovery板设置时钟3,配置tim1的各种参数,这里我随意设置的,2分频,重载值为10000,各个io口是上升沿计数,这里我编码器模式使用的是TT1,因为我不想用那么复杂的多沿计数,只计数TT1的通道脉冲,这样方便程序的编写使用.滤波我设置的3模式,不知道效果如何.下面是TIM1的两个管脚的配置,PE9和PE11的,因为电子手轮输出的是高低电平,所以板卡就不需要上下拉了,直接用OD模式最好.4,编译生成代码,然后打开工程.在main.c文件中user0处添加两个变量,分别准备存储方向信号和脉冲信号/* USER CODE BEGIN 0 */
uint32_t uwDirection = 0;
uint32_t pulsecount = 0;
/* USER CODE END 0 */在main()函数中添加encoder的启动和初始化计数器值为0    /* USER CODE BEGIN 2 */
    HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
    //初始化计数器值为0
    __HAL_TIM_SetCounter(&htim1,0);
    /* USER CODE END 2 */然后在大循环while中添加获取方向信号和脉冲数量的代码    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        //获取转动方向,0正转,1反转
        uwDirection = __HAL_TIM_DIRECTION_STATUS(&htim1);

        //获取计数器计数值,即手轮脉冲计数
        pulsecount = __HAL_TIM_GetCounter(&htim1);

    }ok,代码编写完成了.编译烧写,然后点击keil的调试按钮调试这里我们分别在uwDirection和pulsecount上面点击右键,选择add 到 watch1中另外也添加htm1到观察1中然后点击左侧的全速运行,此时可以看到watch1观察口里是没有任何变化的,这时候你转动手轮,里面的值开始变化正转手轮pulsecount的计数开始从0一个一个增加,反转一下减少一个数值,同样的正转的时候direction一直是0,反转的时候就变成了1具体的操作可以看此贴顶部第一个动态图片.此次教程结束.具体到怎么去用这个encoder,还要考虑定时器的重载事件update,所以还要启用tim的update中断,在中断中记录中断的次数,然后结合你的autoreload数相乘得到实际的转动脉冲数.这里不再具体讲述. 查看全部

1496977140559287.png

GIF.gif

测试工具:

keil5 , stm32cubemx , stm32F407discovery板卡, 广数凯恩帝数控CNC电子手轮(5V六端子100脉冲)

blob.png

应为discovery板并没有内置手轮的差分式外部电路,所以手轮我只用到了vcc ,gnd ,A+,B+这四个端子

分别接到了5V,0V,PE11,PE9这几个引脚上面,硬件未滤波,只是提供演示参考.


以下是cubemx中的配置信息

1,选中tim1的encoder模式

blob.png

2,根据discovery板设置时钟

blob.png

3,配置tim1的各种参数,这里我随意设置的,2分频,重载值为10000,各个io口是上升沿计数,这里我编码器模式使用的是TT1,因为我不想用那么复杂的多沿计数,只计数TT1的通道脉冲,这样方便程序的编写使用.滤波我设置的3模式,不知道效果如何.

blob.png

下面是TIM1的两个管脚的配置,PE9和PE11的,因为电子手轮输出的是高低电平,所以板卡就不需要上下拉了,直接用OD模式最好.

blob.png

4,编译生成代码,然后打开工程.

在main.c文件中user0处添加两个变量,分别准备存储方向信号和脉冲信号

/* USER CODE BEGIN 0 */
uint32_t uwDirection = 0;
uint32_t pulsecount = 0;
/* USER CODE END 0 */

在main()函数中添加encoder的启动和初始化计数器值为0

    /* USER CODE BEGIN 2 */
    HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
    //初始化计数器值为0
    __HAL_TIM_SetCounter(&htim1,0);
    /* USER CODE END 2 */

然后在大循环while中添加获取方向信号和脉冲数量的代码

    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        //获取转动方向,0正转,1反转
        uwDirection = __HAL_TIM_DIRECTION_STATUS(&htim1);

        //获取计数器计数值,即手轮脉冲计数
        pulsecount = __HAL_TIM_GetCounter(&htim1);

    }

ok,代码编写完成了.

编译烧写,然后点击keil的调试按钮调试

blob.png

这里我们分别在uwDirection和pulsecount上面点击右键,选择add 到 watch1中

另外也添加htm1到观察1中

blob.png

然后点击左侧的全速运行,

此时可以看到watch1观察口里是没有任何变化的,这时候你转动手轮,里面的值开始变化

正转手轮pulsecount的计数开始从0一个一个增加,反转一下减少一个数值,同样的正转的时候direction一直是0,反转的时候就变成了1


具体的操作可以看此贴顶部第一个动态图片.


此次教程结束.

具体到怎么去用这个encoder,还要考虑定时器的重载事件update,所以还要启用tim的update中断,在中断中记录中断的次数,然后结合你的autoreload数相乘得到实际的转动脉冲数.这里不再具体讲述.


(转)通过配置SPI1完成W25X16的读写

²º¹5¾ 回复了问题 • 6 人关注 • 2 个回复 • 3611 次浏览 • 2017-06-07 12:00 • 来自相关话题

STM32F042F6P6-USB设备开发最小系统之键盘示例

井底添蛙 发表了文章 • 5 个评论 • 7715 次浏览 • 2017-06-03 00:14 • 来自相关话题

最常见的USB设备要数鼠标和键盘了,STM32F042F6P6这块小板(这里可购买,留言有优惠:购买链接)的鼠标示例已经写了,现在来写下模拟键盘的示例.不多说,开始配置,打开STM32CubeMX,选择STM32F042F6P6芯片,开启pin脚映射,打开USB设备,选择USB设备为HID,设置按键和LED对应引脚的输入输出模式:配置按键和LED引脚的状态及备注名:可以在此修改USB设备名称、厂家、PID\VID等:配置工程输出参数,然后生成并打开工程:按图中所示打开usbd_hid.c文件,找到HID_MOUSE_ReportDesc数组定义处(默认生产HID设备为Mouse,这里数组名不影响,只要里面的描述符是键盘的就行),修改成如下数据: 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //63
 0x09, 0x06, // USAGE (Keyboard)
 0xa1, 0x01, // COLLECTION (Application)
 0x05, 0x07, // USAGE_PAGE (Keyboard)
 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
 0x15, 0x00, // LOGICAL_MINIMUM (0)
 0x25, 0x01, // LOGICAL_MAXIMUM (1)
 0x75, 0x01, // REPORT_SIZE (1)
 0x95, 0x08, // REPORT_COUNT (8)
 0x81, 0x02, // INPUT (Data,Var,Abs)
 0x95, 0x01, // REPORT_COUNT (1)
 0x75, 0x08, // REPORT_SIZE (8)
 0x81, 0x03, // INPUT (Cnst,Var,Abs)
 0x95, 0x05, // REPORT_COUNT (5)
 0x75, 0x01, // REPORT_SIZE (1)
 0x05, 0x08, // USAGE_PAGE (LEDs)
 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
 0x29, 0x05, // USAGE_MAXIMUM (Kana)
 0x91, 0x02, // OUTPUT (Data,Var,Abs)
 0x95, 0x01, // REPORT_COUNT (1)
 0x75, 0x03, // REPORT_SIZE (3)
 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
 0x95, 0x06, // REPORT_COUNT (6)
 0x75, 0x08, // REPORT_SIZE (8)
 0x15, 0x00, // LOGICAL_MINIMUM (0)
 0x25, 0x65, // LOGICAL_MAXIMUM (101)
 0x05, 0x07, // USAGE_PAGE (Keyboard)
 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
 0x81, 0x00, // INPUT (Data,Ary,Abs)
 0xc0, // END_COLLECTION再打开usbd_hid.h文件,修改HID_MOUSE_REPORT_DESC_SIZE的值为63.编译工程,下载到板子上,插上USB线连接到电脑上,是不是识别出为键盘设备了呢?继续修改main.c文件,添加头文件#include "usbd_hid.h"添加一个数组变量,用于传输键盘参数的,byte0是传控制键;byte1是保留键,不用改;byte3~byte7都可以存放传输的按键值 /*
 * buffer[0] - bit0: Left CTRL
 *           -bit1: Left SHIFT
 *           -bit2: Left ALT
 *           -bit3: Left GUI
 *           -bit4: Right CTRL
 *           -bit5: Right SHIFT
 *           -bit6: Right ALT
 *           -bit7: Right GUI 
 * buffer[1] - Padding = Always 0x00
 * buffer[2] - Key 1
 * buffer[3] - Key 2
 * buffer[4] - Key 3
 * buffer[5] - Key 4
 * buffer[6] - Key 5
 * buffer[7] - Key 6
 */
 uint8_t buffer[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};添加按键检测及传输键值到电脑的代码: if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin) == 0)
 {
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
 
  buffer[0] = 0x02; //shift
  buffer[2] = 0x04; // a
  USBD_HID_SendReport(&hUsbDeviceFS, buffer, 8); //send
  HAL_Delay(15); //delay
 
  buffer[0] = 0x00;
  buffer[2] = 0x00;
  USBD_HID_SendReport(&hUsbDeviceFS, buffer, 8);
  HAL_Delay(15);
 
  while(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin) == 0)
  HAL_Delay(15);
 }
 else
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);对应键值可和此文件中的HID Usage ID对应,是16进制(如字符‘a’对应键值为0x04),pdf文件在附件中有(USB_HIDtoKBScanCodeTranslationTable.pdf):再编译文件下载到板子上,试试按下按键时是不是在电脑上就输入了一个大写的‘A’呢? 查看全部

最常见的USB设备要数鼠标和键盘了,STM32F042F6P6这块小板(这里可购买,留言有优惠:购买链接)的鼠标示例已经写了,现在来写下模拟键盘的示例.

不多说,开始配置,打开STM32CubeMX,选择STM32F042F6P6芯片,开启pin脚映射,打开USB设备,选择USB设备为HID,设置按键和LED对应引脚的输入输出模式:

配置按键和LED引脚的状态及备注名:

可以在此修改USB设备名称、厂家、PID\VID等:

配置工程输出参数,然后生成并打开工程:

按图中所示打开usbd_hid.c文件,找到HID_MOUSE_ReportDesc数组定义处(默认生产HID设备为Mouse,这里数组名不影响,只要里面的描述符是键盘的就行),修改成如下数据:

 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //63
 0x09, 0x06, // USAGE (Keyboard)
 0xa1, 0x01, // COLLECTION (Application)
 0x05, 0x07, // USAGE_PAGE (Keyboard)
 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
 0x15, 0x00, // LOGICAL_MINIMUM (0)
 0x25, 0x01, // LOGICAL_MAXIMUM (1)
 0x75, 0x01, // REPORT_SIZE (1)
 0x95, 0x08, // REPORT_COUNT (8)
 0x81, 0x02, // INPUT (Data,Var,Abs)
 0x95, 0x01, // REPORT_COUNT (1)
 0x75, 0x08, // REPORT_SIZE (8)
 0x81, 0x03, // INPUT (Cnst,Var,Abs)
 0x95, 0x05, // REPORT_COUNT (5)
 0x75, 0x01, // REPORT_SIZE (1)
 0x05, 0x08, // USAGE_PAGE (LEDs)
 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
 0x29, 0x05, // USAGE_MAXIMUM (Kana)
 0x91, 0x02, // OUTPUT (Data,Var,Abs)
 0x95, 0x01, // REPORT_COUNT (1)
 0x75, 0x03, // REPORT_SIZE (3)
 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
 0x95, 0x06, // REPORT_COUNT (6)
 0x75, 0x08, // REPORT_SIZE (8)
 0x15, 0x00, // LOGICAL_MINIMUM (0)
 0x25, 0x65, // LOGICAL_MAXIMUM (101)
 0x05, 0x07, // USAGE_PAGE (Keyboard)
 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
 0x81, 0x00, // INPUT (Data,Ary,Abs)
 0xc0, // END_COLLECTION

再打开usbd_hid.h文件,修改HID_MOUSE_REPORT_DESC_SIZE的值为63.

编译工程,下载到板子上,插上USB线连接到电脑上,是不是识别出为键盘设备了呢?

继续修改main.c文件,添加头文件

#include "usbd_hid.h"

添加一个数组变量,用于传输键盘参数的,byte0是传控制键;byte1是保留键,不用改;byte3~byte7都可以存放传输的按键值

 /*
 * buffer[0] - bit0: Left CTRL
 *           -bit1: Left SHIFT
 *           -bit2: Left ALT
 *           -bit3: Left GUI
 *           -bit4: Right CTRL
 *           -bit5: Right SHIFT
 *           -bit6: Right ALT
 *           -bit7: Right GUI 
 * buffer[1] - Padding = Always 0x00
 * buffer[2] - Key 1
 * buffer[3] - Key 2
 * buffer[4] - Key 3
 * buffer[5] - Key 4
 * buffer[6] - Key 5
 * buffer[7] - Key 6
 */
 uint8_t buffer[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

添加按键检测及传输键值到电脑的代码:

 if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin) == 0)
 {
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
 
  buffer[0] = 0x02; //shift
  buffer[2] = 0x04; // a
  USBD_HID_SendReport(&hUsbDeviceFS, buffer, 8); //send
  HAL_Delay(15); //delay
 
  buffer[0] = 0x00;
  buffer[2] = 0x00;
  USBD_HID_SendReport(&hUsbDeviceFS, buffer, 8);
  HAL_Delay(15);
 
  while(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin) == 0)
  HAL_Delay(15);
 }
 else
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

对应键值可和此文件中的HID Usage ID对应,是16进制(如字符‘a’对应键值为0x04),pdf文件在附件中有(USB_HIDtoKBScanCodeTranslationTable.pdf):

再编译文件下载到板子上,试试按下按键时是不是在电脑上就输入了一个大写的‘A’呢?