STM32小实验四--按键控制LED灯

1.实验目的

按下 KEY1,翻转 LED1 状态;按下 KEY2 ,翻转 LED2 状态。

2.硬件清单

  • STM32
  • ST-Link

3.原理图

4.代码

在Drivers/BSP新建文件夹命名为key在这个文件夹中新建key.c和key.h。

4.1key.c

c 复制代码
#include "key.h"
#include "sys.h"
#include "delay.h"
//初始化GPIO口
void key_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                   //使能GPIOA时钟
    //初始化GPIO函数
    gpio_initstruct.Mode = GPIO_MODE_INPUT;             //输入模式
    gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;      //两个按键的引脚
    gpio_initstruct.Pull = GPIO_PULLUP;                 //上拉
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;       //高速
    HAL_GPIO_Init(GPIOA, &gpio_initstruct);
}

//按键扫描函数
uint8_t key_scan(void)
{
    //检测按键1是否按下
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET )
    {
        //消抖
        delay_ms(10);
        //再次判断按键1是否按下
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET )
        {
            //如果确实是按下的状态,等待按键松开
            while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
            {
                
            }
            //返回按键的值
            return 1;
        }
        
    }
    //检测按键2是否按下
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET )
    {
        //消抖
        delay_ms(10);
        //再次判断按键2是否按下
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET )
        {
            //如果确实是按下的状态,等待按键松开
            while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
            {
                
            }
            //返回按键的值
            return 2;
        }
        
    }
    //如果前面情况都不是返回默认值
    return 0;
    
}

初始化GPIO和之前一样,但是模式改为输入模式(gpio_initstruct.Mode = GPIO_MODE_INPUT),gpio_initstruct.Pull = GPIO_PULLUP,这个模式是根据原理图,按键未被按下时的状态是什么,这个就是什么,因为如果按下是上拉,那么初始化时就要设置为下拉。

按键扫描函数编写的步骤:

1.检测按键是否被按下

使用HAL_GPIO_ReadPin库函数读取电平,根据原理图当按下按钮时为低电平,所以使用if语句判断HAL_GPIO_ReadPin是否等于GPIO_PIN_RESET也就是低电平。

2.消抖

就是直接延时10ms。

3.再次判断按键是否被按下

和第一次检测按键是否被按下一样。

4.如果确实是按下的状态,等待按键松开

等待按键松开的方法是使用while循环如果按键没有松开(为低电平)就一直在while循环里,如果按键松开(为高电平)就跳出while循环。

5.返回按键的值

然后使用return返回数值

6.如果前面情况都不是返回默认值

如果没有按下按键就return 0。

检测按键2是否被按下就和按键1一样只需要将pin值修改即可

4.2key.h

c 复制代码
#ifndef __KEY_H__
#define __KEY_H__

#include "sys.h"

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


#endif

.h文件就是将函数名写进去就行,需要注意的是第二个函数的返回值是uint8_t是包含在stm32f1xx.h这个头文件中的,所以要#include "stm32f1xx.h",又因为sys.h中也有stm32f1xx.h,所以我直接就#include "sys.h"了。

4.3main.c

c 复制代码
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();
    key_init();
    uint8_t key_num = 0; 
    while(1)
    { 
        key_num = key_scan();
        
        if(key_num == 1)
        {
            led1_toggle();
        }
        if(key_num == 2)
        {
            led2_toggle();
        }
    }
}

这里面就是调用上面写好的函数,将返回值保存到key_num变量中,然后判断它的值,再进行具体操作。
注意 尽量不要直接key_scan() == 1或key_scan() == 2,这样判断,因为这样判断就相当于每循环一次将要调用两次key_scan()函数,这样按键操作就有很大的延迟,所以我们之间调用一次将返回值存到一个变量中就行。
完结

相关推荐
EVERSPIN1 天前
MCU微控制器,N32H47x高性能MCU机器人关节控制方案
单片机·嵌入式硬件·机器人·mcu微控制器
0南城逆流01 天前
【STM32】知识点介绍三:哈希算法详解
stm32·嵌入式硬件·哈希算法
云山工作室1 天前
基于STM32单片机的正激式开关电源设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·课程设计·毕设
芯希望1 天前
芯伯乐700mA线性稳压器XBLW L78M05H/L78M12H:稳定可靠,简化电源设计
单片机·嵌入式硬件
lingzhilab1 天前
零知IDE——STM32F407VET6驱动SHT40温湿度传感器与ST7789实现智能环境监测系统
stm32·单片机·嵌入式硬件
贝塔实验室1 天前
Altium Designer 6.3 PCB LAYOUT教程(四)
驱动开发·嵌入式硬件·硬件架构·硬件工程·信息与通信·基带工程·pcb工艺
星辰pid1 天前
stm32的gpio模式到底该怎么选择?(及iic,spi,定时器原理介绍)
stm32·单片机·嵌入式硬件
brave and determined1 天前
可编程逻辑器件学习(day3):FPGA设计方法、开发流程与基于FPGA的SOC设计详解
嵌入式硬件·fpga开发·soc·仿真·电路·时序·可编程逻辑器件
axuan126511 天前
10.【NXP 号令者RT1052】开发——实战-RT 看门狗(RTWDOG)
单片机·嵌入式硬件·mcu
-大头.1 天前
Rust高级类型与零成本抽象实战
stm32·单片机·rust