news 2026/9/14 11:46:32

[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_led] LED配置和使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_led] LED配置和使用

文章目录

  • 一、LED
    • 本文导读
  • 二、常用函数
    • 1. 初始化
    • 2. 电平控制
  • 三、驱动源码分析
    • `bsp_led.h`:类型定义与函数声明
    • `bsp_led.c`:初始化与电平控制实现
  • 四、使用示例
    • 1. LED 不亮
    • 2. 亮度异常
    • 3. 引脚冲突
  • 小结

一、LED

本文将介绍 NRF51 如何点亮 LED 灯,涵盖驱动源码分析、使用示例与常见问题排查。

本文导读

本文围绕 NRF51 的点灯流程展开,涵盖以下内容:

  • LED 驱动源码分析:通过bsp_led.hbsp_led.c了解 LED 的类型定义、初始化及电平控制/翻转函数,可跳转至常用函数。
  • 使用示例:演示在main函数中调用bsp_led_init()bsp_led_on()bsp_led_off()bsp_led_toggle()的完整流程,可跳转至使用示例。
  • 常见问题排查:梳理 LED 不亮、亮度异常、引脚冲突等典型问题的排查与解决方法,可跳转至常见问题与排查。

二、常用函数

1. 初始化

voidbsp_led_init(void);voidbsp_led_deinit(void);

bsp_led_init()用于初始化 LED 引脚,将其配置为推挽输出并默认关闭所有 LED;bsp_led_deinit()用于反初始化,将引脚恢复为浮空输入并关闭 LED。两个函数均无参数、无返回值。

2. 电平控制

voidbsp_led_on(bsp_led_tch);voidbsp_led_off(bsp_led_tch);voidbsp_led_toggle(bsp_led_tch);
  • bsp_led_on(ch):点亮指定 LED。
  • bsp_led_off(ch):关闭指定 LED。
  • bsp_led_toggle(ch):翻转指定 LED 的电平状态。

下表对三个电平控制函数进行对比,便于快速选择:

函数输入参数返回值功能描述典型使用场景
bsp_led_on(ch)ch:LED 组号(bsp_led_t枚举)void点亮指定 LED,根据BS_LEDx_LIGHT_LEVEL输出对应电平状态指示、告警提示、按键反馈等需要点亮 LED 的场景
bsp_led_off(ch)ch:LED 组号(bsp_led_t枚举)void关闭指定 LED,输出与点亮相反的电平熄灭指示灯、复位状态、低功耗待机前关闭 LED 等场景
bsp_led_toggle(ch)ch:LED 组号(bsp_led_t枚举)void翻转指定 LED 的电平状态,亮则灭、灭则亮心跳指示、运行状态闪烁、调试信号输出等场景

说明:三个函数的ch参数均需小于BS_LEDN,否则函数内部会直接返回,不会产生任何操作。

三、驱动源码分析

下面分别从bsp_led.hbsp_led.c两个文件分析 LED 驱动的类型定义、初始化及电平控制实现。

bsp_led.h:类型定义与函数声明

bsp_led.h定义了 LED 组号枚举bsp_led_t,并声明了初始化、反初始化及电平控制等接口函数:

