#variables 定义变量
EXT my_bool flag_SwCheck EQ(FALSE);//按键检测标志位 1-检测
EXT uint8_t key_updn EQ(0); // 按键状态,表示哪一个按键被按下
#config 宏定义
#define BUTTON_EN 1 //按键的使能
#define BUTTON_N 3 //按键的数量
#define BUTTON_C 20 //在it文件中按键检测一次的时间。每20ms检测一次。
#bsp 按键的检测
/******************************************************************************
* 功能:进行按键检测
* 返回值:哪一位按键被按下
* 参数:
* 说明:
***********************************************/
extern uint16_t bsp_key_scan()
{
static uint8_t key_previous =0;
uint8_t key_current =0;
uint16_t t;
uint16_t i;
GPIO_TypeDef * keys_port[]={SW1_GPIO_Port,SW2_GPIO_Port,SW3_GPIO_Port};
//重新定义它的端口,变成一个数组。
static uint16_t keys_pin[]={SW1_Pin,SW2_Pin,SW3_Pin};
//重新定义它的引脚,变成一个数组。
for(i=0;i<BUTTON_N;i++)
{
key_current <<= 1;
if( HAL_GPIO_ReadPin(keys_port[BUTTON_N-1-i], keys_pin[BUTTON_N-1-i]) ==GPIO_PIN_RESET)
{
key_current |= 0x01;
}
/*通过for循环,从**大到小**进行按键检测,如果状态是低电平则代表按键被按下。随后,将读取到的状态想移动一位,即变成高位*/
}
t=(((key_current ^ key_previous) &key_current)<<8) | ((key_current ^ key_previous) &key_current );
key_previous = key_current ;
return t;
/*
一次按键只能按一个,所以key_current 只能有一位是 1 或者都是0。
1.相或后如果前后两次按键不同,则相或包含前后两次按键的值,再相与后还是现在的按键状态。
2.相或后如果前后两次按键相同,则相或是0,再相与后还是,则不调用按键处理函数app_key_handler,维持原状,提高了代码的运行效率,减少代码冗余。
*/
}
#app 按键处理函数
/******************************************************************************
* 功能:按键处理函数
* 返回值:
* 参数:key_updn
*********************************************/
extern void app_key_handler(uint8_t key_updn)
{
if(key_updn & 0x01)
{
if(++flag_FlashMode >3)
flag_FlashMode =0;
}
if(key_updn & 0x02)
{
flag_LedMoveDirection = ! flag_LedMoveDirection;
}
if(key_updn & 0x04)
{
flag_LedStop = ! flag_LedStop;
}
}
#it.c 允许调用按键检测函数
const uint16_t blind[]={250,500,1000,2000};
static uint16_t i=0;
if( ++i ==60000)
{
i=0;
}
}
if(i % BUTTON_C ==0)
flag_SwCheck = 1;
//每BUTTON_C毫秒将允许调用标志变成1
#main.c
if(flag_SwCheck ==1)//允许调用按键检测函数
{
key_updn=bsp_key_scan();//把检测到的值给key_updn
flag_SwCheck =0;//标志变成0
}
if(key_updn !=0)//代表有按键按下
{
app_key_handler(key_updn);//处理相应位按键
key_updn =0;
}
本文章使用limfx的vscode插件快速发布