STM32 基础系列教程 24 - USB_HID_key

发布者:备战最新更新时间:2019-05-05 来源: eefocus关键字:STM32  基础系列教程  USB_HID_key 手机看文章 扫描二维码
随时随地手机看文章

前言


学习stm32 USB接口使用,学会用CUBE工具快速创建USB设备工程及调试,关于usb的相关知道请读者提前准备并学习,当然如果不想深究其中原理的话,跟着本文来操作就可以实现基于USB的设备开发了。需要提示的是,stm32在使用usb接口功能是一般需要在DP引脚上上拉一个1.5K电阻到3.3V(部分MCU内部会上拉)。


示例详解


基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。

本示例所用的最小系统板原理图:

从本节开始,关于CUBEMX工具及KEIL工具的操作将不再细讲,如果还有不熟悉的可以查看之前的教程文档。下面直接介绍工程配置:

 

系统时钟树

USB接口配置


USB设备配置(选择Human Interface Device Class(HID),参数可保持默认)

引脚配置


中断配置(保持默认)

工程代码

在usbd_hid.h中做如下更改:


在usbd_hid.c中做如下更改:


/* USB HID device Configuration Descriptor */


__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ]  __ALIGN_END =


{


 


#if 0


  0x09, /* bLength: Configuration Descriptor size */


  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */


  USB_HID_CONFIG_DESC_SIZ,


  /* wTotalLength: Bytes returned */


  0x00,


  0x01,         /*bNumInterfaces: 1 interface*/


  0x01,         /*bConfigurationValue: Configuration value*/


  0x00,         /*iConfiguration: Index of string descriptor describing


  the configuration*/


  0xE0,         /*bmAttributes: bus powered and Support Remote Wake-up */


  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/


 


  /************** Descriptor of Joystick Mouse interface ****************/


  /* 09 */


  0x09,         /*bLength: Interface Descriptor size*/


  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/


  0x00,         /*bInterfaceNumber: Number of Interface*/


  0x00,         /*bAlternateSetting: Alternate setting*/


  0x01,         /*bNumEndpoints*/


  0x03,         /*bInterfaceClass: HID*/


  0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/


  0x02,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/


  0,            /*iInterface: Index of string descriptor*/


  /******************** Descriptor of Joystick Mouse HID ********************/


  /* 18 */


  0x09,         /*bLength: HID Descriptor size*/


  HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/


  0x11,         /*bcdHID: HID Class Spec release number*/


  0x01,


  0x00,         /*bCountryCode: Hardware target country*/


  0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/


  0x22,         /*bDescriptorType*/


  HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/


  0x00,


  /******************** Descriptor of Mouse endpoint ********************/


  /* 27 */


  0x07,          /*bLength: Endpoint Descriptor size*/


  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/


 


  HID_EPIN_ADDR,     /*bEndpointAddress: Endpoint Address (IN)*/


  0x03,          /*bmAttributes: Interrupt endpoint*/


  HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */


  0x00,


  HID_FS_BINTERVAL,          /*bInterval: Polling Interval (10 ms)*/


  /* 34 */


      


#else


       /************** Descriptor of Configuation ****************/


  0x09, /* bLength: Configuation Descriptor size */


  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */


  USB_HID_CONFIG_DESC_SIZ,


  /* wTotalLength: Bytes returned */


  0x00,


  0x01,         /* bNumInterfaces: 1 interface */


  0x01,         /* bConfigurationValue: Configuration value */


  0x00,         /* iConfiguration: Index of string descriptor describing the configuration*/


  0xe0,         /* bmAttributes: Bus powered */ //160911


  /*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits */


  0xFA,         /* MaxPower 500 mA: this current is used for detecting Vbus */          //160911 以2mA为单位


//            0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */


//    0x96,         /* MaxPower 300 mA: this current is used for detecting Vbus */


 


  /************** Descriptor of Custom HID interface ****************/


  /* 09 */


  0x09,         /* bLength: Interface Descriptor size */


  USB_DESC_TYPE_INTERFACE,/* bDescriptorType: Interface descriptor type = 4*/


  0x00,         /* bInterfaceNumber: Number of Interface */


  0x00,         /* bAlternateSetting: Alternate setting */


  0x02,         /* bNumEndpoints */


  0x03,         /* bInterfaceClass: HID */


  0x01,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */


  0x01,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */


  0,            /* iInterface: Index of string descriptor */


 


  /******************** Descriptor of Custom HID ********************/


  /* 18 */


  0x09,         /* bLength: HID Descriptor size */


  HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */


  0x10,0x01,            /* bcdHID: HID Class Spec release number */ //160911 设备版本号BCD码


  0x00,         /* bCountryCode: Hardware target country */


  0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */


  0x22,         /* bDescriptorType */


  CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */


  0x00,


 


  /******************** Descriptor of Custom HID endpoints ******************/


  /* 27 */


  0x07,                   /* bLength: Endpoint Descriptor size */


  USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: = 5*/


  0x82,            /* bEndpointAddress: (IN) = 2*/


  // bit 3...0 : the endpoint number


  // bit 6...4 : reserved


  // bit 7     : 0(OUT), 1(IN)


  0x03,                   /* bmAttributes: Interrupt endpoint */ //160911 0-1bit定义了传输类型,00=控制,01=同步,10=批量,11=中断事务


  //160911 00=Control, 01=Isochronous, 10=Bulk, 11=Interrupt Transaction


  0x08,                   /* wMaxPacketSize: 64 40 Bytes max  */


  0x00,                   //High 8 bit of wMaxPacketSize


  0x01,                   /* bInterval: Polling Interval (1 ms) */  //160911 Used in 01,03 Transaction


  /* 34 */


  0x07,                   /* bLength: Endpoint Descriptor size */


  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: = 5*/


  0x01,            /* bEndpointAddress: (OUT) = 1*/


  0x03,                   /* bmAttributes: Interrupt endpoint */ //160911 0-1bit定义了传输类型,00=控制,01=同步,10=批量,11=中断事务


  //160911 00=Control, 01=Isochronous, 10=Bulk, 11=Interrupt Transaction


  0x08,                   /* wMaxPacketSize: 64 40 Bytes max  */


  0x00,                   //High 8 bit of wMaxPacketSize


  0x01,                   /* bInterval: Polling Interval (1 ms) */  //160911 Used in 01,03 Transaction


  /* 41 */


 


#endif


 


} ;


