自制usb数字键盘(二) 基于stm32cubemx HAL库 usb hid协议
前言
要写一个比较规范的 系统还是比较复杂的。而这次的逻辑代码部分的编写,只是个人觉得较为规范,所以单写一篇,附有注释,和部分讲解。
前一篇,关于基本配置和知识:自制usb数字键盘(一)配置部分
以及,可以先看看我之前写的关于 c 语言 回调函数 的实现:点这里啦
按键部分
参考了网上的工程,个人觉得规范性很棒,于是移植到了这个工程里。
buttom.h 按键头文件部分
#ifndef _MULTI_BUTTON_H_
#define _MULTI_BUTTON_H_
#include "stdint.h"
#include "string.h"
//According to your need to modify the constants.
#define TICKS_INTERVAL 5 //ms 时间间隔
#define DEBOUNCE_TICKS 3 //MAX 8 消抖间隔
#define SHORT_TICKS (300 /TICKS_INTERVAL) //短周期
#define LONG_TICKS (1000 /TICKS_INTERVAL) //长周期
typedef void (*BtnCallback)(void*); //一个参数为任意类型指针的
typedef enum {
PRESS_DOWN = 0,
PRESS_UP,
PRESS_REPEAT,
SINGLE_CLICK,
DOUBLE_CLICK,
LONG_RRESS_START,
LONG_PRESS_HOLD,
number_of_event,
NONE_PRESS
}PressEvent; //按键状态定义
typedef struct Button {
uint16_t ticks; //时间计数
uint8_t repeat : 4; //重复
uint8_t event : 4; //按键状态事件
uint8_t state : 3; //状态?
uint8_t debounce_cnt : 3; //去抖动
uint8_t active_level : 1; //设置按键有效的电平状态
uint8_t button_level : 1; //按键实时电平状态
uint8_t (*hal_button_Level)(void); //获取按键电平 函数指针
BtnCallback cb[number_of_event]; //7种事件状态的回调函数数组 其实也就是函数指针 数组
struct Button* next; //链表,指向下一个按键结构体
}Button;
#ifdef __cplusplus //兼容c++ 的头文件定义
extern "C" {
#endif
void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level);
void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);
PressEvent get_button_event(struct Button* handle);
int button_start(struct Button* handle);
void button_stop(struct Button* handle);
void button_ticks(void);
#ifdef __cplusplus
}
#endif
#endif
这里面比如 长按, 双击 等,在此本文中没有用到,但增加了拓展性,可以自由发挥
buttom.c 按键 实现部分
这里的 回调函数实现 最好跟着 ,上面那篇文章一起看,便于理解。
#include "buttom.h"
#define EVENT_CB(ev) if(handle->cb[ev])handle->cb[ev]((Button*)handle) //回调函数
//button handle list head.
static struct Button* head_handle = NULL; // 准确的说应该是链表尾
//按键初始化
/**
* @brief Initializes the button struct handle.
* @param handle: the button handle strcut.
* @param pin_level: read the HAL GPIO of the connet button level.
* @param active_level: pressed GPIO level.
* @retval None
*/
void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level)
{
memset(handle, sizeof(struct Button), 0); //全部归零
handle->event = (uint8_t)NONE_PRESS; //初始状态
handle->hal_button_Level = pin_level;
handle->button_level = handle->hal_button_Level();
handle->active_level = active_level;
}
//连接 回调函数
/**
* @brief Attach the button event callback function.
* @param handle: the button handle strcut.
* @param event: trigger event type.
* @param cb: callback function.
* @retval None
*/
void button_attach(struct Button* handle, PressEvent event, BtnCallback cb)
{
handle->cb[event] = cb;
}
//获得按键事件
/**
* @brief Inquire the button event happen.
* @param handle: the button handle strcut.
* @retval button event.
*/
PressEvent get_button_event(struct Button* handle)
{
return (PressEvent)(handle->event);
}
//按键处理函数
/**
* @brief Button driver core function, driver state machine.
* @param handle: the button handle strcut.
* @retval None
*/
void button_handler(struct Button* handle)
{
uint8_t read_gpio_level = handle->hal_button_Level();
//ticks counter working..
if((handle->state) > 0) handle->ticks++;
/*------------button debounce handle---------------*/
if(read_gpio_level != handle->button_level) { //如果不等于上一次的电平,说明发送了跳变
//continue read 3 times same new level change
if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) {
handle->button_level = read_gpio_level;
handle->debounce_cnt = 0;
}
} else { //leved not change ,counter reset.
handle->debounce_cnt = 0;
}
/*-----------------State machine-------------------*/
switch (handle->state) { //开始为即 0
case 0:
if(handle->button_level == handle->active_level) { //start press down
handle->event = (uint8_t)PRESS_DOWN;
EVENT_CB(PRESS_DOWN);
handle->ticks = 0;
handle->repeat = 1; //重复 计数+1
handle->state = 1; //按下后状态 变为 1
} else {
handle->event = (uint8_t)NONE_PRESS;
}
break;
case 1:
if(handle->button_level != handle->active_level) { //按键释放
handle->event = (uint8_t)PRESS_UP;
EVENT_CB(PRESS_UP);
handle->ticks = 0;
handle->state = 2; //释放后状态变为 2
} else if(handle->ticks > LONG_TICKS) {
handle->event = (uint8_t)LONG_RRESS_START;
EVENT_CB(LONG_RRESS_START);
handle->state = 5; //如果按下时间超过 长间隔 状态变为5
}
break;
case 2:
if(handle->button_level == handle->active_level) { //检测到再次按下
handle->event = (uint8_t)PRESS_DOWN;
EVENT_CB(PRESS_DOWN);
handle->repeat++;
if(handle->repeat == 2) {
EVENT_CB(DOUBLE_CLICK); // repeat hit
}
EVENT_CB(PRESS_REPEAT); // repeat hit
handle->ticks = 0; //计数归 0
handle->state = 3; //第二次被按下 但还没有释放 状态变为3
} else if(handle->ticks > SHORT_TICKS) { //如果单击过后 短间隔内 没有再次按下
if(handle->repeat == 1) {
handle->event = (uint8_t)SINGLE_CLICK;
EVENT_CB(SINGLE_CLICK);
} else if(handle->repeat == 2) {
handle->event = (uint8_t)DOUBLE_CLICK;
}
handle->state = 0;
}
break;
case 3:
if(handle->button_level != handle->active_level) { //如果第二次被释放
handle->event = (uint8_t)PRESS_UP;
EVENT_CB(PRESS_UP);
if(handle->ticks < SHORT_TICKS) { //如果第二次 按下持续时间小于短间隔
handle->ticks = 0;
handle->state = 2; // 状态 为 2
} else {
handle->state = 0; // 状态 归 0
}
}
break;
case 5:
if(handle->button_level == handle->active_level) { //如果 为单次长按
//continue hold trigger
handle->event = (uint8_t)LONG_PRESS_HOLD;
EVENT_CB(LONG_PRESS_HOLD);
} else { //releasd
handle->event = (uint8_t)PRESS_UP;
EVENT_CB(PRESS_UP);
handle->state = 0; //reset //释放后归 0
}
break;
}
}
//添加按键结构体 到链表里
/**
* @brief Start the button work, add the handle into work list.
* @param handle: target handle strcut.
* @retval 0: succeed. -1: already exist.
*/
int button_start(struct Button* handle)
{
struct Button* target = head_handle;
while(target) {
if(target == handle) return -1; //already exist.
target = target->next;
} //查询是否已经加入 该按键结构体
handle->next = head_handle; // 在尾部直接插入链表
head_handle = handle; // 设置新的链表尾
return 0;
}
//从链表里删去该结构体
/**
* @brief Stop the button work, remove the handle off work list.
* @param handle: target handle strcut.
* @retval None
*/
void button_stop(struct Button* handle)
{
struct Button** curr;
for(curr = &head_handle; *curr; ) {
struct Button* entry = *curr;
if (entry == handle) {
*curr = entry->next;
// free(entry);
} else
curr = &entry->next;
}
}
//在定时器里 每5ms调用一次,刷新每个按键的状态
/**
* @brief background ticks, timer repeat invoking interval 5ms.
* @param None.
* @retval None
*/
void button_ticks()
{
struct Button* target;
for(target=head_handle; target; target=target->next) {
button_handler(target);
}
}
usb键盘部分
usb键盘头文件部分 keyboard_hid.h
#ifndef TM_USB_HIDDEVICE_H
#define TM_USB_HIDDEVICsE_H 100
//usb状态描述
/**
* @brief USB HID device enumeration
*/
typedef enum {
TM_USB_HIDDEVICE_Status_LibraryNotInitialized = 0x00, /*!< Library is not initialized yet */
TM_USB_HIDDEVICE_Status_Connected, /*!< Device is connected and ready to use */
TM_USB_HIDDEVICE_Status_Disconnected, /*!< Device is not connected */
TM_USB_HIDDEVICE_Status_IdleMode, /*!< Device is is IDLE mode */
TM_USB_HIDDEVICE_Status_SuspendMode /*!< Device is in suspend mode */
} TM_USB_HIDDEVICE_Status_t;
//按键状态描述
/**
* @brief Button status enumeration
*/
typedef enum {
TM_USB_HIDDEVICE_Button_Released = 0x00, /*!< Button is not pressed */
TM_USB_HIDDEVICE_Button_Pressed = 0x01 /*!< Button is pressed */
} TM_USB_HIDDEVICE_Button_t;
//键盘结构体
/**
* @brief Keyboard structure
* @note Keyboard has special 8 buttons (CTRL, ALT, SHIFT, GUI (or WIN), all are left and right).
* It also supports 6 others keys to be pressed at same time, let's say Key1 = 'a', Key2 = 'b', and you will get "ab" result on the screen.
* If key is not used, then 0x00 value should be set!
*/
typedef struct {
TM_USB_HIDDEVICE_Button_t key1; /*!< Game pad button 1 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key2; /*!< Game pad button 2 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key3; /*!< Game pad button 3 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key4; /*!< Game pad button 4 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_key_t enumeration */
TM_USB_HIDDEVICE_Button_t key5; /*!< Game pad button 5 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key6; /*!< Game pad button 6 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key7; /*!< Game pad button 7 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key8; /*!< Game pad button 8 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key9; /*!< Game pad button 8 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
TM_USB_HIDDEVICE_Button_t key10; /*!< Game pad button 8 status. This parameter can be a value of @ref TM_USB_HIDDEVICE_Button_t enumeration */
} TM_USB_HIDDEVICE_Keyboard_t;
/**
* @brief Initializes USB HID Device library
* @param None
* @retval TM_USB_HIDDEVICE_Status_Disconnected
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_Init(void);
/**
* @brief Gets USB status
* @param None
* @retval Library usage status:
* - TM_USB_HIDDEVICE_Status_Connected: Library is ready to use with USB
* - Others: Look for @ref TM_USB_HIDDEVICE_Status_t enumeration
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_GetStatus(void);
/**
* @brief Sets default values to work with keyboard
* @param *Keyboard_Data: Pointer to empty @ref TM_USB_HIDDEVICE_Keyboard_t structure
* @retval Member of @ref TM_USB_HIDDEVICE_Status_t enumeration
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardStructInit(TM_USB_HIDDEVICE_Keyboard_t* Keyboard_Data);
/**
* @brief Sends keyboard report over USB
* @param *Keyboard_Data: Pointer to @ref TM_USB_HIDDEVICE_Keyboard_t structure to get data from
* @retval Member of @ref TM_USB_HIDDEVICE_Status_t enumeration
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardSend(TM_USB_HIDDEVICE_Keyboard_t* Keyboard_Data);
/**
* @brief Release all buttons from keyboard
* @note If you press a button and don't release it, computer will detect like long pressed button
* @param None
* @retval Member of @ref TM_USB_HIDDEVICE_Status_t enumeration
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardReleaseAll(void);
/**
* @brief Sends custom HID report over USB
* @param *buff: Pointer to data to be sent
* @param count: Number of bytes to be sent
* @retval Member of @ref TM_USB_HIDDEVICE_Status_t enumeration
*/
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_SendCustom(uint8_t* buff, uint8_t count);
/* C++ detection */
#ifdef __cplusplus
}
#endif
#endif
usb键盘 实现部分 keyboard_hid.c
#include "main.h"
#include "stm32f1xx_hal.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
#include "usbd_customhid.h"
#include "keyboard_hid.h"
#define USB_OTG_dev hUsbDeviceFS
extern TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_INT_Status; // 状态句柄
extern USBD_HandleTypeDef hUsbDeviceFS;
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_Init(void) { // 初始化状态
TM_USB_HIDDEVICE_INT_Status = TM_USB_HIDDEVICE_Status_Connected;
return TM_USB_HIDDEVICE_INT_Status;
}
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_GetStatus(void) { // 获取状态
return TM_USB_HIDDEVICE_INT_Status;
}
//键盘初始化
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardStructInit(TM_USB_HIDDEVICE_Keyboard_t* Keyboard_Data) {
Keyboard_Data->key1 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key2 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key3 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key4 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key5 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key6 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key7 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key8 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key9 = TM_USB_HIDDEVICE_Button_Released;
Keyboard_Data->key10 = TM_USB_HIDDEVICE_Button_Released;
return TM_USB_HIDDEVICE_INT_Status;
}
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardSend(TM_USB_HIDDEVICE_Keyboard_t* Keyboard_Data) {
uint8_t buff[2] = {0, 0};
/* 检测连接连接状态 */
if (TM_USB_HIDDEVICE_INT_Status != TM_USB_HIDDEVICE_Status_Connected) {
return TM_USB_HIDDEVICE_Status_Disconnected;
}
/* 数据处理 */
buff[0] = 0;
buff[0] |= Keyboard_Data->key1 << 0; /* Bit 0 */
buff[0] |= Keyboard_Data->key2 << 1; /* Bit 1 */
buff[0] |= Keyboard_Data->key3 << 2; /* Bit 2 */
buff[0] |= Keyboard_Data->key4 << 3; /* Bit 3 */
buff[0] |= Keyboard_Data->key5 << 4; /* Bit 4 */
buff[0] |= Keyboard_Data->key6 << 5; /* Bit 5 */
buff[0] |= Keyboard_Data->key7 << 6; /* Bit 6 */
buff[0] |= Keyboard_Data->key8 << 7; /* Bit 7 */
buff[1] = 0;
buff[1] |= Keyboard_Data->key9 << 0; /* Bit 0 */
buff[1] |= Keyboard_Data->key10 << 1; /* Bit 1 */
USBD_CUSTOM_HID_SendReport(&USB_OTG_dev, buff, 2);
return TM_USB_HIDDEVICE_Status_Connected;
}
//归0,弹出
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_KeyboardReleaseAll(void) {
uint8_t buff[2] = {0, 0};
if (TM_USB_HIDDEVICE_INT_Status != TM_USB_HIDDEVICE_Status_Connected) {
return TM_USB_HIDDEVICE_Status_Disconnected;
}
USBD_CUSTOM_HID_SendReport(&USB_OTG_dev, buff, 2);
return TM_USB_HIDDEVICE_Status_Connected;
}
最后的主函数
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
void SystemClock_Config(void);
/* USER CODE BEGIN 0 */
#include "keyboard_hid.h"
#include "buttom.h"
struct Button key1,key2,key3,key4,key5,key6,key7,key8,key9,key10;
uint8_t keyflag1=0;//total 8 keys
uint8_t keyflag2=0;//total 8 keys
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
uint8_t UserBtnflag=0; //按键标志位
TM_USB_HIDDEVICE_Keyboard_t Keyboard;
TM_USB_HIDDEVICE_Status_t TM_USB_HIDDEVICE_INT_Status;
//读取io状态
uint8_t read_key1_GPIO()
{
return HAL_GPIO_ReadPin(key1_GPIO_Port, key1_Pin);
}
uint8_t read_key2_GPIO()
{
return HAL_GPIO_ReadPin(key2_GPIO_Port, key2_Pin);
}
uint8_t read_key3_GPIO()
{
return HAL_GPIO_ReadPin(key3_GPIO_Port, key3_Pin);
}
uint8_t read_key4_GPIO()
{
return HAL_GPIO_ReadPin(key4_GPIO_Port, key4_Pin);
}
uint8_t read_key5_GPIO()
{
return HAL_GPIO_ReadPin(key5_GPIO_Port, key5_Pin);
}
uint8_t read_key6_GPIO()
{
return HAL_GPIO_ReadPin(key6_GPIO_Port, key6_Pin);
}
uint8_t read_key7_GPIO()
{
return HAL_GPIO_ReadPin(key7_GPIO_Port, key7_Pin);
}
uint8_t read_key8_GPIO()
{
return HAL_GPIO_ReadPin(key8_GPIO_Port, key8_Pin);
}
uint8_t read_key9_GPIO()
{
return HAL_GPIO_ReadPin(key9_GPIO_Port, key9_Pin);
}
uint8_t read_key10_GPIO()
{
return HAL_GPIO_ReadPin(key10_GPIO_Port, key10_Pin);
}
//key1
void key1_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT0; //第一字节置1
}
void key1_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT0; //保留其他字节不变的情况下,将第一字节归 0
}
//key2
void key2_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT1;
}
void key2_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT1;
}
//key3
void key3_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT2;
}
void key3_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT2;
}
//key4
void key4_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT3;
}
void key4_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT3;
}
//key5
void key5_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT4;
}
void key5_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT4;
}
//key6
void key6_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT5;
}
void key6_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT5;
}
//key7
void key7_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT6;
}
void key7_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT6;
}
//key8
void key8_PRESS_DOWN_Handler(void* btn)
{
keyflag1|=BIT7;
}
void key8_PRESS_UP_Handler(void* btn)
{
keyflag1&=~BIT7;
}
void key9_PRESS_DOWN_Handler(void* btn)
{
keyflag2|=BIT0; //第一字节置1
}
void key9_PRESS_UP_Handler(void* btn)
{
keyflag2&=~BIT0; //保留其他字节不变的情况下,将第一字节归 0
}
void key10_PRESS_DOWN_Handler(void* btn)
{
keyflag2|=BIT1; //第一字节置1
}
void key10_PRESS_UP_Handler(void* btn)
{
keyflag2&=~BIT1; //保留其他字节不变的情况下,将第一字节归 0
}
//将上面声明的 按键初始化,并将回调函数连接起来,并加入 按键链表里面
void UserKeys_Init(void)
{
button_init(&key1, read_key1_GPIO, 0);//key is Low voltage valid
button_attach(&key1, PRESS_DOWN, key1_PRESS_DOWN_Handler);
button_attach(&key1, PRESS_UP, key1_PRESS_UP_Handler);
button_start(&key1);
button_init(&key2, read_key2_GPIO, 0);//key is Low voltage valid
button_attach(&key2, PRESS_DOWN, key2_PRESS_DOWN_Handler);
button_attach(&key2, PRESS_UP, key2_PRESS_UP_Handler);
button_start(&key2);
button_init(&key3, read_key3_GPIO, 0);//key is Low voltage valid
button_attach(&key3, PRESS_DOWN, key3_PRESS_DOWN_Handler);
button_attach(&key3, PRESS_UP, key3_PRESS_UP_Handler);
button_start(&key3);
button_init(&key4, read_key4_GPIO, 0);//key is Low voltage valid
button_attach(&key4, PRESS_DOWN, key4_PRESS_DOWN_Handler);
button_attach(&key4, PRESS_UP, key4_PRESS_UP_Handler);
button_start(&key4);
button_init(&key5, read_key5_GPIO, 0);//key is Low voltage valid
button_attach(&key5, PRESS_DOWN, key5_PRESS_DOWN_Handler);
button_attach(&key5, PRESS_UP, key5_PRESS_UP_Handler);
button_start(&key5);
button_init(&key6, read_key6_GPIO, 0);//key is Low voltage valid
button_attach(&key6, PRESS_DOWN, key6_PRESS_DOWN_Handler);
button_attach(&key6, PRESS_UP, key6_PRESS_UP_Handler);
button_start(&key6);
button_init(&key7, read_key7_GPIO, 0);//key is Low voltage valid
button_attach(&key7, PRESS_DOWN, key7_PRESS_DOWN_Handler);
button_attach(&key7, PRESS_UP, key7_PRESS_UP_Handler);
button_start(&key7);
button_init(&key8, read_key8_GPIO, 0);//key is Low voltage valid
button_attach(&key8, PRESS_DOWN, key8_PRESS_DOWN_Handler);
button_attach(&key8, PRESS_UP, key8_PRESS_UP_Handler);
button_start(&key8);
button_init(&key9, read_key9_GPIO, 0);//key is Low voltage valid
button_attach(&key9, PRESS_DOWN, key9_PRESS_DOWN_Handler);
button_attach(&key9, PRESS_UP, key9_PRESS_UP_Handler);
button_start(&key9);
button_init(&key10, read_key10_GPIO, 0);//key is Low voltage valid
button_attach(&key10, PRESS_DOWN, key10_PRESS_DOWN_Handler);
button_attach(&key10, PRESS_UP, key10_PRESS_UP_Handler);
button_start(&key10);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)// 定时器回调函数
{
if(htim->Instance ==TIM2)//tim6 5ms
{
button_ticks();//recommand 5ms for key scan
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
MX_USB_DEVICE_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
UserKeys_Init();
TM_USB_HIDDEVICE_Init();
TM_USB_HIDDEVICE_KeyboardStructInit(&Keyboard);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (TM_USB_HIDDEVICE_GetStatus() == TM_USB_HIDDEVICE_Status_Connected)
{
if(keyflag1||keyflag2)
{
if(keyflag1&BIT0)//k1
{
Keyboard.key1 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key1 =TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT1)//k2
{
Keyboard.key2 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key2 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT2)//k3
{
Keyboard.key3=TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key3=TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT3)//k4
{
Keyboard.key4 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key4 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT4)//k5
{
Keyboard.key5= TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key5 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT5)//k6
{
Keyboard.key6 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key6 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT6)//按键7设为鼠标左键单击
{
Keyboard.key7 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key7 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag1&BIT7)//按键8设为鼠标右键单击
{
Keyboard.key8 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key8 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag2&BIT0)//按键8设为鼠标右键单击
{
Keyboard.key9 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key9 = TM_USB_HIDDEVICE_Button_Released;
}
if(keyflag2&BIT1)//按键8设为鼠标右键单击
{
Keyboard.key10 = TM_USB_HIDDEVICE_Button_Pressed;
}
else
{
Keyboard.key10 = TM_USB_HIDDEVICE_Button_Released;
}
TM_USB_HIDDEVICE_KeyboardSend(&Keyboard); /* Send keyboard report */
}
else
{
TM_USB_HIDDEVICE_KeyboardReleaseAll();
}
}
else
{
TM_USB_HIDDEVICE_KeyboardReleaseAll();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
结语
有错误,有问题,麻烦留言指出,感激不进
有帮助,求赞
date:2021.9.9
author:_zs_dawn