NRF单片机开发环境搭建

补档声明

由于我的博客服务器和备案到期,所以选择转移到博客园平台来进行保存和记录。以后也有可能会在上面不定期更新一些技术类博客。

前言

20250911224413

NRF52系列是一款性能较强,带蓝牙模组(支持普通蓝牙和BLE蓝牙),主打极低功耗的MCU。常用于无线鼠标和键盘以及可穿戴设备主控。
最近一个项目需要用到NRF52840这个芯片的蓝牙,以及其芯片本身的低功耗特性。
搭建其开发工具链的过程中也遇到了一些值得记录的问题,这篇文就简单介绍一下如何搭建工具链,以及和SDK工程相关的设置。加快后来者的调试速度🙂。
这篇文的目的是快速在一台Windows电脑上安装nRF芯片的开发环境,并点亮一个nRF开发板上的LED,并使用RTT打印调试消息,以及进行蓝牙广播,成功连接后改变led的亮灭。达到快速构建一个最小可用demo环境。
整体搭建预计时间30分钟,不包括下载安装包的时间。
硬件准备:
JLINK或者DAP-Link
nrf52840开发板
电脑,系统Window10以上

下载并安装SEGGER

官网下载地址: SEGGER官网地址

20250911224806

下载后进行安装,一路next,安装过程中会弹出一些驱动的安装窗口,也一并装上。
装好后打开,看下能否正常运行,注意此时电脑的USB口不能插上任何CMSIS-DAP调试器,否则会导致整个界面卡住,此时拔掉就可以正常打开了(这个bug报告2022年就有了,但是一直没修)。

下载nRF SDK和nRF SoftDevice协议栈

SDK版本选择17.1.0,这也是最新的,不再有后续更新了的,支持nrf52系列的SDK了。
下面的SoftDevice先默认全部下载下来,反正SoftDevice是蓝牙协议栈,大小只有几百K,可以后面再研究。

官网下载地址: SDK官网地址

20250911225033

20250911225043

20250911225052

关于开发方案的说明

传统的单片机开发通常需要开发者从零开始构建完整的工程架构。首先,开发者需要获取厂商提供的最小系统示例代码(如果有的话),然后逐步添加必要的库文件和支持文件。整个开发流程包括:

启动文件配置:编写或配置startup汇编文件,负责系统启动时的基本初始化
中断向量表设置:定义和配置中断向量表,确保系统能够正确响应各种中断
系统时钟配置:初始化系统时钟和各个外设时钟
外设初始化:配置GPIO、串口、定时器等外设模块
用户代码编写:最终进入main函数,根据库手册编写应用层逻辑代码

目前市面上的单片机开发IDE种类繁多,各有特色:

  • KEIL MDK:ARM Cortex-M系列单片机的经典IDE,调试功能强大
  • IAR Embedded Workbench:支持多种架构,代码优化能力出色
  • ESP-IDF:乐鑫ESP32系列专用开发框架,基于FreeRTOS
  • Segger Embedded Studio:轻量级IDE,支持多种调试器
  • STM32CubeIDE:STM32官方IDE,集成了CubeMX配置工具
  • VSCode + PlatformIO/CLion:现代化的跨平台开发环境
  • Arduino IDE:面向初学者的简化开发环境

其中笔者比较熟悉的STM32官方提供的CubeMX是一个图形化配置工具,它能够:

  • 可视化配置芯片引脚功能和外设参数
  • 自动生成初始化代码和工程框架
  • 智能管理库文件依赖关系
  • 支持多种IDE输出格式
    这种方式大大简化了开发流程,特别适合STM32系列单片机的快速开发。

还有Arduino平台通过高度抽象的硬件抽象层,让开发者能够:

  • 使用简化的API函数操作硬件
  • 无需关心底层寄存器配置
  • 快速上手,专注于应用逻辑开发
  • 享受丰富的社区库资源

但是在很多情况下,开发者仍需要采用更接近底层的开发方式:

  1. 从官方网站下载对应单片机的SDK包
  2. 手动创建工程并导入必要的源文件和头文件
  3. 根据数据手册和参考文档配置寄存器
  4. 调用SDK提供的API函数实现功能
    这种方式虽然学习曲线较陡,但能够让开发者更深入理解硬件工作原理,实现更精细的控制和优化。

目前我探索到的nrf系列芯片开发工具栏有两套,一套是SEGGER+SDK,另一套是KEIL+SDK。