加入


__ALIGN_BEGIN static uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =


{


  0x05, 0x01, // USAGE_PAGE (Generic Desktop)


  0x09, 0x06, // USAGE (Keyboard)


  0xa1, 0x01, // COLLECTION (Application)


 


  // 输入,第一个字节表示特殊功能键 LeftControl -- Right GUI


  0x05, 0x07, //     USAGE_PAGE (Keyboard/Keypad)


  0x19, 0xe0, //     USAGE_MINIMUM (Keyboard LeftControl)


  0x29, 0xe7, //     USAGE_MAXIMUM (Keyboard Right GUI)


  0x15, 0x00, //     LOGICAL_MINIMUM (0)


  0x25, 0x01, //     LOGICAL_MAXIMUM (1)


  0x95, 0x08, //     REPORT_COUNT (8)


  0x75, 0x01, //     REPORT_SIZE (1)


  0x81, 0x02, //     INPUT (Data,Var,Abs)


 


  // 输入,第二个字节是常值0,给OEM使用


  0x95, 0x01, //     REPORT_COUNT (1)


  0x75, 0x08, //     REPORT_SIZE (8)


  0x81, 0x03, //     INPUT (Cnst,Var,Abs)


 


  // 输入,第三到8个字节,用来表示最多同时6个按键按下


  0x95, 0x06, //   REPORT_COUNT (6)


  0x75, 0x08, //   REPORT_SIZE (8)


  0x25, 0xFF, //   LOGICAL_MAXIMUM (255)


  0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))


  0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)


  0x81, 0x00, //     INPUT (Data,Ary,Abs)


 


  // 输出,第一个字节前两位 分别表示两个LED灯状态


  0x25, 0x01, //     LOGICAL_MAXIMUM (1)


  0x95, 0x02, //   REPORT_COUNT (2)


  0x75, 0x01, //   REPORT_SIZE (1)


  0x05, 0x08, //   USAGE_PAGE (LEDs)


  0x19, 0x01, //   USAGE_MINIMUM (Num Lock)

[1] [2]
关键字:STM32  基础系列教程  USB_HID_key 引用地址:STM32 基础系列教程 24 - USB_HID_key

上一篇:STM32 基础系列教程 25 - USB_HID_mouse
下一篇:STM32 基础系列教程 23 - USB_cdc

推荐阅读最新更新时间:2024-11-13 17:50

