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()函数,这样按键操作就有很大的延迟,所以我们之间调用一次将返回值存到一个变量中就行。
完结

相关推荐
蓬荜生灰3 小时前
STM32(13)-- 位带操作
stm32·单片机·嵌入式硬件
哎呦 你干嘛~5 小时前
plc单片机485通讯
单片机·嵌入式硬件
szxinmai主板定制专家6 小时前
基于 PC 的控制技术+ethercat+linux实时系统,助力追踪标签规模化生产,支持国产化
arm开发·人工智能·嵌入式硬件·yolo·fpga开发
泡泡糖的中文规格书9 小时前
【硬件设计】LM358DR2G中文文档深度解读:高质量翻译与芯片特性全解析
嵌入式硬件·规格说明书·电路设计·运放·中文翻译·datasheet
czwxkn10 小时前
2STM32(stdl)GPIO输入
stm32·单片机·嵌入式硬件
码农三叔11 小时前
(9-1)电源管理与能源系统:电池选择与安全
人工智能·嵌入式硬件·安全·机器人·能源·人形机器人
qq_2466461912 小时前
openclaw快速安装-windows版
windows·stm32·单片机
染予14 小时前
13.AD软件操作:原理图如何导入PCB及导入常见错误
嵌入式硬件
小莞尔15 小时前
【51单片机】【protues仿真】 基于51单片机波形发生器系统
c语言·单片机·嵌入式硬件·物联网·51单片机