![[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_led] LED配置和使用](http://pic.xiahunao.cn/yaotu/[单片机框架][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.h与bsp_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 引脚将其配置为推挽输出并默认关闭所有 LEDbsp_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)chLED 组号bsp_led_t枚举void点亮指定 LED根据BS_LEDx_LIGHT_LEVEL输出对应电平状态指示、告警提示、按键反馈等需要点亮 LED 的场景bsp_led_off(ch)chLED 组号bsp_led_t枚举void关闭指定 LED输出与点亮相反的电平熄灭指示灯、复位状态、低功耗待机前关闭 LED 等场景bsp_led_toggle(ch)chLED 组号bsp_led_t枚举void翻转指定 LED 的电平状态亮则灭、灭则亮心跳指示、运行状态闪烁、调试信号输出等场景说明三个函数的ch参数均需小于BS_LEDN否则函数内部会直接返回不会产生任何操作。三、驱动源码分析下面分别从bsp_led.h与bsp_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 ------------------------------------------------------------------*/#includestdint.h/* Public enum ---------------------------------------------------------------*/typedefenum{BSP_LED_00,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 ------------------------------------------------------------------*/#includeRTE_Components.h#includeCMSIS_device_header#includenrf_gpio.h#includebsp_gpio.h#includebsp_led.h/* Private Includes ----------------------------------------------------------*/#includebusiness_gpio.h#includebusiness_function.h/* Private Define ------------------------------------------------------------*//* Private Variables ---------------------------------------------------------*/#ifBS_LEDN!0staticconstuint16_tg_led_pin[BS_LEDN]{#if(BS_LEDN0)BS_LED0_PIN#endif#if(BS_LEDN1),BS_LED1_PIN#endif#if(BS_LEDN2),BS_LED2_PIN#endif#if(BS_LEDN3),BS_LED3_PIN#endif#if(BS_LEDN4),BS_LED4_PIN#endif#if(BS_LEDN5),BS_LED5_PIN#endif#if(BS_LEDN6),BS_LED6_PIN#endif#if(BS_LEDN7),BS_LED7_PIN#endif};staticconstbool g_led_light_state[BS_LEDN]{#if(BS_LEDN0)BS_LED0_LIGHT_LEVEL#endif#if(BS_LEDN1),BS_LED1_LIGHT_LEVEL#endif#if(BS_LEDN2),BS_LED2_LIGHT_LEVEL#endif#if(BS_LEDN3),BS_LED3_LIGHT_LEVEL#endif#if(BS_LEDN4),BS_LED4_LIGHT_LEVEL#endif#if(BS_LEDN5),BS_LED5_LIGHT_LEVEL#endif#if(BS_LEDN6),BS_LED6_LIGHT_LEVEL#endif#if(BS_LEDN7),BS_LED7_LIGHT_LEVEL#endif};/* Public Function Prototypes -----------------------------------------------*//** * brief led初始化 使能引脚时钟 配置为推免输出 * note NULL * retval None */voidbsp_led_init(void){uint8_ti;for(i0;iBS_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_LEDN0){return;}for(i0;iBS_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(chBS_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(chBS_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(chBS_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){}#endifbsp_led.c初始化与电平控制实现bsp_led.c实现了上述接口。核心逻辑包括引脚映射表g_led_pin[]通过BS_LEDN与BS_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 版本替换为其它延时函数。#includestdbool.h#includenrf_delay.h/* 根据需要引入对应延时函数 */#includebsp_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_0与BSP_LED_1交替闪烁。实际使用时请根据硬件原理图确认BS_LED0_PIN与BS_LED1_PIN对应的 GPIO 引脚号。#includestdbool.h#includenrf_delay.h/* 根据需要引入对应延时函数 */#includebsp_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_PIN、BS_LED1_PIN与硬件连接一致。若需要同时控制多个 LED可分别调用bsp_led_on()/bsp_led_off()操作不同的bsp_led_t枚举值。## 常见问题与排查1. LED 不亮现象调用bsp_led_on()后 LED 没有任何反应。排查步骤确认bsp_led_init()是否已被调用。检查g_led_pin[]中的引脚号是否与硬件原理图一致。检查BS_LEDN是否大于 0若为 0所有 LED 函数都是空实现。用万用表测量 GPIO 引脚电平观察调用bsp_led_on()前后电平是否变化。确认该引脚没有被其它外设抢占也没有被bsp_led_deinit()反初始化。解决方法修正引脚配置并在使用前调用bsp_led_init()。核对BS_LEDx_LIGHT_LEVEL的电平逻辑高电平点亮的 LED 配置为true低电平点亮的 LED 配置为false。2. 亮度异常现象LED 能点亮但亮度偏暗、偏亮或闪烁。排查步骤检查 GPIO 是否配置为推挽输出避免误配为开漏或输入模式。检查硬件限流电阻与供电电压是否合理。确认该引脚没有被其它外设复用导致电平被拉低或拉高。检查快速翻转时 GPIO 是否发生误操作。解决方法将 GPIO 配置为BSP_GPIO_PIN_OUT_PP推挽输出。根据 LED 参数调整限流电阻。给 LED 分配独立、空闲的 GPIO 引脚。3. 引脚冲突现象LED 点亮后影响串口、SPI、I2C 等功能或外设初始化后 LED 失控。排查步骤核对g_led_pin[]使用的引脚是否与外设复用。查看芯片默认引脚功能和复用配置确认初始化顺序是否会互相覆盖。检查 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 引脚配置、电平逻辑和初始化调用遇到问题优先排查硬件连接与引脚复用情况。