先说一下思路:在手册里可以看到
引脚是和VDD相连的所以没按下引脚是高电平,按下就是低电平。这里我们需要检测按键有没有被按下,就需要配置定时器中断每隔一段时间扫描按键。
把需要的引脚设置为输入模式(GPIO_Input),然后模式设置为上拉模式
参考手册76页
找到Timers配置TIM4
时钟源选择内部时钟 。点击设置psc和arr
因为总线频率是80MHz,所以就是10ms扫描一次 。
在NVIC中把中断使能
生成代码。
新建interrupt.c和.h文件。编译一下,复制hal_tim.h的2531行的函数。
interrupt.c
#include "interrupt.h"
struct keys key[4] = {0,0,0};
//10ms扫描一次按键
//中断回调函数,只要定时器发生中断就会执行
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM4)//判断中断是否是TIM4发生
{
key[0].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i= 0; i<4 ; i++)//循环4个按键
{
switch(key[i].judge_sta)
{
case 0:
{
if(key[i].key_sta == 0)
{
key[i].judge_sta = 1; //过10ms进入下一步
}
}
break;
case 1:
{
if(key[i].key_sta == 0)
{
key[i].judge_sta = 2; //过10ms进入下一步
key[i].single_flag = 1; //按键触发标志位
}else{
key[i].judge_sta = 0; //消除抖动(按键停止触发了)
}
}
break;
case 2:
{
if(key[i].key_sta == 1) //松开按键
{
key[i].judge_sta = 0; //恢复状态位
}
}
break;
}
}
}
}
interrupt.h
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include "main.h"
#include "stdbool.h" //因为只需要表示两个状态所以用bool类型,节省空间
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
struct keys
{
uchar judge_sta; //运行状态
bool key_sta; //按键状态
bool single_flag; //短按键触发标志位
};
#endif
main.c中添加
extern struct keys key[];
HAL_TIM_Base_Start_IT(&htim4);//打开定时器4
if(key[i].single_flag == 1)
{
//需要执行的操作
key[i].single_flag = 0;//恢复标志位
}
结束。