从零实现BLE协议栈(2-4)实验:02_active_scan
2-4 动手实验:编译运行 02_active_scan
本篇是第 2 章的配套实验,将 2-1 到 2-3 中讲解的主动扫描和 SW TIFS 机制完整跑通。
配套代码: https://github.com/ixbwer/write-BLE-stack-from-scratch/tree/master/02_active_scan
一、概述
02_active_scan 在 01_tx_advertise 基础上增加了 RX 能力:发完 ADV_IND 后,利用 TIMER1 + PPI 实现软件 T_IFS(150 µs),在 T_IFS 窗口内切换到 RX 模式接收 SCAN_REQ,并在收到合法请求后立即回复 SCAN_RSP。
通过本实验,你将验证:
- SW TIFS 定时链路(TIMER1 CC[0] → RXEN, TIMER1 CC[1] → TXEN)是否生效
- ADV_IND → SCAN_REQ → SCAN_RSP 三步交互是否完成
- SCAN_RSP 中携带的设备名是否正确
二、实验环境
| 项目 | 说明 |
|---|---|
| 开发板 | nRF52 DK (PCA10040) — nRF52832 |
| 测试工具 | nRF52840 Dongle + bumble_scan_req.py |
| 构建系统 | Zephyr west + GCC (zephyr-sdk-0.17.4) |
| 串口查看 | 任何串口终端(115200 baud) |
三、编译与烧录
west build -b nrf52dk/nrf52832 .\write-BLE-stack-from-scratch\02_active_scan\ -p
west flash
编译产物:
Memory region Used Size Region Size %age Used
FLASH: 47332 B 512 KB 9.03%
RAM: 13488 B 64 KB 20.58%
四、串口日志
*** Booting Zephyr OS build v4.3.0-4808-ga5d4626b8c16 ***
=== BLE PHY SW TIFS Demo ===
使用 TIMER1 + PPI 实现软件 TIFS 定时
对应真实 Controller 的 !CONFIG_BT_CTLR_TIFS_HW 路径
HFCLK started
Radio configured: BLE 1M (SW TIFS mode, TIFS register=0)
SW_SWITCH_TIMER (TIMER1) configured: 1MHz, 16-bit
PPI configured:
CH14: RADIO END → TIMER1 CLEAR
CH15: TIMER1 CC[0] → RADIO RXEN
CH16: TIMER1 CC[1] → RADIO TXEN
ADV_IND PDU built: type=0x00 len=19
SCAN_RSP PDU built: type=0x04 len=24
Advertising started (SW TIFS mode: TIMER1 + PPI)
[SW-TIFS] events: 10 | SCAN_REQ rx: 0 | SCAN_RSP tx: 0
[SW-TIFS] events: 20 | SCAN_REQ rx: 0 | SCAN_RSP tx: 0
[SW-TIFS] events: 30 | SCAN_REQ rx: 1 | SCAN_RSP tx: 1
日志中的关键字段:
TIFS register=0:确认未使用硬件 TIFS 寄存器,完全由 TIMER1+PPI 实现type=0x00:ADV_IND(可连接可扫描的广播),与 Demo 01 的 ADV_NONCONN_IND (0x02) 不同type=0x04:SCAN_RSP PDU 类型SCAN_REQ rx / SCAN_RSP tx:计数器,每收到一次合法 SCAN_REQ 就 +1
五、运行测试
方法 A:nRF Connect App
打开手机上的 nRF Connect App → Scan,你会看到名为 "ZephyrSW-ScanRsp" 的设备。

方法 B:使用 nRF 52840 Dongle
使用 nRF52840 Dongle 发送 SCAN_REQ:
.\write-BLE-stack-from-scratch\tools\venv\Scripts\python.exe `
.\write-BLE-stack-from-scratch\tools\bumble_scan_req.py `
--transport usb:2FE3:000B `
--target 66:55:44:33:22:11 `
--duration 5
输出示例:
Starting Active Scan for 5s ...
============================================================
★ SCAN_RSP #1 from 66:55:44:33:22:11
============================================================
RSSI: -67 dBm
Address Type: Random
AD Structures (1):
[Complete Local Name] (16 bytes): "ZephyrSW-ScanRsp"
...(每收到一个 ADV_IND,bumble 自动发送 SCAN_REQ,触发 SCAN_RSP)...
============================================================
Scan completed.
ADV received : 2
SCAN_RSP received: 15
Unique devices : 1
============================================================
测试完成后,串口计数器也会同步更新:
[SW-TIFS] events: 790 | SCAN_REQ rx: 119 | SCAN_RSP tx: 119
SCAN_REQ rx 与 SCAN_RSP tx 始终相等,说明每次收到的 SCAN_REQ 都正确触发了回复。
方法 C:
完整的时序图

ADV_IND 信息

SCAN_REQ 信息

SCAN_RSP 信息

本系列教程同款硬件:👇
芯片: nRF 52832 开发板
工具: nRF 52840 BLE Dongle 蓝牙嗅探器
工具: 逻辑分析仪
工具: BPA low energy 蓝牙分析仪
本文版权归作者:ixbwer所有,转载请注明原文链接:https://www.cnblogs.com/ixbwer/p/19799806,否则保留追究法律责任的权利。

浙公网安备 33010602011771号