STM32基础教程(CubeMX)—— 按键检测

按键检测

CubeMX的操作

普通按键检测的I/O口设置
  1. 将按键对应的I/O口设置为输入模式。
  2. 如果按键使用上拉电阻则设置I/O口为上拉电阻,如果按键使用的是下拉电阻则设置I/O口味下拉电阻。
外部中断按键检测的I/O口设置
  1. 将按键对应的I/O口设置为EXTI模式,并打开外部中断。
  2. 如果按键使用上拉电阻则设置I/O口为上拉电阻,如果按键使用的是下拉电阻则设置I/O口味下拉电阻。

注意,该配置的I/O口也可以使用普通的按键检测。

Keil5的操作

普通按键检测
  1. 检测按键是否按下。
  2. 执行按键按下后应该执行的操作。
  3. 开始新一轮的按键检测。
软件去抖的按键检测
  1. 检测按键是否按下。
  2. 延时一小段时间(10~30ms),去除抖动,再次检测按键是否按下。
  3. 执行按键按下后应该执行的操作。
  4. 检测是否松开了按键,如果是,则开始新一轮的按键检测,如果不是,则等待松手,松手后再进行新一轮的按键检测。

如果是编写一个按键检测函数,可以在第3步检测到后将标志变量变为有效,而不是真的去执行应该执行的操作。

按键检测函数例程:
/**
  * @brief 检测按键是否按下
  * @param Key_Port是按键对应的IO口端口;Key_Pin是按键对应的IO口编号;Level是按键按下对应的电平状态
  * @retval 如果按下返回1,如果没有按下返回0
  */
uint16_t Key_Detection(GPIO_TypeDef * Key_Port, uint16_t Key_Pin, GPIO_PinState Level)
{
	uint16_t Key_State = 0;
	if(Level == HAL_GPIO_ReadPin(Key_Port,Key_Pin))
	{
		HAL_Delay(15);
		if(Level == HAL_GPIO_ReadPin(Key_Port,Key_Pin))
		{
			Key_State = 1;
		}
		while(Level == HAL_GPIO_ReadPin(Key_Port,Key_Pin));
	}
	return Key_State;
}
外部中断的按键检测
  1. 在左侧的工程界面中找到用户应用文件夹下的"stm32f1XX_it.c"文件打开,这个文件就是专门存放处理中断的函数的。
  2. 在该文件中搜索EXTI,即可找到处理对应中断的中断服务函数,每个中断服务函数都调用了同一个函数,该函数会完成中断检测、中断标志位的清除、并调用回调函数。
  3. 找到回调函数"HAL_GPIO_EXTI_Callback",去除前面的"weak"标记,并把整个函数复制到自己的.c文件或是"stm32f1XX_it.c"文件中进行使用。

应当注意,所有的外部中断使用同一个回调函数,通过传入参数(IO口编号)的不同来分辨是哪个外部中断被触发。另外,外部中断无法去抖,一般单片机的外部中断输入段都会进行硬件去抖,但如果它还无法消抖,那就自己对按键进行硬件消抖。

按键检测并亮灯的例程:
/**
  * @brief 这是外部中断的回调函数,功能为按键控制LED灯,并保存灯的亮灭状态。
  * 使用之前需要将三个按键分别设置别名“Key1”、“Key2”和“Key3”,LED设置为“Led2”和"Led3"。
  * 按键1控制LED2,按键2控制LED3,按键3熄灭两盏LED。
  * 两个外部变量是用来记录LED灯状态的,应该放在主函数所在文件中作为全局变量。
  */
>extern uint16_t led2_state, led3_state;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == Key1_Pin)
	{
		if(1 == led2_state)
		{
		HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
		led2_state=0;
		}
		else if(0 == led2_state)
		{
		HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
		led2_state=1;
		}
	}
	if(GPIO_Pin == Key2_Pin)
	{
		if(1 == led3_state)
		{
		HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
		led3_state=0;
		}
		else if(0 == led3_state)
		{
		HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
		led3_state=1;
		}
	}
	if(GPIO_Pin == Key3_Pin)
	{
		led2_state = 0;
		led3_state = 0;
		HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
	}
}


猜你喜欢

转载自blog.csdn.net/weixin_43718316/article/details/107985405