入门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),当按键状态变化时,触发中断处理函数。

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

相关推荐
广药门徒8 小时前
STM32简易计算机设计
stm32·单片机·嵌入式硬件
Ronin-Lotus9 小时前
嵌入式硬件篇---拓展板
嵌入式硬件
天天爱吃肉821810 小时前
【低成本STM32的T-BOX开发实战:高可靠的车联网解决方案】
stm32·单片机·嵌入式硬件·云原生
不脱发的程序猿12 小时前
在超频单片机时,需要注意哪些稳定性问题?
单片机·嵌入式硬件
sword devil90013 小时前
STM32项目实战:ADC采集
stm32·单片机·嵌入式硬件
-liming-13 小时前
单片机设计_停车场车位管理系统(AT89C52、LCD1602)
单片机·嵌入式硬件·51单片机
不脱发的程序猿14 小时前
单片机超频怎么搞?
单片机·嵌入式硬件·单片机超频
hahaha601614 小时前
uart16550详细说明
stm32·单片机·嵌入式硬件
Invinciblenuonuo15 小时前
STM32八股【9】-----volatile关键字
stm32·单片机·嵌入式硬件
深圳市青牛科技实业有限公司 小芋圆15 小时前
CS4334:一款高性能的立体声音频数模转换器
科技·嵌入式硬件·音视频·智能家居·新能源·工控主板