/******************************************************************************** * @file bsp_led.h * @author jianqiang.xue * @version V1.0.0 * @date 2021-04-03 * @brief LED驱动头文件 ********************************************************************************/#ifndef__BSP_LED_H#define__BSP_LED_H/* Includes ------------------------------------------------------------------*/#include<stdint.h>/* Public enum ---------------------------------------------------------------*/typedefenum{BSP_LED_0=0,BSP_LED_1,BSP_LED_2,BSP_LED_3,BSP_LED_4,BSP_LED_5,BSP_LED_6,BSP_LED_7}bsp_led_t;/* Public Function Prototypes ------------------------------------------------*/voidbsp_led_init(void);voidbsp_led_deinit(void);voidbsp_led_on(bsp_led_tch);voidbsp_led_off(bsp_led_tch);voidbsp_led_toggle(bsp_led_tch);#endif
/******************************************************************************** * @file bsp_led.c * @author jianqiang.xue * @version V1.0.0 * @date 2021-07-01 * @brief LED控制 ********************************************************************************//* Includes ------------------------------------------------------------------*/#include"RTE_Components.h"#includeCMSIS_device_header#include"nrf_gpio.h"#include"bsp_gpio.h"#include"bsp_led.h"/* Private Includes ----------------------------------------------------------*/#include"business_gpio.h"#include"business_function.h"/* Private Define ------------------------------------------------------------*//* Private Variables ---------------------------------------------------------*/#ifBS_LEDN!=0staticconstuint16_tg_led_pin[BS_LEDN]={#if(BS_LEDN>0)BS_LED0_PIN#endif#if(BS_LEDN>1),BS_LED1_PIN#endif#if(BS_LEDN>2),BS_LED2_PIN#endif#if(BS_LEDN>3),BS_LED3_PIN#endif#if(BS_LEDN>4),BS_LED4_PIN#endif#if(BS_LEDN>5),BS_LED5_PIN#endif#if(BS_LEDN>6),BS_LED6_PIN#endif#if(BS_LEDN>7),BS_LED7_PIN#endif};staticconstbool g_led_light_state[BS_LEDN]={#if(BS_LEDN>0)BS_LED0_LIGHT_LEVEL#endif#if(BS_LEDN>1),BS_LED1_LIGHT_LEVEL#endif#if(BS_LEDN>2),BS_LED2_LIGHT_LEVEL#endif#if(BS_LEDN>3),BS_LED3_LIGHT_LEVEL#endif#if(BS_LEDN>4),BS_LED4_LIGHT_LEVEL#endif#if(BS_LEDN>5),BS_LED5_LIGHT_LEVEL#endif#if(BS_LEDN>6),BS_LED6_LIGHT_LEVEL#endif#if(BS_LEDN>7),BS_LED7_LIGHT_LEVEL#endif};/* Public Function Prototypes -----------------------------------------------*//** * @brief led初始化 使能引脚时钟 配置为推免输出 * @note NULL * @retval None */voidbsp_led_init(void){uint8_ti;for(i=0;i<BS_LEDN;i++){/* Configure the GPIO_LED pin */bsp_gpio_init_output(NULL,g_led_pin[i],BSP_GPIO_PIN_OUT_PP);/* Reset PIN to switch off the LED */bsp_gpio_set_pin(NULL,g_led_pin[i],(bsp_gpio_pin_state_t)!g_led_light_state[i]);}}/** * @brief led反初始化 将引脚配置为浮空输入 * @note NULL * @retval None */voidbsp_led_deinit(void){uint8_ti;if(BS_LEDN==0){return;}for(i=0;i<BS_LEDN;i++){/* Turn off LED */bsp_gpio_set_pin(NULL,g_led_pin[i],(bsp_gpio_pin_state_t)!g_led_light_state[i]);/* DeInit the GPIO_LED pin */bsp_gpio_deinit(NULL,g_led_pin[i]);}}/** * @brief 点亮LED * @note NULL * @param ch: LED组号 * @retval None */voidbsp_led_on(bsp_led_tch){if(ch>=BS_LEDN){return;}bsp_gpio_set_pin(NULL,g_led_pin[ch],(bsp_gpio_pin_state_t)g_led_light_state[ch]);}/** * @brief 关闭LED * @note NULL * @param ch: LED组号 * @retval None */voidbsp_led_off(bsp_led_tch){if(ch>=BS_LEDN){return;}bsp_gpio_set_pin(NULL,g_led_pin[ch],(bsp_gpio_pin_state_t)!g_led_light_state[ch]);}/** * @brief 翻转LED * @note NULL * @param ch: LED组号 * @retval None */voidbsp_led_toggle(bsp_led_tch){if(ch>=BS_LEDN){return;}bsp_gpio_set_toggle(NULL,g_led_pin[ch]);}#elsevoidbsp_led_init(void){}voidbsp_led_deinit(void){}voidbsp_led_on(bsp_led_tch){}voidbsp_led_off(bsp_led_tch){}voidbsp_led_toggle(bsp_led_tch){}#endif

bsp_led.c:初始化与电平控制实现

