蓝桥杯嵌入式准备(GPIO输入—按键检测)

硬件设计:

按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,使用按键时会产生下图中的带波纹信号,需要用软件消抖处理滤波,不方便输入检测。,它利用电容充放电的延时,消除了波纹,从而简化软件的处理,软件只需要直接检测引脚的电平即可,但是本实验用的是软件消抖。、

高从按键的原理图可知,这些按键在没有被按下的时候,GPIO引脚的输入状态为低电平,当按键按下时,GPIO引脚的输入状态为低电平。只要我们检测引脚的输入电平,即可判断按键是否被按下。

在配置的时候将PB0、PB1、PB2、PA0设置为GPIO_Input,其余参数默认即可

软件设计:

key.c

#include "key.h"

/*
 * @函数名称:KEY_GPIO_Init(void)
 * @入口参数: void
 * @出口参数: void
 * @函数作用: 初始化KEY各引脚
 **/
void KEY_GPIO_Init(void)
{
	 GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB0 PB1 PB2 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/*
 * @函数名称:KEY_Scan(void)
 * @入口参数: void
 * @出口参数: key_value
 * @函数作用: 识别按键
 **/
unsigned char KEY_Scan(void)
{
	unsigned char key_value=0;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)
		key_value=1;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)
		key_value=2;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)
		key_value=3;
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)
		key_value=4;
	return key_value;
	
}

/*
 * @函数名称:void KEY_Distinguish(void)
 * @入口参数: void
 * @出口参数: void
 * @函数作用: 扫描按键 是 上升沿 下降沿
 **/
/* USER CODE BEGIN PV */
__IO uint32_t uwTick_last;
unsigned char key_Val,key_Dwon,key_Up,key_last,key_Status;
/* USER CODE END PV */
void KEY_Distinguish(void)
{
	if(uwTick-uwTick_last<100) return ;//减速函数每隔多少时间扫描一下
	uwTick_last=uwTick;
	
	//判断连续两次间隔的状态
	key_Val=KEY_Scan();
	key_Dwon=key_Val & (key_last ^ key_Val);
	key_Up=~key_Val & (key_last ^ key_Val);
	key_last=key_Val;
	
	if((key_Up==0&&key_Dwon!=0&&key_last==0)||
		(key_Up==0&&key_Dwon==0&&key_last!=0))//情况一:
	{
		key_Status=0;
	}
	
	if((key_Up!=0&&key_Dwon==0&&key_last!=0)||
		(key_Up==0&&key_Dwon==0&&key_last==0))//情况二:
	{
		key_Status=1;
	}
}


 * @函数名称:void KEY_Distinguish(void) 函数解释是

uwTick:全局变量,主要作用是滴答定时器每进入中断一次umTick就会增加一次

同理可以说umTick每增加一个数,就计数1ms。(具体为什么是一毫秒请了解滴答定时器)

if(uwTick-uwTick_last<100);每隔100ms扫描一次,长按短按就在定义一个变量每次扫描的时候加一然后对此判断。

      扫描按键算法解读:以按下按键4为例子

       key_Val=KEY_Scan();

       key_Dwon=key_Val & (key_last ^ key_Val);

       key_Up=~key_Val & (key_last ^ key_Val);

       key_last=key_Val;

//情景一:两次连续扫描,按键得到的结果从0(都没按下)到4得到了低电平

// key_Val=4(0000 0100)

// key_Dwon=0000 0100(4) & (0000 0000 ^ 0000 0100(4))=0000 0100(4) & 0000 0100=0000 0100(4)

// key_Up=1111 1011 & (0000 0000 ^ 0000 0100)= 1111 1011 & 0000 0100=0000 0000(0)

// key_last=0000 0100(4)

//情景2:产生下降沿的时候,按键一直按着

// key_Val=4(0000 0100)

// key_Dwon=0000 0100 & (0000 0100 ^ 0000 0100)=0000 0100 & 0000 0000=0000 0000(0)

// key_Up=1111 1011 & (0000 0100 ^ 0000 0100)= 1111 1011 & 0000 0000=0000 0000(0)

// key_last=0000 0100(4)

//情景3:一直按着随后抬起

// key_Val=0(0000 0000)

// key_Dwon=0000 0000 & (0000 0100 ^ 0000 0000)=0000 0000 & 0000 0100=0000 0000 (0)

// key_Up=1111 1111 & (0000 0100 ^ 0000 0000)= 1111 1111 & 0000 0100=0000 0100(4)

// key_last=0000 0000(0)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值