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 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg20055 小时前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT7 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen7 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠10 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_10 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技12 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计12 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦14 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报14 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机