谈一下STM32的启动流程
STM32三种启动模式 下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存,这就是所谓的启动过程。 STM32上电或者复位后,代码区始终从0x00000000开始,其实就是将存储空间的地址映射到0x00000000中。三种启动模式如下: 从主闪存存储器启动,将主Flash地址0x08000000映射到0x00000000,这样代码启动之后就相当于从0x08000000开始。主闪存存储器是STM32内置的Flash,作为芯片内置的Flash,是正常的工作模式。一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。 从系统存储器启动。首先控制BOOT0、BOOT1管脚
[单片机]
谈一下<font color='red'>STM32</font>的启动流程
stm32对flash的读写保护与解除
一、STM32对内部Flash的保护措施 所有STM32的芯片都提供对Flash的保护,防止对Flash的非法访问 - 写保护和读保护。 1、读保护即大家通常说的“加密”,是作用于整个Flash存储区域。一旦设置了Flash的读保护,内置的Flash存储区只能通过程序的正常执行才能读出,而不能通过下述任何一种方式读出:A、 通过调试器(JTAG或SWD); B、从RAM中启动并执行的程序; 2、写保护是以四页(1KB/页) Flash存储区为单位提供写保护,对被保护的页实施编程或擦除操作将不被执行,同时产生操作错误标志。 读与写设置的效果见下表: 读保护 写保护 对Flash的操作功能 有效 有效 CPU只能
[单片机]
<font color='red'>stm32</font>对flash的读写保护与解除
STM32上使用UCOSII--软件定时器和任务延时
一、软件定时器 UCOSII 从 V2.83 版本以后,加入了软件定时器,这使得UCOSII的功能更加完善,在其上的应用程序开发与移植也更加方便。在实时操作系统中一个好的软件定时器实现要求有较高的精度、较小的处理器开销,且占用较少的存储器资源。 UCOSII 通过 OSTimTick函数对时钟节拍进行加1操作,同时遍历任务控制块,以判断任务延时是否到时。软件定时器同样由OSTimTick提供时钟,但是软件定时器的时钟还受OS_TMR_CFG_TICKS_PER_SEC 设置的控制,也就是在UCOSII的时钟节拍上面再做了一次“分频”,软件定时器的最快时钟节拍就等于 UCOSII 的系统时钟节拍。这也决定了软件定时器的精度。
[单片机]
STM32使用LC10模块实现串口以太网与串口数据库功能
往期文章中,我们介绍了“使用LS10串口数据库模块实现单片机本地SQL数据库数据存取功能”,见电子发烧友链接:https://bbs.elecfans.com/jishu_2290773_1_1.html 本文介绍的LC10模块是对LS10模块的硬件与软件升级,LC10模块不仅支持串口数据库功能,还支持串口以太网功能。(仅需要串口数据库功能的小伙伴,请依然关注LS10模块哦) LC10模块支持建立5路tcp socket,支持域名,支持DHCP。 AT命令手册下载地址: 链接:https://pan.baidu.com/s/11drK4TtZOkejpPWviodvYQ 提取码:LC10 tcp AT命令举例如下: Rdy //
[单片机]
STM32启动过程全解
本文主要阐述了STM32启动过程全面解析,包括启动过程的介绍、启动代码的陈列以及深入解析。   相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC = 0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况:   1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;  
[模拟电子]
<font color='red'>STM32</font>启动过程全解
STM32学习笔记(2):外部中断的使用
中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。今天就将来探讨一下关于STM32中的中断系统。 1 基本概念 ARM Coetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。 STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字
[单片机]
定时器做PWM脉冲
简介 STM32 的定时器除了 TIM6 和 TIM7。其他的定时器都可以用来产生 PWM 输出。 高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。 通用定时器也能同时产生多达 4路的 PWM 输出, PWM 寄存器与功能原理 TIMx_CCR1~4,捕获/比较寄存器 该寄存器的值与 CNT 的值比较,可以控制 PWM 的输出脉宽 TIMx_CCMR1/2,捕获 / 比较模式寄存器 CCMR1/2:OCxM 位,用于设置 PWM模式1 ,只要TIMx_CNT CCR(计数值小于比较标准值)则为有效电平 PWM模式2 ,只要TIMx_CNT CCR(计数值小于比较标准
[单片机]
stm32中的NVIC_Configuration(void)函数
用于映射中断的处理函数,就知道这么多,不求甚解呀, void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved