nordic蓝牙笔记之协议栈连接
1,nrf52不是开源协议栈
2,nrf52支持freertos
3,下载方式不一样了,用的是nrfgo studio
4,蓝牙协议栈相关的有10个实验,工作量不大。
nordic协议栈没有开源,所以只留了一些配置接口。
配置设备角色是主机还是从机
实际蓝牙手表上,MTU设置为247字节,如果需要OTA的话,设置成512字节。
设置连接间隔,设置设备名称,
配对是在蓝牙连接成功之后进行的,
在配对时,密钥建立加密和认证的链接
外围设备需要中央设备提供密钥以完成配对过程,中央设备发送密钥后,
什么是绑定 ?
就是已经连接的2个设备,在配对时会有一个长久的密钥,在断开后第二次以后连接,可以使用这个长久的密钥快速连接。
蓝牙连接间隔
在蓝牙连接过程中,在一定的时间后,会使用跳频机制,到别的信道上进行通信。
切换信道是在链路层执行的。
刚开始连接时的默认连接参数是主机决定的连接时间

BLE协议栈为什么要设计从机潜伏周期?解决什么问题?
从机没有连接数据要发的时候,会跳过一定的连接事件,在干扰大或者举例远时可以减少掉线率,而且这样做功耗更低。
蓝牙初始化之后,第一次从机发起连接参数更新,如果主机没有发送跟新响应,从机会再发起一次参数更新,如果一直失败,
从机会继续发起参数跟新请求,直到达到最大次数,最后断开连接。


连接参数跟新过程---我的总结---在从设备发送请求,请求中带了最小值,最大值,延迟值发给主机后,主机回响应的包中
在LL_Connect_Update_Req字段的Interval字段表示了协商成功后的参数值,
蓝牙连接参数在蓝牙手表和手机连接的过程中会更新吗
非常明确的结论:
会更新,而且一定会更新。
蓝牙手表和手机建立连接后,连接参数(连接间隔、延迟、超时)在整个连接生命周期内都可以被动态更新,不是一成不变的。
1. 谁可以发起更新?
BLE 协议里有两方都能发起更新:
- 主机(手机)
iOS / Android 拥有最高控制权,随时可以要求改连接间隔。 - 外设(你的蓝牙手表)
手表觉得功耗太高、数据太慢,也可以主动请求更新。
2. 什么时候会触发更新?(真实场景)
① 刚连接上时
- 手表广播时携带建议连接参数
- 手机连接后立刻替换成自己的策略
→ iOS 尤其明显,经常强制把间隔拉大
② 手表主动申请更新(最常见)
- 要开始大量传输数据(OTA 升级、同步表盘、同步健康数据)
→ 请求更小连接间隔:10ms ~ 20ms - 数据传完,进入待机省电
→ 请求更大连接间隔:100ms ~ 500ms
③ 手机主动强制更新(你控制不了)
- iOS 为了省电,会在后台自动拉大连接间隔
- Android 不同厂商策略不同,但也会动态调整
④ 信号差、重连、跳频时
系统会自动调整连接间隔保证稳定。
3. 蓝牙手表典型的参数变化路径(真实流程)
- 刚连接
连接间隔:20ms ~ 40ms - 待机几秒后
iOS 强制改成:100ms ~ 200ms(更省电) - 开始同步心率/通知
手表请求:20ms ~ 40ms - 开始 OTA 升级
手表请求最小间隔:7.5ms ~ 15ms - 回到锁屏待机
间隔又变大:200ms ~ 500ms
4. 代码层面怎么体现?
在 ESP32 / NuttX / Zephyr 中都有:
- 连接参数更新回调函数
- 外设主动发起更新的 API
例如 NuttX / Zephyr:
// 手表主动请求更新连接参数
bt_conn_le_param_update(conn, &new_params);
手机端更新后,手表会收到回调:
static void conn_param_updated_cb(struct bt_conn *conn, uint16_t intv,
uint16_t latency, uint16_t timeout)
{
// 连接间隔已经变了
}
5. 最重要的现实(做手表必须知道)
- iOS 拥有绝对控制权
你设再小的间隔,它后台照样给你拉大 - Android 相对灵活
- 连接参数不是固定一次配置,而是全程动态协商
- 想要低延迟 → 手表必须主动发起参数更新
- 想要低功耗 → 让连接间隔变大
一句话总结
蓝牙连接参数不是固定的,从连接到断开,会根据场景(待机/数据/OTA)不断更新。手机和手表都能发起更新,但手机优先级更高。
如果你需要,我可以告诉你:
- 如何让 iOS 不随意拉大连接间隔
- 手表在什么时候发起更新最合理
- 不同场景(心率、通知、OTA)的最佳连接参数配置
蓝牙连接时的连接间隔在实现上是配置了一个范围,而不是一个固定的值,是吗?
完全正确,而且这是 BLE 协议的硬性规范。
核心结论
- BLE 连接时,配置的一定是「范围」,不是固定值
- 最小连接间隔
conn_intv_min - 最大连接间隔
conn_intv_max
- 最小连接间隔
- 最终真正使用的间隔,由主机(手机/网关)在这个范围内选一个值
- 外设(手表/传感器)只能提供建议范围,不能强制固定值
为什么必须是范围?
- BLE 是异步无线通信,空中可能有干扰、多设备抢信道
- 协议规定:Controller 会在范围内自动跳变、微调,保证稳定性
- 手机系统(iOS/Android)会根据功耗、信号质量动态选择
- 如果你强行写一样,协议栈也不会报错,但不符合规范,兼容性差
实际参数范围(单位:1.25ms)
- 范围:6 ~ 3200
- 最小:
6→ 7.5ms - 最大:
3200→ 4s
蓝牙手表典型配置
- 普通低功耗:
min = 16(20ms)max = 32(40ms)
- 超低功耗(心率计、传感器):
min = 100max = 200
- 高速通信(OTA、表盘同步):
min = 6max = 16
代码里长什么样(ESP32 / NuttX / Zephyr 都一样)
/* 连接参数范围 */
conn_params.min_interval = 16;
conn_params.max_interval = 32; // 必须 ≥ min
conn_params.latency = 0;
conn_params.timeout = 400;
一句话记住
BLE 连接间隔 → 外设给范围,主机定最终值,不可能固定死。
如果你愿意,我可以告诉你:
- 手表不同场景(待机/心率/OTA)分别推荐什么范围
- iOS 和 Android 对连接间隔的真实行为区别
- 怎么设置才能既省电又不卡顿
浙公网安备 33010602011771号