[蓝桥杯嵌入式有手就行]5_GPIO(下)

[蓝桥杯嵌入式有手就行]系列文章

第一章 开发环境的配置
第二章 从点灯开始
第三章 学会看手册
第四章 GPIO(上)
第五章 GPIO(下)
第六章 LCD
第七章 串口
第八章 I2C
第九章 ADC
第十章 TIM(上)
第十一章 TIM(下)
第十二章 RTC
第十三章 14届模拟题1
第十四章 14届模拟题2
第十五章 14届真题解析
未完待续…



前言

注:本系列基于2023年蓝桥杯实战情况就行编写,所有软件均采用2023年赛点资源包
本文将讲解GPIO输入(不含复用)部分。在板子上的体现,就是按键。


一、内部结构

下图在参考手册9.1节。本文主讲输入,所以我们只看上面一个虚线框,以及右侧I/O引脚。
在这里插入图片描述

1、Input driver(上方的虚线框)

1、浮空输入模式

在这里插入图片描述

2、输入上拉模式

在这里插入图片描述

3、输入下拉模式

在这里插入图片描述

4、高阻态模拟输入模式

在这里插入图片描述
注意:此模式的时候,信号不经过TTL施密特触发器

2、I/O引脚(两个虚线框右侧)

在这里插入图片描述
我们可以看到,这里有2个电阻,2个二极管。在配置为输入模式时,通过上下拉电阻和开关(可以通过寄存器控制开关状态)把输入线电平拉高或者降低,电阻值大概在40kΩ。这里两个保护二极管,可以理解为这两个二极管将外部输入的电压钳制在VDDIOX和Vss之间(一般是VDD和GND),从而防止过高或过低的电流进入,导致芯片损坏。

二、按键模块原理分析

1、原理图

在这里插入图片描述
通过原理图,我们可以发现其一段是保护电阻,另一端通过按钮接地
对引脚状态进行分析。

按键状态效果
按下引脚接地,输入低电平
松开引脚通过一个保护电阻接VDD,输入高电平

2、抖动问题

通过原理图,我们可以发现按键没有并联电容,因机械结构特性,在按下或者松开的瞬间,信号不可避免的会出现一些波动。
这个信号不好捕捉,百度找的图。我实测大概1ms左右。但是,对80M主频的单片机来说,太慢了。所以消抖是一定要做的。
在这里插入图片描述

三、软件部分

1、cubemx配置

我们只需要将引脚功能配置为GPIO_Input
在这里插入图片描述

2、代码示例

按键扫描程序

unsigned char key_scan(void)
{
  unsigned char unkey_val = 0;

  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)    unkey_val = 1;
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)    unkey_val = 2;
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)    unkey_val = 3;
  if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)    unkey_val = 4;

  return unkey_val;
}

按键功能实现。以上一篇的led为例。这里的代码相对完善,当然我们完全可以对其进行优化以便适应要求。

unsigned char uwTick_key;
unsigned char uckey_val, uckey_down, uckey_old, uckey_up;

void key_proc(void)
{
  if ((uwTick - uwTick_key) < 50) return;//这里延时50ms,为了消抖,可满足大部分题目要求
  uwTick_key = uwTick;

  uckey_val - key_scan();
  uckey_down = uckey_val & (uckey_old ^ uckey_val);
  uckey_up = ~uckey_val & (uckey_old ^ uckey_val);
  uckey_old = uckey_val;

  switch (uckey_down)
  {
  	case 1:  led_disp(1);  break;
  	case 2:  led_disp(2);  break;
 	case 3:  led_disp(3);  break;
  	case 4:  led_disp(4);  break;
 	default: led_disp(0);  break;//注意上一节中的代码要修改,0是没有反应的
  }
}

四、问题

1、按键扫描相对消耗资源,是否有其他办法

当我们没有同时使用B1和B4按钮的时候,我们可以将引脚配置为GPIO_EXITx,并设置为External Interrupt Mode with Falling edge trigger detection或者External Interrupt Mode with Rising/Falling edge trigger detection这样我们就可以通过外部中断的形式获取按键状态。
这里以PA0(也就是B4按键)为例,此时PB0(B1按键)无法设置为外部中断0
在这里插入图片描述

只有按下按钮,产生了一个下降沿事件,才会进入外部中断,才会去执行按键相关程序。
而上升沿检测,主要是为了实现长短按的区分。具体需要根据实际情况去选择。
而代码上相对上面就会简洁许多。

void HAL_GPIO_EXIT_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_0) key_down=4;
}

总结

至此,GPIO(不含复用)部分的内容就粗略的讲完了,应对比赛就足够了。接下来就LCD屏幕了。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工具人呵呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值