由于SEGGER对nrf系列芯片的支持比较好,所以本篇文章聚焦于SEGGER+SDK的开发方式。

工程修改

字段大小修改

SEGGER新版本下每个工程都需要进行的修改,这是由于SDK17.1的工程设置有点问题,是基于旧版SEGGER的。导致新版SEGGER IDE打开工程后会出现由于工程字段大小设置不对而造成编译错误。

下载完成后解压SDK,可以看到一个这样的文件夹名nRF5_SDK_17.1.0_ddde560,examples路径下就是各个例程,其中pca10056代表是nrf52840板子,blank是裸机,mbr是带bootloader的。
进入工程的ses路径

然后打开类似于blinky_pca10056.emProject的segger工程。

20250911225235

打开后就能看到这个界面,然后我们直接按F7编译

20250911225244

20250911225252

然后我们就能看到这个经典错误,这个错误乍一看是不是以为是内存或者FLASH爆了,但是这只是个简单的LED闪烁,不应该出现这种问题。其实这是由于SDK不知道为什么把工程的两个size字段设置为了0x4。导致编译出来的工程必超过这个大小,导致编译器报错。

我们在左侧工程名称上右键,然后选择Edit Section Placement,然后把其中的两个字段的0x4删去,只保留""

20250911225311

20250911225316

然后按下F7开始编译,就会发现直接OK了。

20250911225323

虽说nRF SDK已经停止更新,停留在17.1版本了,但是这也太不走心了😳,给的例程总要能过一下编译吧。

使用NRF_LOG

在任何使用了NRF_LOG的工程里,都需要进行下列修改,才能正常使用。

首先打开个使用了NRF_LOG的工程,然后按F7进行编译,会发现有这样的错误提示

20250911225419

20250911225427

这错误我怀疑是SEGGER的RTT版本没有和SDK对齐导致的,但是好玩的是,这个文件其实整个都被bypass掉了,所以我们只需要在工程上右键删掉这个文件就可以了。

20250911225437

此外还有一种错误,error: unknown type name '__printf_tag_ptr'

20250911225451

这时候需要在工程里把Library IO改成RTT

20250911225500

20250911225504

然后将**__printf_tag_ptr*替换为FILE,然后按F7编译就可以了
最后,一定要检查sdk_config.h里宏定义是下列情况,这样情况下是使用RTT而不是串口,建议尽量使用RTT.

串口打印需要时间且占用管脚,且如果这个管脚其他的设备也在使用,就会造成错误。

20250911225535

NRF_LOG_BACKEND_RTT_ENABLED 1
NRF_LOG_BACKEND_UART_ENABLED 0
此外,NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64这个值可以稍微调大一点,比如256,这样就能容纳更多内容,FLUSH不用那么频繁。

I2S位数问题

由于nrf52系列的设计问题,官方驱动的I2S并不支持24bit的数据放在一个32bit的slot中,会触发I2S时钟倍数关系的错误强制检查。
而把24bit的数据放在一个32bit的slot中,也就是说产生一个SCK是WS的64倍的频率,是INMP411这种I2S麦克风时序要求所必须的。不幸的是,nrf52系列由于上述设计问题,最高只能产生48x的时钟。
所以理论上是用不了的。只能去用原生16bit或者原生32bit的I2S数字麦克风,然而这种麦克风在市面上并不常见,最常见的还是24bit的。
但是还是有方法的,也就是用PWM波形来模拟I2S的时钟,自己去产生时钟倍数关系,然后把I2S设置成从模式,绕过主模式下的时钟关系检查,然后用从模式来获取数据
参考这个链接
https://github.com/gregtomasch/nRF52_24-bit-_I2S_Microphone_Audio_Recording_Utility

蓝牙初始化问题

由于蓝牙时钟的默认设置,会导致初始化的时候出现问题,需要在sdk_config.h中进行如下修改

20250911225627

最小蓝牙demo工程构建

打开sdk的example文件夹下ble_uart_app的SEGGER工程.
按照上述说明对工程进行修改.
直接烧录到单片机.
用手机看有没有ble_uart_app设备,如果有,就可以进行愉快的开发了.

此外,需要注意的是,nrf的外设开启和很多配置需要通过修改sdk_config.h来完成
而且官方提供的sdk例程里,如果没有用到此项外设例如I2S,是完全不会有此项的配置信息的。😓
需要从别的用到了这一项的例程中copy一份过来,再进行配置打开或关闭。

posted @ 2026-02-19 14:19  Badboy02  阅读(2)  评论(0)    收藏  举报