DIY一个usb数字键盘(二)逻辑部分 基于stm32cubemx HAL库 usb hid协议

本文介绍了如何使用STM32CubeMX和HAL库来构建一个USB数字键盘,包括按键处理和USBHID协议的实现。文章详细展示了按键消抖、多种按键状态(如单击、双击、长按)的检测,并提供了按键回调函数的使用。同时,给出了USB键盘的结构体定义和发送键盘报告的函数。整个实现包括了初始化、状态管理和定时器驱动的按键扫描。
摘要由CSDN通过智能技术生成

前言

要写一个比较规范的 系统还是比较复杂的。而这次的逻辑代码部分的编写,只是个人觉得较为规范,所以单写一篇,附有注释,和部分讲解。
前一篇,关于基本配置和知识:自制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

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值