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

相关推荐
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
Lester_11014 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元4 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
三佛科技-187366133974 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315204 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书4 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
Alaso_shuang5 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
脚后跟5 天前
AI助力嵌入式物联网项目全栈开发
嵌入式硬件·物联网·ai编程
2501_918126915 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
z20348315205 天前
STM32F103系列单片机定时器介绍(一)
stm32·单片机