前言
一、内部结构
1、Input driver(上方的虚线框)
1、浮空输入模式
2、输入上拉模式
3、输入下拉模式
4、高阻态模拟输入模式
2、I/O引脚(两个虚线框右侧)
二、按键模块原理分析
1、原理图
2、抖动问题
三、软件部分
1、cubemx配置
2、代码示例
四、问题
1、按键扫描相对消耗资源,是否有其他办法
总结
前言
注:本系列基于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屏幕了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050091/viewspace-3117696/ ,如需转载,请注明出处,否则将追究法律责任。