低功耗超宽带收发器:DW1000设备驱动API指南
手册下载:DW1000 Device Driver API Guide
一、概况
(一)、DW1000 核心功能
1. 基础通信功能
- UWB 收发:支持 6 个信道(1/2/3/4/5/7),3 种数据率(110kbps/850kbps/6.8Mbps),可配置前导码长度(64~4096 符号),满足短距高速或长距低功耗需求(P20-22)。
- 精确时间戳:TX/RX 时间戳精度达 15.65 皮秒(通过
dwt_readtxtimestamp()
/dwt_readrxtimestamp()
),支撑双向测距(如示例 5a/b,P87)。
2. 测距与定位(核心卖点)
- 双向测距(DS TWR):通过 3 帧交互(poll→response→final),抵消时钟偏移,精度厘米级(手册示例 5a/b,P87)。
- 单向测距(SS TWR):2 帧交互,v4.0.6 后通过
dwt_readcarrierintegrator()
校准时钟偏移,简化实现(示例 6a,P87)。
3. 低功耗优化
- DEEPSLEEP 模式:电流仅 100nA,通过
dwt_configuresleep()
+dwt_entersleep()
实现,唤醒需 SPICSn 拉低≥500μs(P43)。 - 低功耗监听(LPL):周期性唤醒 RX(如示例 8a/b,P88),占空比可配,延长电池寿命(P45)。
4. 开发便利性
- 25 个示例代码:覆盖简单 TX/RX、双缓冲、连续波测试等场景(附录 1,P82-89),如示例 1a(简单 TX)直接调用
dwt_writetxdata()
→dwt_starttx()
(P83)。 - 诊断与校准:提供载波积分器(
dwt_readcarrierintegrator()
)、温度 / 电压采样(dwt_readtempvbat()
),支持硬件调试(P74)。
(二)、注意事项
1. SPI 频率硬约束(致命错误点)
- 调用
dwt_initialise()
/ 校准函数前,SPI 频率必须 < 3 MHz(P18),否则初始化失败(返回DWT_ERROR
)。 - 示例:校准睡眠计数器(
dwt_calibratesleepcnt()
)时,需先降 SPI 至 3MHz(P40代码示例)。
2. ESD 防护(硬件安全红线)
- DW1000 为 ESD 敏感器件,操作时需防静电(如佩戴手环),避免引脚静电击穿(P2)。
3. 禁止用于安全关键场景
- 手册明确声明:禁止用于生命支持等安全关键应用(如医疗设备),否则风险自负(P2)。
4. OTP 编程不可逆
- OTP 内存仅可写一次(如烧写 EUI、校准值),错误写入将永久损坏设备(P63)。
5. 中断互斥处理
- SPI 操作需通过
decamutexon()
/decamutexoff()
禁用 DW1000 中断,防止前台中断与后台 SPI 冲突(P12)。
6. RX 配置陷阱
- SFD 超时(
sfdTO
)不可设为 0,默认 4161 符号(P20);双缓冲模式需在 IDLE 下配置(dwt_setdblrxbuffmode()
,P36)。
(三)、软件调用与硬件映射的交互逻辑
层级 | 软件 / 硬件组成 | 核心职责 | 与下一层交互方式 |
---|---|---|---|
1. 上层应用层 | 开发者编写的应用代码(如 TX/RX 业务逻辑、测距算法) | 定义业务需求,调用 API 函数触发硬件操作(如 “发送数据”“进入低功耗”),处理回调事件(如 “TX 完成”“RX 成功”) | 调用 DW1000 API 函数(如dwt_starttx() 、dwt_rxenable() ) |
2. API 函数层 | DW1000 设备驱动核心(如dwt_initialise() 、dwt_configure() 、dwt_isr() ) | 封装底层硬件操作,屏蔽寄存器细节,提供标准化接口;处理硬件事件解析(如中断状态判断) | 调用 SPI 抽象层函数(writetospi() /readfromspi() ) |
3. SPI 抽象层 | 平台相关的 SPI 读写函数(writetospi() 、readfromspi() ) | 抽象目标微处理器的 SPI 硬件差异,将 API 函数的 “配置 / 数据需求” 转换为 SPI 总线信号(如寄存器地址 + 数据) | 驱动目标微处理器的 SPI 物理接口(引脚、时钟、数据格式) |
4. 硬件层 | DW1000 IC(含 SPI 引脚、IRQ 引脚、TX/RX 射频模块、寄存器组)+ 目标微处理器硬件(SPI 控制器、IRQ 逻辑) | 执行软件下发的操作(如射频发射、接收、睡眠),通过寄存器存储状态,通过 IRQ 引脚反馈事件 | 硬件引脚信号交互(SPI 数据 / 时钟、IRQ 电平) |
(四)、核心交互通道:SPI 接口
SPI 接口是 DW1000 软件与硬件交互的唯一数据通道,手册 “5.77 SPI DRIVER FUNCTIONS”及 “2 GENERAL FRAMEWORK”详细定义了其交互规则:
1. SPI 硬件引脚与信号定义
DW1000 通过 4 个 SPI 引脚与目标微处理器连接,各引脚功能与交互方向固定:
- SPIMOSI:微处理器→DW1000(发送寄存器地址、配置数据、TX 帧数据);
- SPIMISO:DW1000→微处理器(返回寄存器状态、RX 帧数据、设备 ID);
- SPICSn:微处理器→DW1000(片选信号,低电平有效,用于启动 SPI 传输);
- SPICLK:微处理器→DW1000(时钟信号,同步 SPI 数据传输,速率需按 API 要求配置)。
2. SPI 抽象层的 “硬件解耦” 逻辑
为适配不同微处理器的 SPI 硬件(如 STM32、ARM),手册将 SPI 操作抽象为writetospi()
和readfromspi()
两个通用函数,交互逻辑如下:
- 软件调用:API 函数(如
dwt_writetxdata()
)需向 DW1000 写数据时,调用writetospi()
,传入 “头长度 + 头数据(如寄存器地址)+ 数据长度 + 数据缓冲区”;需读数据时(如dwt_readdevid()
),调用readfromspi()
,传入 “头数据 + 接收缓冲区”(; - 硬件适配:移植时需在目标系统代码中实现
writetospi()
/readfromspi()
的底层逻辑,驱动微处理器的 SPI 控制器生成符合 DW1000 要求的时序(如时钟极性、相位);SPI 接口的初始化(如速率、模式)属目标系统职责,不在 DW1000 驱动范围内。
3. SPI 交互的关键约束
- 速率约束:部分 API 函数(如
dwt_initialise()
、dwt_calibratesleepcnt()
)调用前,SPI 速率必须设置为 **<3 MHz**,否则硬件无法正确解析指令,导致初始化失败或校准错误; - 互斥保护:SPI 传输期间需通过
decamutexon()
/decamutexoff()
禁用 DW1000 的 IRQ 中断,防止前台中断(如 “RX 完成”)与后台 SPI 访问(如 “写 TX 数据”)冲突,避免数据传输错误。
(五)、中断触发机制:IRQ 引脚
DW1000 硬件通过 IRQ 引脚向软件反馈事件(如 “TX 完成”“RX 错误”),手册 “4 INTERRUPT HANDLING”及 “5.44 dwt_isr ()”定义了完整交互逻辑:
1. 中断触发流程
- 硬件事件产生:DW1000 执行操作后(如完成数据发送、检测到错误帧),内部状态寄存器对应位(如
DWT_INT_TFRS
(TX 完成)、DWT_INT_RFCE
(RX CRC 错误))置 1,同时拉低 IRQ 引脚(断言中断); - 目标中断响应:目标微处理器的 IRQ 检测逻辑识别到 DW1000 的 IRQ 引脚电平变化,触发目标系统的中断处理函数;
- 驱动中断处理:目标中断处理函数调用 DW1000 驱动的
dwt_isr()
函数,由其完成 “事件解析→状态清除→回调触发”。
2. dwt_isr()
的事件处理逻辑
dwt_isr()
是软件与硬件事件交互的核心函数,具体交互步骤如下:
- 读取硬件状态:
dwt_isr()
通过readfromspi()
读取 DW1000 的状态寄存器(地址 0xF),获取当前硬件事件类型; - 解析与清除事件:按优先级解析事件(RX 成功→TX 完成→RX 超时→RX 错误),清除对应状态寄存器位(避免重复触发);
- 回调反馈软件:根据事件类型调用上层应用注册的回调函数(如 RX 成功调用
cbRxOk()
、TX 完成调用cbTxDone()
),将硬件事件转换为软件可处理的业务事件。
3. 中断交互的关键细节
- 电平 / 边沿敏感适配:若目标微处理器 IRQ 为边沿敏感,需在中断处理中重新检查 IRQ 引脚状态,确保未处理的事件被触发(如 “处理第一个中断时,第二个事件产生”);若为电平敏感,仅需处理一次;
- 无中断场景适配:若目标系统不支持中断,可在后台循环中调用
dwt_checkirq()
检查 IRQ 引脚状态,若返回 1(中断活跃)则调用dwt_isr()
,实现轮询式事件处理。
(六)、案例: “系统启动 + TX 发送”
结合手册 “3 TYPICAL SYSTEM START-UP”及 “5.13~5.15 TX 控制”,以最常见的 “系统启动→配置硬件→发送数据” 流程为例,完整交互逻辑如下:
- 硬件初始化(目标系统):微处理器初始化自身 SPI 控制器(设置速率 < 3 MHz、模式、引脚),确保
writetospi()
/readfromspi()
可驱动 SPI 硬件; - 软件初始化(驱动调用):
- 调用
dwt_softreset()
:通过writetospi()
向 DW1000 复位寄存器写指令,硬件执行软件复位,恢复默认状态(IDLE); - 调用
dwt_initialise(DWT_LOADUCODE)
:通过readfromspi()
读取设备 ID(验证为 0xDECA0130),通过writetospi()
加载 LDE 微码到硬件,完成初始化;
- 调用
- 硬件配置(API 调用):
- 调用
dwt_configure()
:通过writetospi()
向信道、PRF、前导长度等寄存器写配置值,硬件更新 TX/RX 射频参数; - 调用
dwt_configuretxrf()
:通过writetospi()
写 PGdly(脉冲延迟)和 TX 功率值,硬件配置射频输出参数;
- 调用
- TX 数据发送(业务触发):
- 调用
dwt_writetxdata()
:通过writetospi()
将 TX 数据写入 DW1000 的 TX 缓冲区,硬件暂存数据; - 调用
dwt_writetxfctrl()
:通过writetospi()
配置帧长度和缓冲区偏移,硬件准备发送; - 调用
dwt_starttx(DWT_START_TX_IMMEDIATE)
:通过writetospi()
向 TX 控制寄存器写 “立即发送” 指令,硬件启动射频模块发送数据;
- 调用
- 事件反馈(中断处理):
- 硬件完成发送后,置位
DWT_INT_TFRS
状态位,拉低 IRQ 引脚; - 微处理器中断逻辑调用
dwt_isr()
,读取状态寄存器识别 “TX 完成”,清除状态位,调用cbTxDone()
通知上层应用。
- 硬件完成发送后,置位
(七)、交互的关键约束:软件与硬件的适配边界
手册中明确了多类软件与硬件交互的约束,若违反将导致交互失败或硬件异常:
- 硬件状态依赖:软件调用 API 需遵循硬件状态逻辑,如
dwt_configure()
需在 DW1000 处于 IDLE 时调用(需先调用dwt_forcetrxoff()
关闭 TX/RX),否则硬件无法响应配置指令 ; - 缓冲区交互规则:DW1000 的 TX 缓冲区数据在睡眠模式(DEEPSLEEP/SLEEP)下不保留,软件唤醒后需重新调用
dwt_writetxdata()
写数据,再触发发送 ; - OTP 硬件特性:DW1000 的 OTP 内存为 “一次可编程”,软件调用
dwt_otpwriteandverify()
烧写数据后不可修改,错误烧写将永久损坏硬件功能 ; - ESD 硬件防护:软件开发过程中需配合硬件防静电操作(如佩戴手环),否则 ESD 可能损坏 DW1000 硬件,导致 SPI 无响应 。
二、API 函数功能分类
(一)、设备识别与复位类
1. dwt_readdevid
- 功能:读取 DW1000 的 32 位设备标识符(DEV_ID),用于验证 SPI 连接与设备合法性。
- 关键参数:无输入参数。
- 返回值:
uint32
,32 位设备 ID(DW1000 固定为0xDECA0130
);0xFFFFFFFF
表示错误(仅 DEEP_SLEEP/SLEEP 模式下此值可能合法)。 - 约束:可随时调用,无需初始化前置操作。
2. dwt_getpartid
- 功能:读取工厂编程的 32 位部件 ID(Part ID),用于设备型号确认。
- 关键参数:无输入参数。
- 返回值:
uint32
,32 位 Part ID 值。 - 约束:需在
dwt_initialise()
调用后使用,否则本地存储值无效。
3. dwt_softreset
- 功能:对 DW1000 执行软件复位,恢复所有寄存器至默认值,清空 AON(始终开启)配置,复位后设备进入 IDLE 状态。
- 关键参数:无输入 / 返回参数。
- 约束:
- 复位后需重新配置 TX/RX 参数;
- 也可通过 RSTn 引脚复位(拉低≥10ns,禁止驱动高电平)。
4. dwt_rxreset
- 功能:对 DW1000 接收器执行软件复位,恢复接收器至 “干净状态”(如 RX 错误后恢复)。
- 关键参数:无输入 / 返回参数。
- 约束:仅影响接收器,不改变 TX 配置或设备整体状态。
(二)、初始化与配置类
1. dwt_initialise
- 功能:初始化 DW1000 核心功能,包括验证设备 ID、软件复位、加载 LDE 微码(可选)、读取 OTP 校准值(LDO 调谐、晶体微调)并存储 Part ID/Lot ID。
- 关键参数:
- 输入:
uint16 config
(位掩码,DWT_LOADNONE
= 不加载 OTP;DWT_LOADUCODE
= 加载 LDE 微码,用于 RX 时间戳生成与信号质量统计)。 - 返回:
int
,DWT_SUCCESS
(0)表示成功,DWT_ERROR
(-1)表示失败。
- 输入:
- 约束:
- 调用前SPI 频率必须≤3 MHz;
- 初始化失败后,禁止后续配置与操作。
2. dwt_configure
- 功能:配置 DW1000 的 TX/RX 信道参数(如信道、PRF、前导长度、数据率),需配合
dwt_configuretxrf()
完成完整射频配置。 - 关键参数:
- 输入:
dwt_config_t *config
(结构体指针,核心字段如下):字段 说明 chan
信道号(仅支持 1、2、3、4、5、7) prf
脉冲重复频率( DWT_PRF_16M
=16MHz,DWT_PRF_64M
=64MHz)txPreambLength
前导长度( DWT_PLEN_64
~DWT_PLEN_4096
,推荐值见表 3)dataRate
数据率( DWT_BR_110K
=110kbps,DWT_BR_850K
=850kbps,DWT_BR_6M8
=6.8Mbps)sfdTO
SFD 超时(符号数,不可为 0,默认 4161
,推荐值 = 前导长度 + 1+SFD 长度 - PAC size)
- 输入:
- 约束:
- 配置前需调用
dwt_forcetrxoff()
使设备进入 IDLE 状态; - 若开启
DWT_API_ERROR_CHECK
,函数会校验参数并断言错误。
- 配置前需调用
3. dwt_configuretxrf
- 功能:配置 DW1000 的 TX 射频参数(脉冲发生器延迟、TX 功率),需与
dwt_configure()
配合使用。 - 关键参数:
- 输入:
dwt_txconfig_t *config
(结构体指针,核心字段如下):字段 说明 PGdly
脉冲发生器延迟(推荐值见表 5,如信道 1=0xC9、信道 7=0x93) power
TX 功率值(智能功率禁用看表 6,启用看表 7,适配 EVB1000,其他硬件需校准)
- 输入:
- 约束:功率值需与
dwt_setsmarttxpower()
的使能状态匹配(禁用→表 6,启用→表 7)。
(三)、TX 控制类
1. dwt_writetxdata
- 功能:将 TX 帧数据写入 DW1000 的 TX 缓冲区,自动预留 2 字节 CRC(传输时硬件添加)。
- 关键参数:
- 输入:
uint16 txFrameLength
:帧总长度(含 2 字节 CRC);uint8 *txFrameBytes
:待发送数据缓冲区指针;uint16 txBufferOffset
:TX 缓冲区起始偏移(通常为 0)。
- 返回:
int
,DWT_SUCCESS
(0)表示成功,DWT_ERROR
(-1)表示失败(如数据超缓冲区长度)。
- 输入:
- 约束:
- 标准 PHR 模式(
DWT_PHRMODE_STD
)支持帧长 5~127 字节,长帧需启用DWT_PHRMODE_EXT
; - 需先调用
dwt_configure()
配置参数,再写入数据。
- 标准 PHR 模式(
2. dwt_writetxfctrl
- 功能:配置 TX 帧控制寄存器,包括帧长度、缓冲区偏移及是否标记为 “测距帧”。
- 关键参数:
- 输入:
uint16 txFrameLength
:帧总长度(同dwt_writetxdata
);uint16 txBufferOffset
:TX 缓冲区偏移(同dwt_writetxdata
);int ranging
:是否为测距帧(1 = 是,0 = 否,影响 PHR 中的测距位)。
- 输入:
- 约束:需与
dwt_writetxdata
的参数保持一致,否则发送数据异常。
3. dwt_starttx
- 功能:启动 TX 传输,支持立即发送或延迟发送。
- 关键参数:
- 输入:
uint8 mode
(传输模式,见表 8):模式值 说明 0 立即发送 1 延迟发送(需先调用 dwt_setdelayedtrxtime()
设置起始时间)2 立即发送 + TX 后自动启用 RX(等待响应,如 ACK) 3 延迟发送 + TX 后自动启用 RX - 返回:
int
,DWT_SUCCESS
(0)表示成功,DWT_ERROR
(-1)表示失败(如延迟发送超时)。
- 输入:
- 约束:延迟发送时,若系统时间已过设定值,传输会被中止并返回错误。
4. dwt_setdelayedtrxtime
- 功能:设置延迟 TX/RX 的起始时间(32 位高字节,单位≈8ns),用于
dwt_starttx(mode=1/3)
或dwt_rxenable(mode=DWT_START_RX_DELAYED)
。 - 关键参数:
- 输入:
uint32 starttime
:延迟起始时间(系统时间的高 32 位,低 9 位固定为 0)。
- 输入:
- 约束:系统时间为 40 位,溢出周期 17.2 秒,需注意时间 - wrap 问题。
(四)、RX 控制类
1. dwt_rxenable
- 功能:启用 DW1000 接收器,支持立即启用或延迟启用(低功耗场景)。
- 关键参数:
- 输入:
int mode
(启用模式,位掩码):模式值 说明 DWT_START_RX_IMMEDIATE
立即启用 RX DWT_START_RX_DELAYED
延迟启用 RX(需先调用 dwt_setdelayedtrxtime()
)DWT_IDLE_ON_DLY_ERR
延迟超时后进入 IDLE(否则自动启用 RX) - 返回:
int
,DWT_SUCCESS
(0)表示成功,DWT_ERROR
(-1)表示延迟超时。
- 输入:
- 约束:启用前需确保设备已初始化并配置参数。
2. dwt_setsniffmode
- 功能:启用 / 禁用低占空比 SNIFF 模式(RX 周期性开关,降低功耗)。
- 关键参数:
- 输入:
int enable
:1 = 启用,0 = 禁用;uint8 timeOn
:RX 开启时间(PAC 单位,自动 + 1,最小 1→2 PAC);uint8 timeOff
:RX 关闭时间(≈1μs 单位)。
- 输入:
- 约束:SNIFF 模式会降低 RX 灵敏度,需根据通信距离调整占空比。
3. dwt_setdblrxbuffmode
- 功能:启用 / 禁用双缓冲 RX 模式(避免 RX 溢出,支持连续接收)。
- 关键参数:
- 输入:
int enable
:1 = 启用,0 = 禁用。
- 输入:
- 约束:
- 需在 IDLE 状态下配置(禁用 RX 后);
- 启用后需在 RX 回调中调用
dwt_rxenable(DWT_NO_SYNC_PTRS)
重新启用 RX。
4. dwt_readrxdata
- 功能:从 RX 缓冲区读取接收数据。
- 关键参数:
- 输入:
uint8 *buffer
:接收数据缓冲区指针;uint16 len
:读取字节数;uint16 bufferOffset
:RX 缓冲区起始偏移。
- 输入:
- 约束:需在 “RX 成功” 事件(
DWT_INT_RFCG
)后调用,否则数据无效。
(五)、低功耗管理类
1. dwt_configuresleep
- 功能:配置 DW1000 的 SLEEP/DEEPSLEEP 模式参数(唤醒源、唤醒后行为)。
- 关键参数:
- 输入:
uint16 mode
:睡眠模式(位掩码,见表 10,如DWT_PRESRV_SLEEP
= 保留睡眠设置、DWT_GOTORX
= 唤醒后自动 RX);uint8 wake
:唤醒源(位掩码,见表 11,如0x1
=SPICSn 唤醒、0x2
=WAKEUP 引脚唤醒)。
- 输入:
- 约束:TX/RX 配置在睡眠模式下保留,但 TX 缓冲区数据不保留。
2. dwt_entersleep
- 功能:使 DW1000 进入 SLEEP/DEEPSLEEP 模式(需先调用
dwt_configuresleep()
配置)。 - 关键参数:无输入 / 返回参数。
- 约束:
- DEEPSLEEP 电流≈100nA,唤醒需 SPICSn 拉低≥500μs 或 WAKEUP 引脚高电平≥500μs;
- 进入前需确保无未处理中断,否则无法睡眠。
3. dwt_setlowpowerlistening
- 功能:启用 / 禁用低功耗监听(LPL)模式(设备周期性唤醒 RX 采样前导,其余时间睡眠)。
- 关键参数:
- 输入:
int enable
:1 = 启用,0 = 禁用。
- 输入:
- 约束:启用前需配置:
dwt_configuresleep()
(长睡眠参数);dwt_calibratesleepcnt()
(校准低功耗振荡器);dwt_setsnoozetime()
(短睡眠时间)。
(六)、中断与回调类
1. dwt_setcallbacks
- 功能:配置 TX/RX 事件的回调函数(TX 完成、RX 成功、RX 超时、RX 错误)。
- 关键参数:
- 输入:
dwt_cb_t cbTxDone
:TX 完成回调;dwt_cb_t cbRxOk
:RX 成功回调;dwt_cb_t cbRxTo
:RX 超时回调;dwt_cb_t cbRxErr
:RX 错误回调。
- 回调数据:
dwt_cb_data_t
结构体(含帧长度、状态、rx_flags
(测距位标识))。
- 输入:
- 约束:回调函数需在中断上下文执行,避免耗时操作。
2. dwt_setinterrupt
- 功能:启用 / 禁用 DW1000 的中断事件(如 TX 完成、RX 成功)。
- 关键参数:
- 输入:
uint32 bitmask
:中断事件掩码(见表 12,如DWT_INT_TFRS
=TX 完成、DWT_INT_RFCG
=RX 成功);uint8 enable
:1 = 启用,0 = 禁用。
- 输入:
- 约束:仅启用的中断事件会触发 IRQ 引脚断言。
3. dwt_isr
- 功能:DW1000 中断服务函数(ISR),解析硬件事件、清除状态、调用回调。
- 关键参数:无输入 / 返回参数。
- 约束:
- 需由目标微处理器的中断处理函数调用;
- 事件处理优先级:RX 成功→TX 完成→RX 超时→RX 错误。
(七)、诊断与校准类
1. dwt_readdiagnostics
- 功能:读取 RX 帧质量诊断数据(如噪声、第一路径幅度、CIR 增长值)。
- 关键参数:
- 输入:
dwt_rxdiag_t *diagnostics
:诊断数据结构体指针(含maxNoise
、firstPath
、rxPreamCount
等字段)。
- 输入:
- 约束:需在 “RX 成功” 事件后调用,否则数据无效。
2. dwt_calibratesleepcnt
- 功能:校准 DW1000 的低功耗振荡器(L-C 振荡器),返回 XTAL/2 周期数(用于精确设置睡眠时长)。
- 关键参数:
- 返回:
uint16
,1 个低功耗振荡器周期对应的 XTAL/2 周期数。
- 返回:
- 约束:调用前SPI 频率必须≤3 MHz。
3. dwt_readcarrierintegrator
- 功能:读取 RX 载波积分器值,反映远程发射器与本地时钟的频率偏移(用于 SS TWR 测距精度优化)。
- 关键参数:
- 返回:
int32
,32 位有符号载波积分值(正值 = 本地时钟比远程快)。
- 返回:
- 约束:需在 “RX 成功” 事件后调用,且仅适用于有效帧(CRC 正确)。
三、API之二次开发
(一)、基础初始化与硬件适配类(二次开发前置必用)
1. dwt_initialise
- 功能:二次开发中用于 DW1000 硬件初始化,完成设备合法性验证(读设备 ID)、软件复位、LDE 微码加载(支撑 RX 时间戳)及 OTP 校准值(LDO 调谐、晶体微调)读取,是所有功能开发的前置操作。
- 关键参数:
- 输入:
uint16 config
(位掩码,二次开发常用DWT_LOADUCODE
,加载 LDE 微码以支持高精度 RX;若无需 LDE 功能则用DWT_LOADNONE
); - 返回:
int
(DWT_SUCCESS=0
表示初始化成功,DWT_ERROR=-1
表示硬件适配失败,需排查 SPI 连接或设备型号)。
- 输入:
- 二次开发约束:
- 调用前SPI 频率必须≤3 MHz(手册明确要求,否则初始化失败,适配不同 MCU 时需先配置 SPI 速率);
- 若返回
DWT_ERROR
,需优先排查 SPI 引脚接线(SPIMOSI/SPIMISO/SPICSn/SPICLK)及设备供电,再重试初始化。
2. dwt_configure
- 功能:二次开发中用于适配不同通信场景的 TX/RX 参数,如调整信道、数据率、前导长度,支撑自定义通信协议(如低速率长距通信、高速率短距通信)。
- 关键参数:
- 输入:
dwt_config_t *config
(结构体指针,二次开发核心配置字段如下):字段 二次开发作用 chan
选择 UWB 信道(1/2/3/4/5/7),需根据地区法规(如 FCC/CE)及抗干扰需求适配(如信道 7 避开 2.4GHz 干扰) prf
配置脉冲重复频率( DWT_PRF_16M
/DWT_PRF_64M
),16M 适用于长距,64M 适用于高速率txPreambLength
调整前导长度( DWT_PLEN_64
~DWT_PLEN_4096
),二次开发中长前导(如 2048)提升弱信号接收率,短前导(如 64)降低功耗dataRate
适配数据率( DWT_BR_110K
/DWT_BR_850K
/DWT_BR_6M8
),如传感器数据传输用 110Kbps,视频流用 6.8MbpssfdTO
SFD 超时(符号数,不可为 0),二次开发需按 TX 前导长度计算(推荐值 = 前导长度 + 1+SFD 长度 - PAC size),避免误触发超时
- 输入:
- 二次开发约束:
- 配置前需调用
dwt_forcetrxoff()
使设备进入 IDLE 状态(避免与当前 TX/RX 操作冲突,适配多功能切换场景); - 若开发 “动态信道切换” 功能,需先关 RX/TX,再重新调用此函数配置新参数。
- 配置前需调用
3. dwt_readdevid
- 功能:二次开发中用于硬件适配验证,读取 DW1000 的 32 位设备 ID(固定为
0xDECA0130
),确认 SPI 通信正常及设备为正品 DW1000(排除硬件选型错误)。 - 关键参数:
- 返回:
uint32
(0xDECA0130
表示设备正常,0xFFFFFFFF
表示 SPI 通信异常或设备处于 DEEP_SLEEP/SLEEP 模式)。
- 返回:
- 二次开发场景:硬件量产适配时,可在初始化流程中加入此函数校验,自动过滤故障设备或错焊芯片。
(二)、通信功能扩展类(二次开发核心功能支撑)
1. dwt_writetxdata
+ dwt_writetxfctrl
+ dwt_starttx
(TX 功能扩展三组合)
- 功能:二次开发中用于自定义 TX 数据发送,支撑不同协议帧(如用户自定义传感器帧、测距 poll 帧、唤醒帧)的构建与传输,是 “数据上行 / 下行” 功能的核心。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_writetxdata
输入: txFrameLength
(帧长,含 2 字节 CRC)、txFrameBytes
(自定义数据指针)、txBufferOffset
(缓冲区偏移,通常为 0);返回:int
(成功 / 失败)写入自定义数据(如传感器 ID + 采集值、设备 EUI),二次开发需注意帧长匹配 dwt_configure
的dataRate
(如 6.8Mbps 支持短帧,110Kbps 支持长帧)dwt_writetxfctrl
输入: txFrameLength
(同dwt_writetxdata
)、txBufferOffset
(同前)、ranging
(1 = 标记为测距帧,0 = 普通数据帧)二次开发中 ranging=1
用于测距功能扩展(标记帧为测距交互帧),ranging=0
用于普通数据传输dwt_starttx
输入: uint8 mode
(传输模式,二次开发常用0
= 立即发、2
=TX 后自动 RX(等 ACK));返回:int
(成功 / 失败)适配不同发送逻辑:立即发用于广播数据,模式 2 用于 “请求 - 响应” 场景(如发指令后等设备回复) - 二次开发约束:
- 标准 PHR 模式(
DWT_PHRMODE_STD
)支持帧长 5~127 字节,若开发长帧传输(如≥128 字节),需在dwt_configure
中设置phrMode=DWT_PHRMODE_EXT
; - 延迟发送(
mode=1/3
)需先调用dwt_setdelayedtrxtime()
设置起始时间,避免超时失败。
- 标准 PHR 模式(
2. dwt_rxenable
+ dwt_readrxdata
(RX 功能扩展二组合)
- 功能:二次开发中用于自定义 RX 数据接收,支撑不同协议帧的解析(如传感器响应帧、测距 response 帧),是 “数据接收与处理” 功能的核心。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_rxenable
输入: int mode
(DWT_START_RX_IMMEDIATE
= 立即启用 RX、DWT_START_RX_DELAYED
= 延迟启用 RX);返回:int
(成功 / 失败)适配低功耗场景:立即 RX 用于实时接收,延迟 RX(配合 dwt_setdelayedtrxtime()
)用于定时唤醒接收,降低待机功耗dwt_readrxdata
输入: uint8 *buffer
(接收数据缓冲区)、uint16 len
(读取字节数)、uint16 bufferOffset
(RX 缓冲区偏移)二次开发中用于读取自定义帧数据,可通过 bufferOffset
跳过帧头(如仅读取 payload 部分),提升解析效率 - 二次开发约束:
- 启用 RX 前需确保设备已通过
dwt_configure
配置匹配的信道 / PRF / 前导(否则无法接收目标帧,需在二次开发中加入 “参数一致性校验” 逻辑); - 双缓冲 RX(
dwt_setdblrxbuffmode(1)
)适配高吞吐场景,需在 RX 回调中调用dwt_rxenable(DWT_NO_SYNC_PTRS)
重新启用 RX,避免数据溢出。
- 启用 RX 前需确保设备已通过
3. dwt_setcallbacks
+ dwt_setinterrupt
(中断与异步处理类)
- 功能:二次开发中用于实现异步通信逻辑(如 TX 完成后自动触发下一次发送、RX 成功后立即解析数据),避免轮询占用 CPU 资源,支撑多任务并发场景。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_setcallbacks
输入: cbTxDone
(TX 完成回调)、cbRxOk
(RX 成功回调)、cbRxTo
(RX 超时回调)、cbRxErr
(RX 错误回调)二次开发中在回调函数内实现业务逻辑:如 cbRxOk
中解析接收数据、cbTxDone
中标记发送完成状态、cbRxErr
中加入故障重试机制dwt_setinterrupt
输入: uint32 bitmask
(中断掩码,如DWT_INT_TFRS
=TX 完成、DWT_INT_RFCG
=RX 成功)、uint8 enable
(1 = 启用,0 = 禁用)按需启用中断:如仅开发 TX 功能则只启用 DWT_INT_TFRS
,减少无效中断触发;开发测距功能需启用DWT_INT_RFCG
(RX 成功)和DWT_INT_TFRS
(TX 完成) - 二次开发约束:
- 回调函数运行在中断上下文,需避免耗时操作(如复杂数据运算),建议仅做 “数据缓存 + 状态标记”,业务逻辑在主循环处理;
- SPI 操作需通过
decamutexon()
/decamutexoff()
实现互斥(避免中断中 SPI 访问与主循环冲突,二次开发需在 SPI 相关 API 调用前后加入互斥保护)。
(三)、低功耗优化类(二次开发电池设备必用)
1. dwt_configuresleep
+ dwt_entersleep
(睡眠模式适配)
- 功能:二次开发中用于 DW1000 低功耗模式配置与激活,支撑电池供电设备(如无线传感器、定位标签)的续航优化,是低功耗场景核心 API。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_configuresleep
输入: uint16 mode
(睡眠模式,二次开发常用DWT_PRESRV_SLEEP
(保留睡眠设置,避免重复配置)+DWT_GOTORX
(唤醒后自动 RX))、uint8 wake
(唤醒源,常用0x1
=SPICSn 唤醒、0x2
=WAKEUP 引脚唤醒)适配不同唤醒场景:SPICSn 唤醒用于 MCU 主动唤醒(如定时轮询),WAKEUP 引脚唤醒用于外部触发唤醒(如传感器触发) dwt_entersleep
无输入 / 返回参数 激活睡眠模式,二次开发需在 “无未处理中断” 时调用(否则无法睡眠,需先通过 dwt_checkirq()
检查中断状态) - 二次开发约束:
- DEEPSLEEP 模式下 TX 缓冲区数据不保留,唤醒后需重新调用
dwt_writetxdata()
写入数据,再启动发送; - 唤醒信号需满足时长要求(SPICSn 拉低≥500μs、WAKEUP 引脚高电平≥500μs),二次开发中需确保 MCU 输出的唤醒信号时长达标,避免唤醒失败。
- DEEPSLEEP 模式下 TX 缓冲区数据不保留,唤醒后需重新调用
2. dwt_setlowpowerlistening
+ dwt_setsnoozetime
(低功耗监听适配)
- 功能:二次开发中用于实现 “周期性唤醒监听”(LPL 模式),设备大部分时间睡眠,仅短暂唤醒 RX 采样前导,大幅降低待机功耗,适用于远距离低频次通信场景(如资产定位标签)。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_setlowpowerlistening
输入: int enable
(1 = 启用 LPL,0 = 禁用)启用后设备进入 LPL 模式,二次开发需配合 dwt_configuresleep()
配置长睡眠时长,平衡功耗与响应速度dwt_setsnoozetime
输入: uint8 snooze_time
(短睡眠时间,单位≈26.7μs,自动 + 1,最小 1→53μs)调整 LPL 模式中 RX 两次唤醒的间隔(短睡眠),二次开发中根据通信频次设置:如 100ms 通信一次,可设 snooze_time
使短睡眠占比≤10% - 二次开发约束:
- 启用 LPL 前需完成:
dwt_calibratesleepcnt()
(校准低功耗振荡器,确保睡眠时长准确)、dwt_setpreambledetecttimeout()
(配置 RX 监听超时); - LPL 模式会降低 RX 灵敏度,二次开发需通过测试调整 “监听时长” 与 “睡眠时长” 比例,平衡功耗与通信距离。
- 启用 LPL 前需完成:
(四)、测距功能集成类(二次开发定位场景必用)
1. dwt_readtxtimestamp
+ dwt_readrxtimestamp
(时间戳读取)
- 功能:二次开发中用于获取 TX/RX 帧的精确时间戳(40 位,精度 15.65 皮秒),是双向测距(TWR)计算 “飞行时间(TOF)” 的核心数据来源,支撑厘米级定位功能。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_readtxtimestamp
输入: uint8 *timestamp
(5 字节缓冲区,存储 40 位 TX 时间戳,低字节在前)读取 TX 帧的 RMARKER(天线发射)时间戳,二次开发中需在 cbTxDone
(TX 完成回调)中调用,确保时间戳有效dwt_readrxtimestamp
输入: uint8 *timestamp
(5 字节缓冲区,存储 40 位 RX 时间戳,低字节在前)读取 RX 帧的 RMARKER(天线接收)时间戳,二次开发中需在 cbRxOk
(RX 成功回调)中调用,用于 TOF 计算 - 二次开发约束:
- 时间戳需配合
dwt_settxantennadelay()
/dwt_setrxantennadelay()
校准(补偿天线延迟,否则测距误差大),二次开发中需先通过校准工具获取天线延迟值并写入; - 40 位时间戳溢出周期为 17.2 秒,二次开发中需加入 “时间 - wrap” 处理逻辑(如记录溢出次数),避免长时长测距时时间戳计算错误。
- 时间戳需配合
2. dwt_readcarrierintegrator
- 功能:二次开发中用于读取 RX 载波积分器值,反映远程发射器与本地 DW1000 的时钟偏移(单位:Hz),可用于校准单向双向测距(SS TWR)的时钟误差,提升定位精度(手册 v2.4 新增功能)。
- 关键参数:
- 返回:
int32
(32 位有符号值,正值表示本地时钟比远程快,负值表示本地时钟比远程慢)。
- 返回:
- 二次开发适配:
- 在 SS TWR 测距场景中,通过此函数获取时钟偏移后,代入公式
clockOffsetPPM = 时钟偏移Hz × 信道PPM系数
(如信道 5 用HERTZ_TO_PPM_MULTIPLIER_CHAN_5
),校准 TOF 计算结果; - 需在 “RX 成功”(
DWT_INT_RFCG
)后调用,且仅适用于 CRC 正确的有效帧,否则时钟偏移数据无效。
- 在 SS TWR 测距场景中,通过此函数获取时钟偏移后,代入公式
(五)、硬件交互与校准类(二次开发定制化必用)
1. dwt_otpwriteandverify
- 功能:二次开发中用于向 DW1000 的 OTP(一次可编程)内存烧录定制化数据,如设备唯一 EUI、硬件校准值(TX 功率、天线延迟),支撑量产设备的身份标识与性能优化。
- 关键参数:
- 输入:
uint32 value
(32 位待烧录数据)、uint16 address
(OTP 地址,需参考手册表 15,如0x000
/0x001
烧录 64 位 EUI、0x010
~0x01B
烧录各信道 TX 功率); - 返回:
int
(DWT_SUCCESS=0
表示烧录并验证成功,DWT_ERROR=-1
表示烧录失败)。
- 输入:
- 二次开发约束:
- OTP 内存一次可编程,烧录错误后无法修改,二次开发中需加入 “数据校验 + 烧录确认” 逻辑(如先读 OTP 地址确认未烧录,再执行烧录);
- 烧录前需确保 SPI 频率≤3 MHz,且设备处于 IDLE 状态,避免烧录过程中被中断导致 OTP 损坏。
2. dwt_setgpiodirection
+ dwt_setgpiovalue
(GPIO 自定义控制)
- 功能:二次开发中用于控制 DW1000 的 GPIO 引脚,适配外部硬件扩展(如驱动 LED 指示灯、控制外部 PA/LNA(功率放大器 / 低噪声放大器)、触发外部传感器),提升设备定制化能力。
- 关键参数与二次开发适配:
函数名 关键参数 二次开发作用 dwt_setgpiodirection
输入: uint32 gpioNum
(GPIO 位掩码,如GxM0
对应 GPIO0)、uint32 direction
(0 = 输出,非 0 = 输入)配置 GPIO 方向:如二次开发中需驱动 LED 则设为输出,需读取外部传感器状态则设为输入 dwt_setgpiovalue
输入: uint32 gpioNum
(GPIO 位掩码)、uint32 value
(0 = 拉低,非 0 = 拉高)控制 GPIO 输出电平:如 TX 时拉高 GPIO1 驱动 PA 使能,RX 时拉高 GPIO2 驱动 LNA 使能,提升射频性能 - 二次开发约束:
- GPIO 引脚功能需参考 DW1000 数据手册(手册附录 2 推荐查阅 [1]),避免占用专用引脚(如 IRQ、RSTn);
- 控制外部 PA/LNA 时,需配合
dwt_setlnapamode()
启用对应功能,确保 GPIO 控制逻辑与射频模块时序匹配。
四、API之输入输出
(一)、数据输出类(DW1000→外部设备,TX 相关)
此类 API 用于将数据从软件写入 DW1000 硬件,并通过射频模块发送到外部 UWB 设备(如其他 DW1000 节点),是 “数据上行 / 指令下发” 的核心。
1. dwt_writetxdata
- 功能:数据输出的 “准备步骤”—— 将待发送的帧数据写入 DW1000 的 TX 缓冲区,为后续射频发送做准备(输出数据暂存)。
- 关键参数:
- 输入:
uint16 txFrameLength
:帧总长度(含 2 字节 CRC,DW1000 传输时自动添加,软件无需手动计算);uint8 *txFrameBytes
:待输出数据的缓冲区指针(如用户自定义的传感器数据、测距指令帧);uint16 txBufferOffset
:TX 缓冲区的起始偏移(通常设为 0,即从缓冲区首地址开始写入);
- 返回:
int
(DWT_SUCCESS=0
表示数据写入成功,DWT_ERROR=-1
表示失败,如 “帧长 + 偏移” 超过 TX 缓冲区容量)。
- 输入:
- 约束:
- 帧长需匹配
dwt_configure()
的phrMode
配置:标准模式(DWT_PHRMODE_STD
)支持 5~127 字节,长帧模式(DWT_PHRMODE_EXT
)支持 5~1023 字节; - 需在
dwt_initialise()
和dwt_configure()
调用后使用(确保 DW1000 已初始化并配置射频参数); - 写入的数据不包含 CRC,DW1000 会在发送时自动添加 2 字节 CRC。
- 帧长需匹配
2. dwt_writetxfctrl
- 功能:数据输出的 “配置步骤”—— 配置 TX 帧控制寄存器,定义 DW1000 如何发送已写入缓冲区的数据(如帧长度、是否标记为 “测距帧”)。
- 关键参数:
- 输入:
uint16 txFrameLength
:帧总长度(需与dwt_writetxdata
的txFrameLength
完全一致,否则发送数据异常);uint16 txBufferOffset
:TX 缓冲区偏移(需与dwt_writetxdata
的txBufferOffset
一致,确保数据读取地址正确);int ranging
:帧类型标记(1=“测距帧”,PHR 中测距位置 1;0=“普通数据帧”),仅用于外部设备识别帧用途,不影响 DW1000 发送逻辑。
- 输入:
- 约束:
- 若开启
DWT_API_ERROR_CHECK
代码开关,函数会校验txFrameLength
合理性(如超过缓冲区容量)并断言错误; - 需在
dwt_writetxdata
之后、dwt_starttx
之前调用,确保配置先于发送。
- 若开启
3. dwt_starttx
- 功能:数据输出的 “执行步骤”—— 启动 DW1000 射频模块,将 TX 缓冲区中的数据发送到外部设备(完成最终数据输出)。
- 关键参数:
- 输入:
uint8 mode
(发送模式,决定输出时机及后续行为):模式值 说明 0 立即发送( DWT_START_TX_IMMEDIATE
):调用后立即启动射频发送数据1 延迟发送:需先调用 dwt_setdelayedtrxtime()
设置起始时间,系统时间达标后发送2 立即发送 + TX 后自动启用 RX:发送完成后立即开启 RX,等待外部设备响应(如 ACK) 3 延迟发送 + TX 后自动启用 RX:延迟发送完成后开启 RX - 返回:
int
(DWT_SUCCESS=0
表示发送启动成功,DWT_ERROR=-1
表示失败,如延迟发送时 “系统时间已过设定值”)。
- 输入:
- 约束:
- 延迟发送(模式 1/3)时,若
dwt_starttx
调用过晚(系统时间超过dwt_setdelayedtrxtime()
设置的starttime
),发送会被中止并返回错误; - 发送前需确保 TX 缓冲区已通过
dwt_writetxdata
写入数据,否则发送空帧。
- 延迟发送(模式 1/3)时,若
(二)、数据输入类(外部设备→DW1000,RX 相关)
此类 API 用于 DW1000 通过射频模块接收外部设备的数据,并从硬件缓冲区读取到软件中,是 “数据下行 / 响应接收” 的核心。
1. dwt_rxenable
- 功能:数据输入的 “准备步骤”—— 启用 DW1000 接收器,使其进入 “等待接收外部数据” 状态(为数据输入做硬件准备)。
- 关键参数:
- 输入:
int mode
(接收模式,决定 RX 启用时机):模式值 说明 DWT_START_RX_IMMEDIATE
立即启用 RX:调用后接收器立即启动,等待外部数据 DWT_START_RX_DELAYED
延迟启用 RX:需先调用 dwt_setdelayedtrxtime()
设置起始时间,达标后启动 RXDWT_IDLE_ON_DLY_ERR
延迟超时保护:若延迟启用时系统时间已过设定值,接收器不启用(进入 IDLE) - 返回:
int
(DWT_SUCCESS=0
表示 RX 启用成功,DWT_ERROR=-1
表示延迟超时)。
- 输入:
- 约束:
- 启用 RX 前需调用
dwt_forcetrxoff()
使 DW1000 进入 IDLE 状态(避免与当前 TX/RX 操作冲突); - 需先通过
dwt_configure()
配置匹配的信道、PRF、前导长度(否则无法接收外部设备的目标数据)。
- 启用 RX 前需调用
2. dwt_readrxdata
- 功能:数据输入的 “执行步骤”—— 从 DW1000 的 RX 缓冲区读取已接收的外部数据,存入软件缓冲区(完成最终数据输入)。
- 关键参数:
- 输入:
uint8 *buffer
:软件侧的接收缓冲区指针(用于存储从 DW1000 读取的输入数据);uint16 len
:需读取的字节数(通常设为接收帧的实际长度,可从dwt_cb_data_t
的datalength
字段获取);uint16 bufferOffset
:RX 缓冲区的起始偏移(可设为 0 读取完整帧,或设为特定值跳过帧头仅读取 payload);
- 输入:
- 约束:
- 需在 “RX 成功” 事件(
DWT_INT_RFCG
,即外部数据已正确接收并通过 CRC 校验)后调用,否则读取的数据无效; - 若启用双缓冲 RX(
dwt_setdblrxbuffmode(1)
),需在读取当前帧数据后,调用dwt_rxenable(DWT_NO_SYNC_PTRS)
重新启用 RX,避免下一帧数据溢出。
- 需在 “RX 成功” 事件(
(三)、硬件存储数据输入输出(软件↔DW1000 硬件)
此类 API 用于软件与 DW1000 的硬件存储(OTP、寄存器)之间的配置 / 校准数据交互,支撑二次开发中的设备定制化(如烧录唯一 EUI、存储校准值)。
1. dwt_otpread
(硬件→软件,数据输入)
- 功能:从 DW1000 的 OTP(一次可编程)内存读取数据(如工厂校准值、用户烧录的 EUI),输入到软件中用于配置或验证。
- 关键参数:
- 输入:
uint32 address
:OTP 内存的起始地址(32 位字地址,需参考手册表 15,如0x000
/0x001
对应 64 位 EUI、0x010
对应信道 1 TX 功率);uint32 *array
:软件侧的 32 位数组指针(用于存储从 OTP 读取的数据);uint8 length
:需读取的 32 位数据个数(如读取 64 位 EUI 需设为 2);
- 输入:
- 约束:
- OTP 地址需在有效范围内(手册表 15 定义为
0x000
~0x400
),超出范围会读取无效数据; - 若 OTP 地址未烧录数据(如用户未自定义 EUI),读取值为默认无效值(如
0xFFFFFFFF
)。
- OTP 地址需在有效范围内(手册表 15 定义为
2. dwt_otpwriteandverify
(软件→硬件,数据输出)
- 功能:将软件中的配置 / 校准数据(如设备 EUI、TX 功率校准值)烧录到 DW1000 的 OTP 内存(一次可编程),完成硬件存储的永久数据输出。
- 关键参数:
- 输入:
uint32 value
:需烧录的 32 位数据(如信道 2 的 TX 功率值0x75757575
);uint16 address
:OTP 内存的目标地址(需参考手册表 15,仅烧录用户可自定义区域,如0x000
~0x003
(EUI)、0x010
~0x01B
(TX 功率));
- 返回:
int
(DWT_SUCCESS=0
表示烧录并验证成功,DWT_ERROR=-1
表示烧录失败)。
- 输入:
- 约束:
- OTP 内存一次可编程,烧录后无法修改,错误写入(如烧录到 reserved 区域)会永久损坏 DW1000 功能;
- 烧录前需确保 SPI 频率≤3 MHz,且 DW1000 处于 IDLE 状态,避免烧录过程被中断;
- 烧录后建议调用
dwt_otpread
验证数据,确保烧录正确。
3. dwt_writetodevice
/ dwt_readfromdevice
(软件↔寄存器,数据输入输出)
- 功能:底层寄存器数据交互 ——
dwt_writetodevice
将软件数据写入 DW1000 的特定寄存器(输出),dwt_readfromdevice
从寄存器读取数据到软件(输入),支撑 API 未覆盖的硬件定制化配置(如特殊射频参数)。 - 关键参数:
函数名 关键参数 输入 / 输出方向 dwt_writetodevice
输入: uint16 regID
(寄存器组 ID,如 0 = 通用寄存器、9=TX 缓冲区)、uint16 index
(寄存器子地址)、uint32 length
(写入字节数)、const uint8 *buffer
(待写入数据指针)软件→硬件(输出) dwt_readfromdevice
输入: uint16 regID
(同左)、uint16 index
(同左)、uint32 length
(读取字节数)、uint8 *buffer
(接收数据指针)硬件→软件(输入) - 约束:
- 需熟悉 DW1000 寄存器映射(手册附录 2 推荐参考 [1]《DW1000 Data Sheet》),错误操作寄存器可能导致硬件异常;
- 若开启
DWT_API_ERROR_CHECK
代码开关,函数会校验regID
和length
合理性并断言错误; - 调用前需确保 DW1000 已初始化,且 SPI 操作通过
decamutexon()
/decamutexoff()
实现互斥(避免中断冲突)。
五、示例详细介绍
手册附录 1 提供 25 个针对 DW1000 的示例应用,均基于 Decawave EVB1000 硬件设计,核心目标是通过 “最小化代码” 演示 API 功能(如 TX/RX、低功耗、测距),避免冗余逻辑。所有示例均含main.c
和 CooCox 项目文件,需用 CooCox IDE 1.7.8 + 和 GNU ARM 工具链构建,以下按 “功能类别” 详细拆解各示例的核心逻辑、API 用法及关键约束。
(一)、示例整体基础信息
1. 包结构
示例包的文件夹结构明确,支撑跨平台移植与快速定位:
目录 / 文件 | 功能描述 |
---|---|
STM32F10x_StdPeriph_Driver | STM32F1 系列微处理器的硬件抽象层(HAL),适配 EVB1000 的 MCU |
Linker Script | STM32F105RC 处理器的链接脚本,定义代码 / 数据存储地址 |
Platform | 平台相关代码:中断管理(deca_irq.c )、互斥(deca_mutex.c )、睡眠(deca_sleep.c ) |
Examples | 各示例项目文件夹,每个示例独立含main.c 和.coproj (CooCox 项目文件) |
2. 构建与运行步骤
- 工具准备:安装 CooCox IDE 1.7.8(http://www.coocox.org/software.html)、GNU ARM 嵌入式工具链(https://launchpad.net/gcc-arm-embedded);
- 项目导入:解压包后用 CooCox IDE 打开示例的
.coproj
文件; - 工具链配置:在 IDE 中设置工具链路径(如
C:\GNUToolsARMEmbedded\4.8_2014q1\bin
); - 下载调试:用 ST-LINK/V2 探针连接 EVB1000,编译后下载代码,通过调试器观察流程(示例输出少,需靠调试器跟踪变量 / API 调用)。
(二)、功能分类示例详解
类别 1:基础 TX(发送)示例(1a~1d)
核心目标:演示 “数据发送 + 低功耗睡眠” 的组合逻辑,覆盖简单发送到定时睡眠发送的场景。
1. 示例 1a:Simple TX
- 核心功能:循环发送 “硬编码闪烁帧”(固定内容),帧间延迟 1 秒,无低功耗逻辑;
- 实现逻辑(关键 API 调用流程):
dwt_softreset()
(复位)→dwt_initialise(DWT_LOADUCODE)
(初始化)→dwt_configure()
(配置信道 2、PRF 64M、前导 2048)→dwt_configuretxrf()
(配置 PGdly=0xC2、功率 = 0x67676767)→循环:
dwt_writetxdata(frameLen, txData, 0)
(写数据)→dwt_writetxfctrl(frameLen, 0, 0)
(设帧控制)→dwt_starttx(DWT_START_TX_IMMEDIATE)
(立即发送)→deca_sleep(1000)
(延迟 1 秒); - 关键要点:
- 帧内容固定(如含 “DW1000 TX Test”),无需动态生成;
- 延迟用
deca_sleep()
(平台通用睡眠函数),非 DW1000 低功耗模式,功耗较高。
2. 示例 1b:TX with Sleep
- 核心功能:发送一帧后,命令 DW1000 进入 DEEPSLEEP,唤醒后发送下一帧(手动控制睡眠);
- 核心新增 API:
dwt_configuresleep(0x0140, 0x5)
(配置:保留睡眠设置 + 恢复配置,SPICSn 唤醒)→dwt_entersleep()
(进入 DEEPSLEEP)→dwt_spicswakeup(buff, len)
(SPICSn 拉低≥500μs 唤醒); - 关键要点:
- 睡眠期间 DW1000 电流≈100nA,比 1a 的
deca_sleep()
功耗低 1~2 个数量级; - 唤醒后无需重新初始化(
dwt_configuresleep
设DWT_CONFIG
,自动恢复配置),仅需重新写 TX 数据。
- 睡眠期间 DW1000 电流≈100nA,比 1a 的
3. 示例 1c:TX with Auto Sleep
- 核心功能:发送完成后,DW1000 自动进入睡眠(无需手动调用
dwt_entersleep()
); - 核心新增 API:
dwt_entersleepaftertx(1)
(启用 “TX 后自动睡眠”)→dwt_setinterrupt(DWT_INT_TFRS, 0)
(禁用 TX 中断,避免未处理中断阻止睡眠); - 关键要点:
- 自动睡眠触发条件:TX 完成且无未处理中断(需禁用 TX 中断或在回调中处理);
- 唤醒仍需手动调用
dwt_spicswakeup()
,比 1b 少一步 “手动调用dwt_entersleep()
”。
4. 示例 1d:TX with Timed Sleep
- 核心功能:发送后自动睡眠,且通过 “内部睡眠计时器” 唤醒(无需 MCU 主动唤醒),需先校准低功耗振荡器;
- 核心新增 API:
dwt_calibratesleepcnt()
(校准低功耗振荡器,获取lp_osc_cal
)→dwt_configuresleepcnt(sleepTime16)
(计算并设置睡眠时长,如 10 秒)→dwt_configuresleep(0x0148, 0x9)
(配置:唤醒源 = 睡眠计时器); - 关键要点:
- 低功耗振荡器频率(7~13kHz)受温度 / 电压影响,需
dwt_calibratesleepcnt()
校准才能确保睡眠时长准确; - 睡眠计时器基于 28 位计数器,
sleepcnt
设高 16 位(低 12 位固定为 0),计算示例:若lp_osc_cal=9500
,10 秒睡眠需sleepTime16= (10×19.2e6 / 9500) >> 12 ≈24
。
- 低功耗振荡器频率(7~13kHz)受温度 / 电压影响,需
类别 2:基础 RX(接收)示例(2a~2e)
核心目标:演示 “数据接收 + 特殊 RX 模式”(短前导、诊断、低占空比、双缓冲),覆盖不同接收场景的 API 用法。
1. 示例 2a:Simple RX
- 核心功能:无限循环等待接收帧,接收成功后读取数据到本地缓冲区,重新启用 RX;
- 实现逻辑(关键 API 调用流程):
初始化(同 1a)→dwt_forcetrxoff()
(关 RX)→循环:
dwt_rxenable(DWT_START_RX_IMMEDIATE)
(启用 RX)→等待dwt_checkirq()
(轮询 IRQ)→dwt_readrxdata(rxBuffer, rxLen, 0)
(读数据)→dwt_forcetrxoff()
(关 RX,准备下一次接收); - 关键要点:
- 用轮询模式(
dwt_checkirq()
)处理 RX 事件,未用中断(适合简单场景); - 接收后需关 RX 再重新启用,避免缓冲区数据覆盖。
- 用轮询模式(
2. 示例 2b:Simple RX with 64-Symbol Preamble
- 核心功能:接收 “64 符号短前导帧”(普通 RX 模式难以接收短前导),需特殊参数配置;
- 核心新增配置:
dwt_loadopsettabfromotp(DWT_OPSET_64LEN)
(加载 “短前导优化参数集”,容忍 ±15ppm 晶体偏移)→dwt_configure()
(前导长度设DWT_PLEN_64
、PAC size 设DWT_PAC8
); - 关键要点:
- 短前导(64 符号)适合高速率短帧,但易受晶体偏移影响,需
DWT_OPSET_64LEN
参数集优化; - 仅在明确接收短前导帧时使用,长前导场景(如 2048)不推荐(会降低接收灵敏度)。
- 短前导(64 符号)适合高速率短帧,但易受晶体偏移影响,需
3. 示例 2c:Simple RX with Diagnostics
- 核心功能:接收帧后,读取 “RX 诊断数据”(噪声、第一路径幅度、CIR 增长值)和 “信道冲激响应(CIR)数据”;
- 核心新增 API:
dwt_readdiagnostics(&diagData)
(读诊断数据,dwt_rxdiag_t
结构体含maxNoise
、firstPath
、rxPreamCount
)→dwt_readaccdata(accBuffer, accLen, 0)
(读 CIR 数据,存复数值(实部 + 虚部)); - 关键要点:
- 诊断数据需在 “RX 成功” 后立即读取,否则被下一帧覆盖;
- CIR 数据用于分析射频环境(如多径干扰),需通过频谱仪辅助解读,非普通通信必需。
4. 示例 2d:Low Duty-Cycle SNIFF Mode
- 核心功能:用 SNIFF 模式接收(RX 周期性开关,低占空比),降低接收功耗(≈50% 占空比);
- 核心新增 API:
dwt_setsniffmode(1, 1, 1)
(启用 SNIFF:timeOn=1
→2 PAC、timeOff=1
→1μs,占空比≈50%)→dwt_setpreambledetecttimeout(10)
(前导检测超时 = 10 PAC); - 关键要点:
- SNIFF 模式通过 “RX 开 - 关循环” 降低功耗,但会降低接收灵敏度(需测试调整
timeOn
/timeOff
); - 需配合
dwt_configure()
设置长前导(如 1024),确保 RX 开启时能捕获前导。
- SNIFF 模式通过 “RX 开 - 关循环” 降低功耗,但会降低接收灵敏度(需测试调整
5. 示例 2e:RX with Double Buffering
- 核心功能:用双缓冲 RX 模式(两个 RX 缓冲区交替使用),避免 “接收新帧时前一帧未读取” 导致的溢出;
- 核心新增 API 与逻辑:
dwt_setdblrxbuffmode(1)
(启用双缓冲)→dwt_setcallbacks(NULL, cbRxOk, NULL, NULL)
(配置 RX 成功回调)→回调中:
dwt_rxenable(DWT_START_RX_IMMEDIATE | DWT_NO_SYNC_PTRS)
(重新启用 RX,DWT_NO_SYNC_PTRS
避免指针同步冲突)→dwt_readrxdata()
(读当前缓冲区数据); - 关键要点:
- 双缓冲切换由
dwt_isr()
自动处理(无需手动切换指针); - 必须用中断 + 回调模式(轮询无法及时处理双缓冲切换),适合高吞吐接收场景(如连续帧)。
- 双缓冲切换由
类别 3:TX-RX 交互示例(3a~3d)
核心目标:演示 “请求 - 响应” 逻辑(如 TX 后等 ACK、RX 后发响应),覆盖轮询与中断两种交互模式。
1. 示例 3a:TX then Wait for Response
- 核心功能:发送一帧后,启用 RX 等待响应(设超时),超时则重新发送;
- 核心新增 API:
dwt_setrxtimeout(1000)
(设 RX 超时 = 1000×1.0256μs≈1.025ms)→dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXP)
(TX 后自动启用 RX); - 关键要点:
- 用
dwt_setrxtimeout()
避免无限等待,超时后dwt_isr()
触发cbRxTo
回调; - 响应帧需与发送帧参数匹配(信道、PRF、前导),否则无法接收。
- 用
2. 示例 3b:RX then Send Response
- 核心功能:示例 3a 的 “互补端”—— 接收 3a 发送的帧后,发送响应帧;
- 核心逻辑:
RX 成功后(cbRxOk
回调)→dwt_writetxdata(respLen, respData, 0)
(写响应数据)→dwt_starttx(DWT_START_TX_IMMEDIATE)
(发送响应); - 关键要点:
- 需校验接收帧的 “帧控制字段”(如确认是 3a 发送的 “请求帧”),再发送响应;
- 响应帧的前导、PRF 需与请求帧一致,确保 3a 能接收。
3. 示例 3c:TX then Wait for Response with GPIOs/LEDs
- 核心功能:在 3a 基础上,添加 GPIO/LED 控制(TX 时亮 LED1,RX 时亮 LED2),可视化通信状态;
- 核心新增 API:
dwt_setleds(0x03)
(启用 LED,初始化时闪烁一次)→dwt_setgpiovalue(GPIO1, 1)
(TX 时拉高 GPIO1,LED 亮)→dwt_setgpiovalue(GPIO1, 0)
(TX 后拉低); - 关键要点:
- 需确保 EVB1000 的 LED 与 GPIO 引脚连接(如 GPIO1 接 LED1);
- GPIO 控制需先调用
dwt_setgpiodirection(GPIO1, 0)
(设为输出)。
4. 示例 3d:TX then Wait for Response with Interrupts
- 核心功能:用 “中断 + 回调” 替代 3a 的轮询模式,处理 TX 完成、RX 成功、RX 超时事件;
- 核心新增逻辑:
dwt_setcallbacks(cbTxDone, cbRxOk, cbRxTo, cbRxErr)
(配置 4 个回调)→dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | DWT_INT_RFTO, 1)
(启用 TX 完成、RX 成功、RX 超时中断); - 关键要点:
- 回调中仅做 “状态标记”(如
txDoneFlag=1
),业务逻辑(如重新发送)在主循环处理(避免中断上下文耗时操作); - 比轮询模式更高效,适合多任务场景。
- 回调中仅做 “状态标记”(如
类别 4:测试与校准示例(4a~4b、9a~9b)
核心目标:用于 “频谱测试” 和 “温度补偿”,支撑 regulatory 认证与硬件性能优化。
1. 示例 4a:Continuous Wave Mode
- 核心功能:启用 “连续波(CW)模式”,输出固定频率载波(如信道 2 的 3.9936GHz),用于晶体校准或频谱仪测试;
- 实现逻辑:
初始化→dwt_configuretxrf()
(配置 PGdly 和功率)→dwt_configcwmode(2)
(配置信道 2 连续波)→dwt_starttx(DWT_START_TX_IMMEDIATE)
(启动连续波输出)→deca_sleep(120000)
(持续 2 分钟)→dwt_softreset()
(退出测试); - 关键要点:
- 需用频谱仪观察输出(配置:中心频率 = 信道中心频、SPAN=20MHz、RBW=100kHz);
- 连续波模式仅用于测试,正常通信需调用
dwt_softreset()
退出。
2. 示例 4b:Continuous Frame Mode
- 核心功能:启用 “连续帧模式”,循环发送固定帧(无间隔),用于 TX 功率频谱测试(regulatory 认证);
- 核心新增 API:
dwt_configcontinuousframemode(0x1000)
(设帧重复间隔 = 0x1000×8ns≈32.8μs)→dwt_writetxdata(127, txData, 0)
(写 127 字节测试数据)→dwt_starttx(DWT_START_TX_IMMEDIATE)
(启动连续发送); - 关键要点:
- 间隔需≥帧发送时间(否则帧重叠),示例中 0x1000 对应 32.8μs,适配 127 字节 @6.8Mbps(发送时间≈148μs?需确认手册计算);
- 频谱仪配置:中心频 = 信道频、SPAN=2GHz、RBW=1MHz,用于测量 “每 1MHz 带宽功率是否合规”。
3. 示例 9a:TX Bandwidth and Power Reference Measurements
- 核心功能:测量 “基准温度下的带宽 / 功率参数”(如 23℃),为 9b 的补偿算法提供参考值;
- 核心测量内容:
dwt_readtempvbat(0)
(读温度)→dwt_calcpgcount(pgdly)
(读脉冲发生器计数,关联带宽)→dwt_configuretxrf()
(读当前功率寄存器值); - 关键要点:
- 需记录测量值(温度、PGcount、功率值),手动填入 9b 的代码中;
- 测量需在 “芯片默认设置” 下进行(无温度补偿)。
4. 示例 9b:TX Bandwidth and Power Compensation
- 核心功能:基于 9a 的基准值,用补偿算法调整 “脉冲发生器延迟(PGdly)” 和 “TX 功率”,抵消温度对带宽 / 功率的影响;
- 核心新增 API:
dwt_calcbandwidthtempadj(targetPGcount)
(根据当前温度和基准 PGcount,计算补偿后的 PGdly)→dwt_calcpowertempadj(chan, refPower, currTemp, refTemp)
(计算补偿后的 TX 功率); - 关键要点:
- 仅支持信道 2 和 5;
- 补偿后需调用
dwt_configuretxrf()
更新 PGdly 和功率,再启用连续帧模式验证频谱。
类别 5:测距示例(5a~5b、6a~6b)
核心目标:演示 “双向测距(TWR)” 的 initiator(发起端)与 responder(响应端)逻辑,覆盖高精度(DS TWR)和简化(SS TWR)场景。
1. 示例 5a:DS TWR Initiator
- 核心功能:作为 DS TWR(双向双向测距)的发起端,发送 “poll 帧”→接收 “response 帧”→发送 “final 帧”(含本地时间戳),由 responder 计算距离;
- 核心逻辑(时间戳交互):
- 发送 poll 帧,调用
dwt_readtxtimestamp(pollTxTs)
(记录 poll TX 时间戳); - 接收 response 帧,调用
dwt_readrxtimestamp(respRxTs)
(记录 response RX 时间戳); - 发送 final 帧,调用
dwt_setdelayedtrxtime(finalTxTime)
(计算 final TX 时间戳并嵌入帧中);
- 发送 poll 帧,调用
- 关键要点:
- DS TWR 需 3 帧交互(poll→response→final),能抵消时钟偏移,精度达厘米级;
- 时间戳为 40 位,需用
dwt_readtxtimestamp()
/dwt_readrxtimestamp()
读取(5 字节缓冲区)。
2. 示例 5b:DS TWR Responder
- 核心功能:作为 DS TWR 的响应端,接收 poll 帧→发送 response 帧→接收 final 帧,计算飞行时间(TOF)和距离;
- 核心计算逻辑:
接收 poll 帧→dwt_readrxtimestamp(pollRxTs)
(记录 poll RX)→发送 response→dwt_readtxtimestamp(respTxTs)
(记录 response TX)→接收 final 帧(含 initiator 的 3 个时间戳)→计算:
TOF = [(respRxTs - pollTxTs) × (finalRxTs - respTxTs) - (respTxTs - pollRxTs) × (finalTxTs - respRxTs)] / (2 × finalTxTs - 2 × pollTxTs)
;
距离 = TOF × 光速(3×10⁸m/s); - 关键要点:
- 需解析 final 帧中的 initiator 时间戳,确保时间戳格式一致(低字节在前);
- 距离计算需处理时间戳的 “wrap”(40 位溢出),避免负数。
3. 示例 6a:SS TWR Initiator
- 核心功能:作为 SS TWR(单向双向测距)的发起端,发送 poll 帧→接收 response 帧(含 responder 时间戳),计算距离(v4.0.6 后用载波积分器校准时钟偏移);
- 核心新增 API:
dwt_readcarrierintegrator()
(接收 response 帧后,读取载波积分值,计算时钟偏移 PPM)→补偿 TOF 计算; - 关键要点:
- SS TWR 仅需 2 帧交互(poll→response),比 DS TWR 简化,但原精度低;
- v4.0.6 后通过
dwt_readcarrierintegrator()
校准时钟偏移(公式:clockOffsetPPM = 积分值 × FREQ_OFFSET_MULTIPLIER_110KB × HERTZ_TO_PPM_MULTIPLIER_CHAN_5
),精度接近 DS TWR。
4. 示例 6b:SS TWR Responder
- 核心功能:作为 SS TWR 的响应端,接收 poll 帧→发送 response 帧(嵌入本地时间戳:poll RX、response TX);
- 关键逻辑:
接收 poll→dwt_readrxtimestamp(pollRxTs)
→发送 response→dwt_readtxtimestamp(respTxTs)
→将两个时间戳嵌入 response 帧的 payload,发送给 initiator; - 关键要点:
- 无需接收 final 帧,比 DS TWR responder 简化;
- 时间戳需按约定格式嵌入(如前 10 字节存储两个 40 位时间戳),确保 initiator 能解析。
类别 6:低功耗监听(LPL)示例(8a~8b)
核心目标:演示 “周期性唤醒监听” 模式,设备大部分时间睡眠,仅短暂唤醒 RX 采样前导,适合电池供电的远距离低频次通信。
1. 示例 8a:Low-Power Listening RX
- 核心功能:启用 LPL 模式,等待 8b 发送的 “唤醒序列”,被唤醒后发送响应帧,之后重新启用 LPL;
- 核心配置 API:
dwt_setlowpowerlistening(1)
(启用 LPL)→dwt_setsnoozetime(1)
(短睡眠 = 53μs)→dwt_configuresleep(0x0148, 0x9)
(长睡眠配置:唤醒源 = 睡眠计时器)→dwt_calibratesleepcnt()
(校准低功耗振荡器); - 关键逻辑:
LPL 模式下,设备周期性唤醒 RX(“监听窗”)→检测到唤醒序列(多帧连续发送)→退出 LPL→发送响应→重新启用 LPL; - 关键要点:
- 唤醒序列需 “多帧连续发送”(确保 LPL 的监听窗能捕获);
- 若唤醒序列目标地址不是本设备,睡眠至唤醒序列结束后再启用 LPL。
2. 示例 8b:Low-Power Listening TX
- 核心功能:作为 8a 的互补端,周期性发送 “唤醒序列”(10 帧连续发送),唤醒 8a 后进入 “交互期”,等待 8a 的响应;
- 核心逻辑:
循环:发送 10 帧唤醒序列(无间隔)→deca_sleep(1000)
(交互期 1 秒,等待 8a 响应)→deca_sleep(5000)
(5 秒后再次发送唤醒序列); - 关键要点:
- 唤醒序列的前导、PRF 需与 8a 的 LPL 配置匹配;
- 每 2 次唤醒序列中,1 次用正确地址(唤醒 8a),1 次用 dummy 地址(演示 “非目标设备不响应”)。
(三)、共性与使用建议
1. 共性特点
- 硬件依赖:所有示例基于 EVB1000(STM32F105RC MCU),移植到其他硬件需修改
Platform
目录下的 SPI、GPIO、中断代码; - API 一致性:核心初始化流程(
dwt_initialise()
→dwt_configure()
→dwt_configuretxrf()
)在所有示例中统一,仅后续功能 API 不同; - 低功耗逻辑:所有低功耗示例(1b~1d、8a~8b)均依赖
dwt_configuresleep()
+dwt_entersleep()
,需注意唤醒源配置与唤醒信号时长; - 调试方式:示例输出少,需通过 CooCox IDE 的调试器观察变量(如时间戳、接收数据),或添加 GPIO/LED 可视化状态。
2. 使用建议
- 新手入门:优先运行 1a(Simple TX)+2a(Simple RX),掌握基础 TX/RX 流程,再尝试 3a(TX-RX 交互);
- 低功耗开发:从 1b(手动睡眠)→1d(定时睡眠)→8a/b(LPL)逐步深入,重点关注
dwt_calibratesleepcnt()
的校准逻辑; - 测距开发:先理解 5a/b(DS TWR)的三帧交互与时间戳计算,再尝试 6a/b(SS TWR)的简化逻辑与时钟偏移校准;
- 测试认证: regulatory 认证需用 4a(连续波)、4b(连续帧)、9a/b(补偿),确保频谱参数合规。