STM32F103:简单LED控制驱动实现

介绍

在本篇文章中,我们将实现一个基于STM32F103的简单LED控制驱动。LED(Light Emitting Diode,发光二极管)是嵌入式开发中常用的外设,常用于状态指示、调试输出等场合。通过这篇文章,你将学习如何在STM32F103开发板上配置GPIO端口来控制LED的开关与状态翻转。

硬件连接

在硬件部分,我们假设LED连接到STM32F103的GPIO端口。以GPIOB端口为例,将LED分别连接到PB3和PB4引脚。

  • LED1 连接到 GPIOB, GPIO_PIN_3
  • LED2 连接到 GPIOB, GPIO_PIN_4

软件设计

1. LED结构体定义

首先,我们定义一个 LED_TypeDef 结构体,包含LED所在的GPIO端口和引脚号。这样可以灵活地控制不同端口上的LED。

typedef struct {
    GPIO_TypeDef* GPIO_PORT; // GPIO端口
    uint16_t GPIO_PIN;       // GPIO引脚
} LED_TypeDef;

2. LED初始化函数

接下来,我们实现一个LED初始化函数,用于配置GPIO引脚为推挽输出模式,并设置初始状态。

void LED_Init(LED_TypeDef* led)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 使能LED所在端口的时钟
    if (led->GPIO_PORT == GPIOB) {
        __HAL_RCC_GPIOB_CLK_ENABLE();
    } else if (led->GPIO_PORT == GPIOA) {
        __HAL_RCC_GPIOA_CLK_ENABLE();
    }
    // 根据需要添加更多GPIO端口使能 else if
    
    // 配置GPIO引脚为推挽输出模式
    GPIO_InitStruct.Pin = led->GPIO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
    GPIO_InitStruct.Pull = GPIO_NOPULL;         // 不用上拉下拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速(省电)
    
    HAL_GPIO_Init(led->GPIO_PORT, &GPIO_InitStruct);
    
    // 设置默认状态(默认熄灭)
    HAL_GPIO_WritePin(led->GPIO_PORT, led->GPIO_PIN, GPIO_PIN_SET);
}

解释:
1.时钟使能: 使能LED所在的GPIO端口时钟,确保该端口的引脚可以正常工作。
2.GPIO配置: 配置为推挽输出模式,适合用来控制LED的亮灭。
3.初始状态设置: 设置LED的初始状态为熄灭(根据硬件连接,通常使用高电平熄灭LED)。

3. 控制LED状态的函数

我们提供了三个函数来控制LED的状态:
LED_On():点亮LED
LED_Off():关闭LED
LED_Toggle():翻转LED状态(亮/灭)

void LED_On(LED_TypeDef* led)
{
    HAL_GPIO_WritePin(led->GPIO_PORT, led->GPIO_PIN, GPIO_PIN_RESET); // 点亮LED
}

void LED_Off(LED_TypeDef* led)
{
    HAL_GPIO_WritePin(led->GPIO_PORT, led->GPIO_PIN, GPIO_PIN_SET); // 熄灭LED
}

void LED_Toggle(LED_TypeDef* led)
{
    HAL_GPIO_TogglePin(led->GPIO_PORT, led->GPIO_PIN); // 翻转LED状态
}

4. 主函数代码示例

在主函数中,我们通过调用 LED_Init() 来初始化LED,随后可以使用 LED_On()、LED_Off() 或 LED_Toggle() 来控制LED的状态。

int main(void)
{
    HAL_Init();  // 初始化HAL库
    LED_TypeDef LED1 = {GPIOB, GPIO_PIN_3};  // 定义LED1,连接到PB3
    LED_TypeDef LED2 = {GPIOB, GPIO_PIN_4};  // 定义LED2,连接到PB4
    
    // 初始化LED1和LED2
    LED_Init(&LED1);
    LED_Init(&LED2);
    
    while (1)
    {
        // 测试:让LED1每500ms切换状态
        LED_Toggle(&LED1);
        HAL_Delay(500);  // 延迟500ms
    }
}

