STM32-HAL库,按键框架

基于乐育的按键框架
可消抖,单触发,可同时执行按下和抬起两个事件

移植代码

ProcKeyOne.h

#ifndef _PROC_KEY_ONE_H_
#define _PROC_KEY_ONE_H_

#include "main.h"

void  InitProcKeyOne(void);   //初始化ProcKeyOne模块

void  ProcKeyDownKey1(void);  //处理按键按下的事件,即按键按下的响应函数 
void  ProcKeyUpKey1(void);    //处理按键弹起的事件,即按键弹起的响应函数
void  ProcKeyDownKey2(void);  //处理按键按下的事件,即按键按下的响应函数 
void  ProcKeyUpKey2(void);    //处理按键弹起的事件,即按键弹起的响应函数

#endif  //_PROC_KEY_ONE_H_

ProcKeyOne.c

#include "ProcKeyOne.h"
#include "usart.h"			//自行添加,这里以串口打印任务为例

void InitProcKeyOne(void)
{
  
}

void  ProcKeyDownKey1(void)
{  
  PrintfDebug("KEY1 PUSH DOWN\r\n");  //打印按键状态
}

void  ProcKeyUpKey1(void)
{
  PrintfDebug("KEY1 RELEASE\r\n");   //打印按键状态
}

void  ProcKeyDownKey2(void)
{
  PrintfDebug("KEY2 PUSH DOWN\r\n");   //打印按键状态
}

void  ProcKeyUpKey2(void)
{
  PrintfDebug("KEY2 RELEASE\r\n");     //打印按键状态
}

KeyOne.h

#ifndef _KEY_ONE_H_
#define _KEY_ONE_H_

#include "main.h"

//根据自己的按键使用的GPIO更改
//也可以把这部分注释了,用CubeMX配置
#define KEY1_Port GPIOA
#define KEY1_Pin GPIO_PIN_0
#define KEY2_Port GPIOC
#define KEY2_Pin GPIO_PIN_13

//低电平触发方式
#define  KEY_DOWN_LEVEL_KEY1    0x00     //0x00表示按下为低电平
#define  KEY_DOWN_LEVEL_KEY2    0x00     //0x00表示按下为低电平
//高电平触发方式
#define  KEY_UP_LEVEL_KEY1    0xFF     //0xFF表示按下为高电平
#define  KEY_UP_LEVEL_KEY2    0xFF     //0xFF表示按下为高电平
//更多按键自行添加

#define TRUE          1
#define FALSE         0

typedef enum
{
  KEY_NAME_KEY1 = 0,  //按键1
  KEY_NAME_KEY2,      //按键2
  //更多按键自行添加
  KEY_NAME_MAX
}EnumKeyOneName;

void InitKeyOne(void);
void  ScanKeyOne(uint8_t keyName, void(*OnKeyOneUp)(void), void(*OnKeyOneDown)(void));//每10ms调用一次

#endif   //_KEY_ONE_H_

KeyOne.c

#include "KeyOne.h"

#define KEY1    (HAL_GPIO_ReadPin(KEY1_Port , KEY1_Pin )) 
#define KEY2    (HAL_GPIO_ReadPin(KEY2_Port , KEY2_Pin )) 

static  uint8_t  s_arrKeyDownLevel[KEY_NAME_MAX];      //使用前要在InitKeyOne函数中进行初始化   

void InitKeyOne(void)
{  
  //高电平触发方式配置为0xff,低电平触发方式配置为0x00                                                             
  s_arrKeyDownLevel[KEY_NAME_KEY1] = KEY_UP_LEVEL_KEY1;  //按键KEY1按下时为高电平
  s_arrKeyDownLevel[KEY_NAME_KEY2] = KEY_UP_LEVEL_KEY2;  //按键KEY2按下时为高电平
}

void ScanKeyOne(uint8_t keyName, void(*OnKeyOneUp)(void), void(*OnKeyOneDown)(void))
{
  static  uint8_t  s_arrKeyVal[KEY_NAME_MAX];    //用于存放按键的数值
  static  uint8_t  s_arrKeyFlag[KEY_NAME_MAX];   //用于存放按键的标志位
  
  s_arrKeyVal[keyName] = s_arrKeyVal[keyName] << 1;   //左移一位

  switch (keyName)
  {
    case KEY_NAME_KEY1:
      s_arrKeyVal[keyName] = s_arrKeyVal[keyName] | KEY1; //按下/弹起时,KEY1为0/1
      break;                                            
    case KEY_NAME_KEY2:                                 
      s_arrKeyVal[keyName] = s_arrKeyVal[keyName] | KEY2; //按下/弹起时,KEY2为0/1
      break;                                        
    default:
      break;
  }  
  
  //按键标志位的值为TRUE时,判断是否有按键有效按下
  if(s_arrKeyVal[keyName] == s_arrKeyDownLevel[keyName] && s_arrKeyFlag[keyName] == TRUE)
  {
    (*OnKeyOneDown)();                    //执行按键按下的响应函数
    s_arrKeyFlag[keyName] = FALSE;        //表示按键处于按下状态,按键标志位的值更改为FALSE
  }
  
  //按键标志位的值为FALSE时,判断是否有按键有效弹起
  else if(s_arrKeyVal[keyName] == (uint8_t)(~s_arrKeyDownLevel[keyName]) && s_arrKeyFlag[keyName] == FALSE)
  {
    (*OnKeyOneUp)();                      //执行按键弹起的响应函数
    s_arrKeyFlag[keyName] = TRUE;         //表示按键处于弹起状态,按键标志位的值更改为TRUE
  }
}

main.c

#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "KeyOne.h"
#include "ProcKeyOne.h"

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM13_Init();
  MX_USART1_UART_Init();

  InitKeyOne();

  while (1)
  {
    Proc2msTask();
  }
}
static void Proc2msTask(void)   //2ms任务
{
    static int16_t s_iCnt5 = 0;

  if(Get2msFlag())
  {
    if(s_iCnt5 >= 4)
    { 
      ScanKeyOne(KEY_NAME_KEY1, ProcKeyUpKey1, ProcKeyDownKey1);
      ScanKeyOne(KEY_NAME_KEY2, ProcKeyUpKey2, ProcKeyDownKey2);

      s_iCnt5 = 0;
    }
    else
    {
      s_iCnt5++;
    }
    
    Clr2msFlag();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值