bsp_led.c实现了上述接口。核心逻辑包括:

  • 引脚映射表g_led_pin[]:通过BS_LEDNBS_LEDx_PIN宏配置 LED 对应的 GPIO 引脚。
  • 电平映射表g_led_light_state[]:通过BS_LEDx_LIGHT_LEVEL配置每个 LED 的点亮电平(高电平点亮为true,低电平点亮为false)。
  • 初始化bsp_led_init():将引脚配置为推挽输出,并默认输出熄灭电平。
  • 反初始化bsp_led_deinit():关闭 LED 并将引脚恢复为浮空输入。
  • 电平控制bsp_led_on()/bsp_led_off()/bsp_led_toggle():根据ch参数操作对应引脚,ch越界时直接返回。

四、使用示例

下面通过一个完整的main函数示例,演示如何调用bsp_led_init()bsp_led_on()bsp_led_off()bsp_led_toggle()

需要注意的是,示例中的nrf_delay_ms()仅用于示意,实际开发时可根据 SDK 版本替换为其它延时函数。

#include<stdbool.h>#include"nrf_delay.h"/* 根据需要引入对应延时函数 */#include"bsp_led.h"/* 引入 LED 驱动接口 */intmain(void){/* 1. 初始化 LED 引脚为推挽输出,并默认关闭 LED */bsp_led_init();while(true){/* 2. 点亮 LED0 */bsp_led_on(BSP_LED_0);nrf_delay_ms(500);/* 3. 关闭 LED0 */bsp_led_off(BSP_LED_0);nrf_delay_ms(500);/* 4. 翻转 LED0 电平:若当前为亮则熄灭,若为灭则点亮 */bsp_led_toggle(BSP_LED_0);nrf_delay_ms(500);/* 5. 再次翻转,恢复到本轮回退前的状态 */bsp_led_toggle(BSP_LED_0);nrf_delay_ms(500);}}

以上流程会形成 LED0 “亮 → 灭 → 亮 → 灭”的循环效果。实际使用时请根据硬件连接确认BSP_LED_0对应的 GPIO 引脚,并确保BS_LEDN大于 0。

下面再演示同时控制多个 LED 的场景:让BSP_LED_0BSP_LED_1交替闪烁。实际使用时,请根据硬件原理图确认BS_LED0_PINBS_LED1_PIN对应的 GPIO 引脚号。

#include<stdbool.h>#include"nrf_delay.h"/* 根据需要引入对应延时函数 */#include"bsp_led.h"/* 引入 LED 驱动接口 */intmain(void){/* 1. 初始化所有 LED 引脚为推挽输出,并默认关闭 LED */bsp_led_init();while(true){/* 2. 点亮 LED0(对应引脚 BS_LED0_PIN,高电平点亮时输出高电平) */bsp_led_on(BSP_LED_0);/* 3. 关闭 LED1(对应引脚 BS_LED1_PIN,输出与点亮相反的电平) */bsp_led_off(BSP_LED_1);nrf_delay_ms(500);/* 4. 关闭 LED0 */bsp_led_off(BSP_LED_0);/* 5. 点亮 LED1 */bsp_led_on(BSP_LED_1);nrf_delay_ms(500);}}

以上流程会形成 LED0 与 LED1 交替闪烁的效果:LED0 亮时 LED1 灭,LED0 灭时 LED1 亮。请确保BS_LEDN大于等于 2,且BS_LED0_PINBS_LED1_PIN与硬件连接一致。

若需要同时控制多个 LED,可分别调用bsp_led_on()/bsp_led_off()操作不同的bsp_led_t枚举值。## 常见问题与排查

1. LED 不亮

现象:调用bsp_led_on()后 LED 没有任何反应。

排查步骤

  1. 确认bsp_led_init()是否已被调用。
  2. 检查g_led_pin[]中的引脚号是否与硬件原理图一致。
  3. 检查BS_LEDN是否大于 0;若为 0,所有 LED 函数都是空实现。
  4. 用万用表测量 GPIO 引脚电平,观察调用bsp_led_on()前后电平是否变化。
  5. 确认该引脚没有被其它外设抢占,也没有被bsp_led_deinit()反初始化。

