1. 初始化蓝牙控制器
任务说明
本案例要求编写一段初始化蓝牙控制器的代码,完成三件事:给控制器上电、配置系统时钟、读取芯片版本信息。目标平台为 Nordic nRF52832,通过其 SoftDevice 协议栈提供的 API 实现。代码以函数形式给出,可直接在 Keil 或 GCC 工程中调用。
实现代码
#include <stdint.h>
#include "nrf_sdm.h"
#include "nrf_soc.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
// 电源引脚定义(根据实际硬件连接修改)
#define BT_PWR_PIN 21 // 控制蓝牙芯片供电的GPIO
#define BT_PWR_ENABLE 1 // 高电平使能
/**
* @brief 初始化蓝牙控制器
* @return 0 成功;非0 失败(错误码)
*/
uint32_t ble_controller_init(void)
{
uint32_t err_code;
uint8_t chip_version;
uint16_t chip_id;
// 1. 电源控制:拉高GPIO使能供电
nrf_gpio_cfg_output(BT_PWR_PIN);
nrf_gpio_pin_write(BT_PWR_PIN, BT_PWR_ENABLE);
nrf_delay_ms(10); // 等待电源稳定
// 2. 时钟配置:启用SoftDevice内部低频时钟(LFCLK)
// 使用外部32.768kHz晶振,精度更高
err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM,
NULL);
if (err_code != NRF_SUCCESS) {
return err_code;
}
// 3. 读取芯片版本信息
err_code = sd_ble_version_get(&chip_version, &chip_id);
if (err_code != NRF_SUCCESS) {
return err_code;
}
// 版本信息可通过调试器或串口输出查看
// 此处将版本号存入全局变量供外部使用
extern volatile uint8_t g_ble_chip_version;
extern volatile uint16_t g_ble_chip_id;
g_ble_chip_version = chip_version;
g_ble_chip_id = chip_id;
return NRF_SUCCESS;
}
关键说明
上述代码中,sd_softdevice_enable() 是 SoftDevice 协议栈的启动入口,调用后蓝牙协议栈开始运行,同时完成内部时钟树配置。这里选择外部晶振作为低频时钟源,以获得更精准的时序。读取版本信息使用 sd_ble_version_get(),返回的 chip_version 表示芯片版本号(如 0x01 代表 Rev1),chip_id 为芯片标识符。两个全局变量用于将结果暴露给应用层,实际项目中也可直接通过串口打印。
验证方法
将代码编译后烧录到 nRF52832 开发板,在 ble_controller_init() 返回处设置断点。观察:
- 函数返回值为 0(NRF_SUCCESS),表示初始化成功;
- 通过调试器查看
g_ble_chip_version和g_ble_chip_id的值,非零即表示已正确读取; - 若使用串口打印,可输出类似
"chip ver:1, id:0x0000"的信息。
判定标准:返回值为 0 且版本号非零,即可确认电源、时钟和版本读取三个步骤均正常完成。
依赖与编译
本代码依赖 Nordic SDK 17.0.2 及以上版本,需包含 SoftDevice 头文件路径。在工程设置中需定义 S140 或 S132 宏以匹配所用协议栈。链接时需添加 SoftDevice 静态库。若使用外部晶振,需在板级配置中确认 32.768kHz 晶振已焊接并正确连接。