一、原理图
二、CubeMX配置
①四个按键对应的四个引脚PB0、PB1、PB2、PA0都配置为GPIO_Input,并设置为上拉输入,用来检测低电平
②对定时器2进行配置,时钟来源选择内部时钟。因为我们要求定时器定时1ms,所以对参数进行相应的设置
T=(psc+1)*(arr+1)/Tclk
③使能TIM2中断
三、代码实现
按键B1按下,实现LED1状态翻转。按键B2按下,实现LED2状态翻转。
按键B3按下,实现LED3状态翻转。按键B4按下,实现LED4状态翻转。
gpio.h
#define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
#define key_press ((KB1)|(KB2<<1)|(KB3<<2)|(KB4<<3)|0xf0)
gpio.c
unsigned char key_scan(void)
{
static unsigned char key_state=0;
unsigned char key_return=0;
switch(key_state)
{
case 0:
{
if(key_press!=0xff)
key_state=1;
break;
}
case 1:
{
if(key_press!=0xff)
{
switch(key_press)
{
case 0xfe:key_return=1;break;
case 0xfd:key_return=2;break;
case 0xfb:key_return=3;break;
case 0xf7:key_return=4;break;
}
key_state=2;
}
else
key_state=0;
break;
}
case 2:
{
if(key_press==0xff)
key_state=0;
break;
}
}
return key_return;
}
main.c
HAL_TIM_Base_Start_IT(&htim2); //开启定时器2中断
//按键扫描
if(key_flag)
{
key_flag=0;
key_value=key_scan();
if(key_value==1) //B1按下
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);
else if(key_value==2) //B2按下
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);
else if(key_value==3) //B3按下
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_10);
else if(key_value==4) //B4按下
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_11);
}
//定时器回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
key_cnt++;
if(key_cnt==10)
{
key_cnt=0;
key_flag=1;
}
}
}
|