8-使用固件库点亮LED灯

1 创建标准库模板

参考上一章:http://ckun.fun/index.php/2024/12/03/standard_library/

2 硬件设计

在这个LED灯电路连接中,三个LED灯的阳极(正极)连接到3.3V电源,而阴极(负极)则通过各自的电阻连接到STM32的三个GPIO引脚(PH10、PH11、PH12)。通过控制这些GPIO引脚的高低电平,可以实现对LED灯的开关控制。

  • 当GPIO引脚输出高电平(3.3V)时,由于阳极也连接到3.3V,LED灯不会亮起,因为没有电压差;
  • 当GPIO引脚输出低电平(0V),LED的阴极接地,与阳极的电压形成电压差,LED灯亮起。
  • 将GPIO引脚设置为推挽输出模式,允许引脚输出高电平和低电平;
  • 设置为下拉模式,则GPIO 输出低电平,LED灯点亮。

3 软件设计

以下代码来源于野火整合:
https://gitee.com/Embedfire-stm32f429-tiaozhanzhe/ebf_stm32f429_tiaozhanzhe_std_code

3.1 前提准备

  • 在工程目录下面的USER 文件夹中创建LED 文件夹,在新创建的LED 文件夹中创建两个文件led.h 和led.c
  • led.h:LED 灯引脚宏定义
  • led.c:LED 灯引脚函数程序
  • 将led.c 添加进USER 组中

3.2 led.h

#ifndef __LED_H
#define __LED_H

#include "stm32f4xx.h" 

// R 红色灯
#define LED1_PIN                  GPIO_Pin_10                 
#define LED1_GPIO_PORT            GPIOH                      
#define LED1_GPIO_CLK             RCC_AHB1Periph_GPIOH

// G 绿色灯
#define LED2_PIN                  GPIO_Pin_11                 
#define LED2_GPIO_PORT            GPIOH                      
#define LED2_GPIO_CLK             RCC_AHB1Periph_GPIOH

/** 控制LED灯亮灭的宏,
 * LED低电平亮,设置ON=0,OFF=1
 * 若LED高电平亮,把宏设置成ON=1,OFF=0即可
 */
#define ON  0
#define OFF 1

/* 带参宏,可以像内联函数一样使用 */
#define LED1(a)    if (a)\
                    GPIO_SetBits(LED1_GPIO_PORT, LED1_PIN);\
                else\
                    GPIO_ResetBits(LED1_GPIO_PORT, LED1_PIN)

#define LED2(a)    if (a)\
                    GPIO_SetBits(LED2_GPIO_PORT, LED2_PIN);\
                else\
                    GPIO_ResetBits(LED2_GPIO_PORT, LED2_PIN)

#define LED3(a)    if (a)\
                    GPIO_SetBits(LED3_GPIO_PORT, LED3_PIN);\
                else\
                    GPIO_ResetBits(LED3_GPIO_PORT, LED3_PIN)

#define LED4(a)    if (a)\
                    GPIO_SetBits(LED4_GPIO_PORT, LED4_PIN);\
                else\
                    GPIO_ResetBits(LED4_GPIO_PORT, LED4_PIN)

/* 直接操作寄存器的方法控制IO */
#define digitalHi(p, i)         { p->BSRRL = i; }   // 设置为高电平
#define digitalLo(p, i)         { p->BSRRH = i; }   // 输出低电平
#define digitalToggle(p, i)     { p->ODR ^= i; }    // 输出反转状态

/* 定义控制IO的宏 */
#define LED1_TOGGLE              digitalToggle(LED1_GPIO_PORT, LED1_PIN)
#define LED1_OFF                 digitalHi(LED1_GPIO_PORT, LED1_PIN)
#define LED1_ON                  digitalLo(LED1_GPIO_PORT, LED1_PIN)

#define LED2_TOGGLE              digitalToggle(LED2_GPIO_PORT, LED2_PIN)
#define LED2_OFF                 digitalHi(LED2_GPIO_PORT, LED2_PIN)
#define LED2_ON                  digitalLo(LED2_GPIO_PORT, LED2_PIN)

/* 基本混色,后面高级用法使用PWM可混出全彩颜色,且效果更好 */

// 红
#define LED_RED\
        LED1_ON;\
        LED2_OFF

// 绿
#define LED_GREEN\
        LED1_OFF;\
        LED2_ON
                    
// 黑(全部关闭)
#define LED_RGBOFF\
        LED1_OFF;\
        LED2_OFF    

// LED GPIO 初始化函数
void LED_GPIO_Config(void);

#endif

3.3 led.c

#include "./led/led.h"   

void LED_GPIO_Config(void)
{		
    /* 定义一个GPIO_InitTypeDef类型的结构体 */
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 开启LED相关的GPIO外设时钟 */
    RCC_AHB1PeriphClockCmd(LED1_GPIO_CLK | LED2_GPIO_CLK, ENABLE); 

    /* 选择要控制的GPIO引脚 */
    GPIO_InitStructure.GPIO_Pin = LED1_PIN;	

    /* 设置引脚模式为输出模式 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   
    
    /* 设置引脚的输出类型为推挽输出 */
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    
    /* 设置引脚为上拉模式 */
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    /* 设置引脚速率为2MHz */   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 

    /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO */
    GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);	
    
    /* 选择要控制的GPIO引脚 */
    GPIO_InitStructure.GPIO_Pin = LED2_PIN;	
    GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);	
		
    /* 关闭RGB灯 */
    LED_RGBOFF;		
}

3.4 main.c

#include "stm32f4xx.h"
#include "./led/bsp_led.h"

void Delay(__IO uint32_t nCount); 

int main(void)
{
    /* LED 端口初始化 */
    LED_GPIO_Config();

    /* 控制LED灯 */
    while (1)
    {
        /* 点亮LED1 */
        LED1(ON);                // 亮 
        Delay(0xFFFFFF);        // 延时

        LED1(OFF);               // 熄灭 LED1

        /* 点亮LED2 */
        LED2(ON);                // 亮 
        Delay(0xFFFFFF);        // 延时

        LED2(OFF);               // 熄灭 LED2

        /* 点亮红色LED灯 */
        LED_RED;                 // 红
        Delay(0xFFFFFF);        // 延时
        
        /* 点亮绿色LED灯 */
        LED_GREEN;               // 绿
        Delay(0xFFFFFF);        // 延时
        
        /* 关闭所有LED灯 */
        LED_RGBOFF;              // 关闭RGB灯
        Delay(0xFFFFFF);        // 延时
    }
}

void Delay(__IO uint32_t nCount)  // 简单的延时函数
{
    for (; nCount != 0; nCount--);  // 循环计数,消耗时间
}

发表评论