使用按键控制STM32 LED灯亮灭

之前我们已经实现了LED灯的亮灭,我们对LED灯的结构应该有一个大致的了解。接下来我们对按键控制led进行学习。

首先我们要了解一下按键的结构。按键结构如图。

 由此可知,此处我们有两种按键,一种是普通的按键KEY0, KEY1(KEY2),他们连接的串口分别是PE4, PE3(PE2),对应的GPIO口为GPIOE;另一种是重置按键WAKE_UP_KEY,它连接的串口为PA0,对应的GPIO口为GPIOA。这两种按键的区别是阴极(非严格意义上的)的极性,普通按键KEY0的阴极接地,按键未按下的时候呈现高阻态,需要一个稳定的高电平,来维护未按下的状态,于是我们采用上拉输入,来获得一个稳定的高电平;相应的,WAKE_UP_KEY阴极接VCC,当未按下的时候呈现高阻态,需要一个稳定的低电平来维持稳定的未按下状态,于是我们选用下拉输入,来获得稳定的低电平。

总结而言,WAKE_UP_KEY采用下拉输入,KEY0/1/2采用上拉输入,对应的GPIO_IniyTypeDef结构体的成员为Pull。

之后我们再介绍一个针对按键非常重要的知识点——软件消抖:

 我们知道,由于按键中的金属弹性,在按下松开的时候会有一定的不稳定干扰,信号会很乱,导致单片机对按键状态的误判,因此,我们需要了解软件消抖。

接下来直接给出一段按键扫描的程序,其中包含了软件消抖的应用:

uint8_t key_scan(void){

    if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == 0){
        delay_ms(10);

        while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == 0){
            return 1;
        }

    }

    delay_ms(10);
    return 0;
}

以key2为例,软件消抖的原理就是在按键按下后,由触发的低电平给我们的HAL_GPIO_ReadPin()函数一个低电平信号,然后我们采取10ms的延时来消抖,再接受稳定的低电平信号,返回1值表示按键已经按下;松开时候也同理,我们的按键在按下之前一直是低电平,当我们的按键松开时候,按键输出高电平,while循环的条件被破坏,跳出循环和if语句,然后进行后一个延迟,然后在返回0表示没有按下。

这里的HAL_GPIO_ReadPin()函数有两个参数,第一个是对应的GPIO,第二个是对应的GPIO口,作用是读取实时的串口值。

那么接下来我们就进行相应程序文件的编写

key.h:

#ifndef __KEY_H
#define __KEY_H

#include "./SYSTEM/sys/sys.h"

void key_init(void);
uint8_t key_scan(void); 

#endif

key.c:

#include "./BSP/KEY/key.h"

void key_init(void){
    GPIO_InitTypeDef gpio_init_struct;

    __HAL_RCC_GPIOE_CLK_ENALBE();

    gpio_init_struct.Pin = GPIO_PIN_2;
    gpio_init_struct.Mode = GPIO_MODE_INPUT;
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOE, &gpio_init_struct);
}

uint8_t key_scan(void){

    if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == 0){
        delay_ms(10);

        while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == 0){
            return 1;
        }

    }

    delay_ms(10);
    return 0;
}

key_init()和之前的led_init()是类似的,对GPIOE串口进行初始化。

因为KEY2的pin脚为PE2所以设置为GPIO_PIN_2;这里由于是接受按键的输入,所以使用GPIO_MODE_INPUT;上面已经解释过了,使用上拉输入;输入模式不需要调整输出的速度,故不作设置。

对key_scan()函数就不做解释了,上面解释过了。注意这里的key_scan()的类型需要设置为uint8_t,它需要返回一个值来表示相应按键的按下。

之后我们再来编写主函数

main.c:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"

int main(){
    HAL_init();
    sys_stm32_clock_init(RCC_PLL_MUL9);
    delay_init(72);
    key_init();
    led_init();

    while(1){
        if(key_scan() ){
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
        }
        else{
            delay_ms(10);
        }
    }
}

于是我们就能通过一个按键开启对led灯的控制了。

物联沃分享整理
物联沃-IOTWORD物联网 » 使用按键控制STM32 LED灯亮灭

发表评论