1. 芯片选型前,先弄清楚nRF52840到底强在哪里
做低功耗物联网终端选型的时候,nRF52840几乎是绕不开的一个名字。我前年给一套环境监测节点做方案评估,需求清单拉出来:电池供电必须撑一年以上、要支持OTA固件升级、通信协议优先BLE、最好还能顺带兼容Zigbee或者Thread设备做网关。团队里有人推ESP32,有人推nRF52840,争论了快两周才定下来。最后实测数据出来,ESP32在深度睡眠这个维度上确实吃亏,而nRF52840的系统OFF电流做到了微安级别,配合BLE的连接间隔拉长,一节CR2032或者两节AA电池就能跑很久。这个结论几乎是压倒性的。
先看一组核心参数,这些都是选型时真正要落地的点:
| 项目 | nRF52840 规格 | 选型时关注点 |
|---|---|---|
| CPU | Arm Cortex-M4F @ 64 MHz,带FPU | 算力够跑传感器算法,但不适合重负载 |
| 存储 | 1 MB Flash + 256 KB RAM | 协议栈占一部分后,应用空间依然充足 |
| 无线 | BLE 5.0/5.1/5.2,IEEE 802.15.4 | 支持Coded PHY长距离,也能跑Thread/Zigbee |
| 接口 | USB 2.0 FS、NFC-A、ADC、SPI、TWI、UART、I2S、PDM | USB和NFC是很多同类芯片没有的加分项 |
| 安全 | AES-128/CCM,硬件随机数生成器 | 做产品安全通信不用额外贴安全芯片 |
| GPIO | 最多48个可配置IO | 引脚充足,板级设计灵活 |
| 电源 | 内部DCDC/LDO可切换 | DCDC模式能明显降低收发电流 |
这颗芯片不是最新鲜的,但生态成熟度非常高。最直接的体现是资料、例程和问答社区的量级。同样是踩一个蓝牙广播的坑,nRF52840你可能十分钟就能搜到答案,换成冷门芯片可能得泡官方论坛泡三天。对产品研发来说,时间成本往往是选型里最容易被低估的一项。
有人会问,那"比nRF52840更好的"选择是谁?新一代的nRF54L15、双核的nRF5340,在性能和功耗上都更进了一步,但前者量产时间相对短,后者双核架构对固件设计要求更高。如果团队是第一次做BLE产品,我的实际建议是先用nRF52840把整条链路跑通,吃透低功耗和BLE协议之后,再根据产品阶段升级芯片。这套开发经验迁移到nRF53系列和nRF54系列基本是平滑的,因为工具链和驱动框架是同一套思路。
当然它也不是万能的。想用USB跑高速传输,或者想在本地做摄像头图像识别,nRF52840撑不住。这些场景该上Linux小板子或者更强算力的MCU就得上,不要在选型阶段硬刚。搞清楚边界,才能把它用在最合适的槽位上。
2. 内部架构拆解:一颗SoC如何把CPU、射频、外设协同起来
很多新手拿到nRF52840直接开始写代码,跳过架构这一课,结果遇到睡眠唤醒丢数据、外设和射频抢占资源、电流莫名下不去这类问题,排查起来非常痛苦。我的经验是,动手写第一个BLE工程之前,先花半天时间把芯片内部结构读明白。
2.1 Flash布局与"协议栈放哪里"的问题
nRF52840有1MB Flash,但这个Flash不是全部归你。使用传统nRF5 SDK时,Nordic提供一个预编译的SoftDevice协议栈,比如SoftDevice S140,它在Flash底部占一块固定区域,应用程序在它上面链接,两者通过统一API通信。这种方案的优点是协议栈经过严格测试,稳定性好;缺点是链接脚本稍有疏忽就覆写协议栈区域,然后直接跑飞。
改用nRF Connect SDK(NCS)之后,情况变化很大。NCS内建Zephyr RTOS,BLE协议栈以模块形式编译进单一镜像,不再有单独的SoftDevice。这对应用开发反而更友好:内存分配、中断优先级、链接脚本都由框架统一管理,你不用再手动计算协议栈的起始地址。代价是编译体积变大,镜像动辄几百KB,对Flash规划能力有要求。
2.2 射频前端与协议栈的分工
nRF52840的射频前端支持BLE 1M PHY、2M PHY和Coded PHY,输出功率可以从-20 dBm调到+8 dBm。内部集成了功率放大器,但没有集成LNA,如果产品需要极远的接收灵敏度,只能外挂LNA芯片,这在硬件设计时就要预留位置。
射频工作不是孤立的。BLE协议栈负责处理广播、扫描、连接事件、加密等,而应用代码在这些事件之间的空闲时间里运行。也就是说,即使你CPU升到64 MHz,BLE的时序调度仍然是协议栈说了算。应用代码如果在一个回调里执行过长时间计算,可能会错过下一个射频事件,导致连接断开或者丢包。这也是为什么官方一直在强调"不要在BLE回调里做重活",把耗时操作丢到线程或者异步任务里。
2.3 电源管理单元:低功耗的硬件根基
nRF52840的电源架构分两条路径:LDO模式和DCDC模式。LDO结构简单但效率低,DCDC模式通过内部降压转换器把电池电压降到1.3V左右再给核心供电,收发电流能省将近一半。这在第5章会展开讲,这里只提一个容易忽略的点:芯片有多组电源引脚,比如VDD、VDDH、VREGUOUT,硬件设计时不能把DCDC电感省掉,省了之后片内DCDC模块不工作,低功耗指标直接打折。
睡眠模式上,nRF52840有System ON和System OFF两级。System ON下CPU停止,但外设和RAM保持供电,RTC可以继续跑,典型电流在1.5微安级别;System OFF下整个系统几乎完全断电,只能靠GPIO电平变化或者复位唤醒,电流能到0.3微安级别。这两者之间的切换逻辑直接决定产品的待机续航。
2.4 PPI:不用CPU也能让外设协同
PPI(Programmable Peripheral Interconnect)是Nordic芯片一个非常核心的内部机制,理解它之后很多低功耗设计会变得非常舒服。简单说,PPI允许一个外设的事件直接触发另一个外设的任务,中间不需要CPU参与。比如ADC采样完成的事件,可以直接触发一个GPIO输出翻转来关闭传感器电源,整个过程中CPU全程睡大觉。
拿这个做温度监测节点就很合适:RTC产生周期事件,唤醒ADC开启采样,采样完成后通过PPI自动触发SPI读取传感器,读到的数据放到RAM里,等到BLE连接事件到来时再通知出去。CPU只在最后打包数据时醒一下,其余时间都在睡眠。没有PPI的芯片,这些步骤必须CPU逐条驱动,每一条都会带来额外唤醒时间,累积起来电流就下不去。
3. 从SDK选型到点亮板子:开发环境与工程框架搭建全流程
nRF52840的开发环境,因为SDK的迭代,把很多老教程坑得不轻。我刚开始用的时候照着网上的旧帖子装完nRF5 SDK和Keil,调了整整两天,最后发现官方主推的开发路径早就切换到nRF Connect SDK了。这里把现在推荐的搭建流程完整走一遍,并说明过程中容易踩的坑。
3.1 新项目到底选哪套SDK
先给结论:新项目直接用nRF Connect SDK(NCS),不要再用nRF5 SDK。
原因是nRF5 SDK虽然资料多,但已经进入维护阶段,新功能不再更新。而NCS基于Zephyr,好处有三:一是BLE协议栈和RTOS集成度高,应用代码不用关心SoftDevice的具体管理;二是设备树机制让引脚和外设配置全部统一,换板子只需改dts文件;三是Zephyr社区持续维护,很多中间件比如MQTT、传感器驱动、DFU都是开箱即用。
代价是学习曲线更陡。Zephyr的构建系统是CMake加west,第一次看它的Kconfig和devicetree概念,会觉得到处都是魔法层。我的建议是先按官方示例跑通,不要上来就自己搭板级支持,等熟悉操作了再深入。
3.2 环境安装与第一个工程
搭建步骤大致如下:
- 安装nRF Connect for Desktop,这是Nordic的一站式图形工具,里面包含Programmer、Power Profiler等。
- 安装nRF Connect SDK Toolchain,推荐用官方提供的"Toolchain Manager",它会自动装好west、编译器、Python虚拟环境。
- 在终端里创建并构建工程:
west init -m https://github.com/nrfconnect/sdk-nrf --mr v2.6.2 ncs cd ncs west update west build -b nrf52840dk_nrf52840 -d build/hello_world samples/hello_world这里有个容易踩的坑:west update会拉取大量子仓库,网络状况不好时经常超时。建议提前在国际网络中准备代理,或者直接用国内镜像源。拉取完成后再用nRF Connect for Desktop里的Programmer,把生成的.hex文件烧进开发板。
3.3 日志输出与调试配置
烧录完成只是第一步,真正调试时日志输出方式很关键。nRF52840 DK板上自带J-Link调试器,支持两种常用日志通道:RTT和CDC ACM串口。
RTT速度快,几乎不影响时序,适合调试低功耗时序问题;CDC串口方便,适合Web上位机或者串口终端查看。在Zephyr里配置方式是在prj.conf中打开相关选项:
CONFIG_LOG=y CONFIG_USE_SEGGER_RTT=y # 或者 CONFIG_USE_CDC_ACM=y我的习惯是通过RTT打印日志,同时把低功耗电流数据用一个独立GPIO拉高的方式做时间戳。这样用逻辑分析仪就能大致分析睡眠时间和唤醒时间,比单纯看数字日志直观得多。
3.4 板级配置:从官方板卡到自己的PCB
用官方DK开发阶段没问题,但转自研硬件时会遇到设备树配置。Zephyr里所有外设引脚关系都在dts文件中描述。比如你要把UART0放在P0.06和P0.08上,就得在板级dts里覆盖默认的uart0状态:
&uart0 { compatible = "nordic,nrf-uarte"; current-speed = <115200>; tx-pin = <6>; rx-pin = <8>; status = "okay"; };第一次改dts的时候最好对着官方固件里同型号板子的文件多看几遍,因为引脚号是引脚索引,而不是直接用"P0.06"这种形式。改错了编译不会报错,但运行时外设不工作,这类问题排查起来相当费时间。
4. 广播、连接、GATT:BLE应用开发的主线怎么搭
BLE应用开发绕不开三件事:广播让别的设备发现你,连接建立传输通道,GATT定义数据怎么组织。每一步都有参数和设计取舍,下面把主线逻辑理清。
4.1 广播设计:不是发得越频繁越好
BLE广播的最基本单位是广播包,里面包含设备地址、Flags、服务UUID、设备名称等。设计时要决定三个参数:广播间隔、广播数据类型、是否可连接。
一个典型的温湿度传感器广播包,可以按下面方式定义:
#include <zephyr/bluetooth/bluetooth.h> static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_ESS_VAL)), }; static const struct bt_data sd[] = { BT_DATA(BT_DATA_NAME_COMPLETE, "nRF52-Sensor", 12), };广播间隔的选择直接影响功耗和被发现速度。100ms间隔能耗高但设备秒发现;1s间隔功耗低但手机扫描半天看不见。产品如果只做配网阶段高频广播、平时低频广播,可以把两种模式组合实现:未连接时用200ms间隔,连接建立后再通过连接参数协商降低发射频率。
注意BLE广播是空中波,如果你使用可连接且不可扫描的广播类型,手机在扫描时可能只能看到地址而看不到广播包,这个细节会让设备"找不到"的问题变得诡异。经验是开发阶段用可扫描的广播类型,产品发布前再按需调整。
4.2 连接参数:间隔、延迟、超时决定了功耗和实时性
BLE连接建立后,主从设备之间按连接间隔周期性地互相收发数据包。nRF52840作为从设备时,要和手机端协商四个核心参数:
| 参数 | 典型值 | 效果 |
|---|---|---|
| Connection Interval | 30-50ms | 越小实时性越高,功耗越高 |
| Slave Latency | 4-9 | 从设备可跳过多个连接事件,大幅省电 |
| Supervision Timeout | 2000-6000ms | 超过这个时间无包则判定连接断开 |
| PHY | 1M/2M/Coded | 2M省时间,Coded提升距离但效率低 |
比如一个每分钟上报一次数据的传感器节点,连接间隔设40ms、从设备延迟设4,意味着从设备每5个连接事件才应答一次,睡眠时间拉长,电流立刻下来。但如果产品需要遥控器的即时响应,延迟必须设0。
Zephyr里通过如下接口更新连接参数:
bt_le_conn_param_update(conn, BT_LE_CONN_PARAM_INIT(40, 50, 4, 4000));最麻烦的是手机端的策略。iOS和安卓主机的系统策略不一样,有些手机会把从设备请求的连接参数直接驳回,这时候只能靠兼容性测试来调。能被主机接受的参数范围越宽,产品适配性越好。
4.3 GATT服务:数据结构决定上层开发体验
GATT的层级是服务(Service)、特征(Characteristic)、描述符(Descriptor)。特征值用于实际数据读写,支持Read、Write、Notify、Indicate等属性。Notify是流控最常用的方式:从设备主动推数据,主设备收到后回复确认,不需要主设备反复拉取。
一个简单的温湿度服务可以这样定义:
BT_GATT_SERVICE_DEFINE(env_sensor_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_ENV_SENSOR), BT_GATT_CHARACTERISTIC(BT_UUID_TEMP_CELSIUS, BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL), BT_GATT_CCC(NULL, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), );设计GATT时的经验法则是:尽量使用标准UUID(如环境检测服务的0x181A、电池服务的0x180F),这样手机端和第三方App兼容性好。只有标准服务覆盖不了的业务才自定义128-bit UUID。特征值也别搞一个128字节的大杂烩,按业务拆分成多个小特征,上层解析会轻松很多。
5. 低功耗不是玄学:电流实测与系统级优化闭环
低功耗设计是nRF52840最大的卖点,但很多产品最终没有达到预期续航,问题大多出在"只看数据手册,没做系统级实测"。这一章讲一遍完整的优化闭环:从测量工具到参数调节,再到验证。
5.1 用PPK2实测电流,别相信估算值
低功耗调试的工具首推nRF Power Profiler Kit 2(PPK2),它可以直接串在供电回路里,以高采样率记录电流曲线,功耗异常一眼就看出来。
测量之前的准备:断开DCDC电感附近的跳线,给板子外接稳定电源,把PPK2设置成Source模式给目标板供电,从nRF Connect for Desktop里打开Power Profiler。测System OFF时注意,板载J-Link调试器也在耗电,要从板子外部引脚直接供电,否则测出来电流虚高几十倍。
5.2 LDO与DCDC的选择:电流一降半的关键
官方数据里有个直观对比:LDO模式下BLE收发电流约9mA级别,DCDC模式下能降到4mA左右,几乎腰斩。具体数值以官方手册为准,但方向是确定的:对电池供电产品,必须启用内部DCDC。
在Zephyr里可以通过regulator节点配置:
® { regulator-initial-mode = <REGULATOR_MODE_DCDC>; };前提是你的硬件板上按参考设计放了DCDC用的4.7uH电感和电容。很多自研板抄原理图时把电感漏掉,代码里再怎么开DCDC也没用。
5.3 睡眠模式与唤醒源:功耗大战的主战场
大部分物联网节点90%的时间都在睡觉,所以睡眠电流直接影响续航。System ON + RTC唤醒,电流一般在1.5uA附近;System OFF + GPIO唤醒,能到0.3uA。但System OFF唤醒等于软复位,RAM数据丢失,要提前把关键参数存入Flash或非易失存储。
Zephyr中进入睡眠有两种方式:
- 使用
pm_state_force强制进入某个状态; - 让系统在
idle线程中根据设备树自动选择睡眠状态。
推荐第二种,因为Zephyr的电源管理模块会根据唤醒源自动选择最深可能的睡眠模式。代码里只需要在设备树和Kconfig里依次打开对PM的支持,然后把外设的唤醒唤醒机制配好。
5.4 外设功耗与传感器供电关断
一个容易被忽略的事实是:很多传感器的待机电流比芯片本身的睡眠电流还高。比如某些气体传感器工作电流几十mA,即使进入低功耗模式也有百uA级电流。正确做法是给传感器单独加MOS管开关,只在采样前上电,采样完成后立即断电。
用nRF52840的GPIO驱动MOS管栅极,采样时序大致是:唤醒后拉高供电引脚,延时等待传感器稳定,执行I2C读取,读取完成拉低供电引脚,然后进睡眠。整个流程200ms内完成,平均电流摊到30秒周期里微不足道,这就是系统级功耗控制的思路。
5.5 一个完整的低功耗优化案例
拿我之前做的温湿度节点来说,需求是每30秒采集一次并通过BLE通知手机。初版代码跑下来平均电流2.4mA,电池续航两个月,完全不合格。逐步排查后做了四件事:
- 打开DCDC模式,收发电流降约4成。
- 广播间隔从100ms改到1s,连接时间缩短。
- 给传感器加供电开关,待机电流从800uA降到接近0。
- 连接参数改为连接间隔45ms、从设备延迟4。
四步做完,平均电流降到不到40uA,如果配3000mAh电池,理论续航可以按天算,实际至少一年半。关键数据都来自PPK2曲线,而不是估算。低功耗优化本质就是一个"测量-调整-再测量"的闭环,谁跳过测量,谁就等着返工。
6. 物联网应用实战:从环境感知到云端上报的完整链路
单个BLE设备如果不联网,价值有限。真正完整的物联网方案要打通"端侧采集-BLE传输-网关-云平台"这条链路。下面用一个环境监测项目为例,把各环节的落地方法走一遍。
6.1 方案架构与设备分工
在这个项目里,多块nRF52840作为传感器节点,挂载温湿度、气压传感器。它们不直连互联网,而是把数据通过BLE广播或连接发给一台网关。网关可以是一块nRF52840 DK通过USB插到树莓派或PC上,树莓派上跑Python脚本,负责接收BLE数据并转发到云平台。
这种"BLE节点+网关"的架构在现实中有很多变体。市面上那些智能饮水机、智能可乐机的联网方案,本质上也是类似结构:端侧MCU加通信模块采集状态,网关或者手机中转,最后落到云端做业务逻辑。理解了nRF52840这层,其他产品的内核就都能看懂了。
6.2 端侧传感器数据采集
Zephyr对常见传感器驱动封装得比较完整,BME280、SHT40这类基本都有现成驱动。在设备树里打开I2C总线,把传感器节点挂在对应总线上,应用代码使用get_sensor_value函数读取数据即可。
#include <zephyr/drivers/sensor.h> const struct device *dev = DEVICE_DT_GET_ANY(bosch_bme280); struct sensor_value temp, humidity; sensor_sample_fetch(dev); sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);数据采集完成后再把温度值转换成适合GATT传输的格式。温度建议用整数乘以100的方式传输,避免浮点数序列化带来的兼容性问题,手机上再自行还原。
6.3 网关接收与MQTT转发
网关端的Python脚本用bleak库扫到设备并订阅Notify通知,收到数据后通过MQTT发送到云平台。MQTT是目前物联网行业事实标准的轻量级消息协议,一条消息的协议开销只有几个字节,非常适合这种场景。
import asyncio import paho.mqtt.client as mqtt client = mqtt.Client() client.connect("broker.example.com", 1883, 60) def on_data(sender, data: bytearray): temp = int.from_bytes(data[:2], byteorder="big", signed=True) / 100 humidity = int.from_bytes(data[2:4], byteorder="big") / 100 payload = f'{{"temperature":{temp},"humidity":{humidity}}}' client.publish("devices/nrf52840/temperature", payload) async def main(): from bleak import BleakClient async with BleakClient("PUT_DEVICE_MAC_HERE") as client: await client.start_notify("DEVICE_SERVICE_UUID", on_data) await asyncio.sleep(3600) asyncio.run(main())这段代码虽然简单,但需要留意BLE地址格式和蓝牙事务频率。如果公网MQTT频繁掉线,可以先在内网部署一个本地的MQTT Broker做缓冲,再把云端作为桥接,能显著提升稳定性。有些公共物联网平台对新设备购买有各种限制,产品选型阶段最好评估一下平台的政策变化风险,自己架设标准MQTT Broker反而是最可控的方案。
6.4 云端对接与设备管理
云平台侧,关键是处理好设备认证和数据解析。MQTT连接通常需要客户端ID、用户名、密码三元组;设备证书建议每台设备独立发放,避免一个密钥被暴力抓出来之后大规模仿冒设备。
Zephyr端如果需要让nRF52840直接跑MQTT over TLS,注意内存占用。256KB RAM对MQTT TLS握手来说足够,但加密库和证书存储要提前规划。更常见的做法是端侧只做BLE,网关负责协议转换,这样端侧就可以把精力聚焦在低功耗上。
6.5 固件升级:从单板开发走向量产维护
量产后的固件升级是另一个大坑。nRF52840支持DFU(Device Firmware Upgrade),NCS里默认用MCUboot做启动管理,配合west build -t mcuboot可以生成带签名和分区的升级包。手机端可以用nRF Connect App或自己的App发起升级,网关端也可以用nrfutil命令行工具批量推送。
初次配置MCUboot时最容易出错的是Flash分区表。BLE协议栈占多少、MCUboot占多少、应用占多少、升级缓存占多少,必须通过pm.yml文件明确规划,并在设备树里同步。改一次分区表需要同时更新Bootloader和应用两个镜像,否则烧完应用后Bootloader找不到入口,直接变砖。这个分区配置最好在项目第一周就确定下来,后面改动成本极高。
7. 高频翻车现场:芯片锁死、抓包、兼容性问题的处理经验
文章最后一部分,写几个nRF52840开发过程中遇到的高频"翻车"现场。这些都算常规操作中会出现的状况,解决思路比具体命令更重要。
7.1 芯片被"永久锁定"是怎么回事
网上经常能看到"nRF52840永久锁定"的讨论,听起来吓人,实际绝大多数是APPROTECT字段被意外启用导致的。nRF52系列芯片里有一个保护位,设置之后调试器无法读取Flash,固件也无法再通过SWD接口更新,给人的感觉就是芯片废了。
常见触发场景是:升级固件时不小心配置了NRF_APPROTECT_ENABLED,或者擦除时选择了保护选项。遇到这种情况先不要扔片子,尝试用nrfjprog执行恢复流程:
nrfjprog --recover这个命令能对大部分nRF52芯片完成全片擦除并解除保护。但要注意,对于较新节点上加入Secure域支持的芯片,如果安全管理被错误配置得更深,恢复难度会大幅提升。所以最稳妥的办法是"事前防御":不要在量产代码里主动打开APPROTECT,调试固件和管理固件分开。
7.2 BLE空中抓包:不用高价设备也能定位问题
排查BLE连接问题的最高效手段是空中抓包。nRF52840 Dongle加官方Sniffer固件就是一套很实惠的抓包方案。具体做法是:给Dongle烧一个Sniffer固件,然后打开Wireshark,在里面选择nRF Sniffer接口,设置要追踪的MAC地址,就能看到广播包、连接参数更新、加密握手等全部过程。
我之前排查过一例"设备连接成功率低"的问题。设备端死活报错,用抓包才看到主机发送的连接请求里PHY选择到了Coded PHY,而设备端没有启用Coded PHY导致连接失败。这种问题靠代码审查很难发现,抓包一看链路层就一目了然。
7.3 手机端兼容性:iOS和Android的差异
用Flutter或者原生开发做APP时,常常有人抱怨"低功耗蓝牙iOS有问题嘛,为什么Android好好的,iOS回调不触发"。实际排查过几个项目后,我发现问题说出来并不神秘。
iOS对ATT MTU的协商上限和Android不同,iOS经常要求MTU较小,如果你在GATT里一次写超过20字节,数据会被拆分或直接写失败。Flutter的BLE库在iOS上如果没处理maximumWriteValueLength,就很容易出现写大包超时。另外,iOS对后台蓝牙扫描有限制,App退到后台后可能不回调广播数据,这在开发阶段很容易被误判为蓝牙问题。
一个实用的兼容性策略是:把每次上报的数据包控制在20字节以内,连接参数给出宽泛的协商范围,并且不要在iOS端的后台模式下依赖持续扫描。这样绝大多数兼容性问题都能绕过去。
7.4 天线和板级设计的坑
最后提一个硬件层面的坑。nRF52840自带天线匹配网络设计参考,如果自研板的天线走线没有做50欧姆阻抗控制、净空区不够,实测信号强度会惨不忍睹。最典型的症状是RSSI偏低,连接一堵墙就掉线。遇到这种情况别急着怀疑芯片,先把天线部分清理干净,确认参考设计里的电容电感件的选型没被替换。晶振、去耦电容的布局也要贴近芯片引脚,别为了一时布线方便拉长走线,代价是用电稳定性大打折扣。
我在实际项目中还吃过一次亏:PCB改版时把DCDC电感换了一个直流电阻稍大的型号,芯片功能正常,但射频电流上升了0.5mA。这种细枝末节在功能测试里完全看不出问题,只有做功耗实测才会暴露,所以自研硬件出来后第一件事永远是复测电流曲线和射频指标。
做nRF52840开发,后面还有无数琐碎但磨人的细节,但这些翻车现场处理过一次之后,你对这颗芯片的理解会真正上一个台阶。