STM32
直播中

汪潇潇

7年用户 809经验值
私信 关注
[问答]

如何使用STM32固件库通过按键来控制led灯的亮灭?

如何使用STM32固件库通过按键来控制led灯的亮灭?

回帖(1)

刘洋

2021-11-23 14:16:34
前言

LED 灯的控制使用到 GPIO 外设的基本输出功能。
按键检测使用到 GPIO 外设的基本输入功能
本节通过实例来讲述如何使用STM32固件库,通过按键来控制led灯的亮灭。
1.硬件描述

文章是根据野火的STM32f103开发板指南者来进行讨论,在该开发板中,与按键和led有关的外设图如下:
1.1 led硬件描述

这是一个 RGB 灯,里面由红蓝绿三个小灯构成, 使用 PWM 控制时可以混合成 256 不同的颜色。硬件原理图如下:





我们只使用PB0,即绿色灯。
1.2 按键硬件描述

开发板所用按键带硬件消抖功能,它利用电容充放电的延时,消除了波纹,从而简化软件的处理,软件只需要直接检测引脚的电平即可。原理如图:





2.软件部分

2.1 led灯编程要点

1.使能GPIOD端口时钟。
2.初始化GPIO目标引脚为推挽输出模式。
3.编写简单测试程序。
4.方便移植:使用宏。
== 注意:使用推挽输出,原理见寄存器编程GPIO的原理 ==
bsp_led.h内容

#ifndef _BSP_LED_H
#define _BSP_LED_H


#include "stm32f10x.h"
//绿色
#define    LED_G_GPIO_PIN    GPIO_Pin_0
#define    LED_G_GPIO_PROT   GPIOB
#define    LED_G_GPIO_CLK    RCC_APB2Periph_GPIOB
//红色
#define    LED_R_GPIO_PIN    GPIO_Pin_5
#define    LED_R_GPIO_PROT   GPIOB
#define    LED_R_GPIO_CLK    RCC_APB2Periph_GPIOB
//蓝色
#define    LED_B_GPIO_PIN    GPIO_Pin_1
#define    LED_B_GPIO_PROT   GPIOB
#define    LED_B_GPIO_CLK    RCC_APB2Periph_GPIOB


#define    ON        1
#define    OFF       0


#define   LED_G(a)   if(a)
                               GPIO_ResetBits(LED_G_GPIO_PROT, LED_G_GPIO_PIN);
                     else  GPIO_SetBits(LED_G_GPIO_PROT, LED_G_GPIO_PIN);


#define LED_G_TOGGLE {LED_G_GPIO_PROT->ODR ^= LED_G_GPIO_PIN;}


void LED_GPIO_Config(void);


#endif /* _BSP_LED_H */
// bsp :board support package 板级支持包
#include "bsp_led.h"


void LED_GPIO_Config(void)
{
        GPIO_InitTypeDef  GPIO_InitStruct;
       
        RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
       
        GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
       
        GPIO_Init(LED_G_GPIO_PROT, &GPIO_InitStruct);       
}
2.2 按键编程要点

1.使能GPIOD端口时钟。
2.初始化GPIO目标引脚为浮空输入模式。
3.编写简单测试程序。
4.方便移植:使用宏。
== 注意:使用浮空输入,不用上拉,也不用下拉。这样做的原因是在硬件设计中,按键本身通过外部下拉。 ==
bsp_key.h内容

#ifndef _BSP_KEY_H
#define _BSP_KEY_H


#define KEY_ON 1
#define KEY_OFF 0


#include "stm32f10x.h"


#define    KEY1_GPIO_PIN    GPIO_Pin_0
#define    KEY1_GPIO_PROT   GPIOA
#define    KEY1_GPIO_CLK    RCC_APB2Periph_GPIOA


void KEY_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);




#endif /* _BSP_KEY_H */
#include "bsp_key.h"


void KEY_GPIO_Config(void)
{
        GPIO_InitTypeDef  GPIO_InitStruct;
        //配置端口时钟
        RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
       
        GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
       
        GPIO_Init(KEY1_GPIO_PROT, &GPIO_InitStruct);       
}


uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
        /*检测是否有按键按下 */
  if (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )
                {
                        /*等待按键释放 */
                        while (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);
                        return KEY_ON;
                } else
        return KEY_OFF;
}
2.3 主函数

注意,在原来的新建工程模板中,在User文件夹中新增了4个文件,分别是两个.c文件和两个.h文件。你要把他们添加到工程中,并且在魔术棒选项卡中指定两个头文件的路径
main.c内容:

#include "stm32f10x.h"   // 相当于51单片机中的  #include
#include "bsp_led.h"
#include "bsp_key.h"




void Delay(uint32_t count)
{
        for(;count != 0;count--);
}


int main(void)
{
        // 来到这里的时候,系统的时钟已经被配置成72M。
        LED_GPIO_Config();
        KEY_GPIO_Config();
       
        while(1)
        {
                if(Key_Scan(KEY1_GPIO_PROT,KEY1_GPIO_PIN) == KEY_ON)
                        LED_G_TOGGLE;
                       
        }
       
}
后记

这个历程可以下载到开发板,刚开始灯亮,按键按下,灯灭,再次按下,灯亮,如此反复。使用固件库编程相比较寄存器编程来说,方便了很多。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分