STM32学习——GPIO应用之按键实验

GPIO应用二——按键实验

1.按键硬件设计

image-20210722135350307

KEY_UP 按键一端是连接 VCC_3V3 的,另外一端是连接到 IO 口的,KEY_UP 按键是高电平有效

KEY0~KEY2 的按键一端都是接到 GND,这三个按键是低电平有效

2.按键的软件设计

这里还是先介绍一下按键检测的基本原理,硬件上使用的按键是机械按键,按键按下和抬起都会产生电平抖动,抖动过程时间在 5ms~10ms 左右。

image-20210722135534619

有了抖动就得消抖,否则检测的按键就不会准确,去抖动的方式有两种:硬件防抖和软件防抖。

硬件防抖需要借助外接电容和电阻,通过电容充放电来约束电平不能跳变达到去抖动的效果

软件防抖,用延时的方式错过这个抖动的时间再检测。

2.1简单按键实验

接下来先介绍一个简单简单按键实验,作为 GPIO 输入功能的入门。

先介绍一下思路:

  1. 使能按键引脚的时钟

  2. 初始化按键配置,使用 GPIO 的输入模式(注意,硬件连接上并没有外部上拉或者下拉电阻,因此需要根据连接方式使能芯片内部的上拉或者下拉电阻)

  3. 在函数中使用引脚输入电平检测,从而判断按键是否被按下

  4. 当读取到按键按下电平(有效电平)后,进行软件消抖,再次进行输入电平检测,最终确定按键状态

  5. 判断到按键被按下后,进行应用处理

接下来我们一步一步来实现这些功能,先介绍一下使用的 bsp_key.h 文件:

/*
*********************************************************************************************************
*
*	模块名称 : 按键模块
*	文件名称 : bsp_key.h
*	版    本 : V1.0
*	说    明 : 
*	修改记录 :
*		版本号  日期        作者     说明
*		V1.0    xxxx-xx-xx  xxxxx  首发
*********************************************************************************************************
*/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H
#include "sys.h"
///

#define	RCC_ALL_KEY			(WKUP_GPIO_CLK|KEY0_GPIO_CLK|KEY1_GPIO_CLK|KEY2_GPIO_CLK)

//key_up
#define	WKUP_GPIO_PIN		GPIO_Pin_0
#define WKUP_PIN_ID			0								//key_up引脚序号
#define WKUP_GPIO_PORT		GPIOA							//key_up端口号
#define WKUP_GPIO_CLK		RCC_APB2Periph_GPIOA			//key_up时钟
//#define WKUP_FUN_OUT		PGout							
#define WKUP_FUN_IN			PAin							//key_up输入端口配置函数
#define WKUP_GPIO_MODE		GPIO_Mode_IPD					//key_up下拉输入
#define WKUP_ACTIVE_LEVEL	1								//高电平有效

//key_0
#define	KEY0_GPIO_PIN		GPIO_Pin_4
#define KEY0_PIN_ID			4								//key_0引脚序号
#define KEY0_GPIO_PORT		GPIOE							//key_0端口号
#define KEY0_GPIO_CLK		RCC_APB2Periph_GPIOE			//key_0时钟
//#define WKUP_FUN_OUT		PGout							
#define KEY0_FUN_IN			PEin							//key_0输入端口配置函数
#define KEY0_GPIO_MODE		GPIO_Mode_IPU					//key_0上拉输入
#define KEY0_ACTIVE_LEVEL	0								//低电平有效

//key_1
#define	KEY1_GPIO_PIN		GPIO_Pin_3
#define KEY1_PIN_ID			3								//key_1引脚序号
#define KEY1_GPIO_PORT		GPIOE							//key_1端口号
#define KEY1_GPIO_CLK		RCC_APB2Periph_GPIOE			//key_1时钟
//#define WKUP_FUN_OUT		PGout							
#define KEY1_FUN_IN			PEin							//key_1输入端口配置函数
#define KEY1_GPIO_MODE		GPIO_Mode_IPU					//key_1上拉输入
#define KEY1_ACTIVE_LEVEL	0								//低电平有效

//key_2
#define	KEY2_GPIO_PIN		GPIO_Pin_2
#define KEY2_PIN_ID			2								//key_2引脚序号
#define KEY2_GPIO_PORT		GPIOE							//key_2端口号
#define KEY2_GPIO_CLK		RCC_APB2Periph_GPIOE			//key_2时钟
//#define WKUP_FUN_OUT		PGout							
#define KEY2_FUN_IN			PEin							//key_2输入端口配置函数
#define KEY2_GPIO_MODE		GPIO_Mode_IPU					//key_2上拉输入
#define KEY2_ACTIVE_LEVEL	0								//低电平有效