头文件 LED.h

在我们的LED控制驱动中,首先需要定义一个头文件 LED.h,它包含了LED结构体的定义以及相关的函数声明。下面是完整的 LED.h 文件内容:

#ifndef __LED_H
#define __LED_H

#include "stm32f1xx_hal.h"  // 引入STM32 HAL库

// LED结构体,包含GPIO端口和引脚信息
typedef struct{
    GPIO_TypeDef* GPIO_PORT;  // GPIO端口
    uint16_t GPIO_PIN;        // GPIO引脚
} LED_TypeDef;

// 函数声明

/**
 * @brief 初始化LED
 * @param led: LED结构体,包含端口和引脚信息
 * @note 该函数会使能GPIO时钟,配置GPIO引脚为推挽输出模式,默认LED为关闭状态
 */
void LED_Init(LED_TypeDef* led); // 初始化 LED

/**
 * @brief 打开LED
 * @param led: LED结构体,包含端口和引脚信息
 * @note 该函数将GPIO引脚电平设置为低电平,点亮LED
 */
void LED_On(LED_TypeDef* led);  // 打开 LED

/**
 * @brief 关闭LED
 * @param led: LED结构体,包含端口和引脚信息
 * @note 该函数将GPIO引脚电平设置为高电平,熄灭LED
 */
void LED_Off(LED_TypeDef* led); // 关闭 LED

/**
 * @brief 翻转LED状态
 * @param led: LED结构体,包含端口和引脚信息
 * @note 该函数会将LED的状态进行翻转,亮的变灭,灭的变亮
 */
void LED_Toggle(LED_TypeDef* led); // 翻转 LED 状态

#endif  //__LED_H

总结

通过这篇文章,你学习了如何在STM32F103开发板上控制LED。我们实现了LED的初始化、点亮、熄灭和翻转操作,使用了STM32 HAL库的GPIO接口。代码结构简单明了,适用于基础的LED控制任务。

其他

在本次设计中,我主要集中在LED控制的基本功能实现上,但在实际项目中,LED的控制可以结合更多的设计想法,提供更丰富的功能。以下是一些未来可以考虑的设计优化和扩展:

  • 支持多种LED工作模式: 除了常规的点亮、熄灭和翻转,我们可以为LED增加更多的工作模式,例如闪烁频率可调、不同模式下的亮度控制等。通过增加PWM输出控制LED亮度,能够使LED在不同状态下呈现不同的亮度效果,适用于更加复杂的应用场景。
  • 增加LED状态监控功能: 在一些复杂应用中,可能需要实时监控LED的状态。通过引入反馈机制,可以检测LED当前的状态,并根据不同的需求进行动态调整。例如,在调试模式下可以增加LED状态输出到串口,以便于通过调试工具实时观察LED的变化。
  • 使用定时器替代延时: 为了减少对 HAL_Delay() 的依赖,可以使用STM32的定时器来生成精确的时间延迟。定时器的使用不仅提高了系统的效率,也避免了主程序被延迟操作所阻塞,尤其是在需要并发操作多个外设时,这样可以实现更加精确的时间控制。
  • 多LED同步控制: 对于需要同时控制多个LED的应用(例如,状态指示、进度显示等),可以通过进一步抽象设计,将多个LED控制合并为一个模块,提供统一的接口进行同步控制,减少代码冗余和提高代码的可维护性。

为了让LED控制模块更加灵活和可复用,我将LED控制功能封装成了一个单独的底层驱动模块。在这个设计中,我使用了 LED_TypeDef 结构体来存储LED的GPIO端口和引脚信息,这样可以通过传递不同的结构体来控制不同的LED,避免为每个LED写重复代码。

通过这种方式,LED的初始化和控制都封装成了简单的函数,用户只需要调用这些函数即可完成LED控制。这样的设计不仅提高了代码的可维护性,还使得后续在不同项目中复用时更加方便。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