解决方法

  • 修正引脚配置,并在使用前调用bsp_led_init()
  • 核对BS_LEDx_LIGHT_LEVEL的电平逻辑:高电平点亮的 LED 配置为true,低电平点亮的 LED 配置为false

2. 亮度异常

现象:LED 能点亮,但亮度偏暗、偏亮或闪烁。

排查步骤

  1. 检查 GPIO 是否配置为推挽输出,避免误配为开漏或输入模式。
  2. 检查硬件限流电阻与供电电压是否合理。
  3. 确认该引脚没有被其它外设复用,导致电平被拉低或拉高。
  4. 检查快速翻转时 GPIO 是否发生误操作。

解决方法

  • 将 GPIO 配置为BSP_GPIO_PIN_OUT_PP推挽输出。
  • 根据 LED 参数调整限流电阻。
  • 给 LED 分配独立、空闲的 GPIO 引脚。

3. 引脚冲突

现象:LED 点亮后影响串口、SPI、I2C 等功能,或外设初始化后 LED 失控。

排查步骤

  1. 核对g_led_pin[]使用的引脚是否与外设复用。
  2. 查看芯片默认引脚功能和复用配置,确认初始化顺序是否会互相覆盖。
  3. 检查 LED 使用完成后是否正确调用bsp_led_deinit()释放引脚。

解决方法

  • 更换空闲 GPIO 驱动 LED。
  • 如需复用引脚,明确引脚占用与释放时机,避免同时初始化。

下表汇总了三类常见问题的现象、可能原因与解决方法,便于快速查阅:

问题现象可能原因解决方法
LED 不亮调用bsp_led_on()后 LED 没有任何反应未调用bsp_led_init();引脚号与原理图不一致;BS_LEDN为 0;电平逻辑配置错误;引脚被其它外设抢占使用前调用bsp_led_init();核对g_led_pin[]引脚号;确保BS_LEDN大于 0;核对BS_LEDx_LIGHT_LEVEL电平逻辑;释放被占用的引脚
亮度异常LED 能点亮,但亮度偏暗、偏亮或闪烁GPIO 未配置为推挽输出;限流电阻或供电电压不合理;引脚被外设复用拉低/拉高电平;快速翻转导致误操作将 GPIO 配置为BSP_GPIO_PIN_OUT_PP推挽输出;根据 LED 参数调整限流电阻;给 LED 分配独立、空闲的 GPIO 引脚
引脚冲突LED 点亮后影响串口、SPI、I2C 等功能,或外设初始化后 LED 失控g_led_pin[]与外设复用;初始化顺序互相覆盖;使用完成后未释放引脚更换空闲 GPIO 驱动 LED;明确引脚占用与释放时机,避免同时初始化;使用完成后调用bsp_led_deinit()释放引脚

提示:排查问题时建议先确认 GPIO 引脚配置、电平逻辑与初始化调用,再结合硬件连接逐项核对,可快速定位大多数故障。

小结

本节介绍了 NRF51 点亮 LED 的常用函数与排查方法。

核心要点:先通过bsp_led_init()完成引脚初始化,再使用bsp_led_on()/bsp_led_off()/bsp_led_toggle()控制电平;

实际开发时应先确认 GPIO 引脚配置、电平逻辑和初始化调用,遇到问题优先排查硬件连接与引脚复用情况。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 11:44:22

Linux文件系统结构全解析:从目录树、挂载到inode底层原理

直接用一个真实场景开头&#xff1a;你折腾 Linux 半年了&#xff0c;ls、cd、cat这些命令早就滚瓜烂熟&#xff0c;但真遇到“U盘插上为什么没有盘符”、“df显示满了可就是找不到大文件”、“删了日志但空间没释放”这类问题时&#xff0c;还是会愣住。这些问题的根源全在一个…

作者头像 李华
网站建设 2026/9/14 11:41:58

c++——模版

目录 引子 模版是什么 模版格式 函数模版 函数模版的隐式实例化 函数模版的显式实例化 原理 一些使用的例子&#xff08;帮助理解&#xff09; 模版函数的匹配原则 类模板 简单使用 类模板中的成员函数函数放在类外进行定义 原理 非类型模版参数 typename指定类…

作者头像 李华