/
//IO操作函数
#define	WKUP	WKUP_FUN_IN	(WKUP_PIN_ID)
#define	KEY0	KEY0_FUN_IN	(KEY0_PIN_ID)
#define	KEY1	KEY1_FUN_IN	(KEY1_PIN_ID)
#define	KEY2	KEY2_FUN_IN	(KEY2_PIN_ID)

//返回值
#define	NOKEY_NUM	0
#define	WKUP_NUM	1
#define	KEY0_NUM	2
#define	KEY1_NUM	3
#define	KEY2_NUM	4

//*外部函数调用*//
void	bsp_InitKey(void);
uint8_t	bsp_KeyScan(void);

#endif
/*****************************  (END OF FILE) *********************************/

这个头文件主要定义了引脚,先说明一下按键端口的相关宏定义,这个和我们前面介绍GPIO 输出的功能有一点区别

注意一下使用 XXX_FUN_IN,并且输入模式有所差异,这里选择 IPD 或者 IPU 是与硬件连接一一对应的。IPU 为上拉输入,IPD 为下拉输入

注意一下ACTIVE_LEVEL 是设置有效电平的,有效电平在按键硬件连接部分已经介绍了。

特别注意软件设计和硬件设计是相关的,一定是一一对应的。最后为每一个按键按下,以及无键按下各规定了一个唯一的返回值。

接下来是关键的按键扫描函数,我们看看 bsp_key.c 里是怎么描述的

/*
*********************************************************************************************************
*
*	模块名称 : 按键模块
*	文件名称 : bsp_key.c
*	版    本 : V1.0
*	说    明 : 
*	修改记录 :
*		版本号  日期        作者     说明
*		V1.0    xxxx-xx-xx  xxxxx  首发
*********************************************************************************************************
*/
#include	"bsp.h"

/*******************************************************************************
* 函数名           :bsp_InitKey()
* 函数功能      	  :按键初始化函数
* 输入            : 无
* 输出            : 无
*******************************************************************************/
void	bsp_InitKey(void)
{
   
	GPIO_InitTypeDef	GPIO_InitStructure;
	
	/*打开GPIO时钟*/
	RCC_APB2PeriphClockCmd( RCC_ALL_KEY , ENABLE );
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	
	/*配置所有按键GPIO*/
	GPIO_InitStructure.GPIO_Pin=WKUP_GPIO_PIN;		/*WKUP端口*/
	GPIO_InitStructure.GPIO_Mode=WKUP_GPIO_MODE;	/*WKUP模式*/
	GPIO_Init(WKUP_GPIO_PORT,&GPIO_InitStructure);	/*初始化WKUP*/
	
	GPIO_InitStructure.GPIO_Pin=KEY0_GPIO_PIN;		/*KEY0端口*/
	GPIO_InitStructure.GPIO_Mode=KEY0_GPIO_MODE;	/*KEY0模式*/
	GPIO_Init(KEY0_GPIO_PORT,&GPIO_InitStructure);	/*初始化KEY0*/
	
	GPIO_InitStructure.GPIO_Pin=KEY1_GPIO_PIN;		/*KEY1端口*/
	GPIO_InitStructure.GPIO_Mode=KEY1_GPIO_MODE;	/*KEY1模式*/
	GPIO_Init(KEY1_GPIO_PORT,&GPIO_InitStructure);	/*初始化KEY1*/
	
	GPIO_InitStructure.GPIO_Pin=KEY2_GPIO_PIN;		/*KEY2端口*/
	GPIO_InitStructure.GPIO_Mode=KEY2_GPIO_MODE;	/*KEY2模式*/
	GPIO_Init(KEY2_GPIO_PORT,&GPIO_InitStructure);	/*初始化KEY2*/
		
}
/*******************************************************************************
* 函数名         :bsp_KeyScan()
* 函数功能         :键扫函数
* 输入            : 无
* 输出            : 无
*******************************************************************************/
uint8_t	bsp_KeyScan(void)
{
   
	///WKUP
	if(WKUP==WKUP_ACTIVE_LEVEL)					//判断按键是否按下
	{
   
		/*延时消抖*/
		delay_ms(10);
		if
  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值