@zifeng328573112
2026-06-22T12:04:52.000000Z
字数 29775
阅读 160
| 项目 | 内容 |
|---|---|
| 源文档 | 体外程控仪蓝牙通信协议规范.docx |
| 版本 | V1.0 |
| 生成日期 | 2026-05-19 |
所有指令均采用统一帧格式,所有多字节字段均采用小端序(Little-Endian)。
| 字段 | 偏移 | 长度 | 字节序 | 描述 |
|---|---|---|---|---|
| 帧头 | 0 | 1 | 固定值 | 固定值 0xAA |
| 协议版本 | 1 | 1 | - | 当前版本 0x01 |
| 帧标志 | 2 | 1 | - | 帧属性标志(见下表FLAG字段定义) |
| 帧序号 | 3 | 2 | 小端序 | 递增序列号(0x0000-0xFFFF) |
| 发送方角色 | 5 | 1 | - | 发送方设备角色(见1.2节角色定义) |
| 接收方角色 | 6 | 1 | - | 接收方设备角色(见1.2节角色定义) |
| 命令码 | 7 | 2 | 小端序 | 命令类型标识 |
| 数据长度 | 9 | 2 | 小端序 | 整个帧的长度(SOF+VER+FLAG+SEQ+SRC+DST+OPCODE+LEN+Payload+CRC,13-247字节) |
| 数据域 | 11 | 0-N | 小端序 | 命令参数,采用LV格式(见1.3节) |
| 校验码 | 11+N | 2 | 小端序 | CRC-16/CCITT(见第8节) |
帧标志字段(FLAG)位于协议版本之后,用于标识帧的安全属性和控制标志。
| 位 | 名称 | 说明 |
|---|---|---|
| Bit 0 | ENC | 加密标志:0 = Payload为明文,1 = Payload为AES-256-GCM加密数据 |
| Bit 1 | REQ_ACK | 请求ACK:0 = 无需ACK回复,1 = 要求接收方回复ACK(预留) |
| Bits 2-7 | RSV | 保留位,固定为0 |
当前定义的FLAG值:
| 值 | 含义 | 说明 |
|---|---|---|
| 0x00 | 明文帧 | Payload为明文LV格式数据 |
| 0x01 | 加密帧 | Payload为AES-256-GCM加密数据(Ciphertext + GCM Tag) |
注意: 帧标志字段包含在CRC-16/CCITT校验范围内(从协议版本开始到Payload结束),确保标志位不被篡改。
| 项目 | 值 |
|---|---|
| LEN字段 | 整个帧的长度(SOF+VER+FLAG+SEQ+SRC+DST+OPCODE+LEN+Payload+CRC),最小13字节,最大247字节 |
| 最小帧长度 | 13字节(无Payload) |
| 最大帧长度 | 247字节 |
| LEN最小值 | 13(对应13字节总帧长,Payload长度为0) |
| LEN最大值 | 247 |
| Payload最大长度 | 234字节 |
| Payload最小长度 | 1字节(拒绝payload_len=0帧,防止空数据恶意轰炸) |
| 字节序 | 多字节字段采用小端序(LE),单字节字段无需转换 |
小端序(Little-Endian):低位字节存储在低地址。
示例:数值 0x1234(十进制 4660)大端序(BE):[0x12] [0x34] ← 高位在前小端序(LE):[0x34] [0x12] ← 低位在前(本协议采用)
所有多字节字段在帧中的存储顺序均为:
- SEQ(帧序号):低字节在前
- OPCODE(命令码):低字节在前
- LEN(总帧长):低字节在前
- CRC16(校验码):低字节在前
- Payload内的多字节数值:低字节在前
FLAG(帧标志)、SRC_ROLE(发送方角色)和DST_ROLE(接收方角色)为单字节字段,无需字节序转换。
帧头中的发送方角色(SRC_ROLE)和接收方角色(DST_ROLE)用于标识设备身份,实现一主多从通信。
| 值 | 含义 | 说明 |
|---|---|---|
| 0x00 | 主机(程控仪) | 主控制器,负责帧路由与转发 |
| 0x01-0x0A | 从设备1-10 | 最多10个从设备(如IPG等刺激器) |
| 0x0B-0xFF | 保留 | 预留扩展 |
角色校验规则:
- 接收方根据DST_ROLE判断是否处理该帧
- 主机(0x00)处理所有帧,并负责在从设备间转发消息
- 从设备仅处理DST_ROLE等于自身角色的帧,其余丢弃
- 响应帧的SRC_ROLE和DST_ROLE互换(请求的发送方变为响应的接收方)
Payload采用 LV(Length-Value)格式。每个数据段前使用1字节长度前缀标识其长度。
LV格式定义:每段 = [长度(1字节)] + [值(N字节)]长度 = 0 该段不存在(用于保留字段/可选字段)长度 = N 值部分占 N 个字节规则:- 字段按协议定义顺序排列,接收方根据位置确定类型- 保留字段使用长度 0 表示"不存在",不再写占位零- 重复结构中的每个子字段单独加长度前缀
LV格式示例:握手请求(0x0001)
原固定格式(已废弃):字段1(4字节) | 字段2(4字节) | 字段3(8字节)新LV格式:04|字段1(4字节) | 04|字段2(4字节) | 08|字段3(8字节)
加密机制已迁移至独立的《体外程控仪蓝牙通信协议规范_安全加密扩展_V1.0.md》文档。
摘要:
| 阶段 | 算法 | 说明 |
|---|---|---|
| 身份认证 | ECDSA P-256 | 双向Challenge-Response认证,使用设备内置证书签名验证 |
| 数据加密 | AES-256-GCM | 认证完成后使用会话密钥进行对称加密,提供加密+完整性保护 |
详细定义(密钥交换流程、Nonce机制、认证状态机、加密范围、GCM AAD构造等)请参考安全加密扩展文档。
广播与扫描响应仅包含以下 4 个字段:
| 字段 | 说明 |
|---|---|
| 蓝牙名称 | 本地名称 |
| 患者名称 | UTF-8 |
| 设备型号 | UTF-8 |
| 设备序列号 | UTF-8 |
| 承载位置 | 字段 |
|---|---|
| Advertising Data | 蓝牙名称 |
| Scan Response Data | 患者名称、设备型号、设备序列号 |
若长度超限,患者名称、设备型号、设备序列号可截断。
示例:
Advertising Data02 01 060C 09 53 43 53 2D 49 50 47 2D 30 31Scan Response Data12 FF E5 BC A0 E4 B8 89 2C 58 31 30 30 2C 41 30 30 31
字段说明:
- 0C 09 53 43 53 2D 49 50 47 2D 30 31 = 蓝牙名称 SCS-IPG-01
- 12 FF E5 BC A0 E4 B8 89 2C 58 31 30 30 2C 41 30 30 31 = 张三,X100,A001
当前固件采用单一自定义数据通道服务承载本协议第3章定义的完整帧格式。上位机发现该服务后,通过4个独立Characteristic完成读取、写入、Notify事件上报和Indicate可靠响应。
Service UUID:33221100-0000-1000-8000-00805F9B34FB
| 特征名称 | UUID | 属性 | 长度 | 描述 |
|---|---|---|---|---|
| Host Read | 33221101-0000-1000-8000-00805F9B34FB | Read | ≤247 | 上位机读取最近一次命令响应帧;无缓存时返回0字节 |
| Host Write | 33221102-0000-1000-8000-00805F9B34FB | Write / Write Without Response | ≤247 | 上位机向设备下发协议帧 |
| Device Notify | 33221103-0000-1000-8000-00805F9B34FB | Notify | ≤247 | 设备主动上报事件、状态变化及安全告警 |
| Device Indicate | 33221104-0000-1000-8000-00805F9B34FB | Indicate | ≤247 | 设备返回ACK/NACK及命令响应,需上位机确认 |
说明:
- 上位机发送命令统一写入 Host Write 特征值。
- 命令响应统一通过 Device Indicate 特征值返回;同一响应帧同时缓存到 Host Read 特征值。
- 设备主动事件统一通过 Device Notify 特征值上报,不覆盖 Host Read 的最近命令响应缓存。
- 广播/扫描响应中仅暴露 Service UUID,不暴露4个Characteristic UUID。
Service UUID:0x180A(Bluetooth SIG标准服务)
| 特征名称 | UUID | 属性 | 长度 | 描述 |
|---|---|---|---|---|
| Manufacturer Name String | 0x2A29 | Read | ≤20 | 制造商名称(UTF-8) |
| Model Number String | 0x2A24 | Read | ≤20 | IPG型号 |
| Serial Number String | 0x2A25 | Read | ≤20 | IPG唯一序列号 |
| Firmware Revision String | 0x2A26 | Read | ≤20 | 固件版本号 |
| Hardware Revision String | 0x2A27 | Read | ≤20 | 硬件版本号 |
| IEEE 11073-20601 Regulatory Cert Data List | 0x2A2A | Read | ≤32 | IEEE监管认证数据 |
Service UUID:0xFFE0(128位:0000FFE0-0000-1000-8000-00805F9B34FB)
| 特征名称 | UUID | 属性 | 长度 | 描述 |
|---|---|---|---|---|
| OTA Control Point | 0xFFE1 | Write / Indicate | ≤20 | OTA控制点 |
| OTA Data | 0xFFE2 | Write Without Response | ≤244 | OTA固件数据传输通道 |
| OTA Version | 0xFFE3 | Read | ≤20 | 读取当前固件版本号及OTA协议版本号 |
| 命令码 | 名称 | 方向 | 类别 | 典型响应 | 备注 |
|---|---|---|---|---|---|
0x0001 |
握手 | 双向 | 连接建立 | 同命令码响应 | 建链后首条业务指令 |
0x0003 |
身份认证 | 双向 | 兼容保留 | 同命令码响应 | 已废弃,改用 0x0086→0x0088 |
0x0011 |
读取设备配置项 | 双向 | 信息查询 | 同命令码响应 | 支持一次读取多个字段 |
0x0012 |
读取电池状态 | 双向 | 信息查询 | 同命令码响应 | 请求侧需填充 00 |
0x0013 |
写入设备配置项 | 双向 | 配置写入 | ACK / NACK | 支持一次写入多个字段 |
0x0014 |
读取工作状态 | 双向 | 信息查询 | 同命令码响应 | 返回刺激状态、刺激程序组、充电状态 |
0x0015 |
读取电极信息 | 双向 | 信息查询 | 同命令码响应 | 返回电极根数配置、上电极型号、下电极型号 |
0x0016 |
写入电极信息 | 双向 | 信息写入 | ACK / NACK | 写入电极根数配置、上电极型号、下电极型号 |
0x0020 |
读取刺激参数 | 双向 | 参数查询 | 同命令码响应 | 传入刺激组编号,返回组参数和4个程序参数 |
0x0021 |
写入刺激参数 | 双向 | 参数写入 | ACK / NACK | 写入组参数和4个程序参数 |
0x0022 |
写入常规刺激参数 | 程控仪 → IPG | 参数写入 | ACK / NACK | 写入单个 P 程序参数 |
0x0023 |
写入 Burst 刺激参数 | 程控仪 → IPG | 参数写入 | ACK / NACK | 写入单个 P 程序参数 |
0x0024 |
写入高频刺激参数 | 程控仪 → IPG | 参数写入 | ACK / NACK | 写入单个 P 程序参数 |
0x0026 |
实时参数调整 | 双向 | 治疗中微调 | Notify 响应 | 建议 Write Without Response |
0x0030 |
启动刺激 | 双向 | 控制 | 同命令码响应 | 先校验程序组参数完整性 |
0x0032 |
停止刺激 | 双向 | 控制 | 同命令码响应 | 支持正常停止和紧急停止 |
0x0036 |
安全告警通知 | IPG → 程控仪 | 告警 | Notify | 低电量、阻抗异常、刺激异常停止 |
0x0040 |
全阻抗测量 | 双向 | 测量 | 同命令码响应 | 返回各通道阻抗 |
0x0042 |
程序组阻抗测量 | 双向 | 测量 | 同命令码响应 | 面向指定程序组 |
方向:双向(请求与响应使用同一命令码)
功能:连接建立后由程控仪发起握手,IPG回复握手信息
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 程控仪型号 | 04 |
4 | uint32 | 程控仪型号标识 |
| App版本 | 04 |
4 | uint32 | App版本号 |
| 随机数 | 08 |
8 | bytes | 随机数Nonce_C |
请求Payload总长度:1+4 + 1+4 + 1+8 = 19字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| IPG型号 | 04 |
4 | uint32 | IPG型号标识 |
| 固件版本 | 04 |
4 | uint32 | 固件版本号 |
| 随机数 | 08 |
8 | bytes | 随机数Nonce_P |
| 会话令牌 | 04 |
4 | uint32 | 会话令牌(有效期30分钟) |
响应Payload总长度:4×(1+4) = 24字节
方向:双向(请求与响应使用同一命令码)
功能:身份认证(已废弃,仅向后兼容)
⚠ 废弃说明:该指令码保留仅用于向后兼容。完整认证流程已迁移至安全扩展 0x0086→0x0087→0x0088,详见《体外程控仪蓝牙通信协议规范_安全加密扩展_V1.0.md》。新实现应使用安全扩展的认证流程,不再使用 0x0003。
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 认证数据 | 10 |
16 | bytes | ECDSA P-256签名数据(仅向后兼容,详见安全扩展) |
请求Payload总长度:1+16 = 17字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 结果码 | 01 |
1 | uint8 | 0x00=成功,0x01=失败 |
响应Payload总长度:1+1 = 2字节
方向:双向(请求与响应使用同一命令码)
功能:程控仪请求IPG上报当前电池电压
请求Payload(程控仪 → 从设备):无(协议框架层拒绝LEN=0空帧,发送方应填充1字节保留字段00)
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 电池电压 | 02 |
2 | uint16 | 0-5000 | 单位0.001 V,实际值=字段值×0.001 |
响应Payload总长度:1+2 = 3字节
电池状态标志:
| 值 | 描述 |
|---|---|
| 0x00 | 正常 |
| 0x01 | 低电量警告(<20%) |
| 0x02 | 极低电量(<10%) |
| 0x03 | 电池老化 |
| 0x04 | 电池故障 |
| 0xFF | 未知状态 |
请求(0x0012):
AA 01 00 07 00 00 00 12 00 0D 00 00 00
响应(0x0012):
AA 01 00 08 00 01 00 12 00 10 0002 E4 0C - 02|电池电压=3300(3.300V,小端序)00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪一次读取一个或多个设备配置字段
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 字段ID 1 | 01 |
1 | uint8 | 第1个待读取字段标识符 |
| 字段ID 2 | 01 |
1 | uint8 | 第2个待读取字段标识符 |
| ... | ... | ... | ... | 支持连续携带多个字段ID |
请求Payload总长度:N × (1+1) = 2N 字节
字段ID定义:
| ID | 名称 | 最大长度 | 说明 |
|---|---|---|---|
| 0x01 | BLE广播名 | 30 B | 普通用户可改写 |
| 0x02 | S/N序列号 | 64 B | 量产预留 |
| 0x03 | 设备型号名 | 64 B | 量产预留 |
| 0x04 | 固件版本 | 64 B | 量产预留 |
| 0x05 | 硬件版本 | 64 B | 量产预留 |
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 字段ID 1 | 01 |
1 | uint8 | 与请求相同的字段ID |
| 字段值 1 | len |
N1 | UTF-8 string | 第1个字段的值 |
| 字段ID 2 | 01 |
1 | uint8 | 与请求相同的字段ID |
| 字段值 2 | len |
N2 | UTF-8 string | 第2个字段的值 |
| ... | ... | ... | ... | 按请求顺序返回多个字段 |
响应Payload总长度:可变,按返回字段数量和各字段长度确定
场景:一次读取 2 个字段,字段ID分别为 0x01(BLE广播名)和 0x03(设备型号名)
请求(0x0011):
AA 01 00 08 00 00 00 11 00 11 0001 01 - 01|字段ID=0x0101 03 - 01|字段ID=0x0300 00 - CRC16(示例)
响应(0x0011):
AA 01 00 09 00 01 00 11 00 22 0001 01 - 01|字段ID=0x010A 53 43 53 2D 49 50 47 2D 30 31 - 0A|字段值="SCS-IPG-01"01 03 - 01|字段ID=0x0304 58 31 30 30 - 04|字段值="X100"00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪一次写入一个或多个设备配置字段
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 字段ID 1 | 01 |
1 | uint8 | 第1个待写入字段标识符 |
| 字段值 1 | len |
N1 | UTF-8 string | 第1个字段的新值 |
| 字段ID 2 | 01 |
1 | uint8 | 第2个待写入字段标识符 |
| 字段值 2 | len |
N2 | UTF-8 string | 第2个字段的新值 |
| ... | ... | ... | ... | 支持连续写入多个字段 |
请求Payload总长度:可变,按写入字段数量和各字段长度确定
响应:成功返回ACK(0x00F0),失败返回NACK(0x00F1):
- 字段ID无效 → 错误码 0x0105(命令码未定义)
- 值长度超限 → 错误码 0x0103(帧长度异常)
通用规则:
- 后续同类“字段型读取指令”默认支持一次读取多个字段
- 后续同类“字段型写入指令”默认支持一次写入多个字段
场景:一次写入 2 个字段,字段ID分别为 0x01(BLE广播名)和 0x03(设备型号名)
请求(0x0013):
AA 01 00 0A 00 00 00 13 00 23 0001 01 - 01|字段ID=0x010A 53 43 53 2D 49 50 47 2D 30 32 - 0A|字段值="SCS-IPG-02"01 03 - 01|字段ID=0x0304 58 32 30 30 - 04|字段值="X200"00 00 - CRC16(示例)
响应(成功,ACK帧):
AA 01 00 0B 00 01 00 F0 00 17 0002 13 00 - 02|原命令码=0x001301 00 - 01|结果码=成功04 78 56 34 12 - 04|时间戳00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪读取刺激器当前工作状态
请求Payload(程控仪 → 从设备):无(协议框架层拒绝LEN=0空帧,发送方应填充1字节保留字段00)
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 刺激状态 | 01 |
1 | uint8 | 当前刺激状态 |
| 程序组编号 | 01 |
1 | uint8 | 当前刺激程序组编号,未刺激时填 0x00 |
| 充电状态 | 01 |
1 | uint8 | 当前充电状态 |
响应Payload总长度:3 × (1+1) = 6字节
刺激状态定义:
| 值 | 描述 |
|---|---|
| 0x00 | 已停止 |
| 0x01 | 刺激中 |
| 0x02 | 启动中 |
| 0x03 | 停止中 |
充电状态定义:
| 值 | 描述 |
|---|---|
| 0x00 | 未充电 |
| 0x01 | 充电中 |
| 0x02 | 充电完成 |
| 0x03 | 充电异常 |
请求(0x0014):
AA 01 00 0C 00 00 00 14 00 0E 00 00 00
响应(0x0014):
AA 01 00 0D 00 01 00 14 00 13 0001 01 - 01|刺激状态=刺激中01 03 - 01|刺激程序组=301 00 - 01|充电状态=未充电00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪读取当前电极信息
请求Payload(程控仪 → 从设备):无(协议框架层拒绝LEN=0空帧,发送方应填充1字节保留字段00)
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 电极根数配置 | 01 |
1 | uint8 | 当前电极根数配置 |
| 上电极型号 | 0A |
10 | UTF-8 string | 上槽位电极型号,不足补 0x00 |
| 下电极型号 | 0A |
10 | UTF-8 string | 下槽位电极型号,不足补 0x00 |
响应Payload总长度:1+1 + 1+10 + 1+10 = 23字节
电极根数配置定义:
| 值 | 描述 |
|---|---|
| 0x01 | 单根电极 |
| 0x02 | 双根电极 |
请求(0x0015):
AA 01 00 0E 00 00 00 15 00 0E 00 00 00
响应(0x0015):
AA 01 00 0F 00 01 00 15 00 24 0001 02 - 01|电极根数配置=双根电极0A 42 47 2D 31 32 30 31 48 30 31 - 0A|上电极型号="BG-1201H01"0A 42 47 2D 31 32 30 32 48 30 32 - 0A|下电极型号="BG-1202H02"00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪写入当前电极信息
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 电极根数配置 | 01 |
1 | uint8 | 当前电极根数配置 |
| 上电极型号 | 0A |
10 | UTF-8 string | 上槽位电极型号,不足补 0x00 |
| 下电极型号 | 0A |
10 | UTF-8 string | 下槽位电极型号,不足补 0x00 |
请求Payload总长度:1+1 + 1+10 + 1+10 = 23字节
响应:成功返回ACK(0x00F0),失败返回NACK(0x00F1)
请求(0x0016):
AA 01 00 10 00 00 00 16 00 24 0001 02 - 01|电极根数配置=双根电极0A 42 47 2D 31 32 30 31 48 30 31 - 0A|上电极型号="BG-1201H01"0A 42 47 2D 31 32 30 32 48 30 32 - 0A|下电极型号="BG-1202H02"00 00 - CRC16(示例)
响应(成功,ACK帧):
AA 01 00 11 00 01 00 F0 00 17 0002 16 00 - 02|原命令码=0x001601 00 - 01|结果码=成功04 78 56 34 12 - 04|时间戳00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪按刺激组编号读取该组下的刺激参数
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 刺激组编号 | 01 |
1 | uint8 | 待读取的刺激组编号 |
请求Payload总长度:1+1 = 2字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 刺激组编号 | 01 |
1 | uint8 | 与请求相同的刺激组编号 |
| 刺激模式 | 01 |
1 | uint8 | 0x01=常规,0x02=Burst,0x03=高频 |
| RampUp时间 | 02 |
2 | uint16 | 单位 1 ms |
| RampDown时间 | 02 |
2 | uint16 | 单位 1 ms |
| 刺激时间 | 04 |
4 | uint32 | 单位 1 s |
| 停止时间 | 04 |
4 | uint32 | 单位 1 s |
| 程序组频率 | 02 |
2 | uint16 | 组级频率,单位 0.1 Hz |
| 程序数量 | 01 |
1 | uint8 | 固定返回 0x04,表示该组下 P1-P4 |
| 程序1编号 | 01 |
1 | uint8 | P1 |
| 程序1是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序1脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序1分频 | 01 |
1 | uint8 | 分频值 |
| 程序1幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序1电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序2编号 | 01 |
1 | uint8 | P2 |
| 程序2是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序2脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序2分频 | 01 |
1 | uint8 | 分频值 |
| 程序2幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序2电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序3编号 | 01 |
1 | uint8 | P3 |
| 程序3是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序3脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序3分频 | 01 |
1 | uint8 | 分频值 |
| 程序3幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序3电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序4编号 | 01 |
1 | uint8 | P4 |
| 程序4是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序4脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序4分频 | 01 |
1 | uint8 | 分频值 |
| 程序4幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序4电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
响应Payload总长度:固定组参数 + 4 个程序参数,按字段长度确定
说明:
- 请求只传入 刺激组编号
- 响应先返回程序组参数,再固定返回该组下 P1-P4 4 个程序参数
- 刺激模式 / RampUp时间 / RampDown时间 / 刺激时间 / 停止时间 / 程序组频率 属于程序组参数
- 脉宽 / 分频 / 幅值 / 电极配置 属于单个程序参数
- 是否生效 仅取决于该程序的电极配置是否同时包含至少 1 个正极和至少 1 个负极
请求(0x0020):
AA 01 00 12 00 00 00 20 00 0F 0001 03 - 01|刺激组编号=300 00 - CRC16(示例)
响应(0x0020):
AA 01 00 13 00 01 00 20 00 7F 0001 03 - 01|刺激组编号=301 01 - 01|刺激模式=常规02 E8 03 - 02|RampUp时间=1000ms02 E8 03 - 02|RampDown时间=1000ms04 3C 00 00 00 - 04|刺激时间=60s04 1E 00 00 00 - 04|停止时间=30s02 F4 01 - 02|程序组频率=500 (50.0Hz)01 04 - 01|程序数量=401 01 - 01|程序1编号=P101 01 - 01|程序1是否生效=生效02 14 00 - 02|程序1脉宽=200µs01 0A - 01|分频=1002 F4 01 - 02|程序1幅值=50004 03 00 00 01 - 04|程序1电极配置=0x0100000301 02 - 01|程序2编号=P201 01 - 01|程序2是否生效=生效02 12 00 - 02|程序2脉宽=180µs01 08 - 01|分频=802 90 01 - 02|程序2幅值=40004 0C 00 00 03 - 04|程序2电极配置=0x0300000C01 03 - 01|程序3编号=P301 01 - 01|程序3是否生效=生效02 0E 00 - 02|程序3脉宽=140µs01 06 - 01|分频=602 2C 01 - 02|程序3幅值=30004 30 00 00 0C - 04|程序3电极配置=0x0C00003001 04 - 01|程序4编号=P401 01 - 01|程序4是否生效=生效02 0A 00 - 02|程序4脉宽=100µs01 04 - 01|分频=402 C8 00 - 02|程序4幅值=20004 C0 00 00 30 - 04|程序4电极配置=0x300000C000 00 - CRC16(示例)
方向:双向
功能:程控仪按刺激组编号写入该组下的刺激参数
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 刺激组编号 | 01 |
1 | uint8 | 待写入的刺激组编号 |
| 刺激模式 | 01 |
1 | uint8 | 0x01=常规,0x02=Burst,0x03=高频 |
| RampUp时间 | 02 |
2 | uint16 | 单位 1 ms |
| RampDown时间 | 02 |
2 | uint16 | 单位 1 ms |
| 刺激时间 | 04 |
4 | uint32 | 单位 1 s |
| 停止时间 | 04 |
4 | uint32 | 单位 1 s |
| 程序组频率 | 02 |
2 | uint16 | 组级频率,单位 0.1 Hz |
| 程序数量 | 01 |
1 | uint8 | 固定写入 0x04,表示该组下 P1-P4 |
| 程序1编号 | 01 |
1 | uint8 | P1 |
| 程序1是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序1脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序1分频 | 01 |
1 | uint8 | 分频值 |
| 程序1幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序1电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序2编号 | 01 |
1 | uint8 | P2 |
| 程序2是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序2脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序2分频 | 01 |
1 | uint8 | 分频值 |
| 程序2幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序2电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序3编号 | 01 |
1 | uint8 | P3 |
| 程序3是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序3脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序3分频 | 01 |
1 | uint8 | 分频值 |
| 程序3幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序3电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
| 程序4编号 | 01 |
1 | uint8 | P4 |
| 程序4是否生效 | 01 |
1 | uint8 | 0x00=未生效,0x01=生效 |
| 程序4脉宽 | 02 |
2 | uint16 | 单位 10 µs |
| 程序4分频 | 01 |
1 | uint8 | 分频值 |
| 程序4幅值 | 02 |
2 | uint16 | 单位 0.01 mA |
| 程序4电极配置 | 04 |
4 | uint32 | 高 16 位阳极,低 16 位阴极 |
请求Payload总长度:可变,结构与 0x0020 的响应一致
响应:成功返回ACK(0x00F0),失败返回NACK(0x00F1)
请求(0x0021):
AA 01 00 14 00 00 00 21 00 7F 0001 03 - 01|刺激组编号=301 01 - 01|刺激模式=常规02 E8 03 - 02|RampUp时间=1000ms02 E8 03 - 02|RampDown时间=1000ms04 3C 00 00 00 - 04|刺激时间=60s04 1E 00 00 00 - 04|停止时间=30s02 F4 01 - 02|程序组频率=500 (50.0Hz)01 04 - 01|程序数量=401 01 - 01|程序1编号=P101 01 - 01|程序1是否生效=生效02 14 00 - 02|程序1脉宽=200µs01 0A - 01|分频=1002 F4 01 - 02|程序1幅值=50004 03 00 00 01 - 04|程序1电极配置=0x0100000301 02 - 01|程序2编号=P201 01 - 01|程序2是否生效=生效02 12 00 - 02|程序2脉宽=180µs01 08 - 01|分频=802 90 01 - 02|程序2幅值=40004 0C 00 00 03 - 04|程序2电极配置=0x0300000C01 03 - 01|程序3编号=P301 01 - 01|程序3是否生效=生效02 0E 00 - 02|程序3脉宽=140µs01 06 - 01|分频=602 2C 01 - 02|程序3幅值=30004 30 00 00 0C - 04|程序3电极配置=0x0C00003001 04 - 01|程序4编号=P401 01 - 01|程序4是否生效=生效02 0A 00 - 02|程序4脉宽=100µs01 04 - 01|分频=402 C8 00 - 02|程序4幅值=20004 C0 00 00 30 - 04|程序4电极配置=0x300000C000 00 - CRC16(示例)
响应(成功,ACK帧):
AA 01 00 15 00 01 00 F0 00 17 0002 21 00 - 02|原命令码=0x002101 00 - 01|结果码=成功04 78 56 34 12 - 04|时间戳00 00 - CRC16(示例)
单程序写入通用规则(适用于 0x0022 ~ 0x0024):
- 请求中均需携带 刺激组编号 + P程序编号
- 请求中均需携带 是否生效
- 是否生效 的判定仅取决于该程序的电极配置是否同时包含至少 1 个正极和至少 1 个负极
- 只要满足上述条件,当前程序即为生效状态
- 不满足上述条件时,当前程序为未生效状态
用途:写入单个 P 程序的常规(Tonic)模式参数
摘要:方向 = 程控仪 → IPG | 类型 = 单程序参数写入 | 响应 = ACK / NACK
接收方根据 OPCODE = 0x0022 将指定 P 程序设置为常规模式参数。
| 字段 | 长度 | 类型 | 取值 / 单位 | 说明 |
|---|---|---|---|---|
| 刺激组编号 | LV(1) |
uint8 | 1-8 | 所属刺激组编号 |
| P程序编号 | LV(1) |
uint8 | 1-4 | 所属程序编号 |
| 是否生效 | LV(1) |
uint8 | 0x00/0x01 | 0x00=未生效,0x01=生效 |
| 分频 | LV(1) |
uint8 | 1-20 | 程序组频率的分频数 |
| 脉宽 | LV(2) |
uint16 | 20-1000,单位 10 µs |
默认 60 µs |
| 幅值 | LV(2) |
uint16 | 0-25500,单位 0.01 mA |
默认 0 mA |
| 相间间隔 | LV(2) |
uint16 | 0-200,单位 5 µs |
默认 60 µs |
| 电极配置 | LV(4) |
uint32 | bitmap | 高 16 位阳极,低 16 位阴极 |
| 保留 | LV(0) |
- | - | 无保留字段 |
请求总长度:8 个长度前缀 8 B + 字段值 14 B + 保留长度字段 1 B = 23 B
场景:写入刺激组 G3 的 P1,分频10,脉宽200 µs,幅值5.00 mA,相间间隔60×5µs,电极配置阳极E8阴极E0+E1
AA 01 00 0A 00 00 00 22 00 24 0001 03 - 01|刺激组编号=301 01 - 01|P程序编号=101 01 - 01|是否生效=生效01 0A - 01|分频=1002 14 00 - 02|脉宽=200µs(小端序)02 F4 01 - 02|幅值=500 (5.00mA, 小端序)02 3C 00 - 02|相间间隔=60×5µs(小端序)04 03 00 00 01 - 04|电极配置=0x01000003(小端序)00 - 保留(长度0)55 27 - CRC16(小端序)
用途:写入单个 P 程序的 Burst 模式参数
摘要:方向 = 程控仪 → IPG | 类型 = 单程序参数写入 | 响应 = ACK / NACK
接收方根据 OPCODE = 0x0023 将指定 P 程序设置为 Burst 模式参数。
| 字段 | 长度 | 类型 | 取值 / 单位 | 说明 |
|---|---|---|---|---|
| 刺激组编号 | LV(1) |
uint8 | 1-8 | 所属刺激组编号 |
| P程序编号 | LV(1) |
uint8 | 1-4 | 所属程序编号 |
| 是否生效 | LV(1) |
uint8 | 0x00/0x01 | 0x00=未生效,0x01=生效 |
| 簇内频率 | LV(2) |
uint16 | 250-1000,单位 10 Hz |
默认 500 Hz |
| 簇间频率 | LV(2) |
uint16 | 10-100,单位 10 Hz |
Burst 重复频率 |
| 簇内脉冲数 | LV(1) |
uint8 | 1-10 | 默认 5 |
| 脉宽 | LV(2) |
uint16 | 20-1000,单位 10 µs |
默认 130 µs |
| 相间间隔 | LV(2) |
uint16 | 0-200,单位 5 µs |
默认 60 µs |
| 幅值 | LV(2) |
uint16 | 0-25500,单位 0.01 mA |
恒流幅值 |
| 电极配置 | LV(4) |
uint32 | bitmap | 高 16 位阳极,低 16 位阴极 |
| 保留 | LV(0) |
- | - | 无保留字段 |
请求总长度:10 个长度前缀 10 B + 字段值 19 B + 保留长度字段 1 B = 30 B
场景:写入刺激组 G3 的 P2,簇内频率500Hz,簇间频率40Hz,5脉冲/Burst,脉宽350µs,幅值3.50mA
AA 01 00 0B 00 00 00 23 00 2B 0001 03 - 01|刺激组编号=301 02 - 01|P程序编号=201 01 - 01|是否生效=生效02 32 00 - 02|簇内频率=50 (500Hz, 小端序)02 04 00 - 02|簇间频率=4 (40Hz, 小端序)01 05 - 01|簇内脉冲数=502 23 00 - 02|脉宽=35 (350µs, 小端序)02 3C 00 - 02|相间间隔=60 (小端序)02 5E 01 - 02|幅值=350 (3.50mA, 小端序)04 03 00 00 01 - 04|电极配置=0x01000003(小端序)00 - 保留(长度0)BB 42 - CRC16(小端序)
用途:写入单个 P 程序的高频模式参数
摘要:方向 = 程控仪 → IPG | 类型 = 单程序参数写入 | 响应 = ACK / NACK
接收方根据 OPCODE = 0x0024 将指定 P 程序设置为高频模式参数。
| 字段 | 长度 | 类型 | 取值 / 单位 | 说明 |
|---|---|---|---|---|
| 刺激组编号 | LV(1) |
uint8 | 1-8 | 所属刺激组编号 |
| P程序编号 | LV(1) |
uint8 | 1-4 | 所属程序编号 |
| 是否生效 | LV(1) |
uint8 | 0x00/0x01 | 0x00=未生效,0x01=生效 |
| 脉宽 | LV(1) |
uint8 | 固定 30,单位 30 µs |
窄脉冲宽度 |
| 幅值 | LV(2) |
uint16 | 0-25500,单位 0.01 mA |
最大 25.5 mA |
| 电极配置 | LV(4) |
uint32 | bitmap | 高 16 位阳极,低 16 位阴极 |
| 占空比 | LV(1) |
uint8 | 10-100,单位 1 % |
100% 表示持续输出 |
| 周期时长 | LV(4) |
uint32 | 1-86400,单位 1 s |
单个占空比周期总时长 |
| 保留 | LV(0) |
- | - | 无保留字段 |
请求总长度:9 个长度前缀 9 B + 字段值 15 B + 保留长度字段 1 B = 25 B
场景:写入刺激组 G3 的 P4,脉宽30 µs,幅值2.00 mA,占空比50%,周期60 s
AA 01 00 0C 00 00 00 24 00 26 0001 03 - 01|刺激组编号=301 04 - 01|P程序编号=401 01 - 01|是否生效=生效01 1E - 01|脉宽=30µs02 C8 00 - 02|幅值=200 (2.00mA, 小端序)04 03 00 00 01 - 04|电极配置=0x01000003(小端序)01 32 - 01|占空比=50%04 3C 00 00 00 - 04|周期时长=60s(小端序)00 - 保留(长度0)C6 84 - CRC16(小端序)
用途:治疗过程中对程序组参数或单个 P 程序参数进行微调
摘要:方向 = 双向 | 类型 = 参数微调 | 典型响应 =
Indicate
| 字段 | 长度 | 类型 | 取值 / 单位 | 说明 |
|---|---|---|---|---|
| 刺激组编号 | LV(1) |
uint8 | 1-8 | 待调整参数所属刺激组编号 |
| P程序编号 | LV(1) |
uint8 | 0-4 | 程序组参数调整时填 0x00;P 程序参数调整时填 1-4 |
| 参数ID | LV(1) |
uint8 | 见下表 | 待调整的参数标识符 |
| 新值 | LV(N) |
与参数类型一致 | 小端序 | 参数的新值 |
请求总长度:1+1 + 1+1 + 1+1 + 1+N = 7+N B
| 字段 | 长度 | 类型 | 取值 / 单位 | 说明 |
|---|---|---|---|---|
| 刺激组编号 | LV(1) |
uint8 | 与请求一致 | 刺激组编号回显 |
| P程序编号 | LV(1) |
uint8 | 与请求一致 | 程序组参数调整时回显 0x00 |
| 结果码 | LV(1) |
uint8 | 0x00/0x01/0x02/0x03 |
成功 / 参数无效 / 模式不匹配 / 幅值步进超限 |
| 参数ID | LV(1) |
uint8 | 与请求一致 | 参数回显 |
| 生效值 | LV(N) |
与参数类型一致 | 小端序 | 调整后的实际生效值 |
响应总长度:1+1 + 1+1 + 1+1 + 1+1 + 1+N = 8+N B
| ID | 参数名称 | 值类型 | 适用模式 | 范围 | 说明 |
|---|---|---|---|---|---|
0x01 |
RampUp/RampDown | uint16 + uint16 |
组参数 | 单位 1 ms |
先 RampUp,后 RampDown |
0x02 |
刺激时间/停止时间 | uint32 + uint32 |
组参数 | 单位 1 s |
先刺激时间,后停止时间 |
0x03 |
程序组频率 | uint16 | 组参数 | 见组参数定义 | 单位 0.1 Hz |
0x11 |
脉宽 | uint16 | Normal / Burst / HF | 见对应模式定义 | 单位与对应写入指令一致 |
0x12 |
分频 | uint8 | Normal | 1-20 | - |
0x13 |
幅值 | uint16 | Normal / Burst / HF | 见各模式 _AMP_MIN/_MAX |
单步增量 ≤ 0.50 mA(C-03) |
0x14 |
电极配置 | uint32 | Normal / Burst / HF | bitmap | 高 16 位阳极,低 16 位阴极 |
0x15 |
相间间隔 | uint16 | Normal / Burst | 0-200 (5 µs) |
- |
0x16 |
簇内频率 | uint16 | Burst | 250-1000 (10 Hz) |
- |
0x17 |
簇间频率 | uint16 | Burst | 10-100 (10 Hz) |
- |
0x18 |
簇内脉冲数 | uint8 | Burst | 1-10 | - |
0x19 |
占空比 | uint8 | HF | 10-100% | - |
0x1A |
周期时长 | uint32 | HF | 1-86400 s | - |
规则
- 请求建议使用 Write Without Response,以降低治疗中调参延迟
- 响应建议通过 Indicate 返回,避免一次额外 ATT 确认
- 程序组参数调整时,仅需携带刺激组编号,P程序编号固定填0x00
- P 程序参数调整时,必须携带刺激组编号 + P程序编号
-RampUp/RampDown必须成对调整
-刺激时间/停止时间必须成对调整
- 仅校验当前参数的独立范围,不做全量交叉校验
-0x0022~0x0024仍保留用于首次设置和模式切换
- 幅值调整(C-03):单次调整的幅值变化绝对值不得超过50(0.01 mA单位,即0.50 mA)
示例1:调整刺激组 G3 的 RampUp/RampDown
AA 01 00 0D 00 00 00 26 00 11 0001 03 - 01|刺激组编号=301 00 - 01|P程序编号=001 01 - 01|参数ID=0x01(RampUp/RampDown)04 F4 01 20 03 - 04|RampUp=500ms, RampDown=800ms00 00 - CRC16(示例)
示例2:调整刺激组 G3 的循环参数
AA 01 00 0E 00 00 00 26 00 15 0001 03 - 01|刺激组编号=301 00 - 01|P程序编号=001 02 - 01|参数ID=0x02(刺激时间/停止时间)08 3C 00 00 00 1E 00 00 00 - 08|刺激时间=60s, 停止时间=30s00 00 - CRC16(示例)
示例3:调整刺激组 G3 的程序组频率
AA 01 00 0F 00 00 00 26 00 10 0001 03 - 01|刺激组编号=301 00 - 01|P程序编号=001 03 - 01|参数ID=0x03(程序组频率)02 F4 01 - 02|程序组频率=500 (50.0Hz)00 00 - CRC16(示例)
示例4:调整刺激组 G3 的 P1 幅值
AA 01 00 10 00 00 00 26 00 0D 0001 03 - 01|刺激组编号=301 01 - 01|P程序编号=101 13 - 01|参数ID=0x13(幅值)02 26 02 - 02|幅值=550 (5.50mA)00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪启动当前已配置模式的刺激输出,IPG返回启动结果
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 程序组编号 | 01 |
1 | uint8 | 1-8 | 待启动的程序组编号 |
请求Payload总长度:1+1 = 2字节
说明:IPG应先校验指定程序组的参数完整性后再执行
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 结果码 | 01 |
1 | uint8 | 0x00=成功,其他=错误码 |
| 当前模式 | 01 |
1 | uint8 | 0x01=常规,0x02=Burst,0x03=高频 |
响应Payload总长度:1+1 + 1+1 = 4字节
场景:启动程序组 3,当前模式为常规模式
请求(0x0030):
AA 01 00 20 00 00 00 30 00 0F 0001 03 - 01|程序组编号=300 00 - CRC16(示例)
响应(0x0030):
AA 01 00 21 00 01 00 30 00 11 0001 00 - 01|结果码=成功01 01 - 01|当前模式=常规00 00 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪停止刺激输出,支持正常停止和紧急停止
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 程序组编号 | 01 |
1 | uint8 | 1-8 或 0xFF | 待停止的程序组编号,0xFF=停止所有 |
| 停止方式 | 01 |
1 | uint8 | 0x01/0x02 | 0x01=正常斜坡停止,0x02=紧急停止 |
请求Payload总长度:1+1 + 1+1 = 4字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 结果码 | 01 |
1 | uint8 | 0x00=成功,其他=错误码 |
| 停止方式 | 01 |
1 | uint8 | 与请求一致 |
| 数据长度 | 01 |
1 | uint8 | 后续停止结果数据长度 |
| 停止结果数据 | len |
N | bytes | 按停止方式返回不同字段 |
停止结果数据定义:
- 当 停止方式=0x01(正常停止):
- 累计刺激时长:04 + uint32,单位秒,本次刺激的总时长
- 当 停止方式=0x02(紧急停止):
- 停止时间戳:04 + uint32,停止时的系统时间戳
- 停止前状态:01 + uint8,停止前的刺激状态
- 停止前幅值:02 + uint16,停止前的刺激幅值,单位0.01 mA
响应Payload总长度:可变,按停止方式和返回数据确定
场景:停止程序组 3,本次累计刺激时长 120 秒
请求(0x0032):
AA 01 00 22 00 00 00 32 00 11 0001 03 - 01|程序组编号=301 01 - 01|停止方式=正常斜坡停止00 00 - CRC16(示例)
响应(0x0032):
AA 01 00 23 00 01 00 32 00 17 0001 00 - 01|结果码=成功01 01 - 01|停止方式=正常斜坡停止05 - 05|停止结果数据长度=504 78 00 00 00 - 04|累计刺激时长=120秒00 00 - CRC16(示例)
方向:IPG → 程控仪
功能:IPG通过 Notify 主动上报安全相关告警,仅包含以下 3 类:低电量、阻抗异常、刺激异常停止
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 告警类型 | 01 |
1 | uint8 | 见告警类型表 |
| 程序组编号 | 01 |
1 | uint8 | 相关程序组编号;无关时填 0x00 |
| 附加信息 | 02 |
2 | uint16 | 与告警类型相关的附加值(小端序) |
| 时间戳 | 04 |
4 | uint32 | 告警产生时间戳(小端序) |
Payload总长度:1+1 + 1+1 + 1+2 + 1+4 = 12字节
告警类型:
| 值 | 名称 | 附加信息定义 |
|---|---|---|
0x01 |
低电量 | 当前电量百分比(0-100) |
0x02 |
阻抗异常 | 异常通道编号 / 电极编号 |
0x03 |
刺激异常停止 | 停止原因码 |
刺激异常停止原因码:
| 值 | 描述 |
|---|---|
0x0001 |
电量不足导致停止 |
0x0002 |
阻抗异常导致停止 |
0x0003 |
过温导致停止 |
0x0004 |
过流导致停止 |
0x00FF |
其他内部故障 |
说明:
- 该指令仅通过 Device Notify 上报,不要求 ACK
- 低电量建议在电量 <20% 时上报一次,进入 <10% 时再次上报
- 阻抗异常在检测到异常时立即上报
- 刺激异常停止在输出被非正常中断时立即上报
场景1:低电量告警,当前电量 9%
AA 01 00 30 00 01 00 36 00 19 0001 01 - 01|告警类型=低电量01 00 - 01|程序组编号=0x0002 09 00 - 02|附加信息=9%04 78 56 34 12 - 04|时间戳5A C3 - CRC16(示例)
场景2:程序组 3 发生刺激异常停止,原因=阻抗异常
AA 01 00 31 00 01 00 36 00 19 0001 03 - 01|告警类型=刺激异常停止01 03 - 01|程序组编号=302 02 00 - 02|附加信息=停止原因码0x000204 79 56 34 12 - 04|时间戳6B D4 - CRC16(示例)
方向:双向(请求与响应使用同一命令码)
功能:程控仪发起全阻抗测量,IPG返回各通道阻抗值及状态
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 参考电极编号 | 01 |
1 | uint8 | 1-16 | 参考电极触点编号 |
| 测量幅度 | 02 |
2 | uint16 | 20/50/100/200 | 单位0.01 mA |
| 测量脉宽 | 02 |
2 | uint16 | 20-1000 | 单位 µs |
| 测量频率 | 02 |
2 | uint16 | 1-1000 | 单位0.1 Hz |
| (保留) | 00 |
0 | - | - | 无保留字段 |
请求Payload总长度:1+1 + 1+2 + 1+2 + 1+2 + 1 = 12字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 通道数量 | 01 |
1 | uint8 | 1-16 | 本次测量的通道总数 |
| 通道1电极编号 | 01 |
1 | uint8 | 1-16 | 第1个通道的触点编号 |
| 通道1阻抗值 | 04 |
4 | uint32 | 0-99999 | 单位1 Ω(小端序) |
| 通道1状态 | 01 |
1 | uint8 | 见状态表 | 通道状态标志 |
| ... | ... | ... | ... | ... | 每个额外通道重复6字节值 |
响应Payload总长度:1+1 + N×(1+1+1+4+1) = 2 + N×7 字节
注意:每个通道的三个子字段(电极编号、阻抗值、状态)各带独立长度前缀。
通道状态标志:
| 值 | 描述 |
|---|---|
| 0x00 | 正常(100 Ω ≤ Z ≤ 10000 Ω) |
| 0x01 | 电极短路(Z < 100 Ω) |
| 0x02 | 电极故障/开路(Z > 10000 Ω) |
| 0x03 | 测量超时 |
| 0xFF | 测量失败(未知错误) |
方向:双向(请求与响应使用同一命令码)
功能:程控仪发起指定程序组的阻抗测量,IPG返回测量结果
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 程序组编号 | 01 |
1 | uint8 | 1-8 | 待测量的程序组编号 |
| 幅度组 | len |
1-8 | uint16 × N | 最多4个幅值,单位0.01 mA,按小端序连续排列 | |
| 脉宽组 | len |
1-8 | uint16 × N | 最多4个脉宽值,单位 µs,按小端序连续排列 | |
| 测量频率 | 02 |
2 | uint16 | 1-1000 | 单位0.1 Hz |
| (保留) | 00 |
0 | - | - | 无保留字段 |
请求Payload总长度:可变,1+1 + 1+N1 + 1+N2 + 1+2 + 1,其中 N1/N2 最大均为 8 字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 程序组编号 | 01 |
1 | uint8 | 1-8 | 被测量的程序组编号 |
| 测量幅度 | 02 |
2 | uint16 | - | 实际使用的测量幅度,单位0.01 mA |
| 测量脉宽 | 02 |
2 | uint16 | - | 实际使用的测量脉宽,单位µs |
| 测量频率 | 02 |
2 | uint16 | - | 实际使用的测量频率,单位0.1 Hz |
| 通道数量 | 01 |
1 | uint8 | 1-16 | 本次测量的通道总数 |
| 通道1电极编号 | 01 |
1 | uint8 | 1-16 | 第1个通道的触点编号 |
| 通道1阻抗值 | 04 |
4 | uint32 | 0-99999 | 单位1 Ω(小端序) |
| 通道1状态 | 01 |
1 | uint8 | 见状态表 | 通道状态标志 |
| ... | ... | ... | ... | ... | 每个额外通道重复6字节值 |
响应Payload总长度:5个长度前缀(5) + 标头值(8) + N×(3个长度前缀 + 6字节值) = 13 + N×9 字节
通道状态标志:同0x0040。
示例:
程序组3,使用幅度1.0 mA、脉宽200 µs、频率50 Hz,测量3个通道(E0=1250Ω正常,E1=1180Ω正常,E8=1320Ω正常)
Payload(十六进制,小端序):
01 03 - 01|程序组编号=302 64 00 - 02|测量幅度=100 (1.0mA, LE)02 C8 00 - 02|测量脉宽=200 (LE)02 F4 01 - 02|测量频率=500 (50.0Hz, LE)01 03 - 01|通道数量=301 01 04 E2 04 00 00 01 00 - 01|E0 + 04|1250Ω(LE) + 01|正常01 02 04 9C 04 00 00 01 00 - 01|E1 + 04|1180Ω(LE) + 01|正常01 09 04 28 05 00 00 01 00 - 01|E8 + 04|1320Ω(LE) + 01|正常
请求(0x0042):
AA 01 00 15 00 00 00 42 00 10 00 01 03 00 6A 6A
字段解析:
AA - 帧头01 - 协议版本00 - 帧标志=0x00(明文帧)15 00 - 帧序号=21(小端序)00 - 发送方角色=0x00(主机)00 - 接收方角色=0x00(主机)42 00 - 命令码=0x0042(小端序)10 00 - 数据长度=16(总帧长,小端序;11帧头+3Payload+2CRC)01 03 - 01|程序组编号=300 - 保留(长度0)6A 6A - CRC16(小端序)
响应(0x0042):
AA 01 00 16 00 00 00 42 00 35 0001 03 - 01|程序组编号=302 64 00 - 02|测量幅度=100 (1.0mA, 小端序)02 C8 00 - 02|测量脉宽=200µs(小端序)02 F4 01 - 02|测量频率=500 (50.0Hz, 小端序)01 03 - 01|通道数量=301 01 - 01|E004 E2 04 00 00 - 04|1250Ω(小端序)01 00 - 01|正常01 02 - 01|E104 9C 04 00 00 - 04|1180Ω(小端序)01 00 - 01|正常01 09 - 01|E804 28 05 00 00 - 04|1320Ω(小端序)01 00 - 01|正常04 E3 - CRC16(小端序)
方向:程控仪 → IPG
功能:请求IPG进入OTA升级模式
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 目标固件版本 | 04 |
4 | uint32 | 目标固件版本号 |
| 固件包总大小 | 04 |
4 | uint32 | 固件包总字节数 |
| SHA-256摘要 | 20 |
32 | bytes | 固件包SHA-256校验值 |
Payload总长度:3+4+4+32 = 43字节(原40字节)
方向:程控仪 → IPG
功能:传输OTA固件数据块
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 块序号 | 02 |
2 | uint16 | 数据块序号(小端序) |
| 块数据 | len |
N | bytes | 固件数据 |
Payload总长度:1+2 + 1+N = 4+N 字节(原2+N字节)
方向:双向(请求与响应使用同一命令码)
功能:全部数据块传输完成后,程控仪请求IPG执行完整性校验,IPG返校验结果
请求Payload(程控仪 → 从设备):无(协议框架层拒绝LEN=0空帧,发送方应填充1字节保留字段00)
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 结果码 | 01 |
1 | uint8 | 0x00=校验成功,其他=错误码 |
| 接收块总数 | 02 |
2 | uint16 | IPG实际接收的数据块总数(小端序) |
| 计算SHA-256 | 20 |
32 | bytes | IPG计算的固件包SHA-256值 |
| 固件大小 | 04 |
4 | uint32 | IPG接收的固件总字节数(小端序) |
| 预计重启时间 | 02 |
2 | uint16 | 单位秒,预计重启所需时间(小端序) |
响应Payload总长度:5个长度前缀(5) + 1+2+32+4+2 = 47字节
请求(0x0052):
AA 01 00 20 00 00 00 52 00 0D 00 F6 26
字段解析:
AA - 帧头01 - 协议版本00 - 帧标志=0x00(明文帧)20 00 - 帧序号=32(小端序)00 - 发送方角色=0x00(主机)00 - 接收方角色=0x00(主机)52 00 - 命令码=0x0052(小端序)0D 00 - 数据长度=13(总帧长,小端序)F6 26 - CRC16(小端序)
响应(0x0052):
AA 01 00 21 00 00 00 52 00 33 0001 00 - 01|结果码=成功02 2C 01 - 02|接收块总数=300(小端序)20 - 20|SHA256长度=32A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 - SHA-256值(32字节)04 40 E2 01 00 - 04|固件大小=123456(小端序)02 0A 00 - 02|预计重启时间=10秒(小端序)16 62 - CRC16(小端序)
方向:IPG → 程控仪
功能:OTA传输过程中,IPG主动上报传输进度
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 已接收块数 | 02 |
2 | uint16 | 已成功接收的数据块数量(小端序) |
| 总块数 | 02 |
2 | uint16 | 固件包总数据块数量(小端序) |
| 进度百分比 | 01 |
1 | uint8 | 0-100,传输进度百分比 |
| 最后接收块序号 | 02 |
2 | uint16 | 最后成功接收的块序号(小端序) |
| 传输速率 | 02 |
2 | uint16 | 单位字节/秒(小端序) |
Payload总长度:5个长度前缀(5) + 2+2+1+2+2 = 14字节(原9字节)
方向:双向(请求与响应使用同一命令码)
功能:程控仪读取历史刺激记录摘要,IPG返回历史记录
请求Payload(程控仪 → 从设备):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 起始索引 | 02 |
2 | uint16 | 0-65535 | 请求的起始记录索引(小端序) |
| 请求条数 | 01 |
1 | uint8 | 1-20 | 请求返回的记录条数 |
| (保留) | 00 |
0 | - | - | 无保留字段 |
请求Payload总长度:1+2 + 1+1 + 1 = 6字节
响应Payload(从设备 → 程控仪):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 总记录数 | 02 |
2 | uint16 | IPG存储的历史记录总数(小端序) |
| 返回记录数 | 01 |
1 | uint8 | 本次返回的记录条数 |
| 记录1-时间戳 | 04 |
4 | uint32 | 刺激开始时间戳(小端序) |
| 记录1-模式 | 01 |
1 | uint8 | 刺激模式 |
| 记录1-持续时长 | 04 |
4 | uint32 | 单位秒(小端序) |
| 记录1-平均幅值 | 02 |
2 | uint16 | 单位0.01 mA(小端序) |
| 记录1-停止原因 | 01 |
1 | uint8 | 0x01=正常停止,0x02=紧急停止,0x03=异常断连 |
| ... | ... | ... | ... | 每条额外记录重复12字节值 |
响应Payload总长度:2个长度前缀(2) + 2+1 + N×(5个长度前缀(5) + 12) = 5 + N×17 字节
方向:程控仪 → IPG
功能:启动生理信号采集
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 采集通道 | 01 |
1 | uint8 | 1-8 | 采集通道编号 |
| 采样率 | 02 |
2 | uint16 | 100-10000 | 单位Hz(小端序) |
| 采集时长 | 02 |
2 | uint16 | 1-3600 | 单位秒,0=持续采集(小端序) |
| 增益 | 01 |
1 | uint8 | 1/2/4/8 | 信号放大增益倍数 |
| 滤波模式 | 01 |
1 | uint8 | 见模式表 | 滤波器配置 |
| (保留) | 00 |
0 | - | - | 无保留字段 |
Payload总长度:5个长度前缀(5) + 1+2+2+1+1 + 1 = 13字节(原8字节)
滤波模式:
| 值 | 描述 |
|---|---|
| 0x00 | 无滤波 |
| 0x01 | 50Hz陷波(工频滤波) |
| 0x02 | 60Hz陷波 |
| 0x03 | 带通滤波(0.5-100Hz) |
| 0x04 | 高通滤波(>0.5Hz) |
方向:IPG → 程控仪
功能:返回采集的生理信号数据
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 采集通道 | 01 |
1 | uint8 | 采集通道编号 |
| 时间戳 | 04 |
4 | uint32 | 数据包时间戳(小端序) |
| 采样率 | 02 |
2 | uint16 | 实际采样率,单位Hz(小端序) |
| 数据点数 | 01 |
1 | uint8 | 本包包含的数据点数量(1-50) |
| 数据1 | 02 |
2 | int16 | 第1个采样点,单位µV(小端序) |
| 数据2 | 02 |
2 | int16 | 第2个采样点,单位µV(小端序) |
| ... | ... | ... | ... | 每个额外数据点2字节 |
Payload总长度:4个长度前缀(4) + 1+4+2+1 + N×(1+2) = 10 + N×3 字节(原8+N×2字节)
方向:程控仪 → IPG
功能:停止正在进行的信号采集
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 采集通道 | 01 |
1 | uint8 | 1-8 或 0xFF | 待停止的通道编号,0xFF=停止所有 |
Payload总长度:1+1 = 2字节
方向:程控仪 → IPG
功能:下发完整的定时治疗方案配置(1-16个方案)
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 方案总数 | 01 |
1 | uint8 | 1-16 | 本次下发的治疗方案数量 |
| 方案1-程序组编号 | 01 |
1 | uint8 | 1-16 | 绑定的刺激程序组编号 |
| 方案1-开启时刻 | 01 |
1 | uint8 | 0-47 | ON时刻,单位0.5小时 |
| 方案1-停止时刻 | 01 |
1 | uint8 | 1-48 | OFF时刻,单位0.5小时 |
| (方案1-保留) | 00 |
0 | - | - | 无保留字段 |
| ... | ... | ... | ... | ... | 每个额外方案重复 |
Payload总长度:1+1 + N×(3个长度前缀(3) + 3) + N×1 = 2 + N×7 字节(原1+N×4字节)
说明:时刻编码:0=0:00,1=0:30,...,47=23:30,48=24:00
方向:双向(请求与响应使用同一命令码)
功能:程控仪读取IPG当前存储的定时治疗方案
请求Payload(程控仪 → 从设备):无(协议框架层拒绝LEN=0空帧,发送方应填充1字节保留字段00)
响应Payload(从设备 → 程控仪):
Payload格式同0x0070。
方向:程控仪 → IPG
功能:使能或禁用定时治疗功能
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 使能标志 | 01 |
1 | uint8 | 0x00/0x01 | 0x00=禁用,0x01=使能 |
| (保留) | 00 |
0 | - | - | 无保留字段 |
Payload总长度:1+1 + 1 = 3字节(原2字节)
方向:IPG → 程控仪
功能:IPG主动通知当前定时治疗执行状态
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 范围 | 描述 |
|---|---|---|---|---|---|
| 当前执行方案编号 | 01 |
1 | uint8 | 0-8 | 0表示无方案执行中 |
| 执行状态 | 01 |
1 | uint8 | 见状态表 | 当前方案执行状态 |
| 当前程序组编号 | 01 |
1 | uint8 | 1-8 | 当前执行的程序组编号 |
| 剩余时间 | 02 |
2 | uint16 | 0-1440 | 单位分钟(小端序) |
| 定时治疗总使能状态 | 01 |
1 | uint8 | 0x00/0x01 | 功能整体使能状态 |
Payload总长度:5个长度前缀(5) + 1+1+1+2+1 = 11字节(原6字节)
执行状态标志:
| 值 | 描述 |
|---|---|
| 0x00 | 空闲/等待下一个方案 |
| 0x01 | 方案执行中(刺激输出中) |
| 0x02 | 方案斜坡上升中 |
| 0x03 | 方案斜坡下降中 |
| 0x04 | 方案已完成,切换中 |
| 0x05 | 定时治疗已禁用 |
| 0x10 | 错误-绑定的程序组无效 |
| 0x11 | 错误-方案时间冲突 |
| 错误码 | 错误名称 | 严重等级 | 描述 |
|---|---|---|---|
| 0x0101 | CRC校验失败 | 中 | 接收帧的CRC-16/CCITT校验不通过 |
| 0x0102 | 帧序号不连续 | 低 | 接收到的帧序号与预期不一致 |
| 0x0103 | 帧长度异常 | 中 | 帧实际长度与Data Length字段不一致 |
| 0x0104 | 协议版本不匹配 | 高 | 帧头中的协议版本号与IPG不兼容 |
| 0x0105 | 命令码未定义 | 中 | 接收到的命令码不在已定义的命令码表中 |
| 0x0106 | MTU超限/命令过频 | 中 | 报文长度超出MTU或命令间隔<50 ms |
| 0x0107 | 响应超时 | 高 | 程控仪在3000 ms内未收到IPG响应 |
| 错误码 | 错误名称 | 严重等级 | 描述 |
|---|---|---|---|
| 0x0201 | 认证失败 | 高 | Challenge-Response认证不通过 |
| 0x0202 | 会话已过期 | 中 | 会话令牌已超时失效(默认30分钟) |
| 0x0203 | 主机未注册 | 高 | 主机 ECDSA 公钥未在设备端注册,需先执行注册流程 |
| 错误码 | 错误名称 | 严重等级 | 描述 |
|---|---|---|---|
| 0x0301 | 频率超出范围 | 高 | 刺激频率字段值超出当前模式允许的范围 |
| 0x0302 | 脉宽超出范围 | 高 | 脉冲宽度字段值超出当前模式允许的范围 |
| 0x0303 | 幅值超出范围 | 高 | 刺激幅值超出范围或单步增量超过0.50 mA |
| 0x0304 | 电极配置无效 | 高 | 电极bitmap无阳极或无阴极,或阳极阴极位重叠 |
| 0x0305 | 电荷密度超限 | 极高 | 每相电荷密度超过30 µC/cm²安全阈值 |
| 0x0306 | 参数组合不兼容 | 高 | 多个参数之间存在逻辑冲突 |
| 0x0307 | 斜坡时间无效 | 中 | 斜坡时间超出范围或超过刺激时长的一半 |
| 0x0308 | 保留字段非零 | 低 | 保留字段中存在非零字节 |
| 错误码 | 错误名称 | 严重等级 | 描述 |
|---|---|---|---|
| 0x0401 | IPG电池电量不足 | 高 | 电池电量低于10%,无法保障安全刺激输出 |
| 0x0402 | 电极阻抗异常 | 高 | 阻抗测量值超出200-5000 Ω有效范围 |
| 0x0403 | IPG温度过高 | 极高 | IPG内部温度超过安全阈值(41°C) |
| 0x0404 | 刺激输出过流 | 极高 | 刺激输出电流超过硬件安全限值 |
| 0x0405 | 存储空间不足 | 中 | IPG内部Flash存储空间不足 |
| 错误码 | 错误名称 | 严重等级 | 描述 |
|---|---|---|---|
| 0x0501 | 固件包校验失败 | 高 | OTA传输完成后SHA-256校验不通过 |
| 0x0502 | 固件版本不兼容 | 高 | 目标固件版本与当前硬件版本不兼容 |
| 0x0503 | OTA传输中断 | 中 | OTA数据传输过程中连接中断或超时 |
| 编号 | 约束规则 | 计算公式/限值 | 违反错误码 |
|---|---|---|---|
| C-01 | 每相电荷密度限制 | Q/A = (Amplitude × Pulse Width) / 电极面积 ≤ 30 µC/cm² | 0x0305 |
| C-02 | 每相电荷限制 | Q = Amplitude(mA) × Pulse Width(µs) × 10⁻³ ≤ 最大允许电荷 | 0x0305 |
| C-03 | 幅值单步增量限制 | 相邻两次幅值写入的差值 ≤ 0.50 mA | 0x0303 |
| C-04 | 电极阻抗有效范围 | 200-5000 Ω | 0x0402 |
| C-05 | 命令最小间隔 | 相邻两条参数写入命令间隔 ≥ 50 ms | 0x0106 |
| C-06 | 电极配置有效性 | 至少1位阳极和1位阴极置位;阳极与阴极不得重叠 | 0x0304 |
| C-07 | 保留字段校验 | 所有保留字段必须为 0x00(LV格式下不存在即合规) | 0x0308 |
| C-08 | 高频模式幅值上限 | 高频模式下幅值 ≤ 100.00 mA | 0x0303 |
| C-09 | 斜坡时间约束 | 斜坡时间 ≤ 刺激时长 × 0.5 | 0x0307 |
| C-10 | 参数组合兼容性 | Burst模式:簇内频率 > 簇间频率 × 簇内脉冲数 | 0x0306 |
| 参数 | 常规模式 | Burst模式 | 高频模式 | 步进 |
|---|---|---|---|---|
| 频率 | 0.2-120.0 Hz | 簇内:20.0-100.0 Hz,簇间:1.0-10.0 Hz | 1000-10000 Hz | 常规/Burst:0.1 Hz,高频:1 Hz |
| 脉宽 | 20-500 µs | 20-500 µs | 10-100 µs | 1 µs |
| 幅值 | 0-255.00 mA | 0-255.00 mA | 0-100.00 mA | 0.01 mA |
| 斜坡时间 | 0-10000 ms | 0-10000 ms | 不适用 | 1 ms |
| 刺激时长 | 0-86400 s | 0-86400 s | 0-86400 s | 1 s |
| 簇内脉冲数 | 不适用 | 2-10 | 不适用 | 1 |
| 占空比 | 不适用 | 不适用 | 10-100% | 1% |
| 周期时长 | 不适用 | 不适用 | 1-3600 s | 1 s |
方向:IPG → 程控仪
功能:对任何命令的成功确认响应
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 原命令码 | 02 |
2 | uint16 | 被响应的原命令码(小端序) |
| 结果码 | 01 |
1 | uint8 | 0x00=成功 |
| 时间戳 | 04 |
4 | uint32 | IPG处理完成的时间戳(小端序) |
Payload总长度:1+2 + 1+1 + 1+4 = 10字节(原7字节)
方向:IPG → 程控仪
功能:对任何命令的失败/错误响应
Payload格式(LV):
| 字段 | 长度字段 | 值长度 | 类型 | 描述 |
|---|---|---|---|---|
| 原命令码 | 02 |
2 | uint16 | 被响应的原命令码(小端序) |
| 错误码 | 02 |
2 | uint16 | 具体错误码(见错误码表) |
| 错误参数 | 04 |
4 | bytes | 错误相关的附加信息 |
| 时间戳 | 04 |
4 | uint32 | IPG检测到错误的时间戳(小端序) |
Payload总长度:4个长度前缀(4) + 2+2+4+4 = 16字节(原12字节)
错误参数说明:
- 对于参数错误(0x03xx),错误参数字段包含:
- Byte 0-1:错误参数的偏移位置(小端序)
- Byte 2-3:错误参数的实际值(小端序)
- 对于其他错误,错误参数字段为0x00000000
IPG支持最多16个电极触点(E0-E15),电极配置字段(uint32)中:
- 高16位:阳极配置
- 低16位:阴极配置
| 电极编号 | 物理触点 | 阴极位(低16位) | 阳极位(高16位) |
|---|---|---|---|
| E0 | 触点1 | Bit 0 | Bit 16 |
| E1 | 触点2 | Bit 1 | Bit 17 |
| E2 | 触点3 | Bit 2 | Bit 18 |
| E3 | 触点4 | Bit 3 | Bit 19 |
| E4 | 触点5 | Bit 4 | Bit 20 |
| E5 | 触点6 | Bit 5 | Bit 21 |
| E6 | 触点7 | Bit 6 | Bit 22 |
| E7 | 触点8 | Bit 7 | Bit 23 |
| E8 | 触点9 | Bit 8 | Bit 24 |
| E9 | 触点10 | Bit 9 | Bit 25 |
| E10 | 触点11 | Bit 10 | Bit 26 |
| E11 | 触点12 | Bit 11 | Bit 27 |
| E12 | 触点13 | Bit 12 | Bit 28 |
| E13 | 触点14 | Bit 13 | Bit 29 |
| E14 | 触点15 | Bit 14 | Bit 30 |
| E15 | 触点16 | Bit 15 | Bit 31 |
示例:
- 阴极设为E0+E1,阳极设为E8
- 阳极高16位 = 0x0100(Bit 24)
- 阴极低16位 = 0x0003(Bit 0 + Bit 1)
- uint32值 = 0x01000003
| 参数 | 值 |
|---|---|
| 算法名称 | CRC-16/CCITT-FALSE |
| 生成多项式 | 0x1021 |
| 初始值 | 0xFFFF |
| 输入反转 | 否 |
| 输出反转 | 否 |
| 最终异或值 | 0x0000 |
CRC覆盖范围(从VER开始到Payload结束。LEN=总帧长, SOF+...+CRC):| SOF(1) | VER(1) | FLAG(1) | SEQ(2) | SRC(1) | DST(1) | OPCODE(2) | LEN(2) | PAYLOAD(N) | CRC16(2) |↑~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~↑CRC计算从VER字节开始,到Payload最后一个字节结束跳过:SOF(1字节) 和 CRC自身(2字节)
CRC16校验值以小端序存储在帧尾。
示例:CRC值 0x1109存储为:09 11(低字节在前)
FUNCTION crc16_ccitt(data: BYTE[], length: INTEGER) -> UINT16crc ← 0xFFFFFOR i ← 0 TO length - 1crc ← crc XOR (data[i] LEFT_SHIFT 8)FOR j ← 0 TO 7IF (crc AND 0x8000) ≠ 0 THENcrc ← (crc LEFT_SHIFT 1) XOR 0x1021ELSEcrc ← crc LEFT_SHIFT 1END IFEND FORcrc ← crc AND 0xFFFFEND FORRETURN crc // 以小端序写入帧尾END FUNCTION
以读取设备配置项请求(0x0011,帧序号5,无Payload)为例:
CRC计算输入(VER + FLAG + SEQ + SRC + DST + OPCODE + LEN):01 - VER00 - FLAG (0x00=明文)05 00 - SEQ (5, 小端序)00 - SRC_ROLE=0x00(主机)00 - DST_ROLE=0x00(主机)11 00 - OPCODE (0x0011, 小端序)0D 00 - LEN (13 = 总帧长: 11帧头 + 0Payload + 2CRC, 小端序)CRC输入字节序列:01 00 05 00 00 00 11 00 0D 00(10字节)CRC计算结果:0xAB39存储到帧尾:39 AB(小端序)
正常启动:
1. 发送启动命令(0x0030)
2. IPG执行前检查(电池、阻抗、温度、参数)
3. 斜坡上升阶段(状态0x02)
4. 稳态刺激阶段(状态0x01)
正常停止:
1. 发送停止命令(0x0032)
2. 斜坡下降阶段(状态0x03)
3. 刺激停止(状态0x00)
紧急停止:
1. 发送停止命令(0x0032,停止方式=紧急停止)
2. 立即停止(50 ms内)
3. 状态上报(状态0x00)
| 参数 | 规定值 | 说明 |
|---|---|---|
| BLE版本 | 5.0+ | 最低支持BLE 5.0,推荐BLE 5.3 |
| 首选PHY | LE 2M PHY | 支持LE 1M PHY回退 |
| 广播间隔 | 20-100 ms | IPG广播间隔,快速发现模式 |
| 连接间隔 | 7.5-30 ms | 由Central在连接时请求协商 |
| 从机延迟 | 0 | 刺激控制场景不允许跳过连接事件 |
| 监督超时 | 2000 ms | 连接丢失判定时间 |
| MTU | ≥ 247字节 | 连接建立后由Central发起MTU Exchange协商 |
| 安全级别 | LE Secure Connections (LESC) | AES-128-CCM加密,Passkey Entry配对(固定PIN码123456) |
| 绑定 | 必须(Required) | 首次配对后保存密钥,后续自动加密重连 |
| 项目 | 说明 |
|---|---|
| LE Secure Connections (LESC) | 必须使用BLE 4.2+ LESC配对机制 |
| 配对方式 | Passkey Entry(固定PIN码123456),提供MITM保护 |
| AES-128-CCM加密 | 所有BLE链路层PDU均使用AES-128-CCM模式加密 |
| Bonding(绑定) | 必须启用,IPG最多存储3组Bond信息 |
| 设备白名单 | IPG维护已授权程控仪的白名单 |
| 项目 | 说明 |
|---|---|
| Challenge-Response认证 | 使用ECDSA P-256签名验证的后续安全认证(详见安全加密扩展文档) |
| 会话令牌 | 认证成功后生成4字节会话令牌,有效期30分钟 |
| 序列号防重放 | 帧序号严格递增,低于当前窗口的帧序号被丢弃 |
| IPG端独立参数校验 | 不依赖程控仪端的校验结果 |
| 看门狗定时器 | 默认15秒,未收到有效帧则启动断连保护流程 |
| 空帧防护 | 帧校验层拒绝LEN=0的空Payload帧,防止空数据恶意轰炸 |
| 项目 | 说明 |
|---|---|
| 双Bank(A/B分区) | OTA数据写入非活跃分区,失败时自动回滚 |
| SHA-256完整性校验 | IPG独立计算SHA-256并比对 |
| 固件签名验证 | 使用ECDSA P-256签名,IPG验证签名有效性 |
| 版本回退防护 | 仅接受版本号高于当前版本的固件 |
文档结束