入门STM32--按键输入

上一篇博客我们介绍了如何使用GPIO配置跑马灯,根据GPIO的基本结构图,我们能够发现,他肯定不单单有输出的功能,肯定可以检测IO上的电平变化,实际上就是输入的功能。

1.按键

在大多数情况下,按键是一种简单的开关,当按下时会改变电路连接,从而改变电平状态。按键通常与一个上拉电阻或下拉电阻连接,以确保在未按下时,输入引脚处于已知的高电平或低电平。

值得一提的是,这种按键并不是理想的开关,在按下和松开的过程中,电平的变化往往不是理想的,而是伴随着尖峰、抖动。

2. 硬件连接

假设我们使用一个带上拉电阻的按键,连接方式为,一个引脚连接到STM32的GPIO输入引脚,另一个引脚连接到地(GND),同时,在输入引脚与VCC之间连接一个上拉电阻。

当按下按键时,GPIO引脚的电平从高变为低;当松开按键时,引脚电平保持高电平。下图并没有画出上拉电阻,实际上在单片机内部就有。

3. 去抖动

机械按键在按下和释放时,电平可能会在高低之间快速波动,产生"抖动"现象。为了解决这个问题,我们需要在软件中进行去抖动处理,可以通过计时器或延时来实现。

此外,我们还可以通过硬件的方式,来消除"抖动"的影响,可以在按键电路的上拉电阻或者下拉电阻两侧并联电容,消除电压尖峰。

4. STM32 上的按键输入配置

接下来,我们将以STM32的标准库为例详细介绍如何在STM32上配置按键输入,假设按键连接在PE3引脚上。

4.1GPIO 初始化

我们通常会使用一个函数来配置GPIO引脚的模式、速度、上下拉电阻等属性。下面我们详细解释一下GPIO_Config函数。

cpp 复制代码
void GPIO_Config(void)
{
    // 启动GPIOC的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

    // 配置PC13为输入模式,带上拉电阻
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 输入模式,带上拉
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}

4.2 启动 GPIO 端口时钟

cpp 复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

在STM32中,每个外设(包括GPIO端口)都需要通过时钟来驱动。在使用某个GPIO端口之前,必须先启用对应的时钟,否则后续对该端口的配置和操作将无效。

RCC_APB2PeriphClockCmd:这是一个用于管理APB2总线上的外设时钟的函数。

RCC_APB2Periph_GPIOC:这个宏定义代表GPIOC端口对应的时钟。

4.3 结构体参数

GPIO_Pin_3:表示要配置的引脚号。STM32的每个GPIO端口有多个引脚(通常编号为0到15),GPIO_Pin_3表示PE3引脚。

GPIO_Mode_IPU:表示输入模式,带上拉电阻。

GPIO_Speed_2MHz:用于设置GPIO引脚的速度,实际上是引脚的切换速率。对于输入引脚,速度设置一般没有影响,更多的是在输出模式下有意义。

4.4 初始化

cpp 复制代码
GPIO_Init(GPIOE, &GPIO_InitStructure); 

GPIO_Init:这个函数将前面配置好的GPIO_InitTypeDef结构体中的参数应用到指定的GPIO端口。

5. 读取按键状态

在主循环中,我们可以通过读取GPIO引脚的状态来判断按键是否被按下:

cpp 复制代码
while (1)
{
    if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0)
    {
        // 按键按下时执行的操作
    }
    else
    {
        // 按键未按下时的操作
    }
}

注意,有些程序并不是简简单单的向上面那样,还会使用宏定义,简化程序。但对初学者不友好。

6. 去抖动处理

按键抖动可能导致误触发,因此我们可以在软件中添加去抖动处理。以下是一个简单的去抖动处理示例:

cpp 复制代码
#define DEBOUNCE_DELAY 50 // 50毫秒去抖动延时
while (1)
{
    if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET)
    {
        Delay(DEBOUNCE_DELAY);  // 延时去抖动
        if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET)
        {
            // 按键按下且去抖动后执行的操作
        }
    }
}

拓展

为了提高响应速度并减少CPU占用,我们可以将按键引脚配置为外部中断(EXTI),当按键状态变化时,触发中断处理函数。

通过计时器,我们可以实现对按键的长按和短按识别,从而执行不同的操作。

相关推荐
学习噢学个屁1 小时前
基于51单片机的超声波液位测量与控制系统
c语言·单片机·嵌入式硬件·51单片机
电鱼智能的电小鱼1 小时前
EFISH-SBC-RK3588无人机地面基准站项目
linux·网络·嵌入式硬件·机器人·无人机·边缘计算
电鱼智能的电小鱼1 小时前
基于 EFISH-SBC-RK3588 的无人机环境感知与数据采集方案
linux·网络·嵌入式硬件·数码相机·无人机·边缘计算
车载诊断技术3 小时前
不同ECU(MCU/ZCU/CCU)其部署(实现)的功能存在差异
单片机·嵌入式硬件·架构·汽车·电子电器架构·软件定义汽车的电子/电气
美好的事情总会发生3 小时前
32.768kHz晶振详解:作用、特性及与其他晶振的区别
嵌入式硬件·硬件工程·智能硬件
国科安芯5 小时前
面向高性能运动控制的MCU:架构创新、算法优化与应用分析
单片机·嵌入式硬件·安全·架构·机器人·汽车·risc-v
阿让啊5 小时前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
电鱼智能的电小鱼8 小时前
基于 EFISH-SBC-RK3588 的无人机通信云端数据处理模块方案‌
linux·网络·人工智能·嵌入式硬件·无人机·边缘计算
Neil今天也要学习8 小时前
永磁同步电机控制算法-VF控制
单片机·嵌入式硬件
狄加山6759 小时前
STM32 I2C总线通信协议
stm32·单片机·嵌入式硬件