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

相关推荐
LCMICRO-133108477463 小时前
长芯微LPS123完全P2P替代ADP123,高性能、低压差的线性稳压器
单片机·嵌入式硬件·fpga开发·硬件工程·dsp开发·线性稳压器
守护安静星空4 小时前
esp32开发笔记-工程搭建
笔记·单片机·嵌入式硬件·物联网·visual studio code
ACP广源盛139246256734 小时前
破局 Type‑C 切换器痛点@ACP#GSV6155+LH3828/GSV2221+LH3828 黄金方案
c语言·开发语言·网络·人工智能·嵌入式硬件·计算机外设·电脑
时空自由民.6 小时前
ST7701S 3.5寸显示屏
单片机
金戈鐡馬6 小时前
BetaFlight中的定时器引脚绑定详解
stm32·单片机·嵌入式硬件·无人机
Wave8457 小时前
FreeRTOS软件定时器详解
stm32·单片机·freertos
VBsemi-专注于MOSFET研发定制8 小时前
奶茶制作机器人功率MOSFET选型方案——高效、精准与可靠驱动系统设计指南
单片机·嵌入式硬件
水云桐程序员9 小时前
单片机项目从入门到精通
单片机·嵌入式硬件
Wave8459 小时前
STM32 裸机中断与 FreeRTOS 中断管理的四大核心差异
单片机·嵌入式硬件
若忘即安10 小时前
【硬件电路设计18】WIFI+BlueTooth
单片机·嵌入式硬件