STM32按键输入

引言

这一节通过按键输入的实验,完成对IO口配置输入的学习,同时学习如何通过软件去抖动。这一节最终可以实现利用WK_UP按键控制LED亮灭的效果。




准备环节

与上一节点亮LED相类似,这一节也需要在 HARDWARE 文件夹内新建文件 key.hkey.c 。同时将相应的文件加入到工程中。

查看原理图,获取WK_UP按键的相关信息。对应IO口 PA0 。高电平为有效电平,且没有外接下拉电阻。需要利用软件设置IO口为下拉状态。

GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 该函数可以获取到相应IO口的电平状态。




编码

步骤:

  • 使能IO口所在总线的时钟
  • 配置按键相应IO口
  • 配置按键检测函数
  • main函数调用

key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"

#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)	//WK_UP作为相应IO口状态读取的简写
//#define WK_UP PAin(0)	上一行代码与该行效果相同

void KEY_Init(void);	//相应IO口配置初始化
u8 KEY_Scan(void);		//WK_UP按键处理函数
#endif

key.c

#include "key.h"
#include "sys.h" 
#include "delay.h"

void KEY_Init(void){
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能时钟
	//IO口配置  由于是输入模式,所以不需要配置输出速度
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//WK_UP对应PA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;			//初始化 下拉

	GPIO_Init(GPIOA, &GPIO_InitStructure);					//用上述配置的结构体初始化
}

u8 KEY_Scan(void){			//按键检测
	static char flag = 0;	//默认WK_UP按键没有按下
	if (WK_UP == 1){		//此时按键按下,可能是误触
		delay_ms(10);		
		if (WK_UP == 1){	//延迟10ms,再次判断,可以排除误触的情况,称为“软件消抖”
			flag = 1;		//代表按键已经按过,但还未对其处理
		}
	}
	if (WK_UP == 0 && flag == 1){	//此时上一次按键未处理,且上次按键已经释放
		flag = 0;			//复位flag
		return 1;			//主函数根据返回值的不同,进行不同的按键处理
	}
	return 0;
}

//以下是按键检测的另一种写法
//mode为1时,按键支持连按;为0时不支持连按
u8 KEY_Scan(u8 mode){
	static u8 flag = 1;
	if (mode)	flag = 1;	//mode为1时,进入检测函数时,flag就始终为1,即实现按键连按

	if (flag && WK_UP){ 

		delay_ms(10);
		flag = 0;			//flag复位,若mode为0,则下次检测不会再成功,即可阻止按键连按
		if(WK_UP)	return 1;

	}else if(!WK_UP){		//若上次flag被复位,这次按键检测中将会对其置位,使得下次按键检测正常进行
		flag = 1;
	}
	return 0;				//未检测到按键按下,就会返回0
}

main.c

//此处省略头文件,之后一般都会省略头文件

int main(void){
	delay_init();
	LED_Init();		//LED相应IO口初始化
	KEY_Init();		//按键相应IO口初始化

	LED1 = 0;		//点亮LED1

	while(1){
		u8 key = KEY_Scan();	//检测按键状态,返回值是1或0
		if(key == 1){			//按键按下未处理
			LED1 = !LED1;		//点亮或熄灭LED1
		}else{
			delay_ms(10);		//未检测到按键,进行下一次按键检测
		}
	}
}

至此,将程序烧写进单片机,就可以实现开篇提到的按键控制LED亮灭的功能了。这是不是非常的“阿美zing”呢?




补充

main.c中的LED_Init()相关配置代码可以参看之前的这篇文章:

(color{#0000FF}{STM32点亮LED(学习IO口配置输出)})

我是这耀眼的瞬间,是划过天边的刹那火焰。
原文地址:https://www.cnblogs.com/Rane/p/13584874.html