NRF单片机开发环境搭建
补档声明
由于我的博客服务器和备案到期,所以选择转移到博客园平台来进行保存和记录。以后也有可能会在上面不定期更新一些技术类博客。
前言

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

下载后进行安装,一路next,安装过程中会弹出一些驱动的安装窗口,也一并装上。
装好后打开,看下能否正常运行,注意此时电脑的USB口不能插上任何CMSIS-DAP调试器,否则会导致整个界面卡住,此时拔掉就可以正常打开了(这个bug报告2022年就有了,但是一直没修)。
下载nRF SDK和nRF SoftDevice协议栈
SDK版本选择17.1.0,这也是最新的,不再有后续更新了的,支持nrf52系列的SDK了。
下面的SoftDevice先默认全部下载下来,反正SoftDevice是蓝牙协议栈,大小只有几百K,可以后面再研究。
官网下载地址: SDK官网地址



关于开发方案的说明
传统的单片机开发通常需要开发者从零开始构建完整的工程架构。首先,开发者需要获取厂商提供的最小系统示例代码(如果有的话),然后逐步添加必要的库文件和支持文件。整个开发流程包括:
启动文件配置:编写或配置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函数操作硬件
- 无需关心底层寄存器配置
- 快速上手,专注于应用逻辑开发
- 享受丰富的社区库资源
但是在很多情况下,开发者仍需要采用更接近底层的开发方式:
- 从官方网站下载对应单片机的SDK包
- 手动创建工程并导入必要的源文件和头文件
- 根据数据手册和参考文档配置寄存器
- 调用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工程。

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


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


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

虽说nRF SDK已经停止更新,停留在17.1版本了,但是这也太不走心了😳,给的例程总要能过一下编译吧。
使用NRF_LOG
在任何使用了NRF_LOG的工程里,都需要进行下列修改,才能正常使用。
首先打开个使用了NRF_LOG的工程,然后按F7进行编译,会发现有这样的错误提示


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

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

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


然后将**__printf_tag_ptr*替换为FILE,然后按F7编译就可以了
最后,一定要检查sdk_config.h里宏定义是下列情况,这样情况下是使用RTT而不是串口,建议尽量使用RTT.
串口打印需要时间且占用管脚,且如果这个管脚其他的设备也在使用,就会造成错误。

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中进行如下修改

最小蓝牙demo工程构建
打开sdk的example文件夹下ble_uart_app的SEGGER工程.
按照上述说明对工程进行修改.
直接烧录到单片机.
用手机看有没有ble_uart_app设备,如果有,就可以进行愉快的开发了.
此外,需要注意的是,nrf的外设开启和很多配置需要通过修改sdk_config.h来完成
而且官方提供的sdk例程里,如果没有用到此项外设例如I2S,是完全不会有此项的配置信息的。😓
需要从别的用到了这一项的例程中copy一份过来,再进行配置打开或关闭。

NRF52系列单片机开发环境快速搭建
浙公网安备 33010602011771号