ch32v307_camera/doc/设计文档/对接集成指南.md
zhoujie b69717b964 📝 docs(design): 新增系统设计文档集
 feat(system-overview): 创建系统总览文档
- 描述项目背景与硬件平台配置
- 提供 FreeRTOS 任务拓扑表(任务优先级、栈大小、职责)
- 详细说明系统启动序列和初始化依赖关系
- 绘制 2D/1D 状态机完整流程图
- 解释 TEMP_REQ 辅助通道工作机制
- 说明任务间同步机制(Frame_Ready_Flag、双缓冲 TX)

 feat(dvp-module-design): 创建 DVP 模块设计文档
- 提供 DVP 硬件连接引脚映射表
- 描述 DVP 时序配置(信号极性、工作模式)
- 解释 DMA ping-pong 行缓冲机制和切换逻辑
- 说明 DVP IRQ 帧组装流程(STR_FRM/ROW_DONE)
- 定义 FrameBuffer 数据格式和像素访问方式
- 说明 TMP 模式温度换算公式和字节序要求

 feat(qdx-protocol-design): 创建 QDX 协议设计文档
- 描述完整 TLV 帧结构(FrameHeader + TLV + CRC)
- 列出所有 Class/Type 映射表和用途说明
- 解释零拷贝 TX 缓冲区架构(HeadOffset 机制)
- 说明分片机制和最大载荷限制
- 定义 Flags 字段各位含义和使用场景

 feat(tcp-module-design): 创建 TCP 通信模块设计文档
- 描述双流连接架构(控制流 5511 / 数据流 5512)
- 说明握手流程和连接建立时序
- 解释心跳机制和 TCP Keepalive 配置
- 描述配置下发与缓存机制
- 说明数据发送队列和背压处理策略
- 解释 WCHNET 网络栈驱动任务工作机制

 feat(integration-guide): 创建对接集成指南
- 提供网络接入参数表(IP、端口、协议)
- 详细说明握手流程和配置下发格式
- 提供 2D/1D 温度帧解析方法和示例代码
- 说明检测结果上报和 NG 响应机制
- 解释 TEMP_REQ 按需截图工作方式
- 列出错误码表和对接故障排查步骤
2026-03-15 19:17:41 +08:00

13 KiB
Raw Blame History

对接集成指南

文档版本1.0 · 日期2026-03-15 · 适用对象ConfigServer 开发方

本文档描述如何对接 CH32V307 红外采集端,内容直接来源于固件代码,无需阅读源码即可完成对接开发。


1. 网络接入参数

1.1 固定参数

参数
MCU IP 192.168.7.10
MCU 子网掩码 255.255.255.0
MCU 网关 192.168.7.1
以太网规格 1000M RGMII标准以太网帧

1.2 服务端监听要求

Server 端需在 192.168.7.50 上监听两个 TCP 端口MCU 主动连入):

端口 用途 连接方向
5511 控制流(握手/配置/心跳) MCU → Server
5512 数据流(温度帧上报) MCU → Server

两个连接均为 MCU 主动发起Server 侧需以 TCP ServerListen模式等待。


2. 握手流程

MCU 上电并完成内部初始化后,按以下顺序建立连接:

1. MCU 建立控制流 TCP 连接Server 5511
        │
        ↓
2. MCU 发送 TYPE_HANDSHAKEClass=CLASS_SYSTEM=0x04
   Value 结构Handshake_t46 字节):
        ├─ ProtocolVersion: uint16_t = 0x0200协议 v2.0
        ├─ DeviceUUID[16]:  6 字节 MAC 地址填入前 6 字节,其余填 0
        ├─ AuthToken[16]:   全零(当前版本不鉴权)
        ├─ HardwareVersion[8]: "CH32V307"(参考)
        └─ FirmwareVersion[8]: 固件版本号
        │
        ↓
3. Server 回复握手响应(同类型或 TYPE_ACK_PAYLOAD
   MCU 收到响应后标记控制流"就绪"
        │
        ↓
4. MCU 建立数据流 TCP 连接Server 5512
        │
        ↓
5. 系统就绪,开始接受配置并上报数据

重要握手完成前MCU 不会上报任何温度帧。如 Server 长时间未收到数据,请检查握手响应是否正确发送。


3. 配置下发

配置通过**控制流5511**发送,支持三种配置类型,可单独或组合发送。

3.1 Config2D — 2D 触发模式配置

帧格式FrameHeaderClass=0x01, Type=0x22+ TLV + Config2D_t

Config2D_t 全字段(按结构体内存顺序,均小端序):

字段 类型 偏移 说明 推荐初始值
Enabled uint8_t 0 1=启用 2D 模式0=禁用 1
IsLive uint8_t 1 保留,填 0 0
DeviceId uint16_t 2 设备 ID 0
Width uint16_t 4 传感器宽度256 256
Height uint16_t 6 传感器高度192 192
Fps uint8_t 8 期望帧率参考值DVP 硬件控制) 25
Exposure uint32_t 9 曝光时间(传感器支持时有效) 0
AutoExposure uint8_t 13 自动曝光0/1 0
MaskEnabled uint8_t 14 掩码使能 0
MaskThreshold int16_t 15 掩码阈值0.1°C/LSB 0
MaskWidth uint16_t 17 掩码宽度 0
MaskHeight uint16_t 19 掩码高度 0
Angle int16_t 21 旋转角度(当前未使用) 0
TargetWidth uint16_t 23 输出 ROI 宽度(像素) 64
TargetHeight uint16_t 25 输出 ROI 高度(像素) 64
TriggerMode uint8_t 27 0=内部温度触发1=外部 GPIO 触发 1
TriggerGpioLine uint8_t 28 外部触发 GPIO 编号参考MCU 固定 PA15 0
TriggerDelayMs uint16_t 29 触发后延迟采集的时间ms 0
TriggerBurstCount uint8_t 31 每次触发连拍帧数 3
TriggerInternalIntervalMs uint16_t 32 连拍帧间隔ms 200
TriggerTemperatureThreshold int16_t 34 内部触发温度阈值0.1°C/LSB800 = 80.0°C 800
TriggerDebounceIntervalMs uint16_t 36 外部触发防抖时间ms 50
TriggerCondition uint8_t 38 内部触发判据:0=ROI 均值1=ROI 最大值 1
TriggerRoiX uint16_t 39 触发检测 ROI 左上角 X 0
TriggerRoiY uint16_t 41 触发检测 ROI 左上角 Y 0
TriggerRoiW uint16_t 43 触发检测 ROI 宽度0=全帧) 256
TriggerRoiH uint16_t 45 触发检测 ROI 高度0=全帧) 192
NGioDelay uint16_t 47 NG 输出 GPIO 脉宽ms 200
OutputGpioLine uint8_t 49 输出 GPIO 编号(固定 PA8 0
AlarmGpioLine uint8_t 50 告警 GPIO当前未使用 0
AlarmHoldMs uint16_t 51 告警持续时间(当前未使用) 0
StoreNgImagesOnly uint8_t 53 仅存储 NG 图像(当前未使用) 0
TrainingEnabled uint8_t 54 训练模式(当前未使用) 0
TrainingSampleThreshold uint16_t 55 训练样本阈值(当前未使用) 0
ProcessingTimeoutMs uint16_t 57 处理超时ms当前未使用 0
MaxProcessingQueueSize uint8_t 59 最大处理队列(当前未使用) 0
Reserved uint8_t 60 保留,填 0 0

3.2 Config1D — 1D 采集模式配置

帧格式FrameHeaderClass=0x01, Type=0x23+ TLV + Config1D_t

Config1D_t 全字段:

字段 类型 偏移 说明 推荐初始值
Enabled uint8_t 0 1=启用 1D 模式0=禁用 0
RunMode uint8_t 1 0=停止采集1=运行 1
TriggerType uint8_t 2 1=内部连续热帧2=外部PA15 GPIO 1
BufferSize uint16_t 3 采集缓冲区大小(样本数,最大 512 200
TriggerTempLimit int16_t 5 触发温度阈值0.1°C/LSB 500
StartPointsToRemove uint16_t 7 保留 0
ReferenceLength uint16_t 9 参考长度(保留) 0
HighTimerLimit uint16_t 11 外部触发防抖等待时间ms 100
TimerCLimit uint16_t 13 保留 0
NgCountLimit uint8_t 15 触发后连续低温帧数达此值则停止采集 5
LSizeStart uint16_t 16 发送时去掉头部样本数(切片) 0
RSizeStart uint16_t 18 发送时去掉尾部样本数(切片) 0
NGioDelay uint16_t 20 NG 输出脉宽ms1D 使用) 200
OutputGpioLine uint8_t 22 输出 GPIO固定 PA8 0
AlarmGpioLine uint8_t 23 告警 GPIO未使用 0
AlarmHoldMs uint16_t 24 告警持续(未使用) 0

2D 与 1D 互斥Config2D.Enabled=1 时 MCU 进入 2D 模式;Config1D.Enabled=1Config2D.Enabled=0 时进入 1D 模式。同时置 1 时 2D 优先。


4. 温度帧接收

温度帧通过**数据流5512**接收,帧类型为 TYPE_TEMP_FRAME(0x10)Class=CLASS_DATA(0x02)

4.1 2D 温度帧解析

Value 布局TemperatureFrameHeader_t + 像素数组):

[TemperatureFrameHeader_t] 18 字节
    ├─ FrameNumber: uint32_t LE  — 帧序号(与 DVP 帧计数对应)
    ├─ Width:       uint16_t LE  — 输出 ROI 宽度TargetWidth 或有效宽度)
    ├─ Height:      uint16_t LE  — 输出 ROI 高度
    ├─ MinTemp:     int16_t LE   — ROI 内最低温度0.1°C/LSB
    ├─ MaxTemp:     int16_t LE   — ROI 内最高温度0.1°C/LSB
    ├─ AvgTemp:     int16_t LE   — ROI 内平均温度0.1°C/LSB
    ├─ RoiTemp:     int16_t LE   — TriggerRoi 区域特征温度0.1°C/LSB
    ├─ FrameType:   uint8_t      — 帧类型标识0x01=触发帧0x02=TEMP_REQ 帧)
    ├─ Status:      uint8_t      — 状态0=正常)
    ├─ Is2D:        uint8_t      — 1=2D 矩阵帧
    └─ Reserved:    uint8_t      — 填 0

[像素数组] Width × Height × 2 字节
    每个像素uint16_t 小端序
    排列行优先row0 col0, row0 col1, ..., row0 colW-1, row1 col0, ...
    单位0.1°C/LSB转为摄氏度 = 原始值 × 0.1

Python 解析示例

import struct

def parse_2d_frame(data: bytes):
    hdr_fmt = '<IHHhhhhhBBBB'   # TemperatureFrameHeader_t
    hdr_size = struct.calcsize(hdr_fmt)
    frame_num, w, h, min_t, max_t, avg_t, roi_t, _, ft, st, is2d, _ = struct.unpack_from(hdr_fmt, data)
    pixels_raw = struct.unpack_from(f'<{w*h}H', data, hdr_size)
    pixels_celsius = [v * 0.1 for v in pixels_raw]
    # pixels_celsius[row * w + col] = 第 row 行、第 col 列的温度°C
    return {
        'frame_num': frame_num, 'width': w, 'height': h,
        'max_temp': max_t * 0.1, 'min_temp': min_t * 0.1,
        'pixels': pixels_celsius
    }

4.2 1D 温度帧解析

Is2D=0 时,像素数组替换为 1D 样本序列。

Value 布局(同 TemperatureFrameHeader_t但 Width=点数Height=1

[TemperatureFrameHeader_t] 18 字节
    ├─ Width:  实际有效样本点数 N
    ├─ Height: 1
    └─ Is2D:   0

[样本数组] N × 4 字节
    每个样本TempPoint1D_t
    ├─ TimeOffset:  uint16_t LE — 相对采集开始的 ms 偏移
    └─ Temperature: uint16_t LE — 对应时刻温度0.1°C/LSB

Python 解析示例

def parse_1d_frame(data: bytes):
    hdr_fmt = '<IHHhhhhhBBBB'
    hdr_size = struct.calcsize(hdr_fmt)
    frame_num, n, _, min_t, max_t, avg_t, _, _, ft, st, is2d, _ = struct.unpack_from(hdr_fmt, data)
    points = []
    for i in range(n):
        t_off, temp = struct.unpack_from('<HH', data, hdr_size + i*4)
        points.append({'time_ms': t_off, 'temp_c': temp * 0.1})
    return {'frame_num': frame_num, 'points': points}

5. 检测结果下发与 NG 输出

5.1 下发检测结果

Server 在图像处理完成后,通过**控制流5511**发送 TYPE_DETECTION_RESULT(0x40)Class=CLASS_CONTROL=0x01

Value 结构DetectionResult_t8 字节):

字段 类型 说明
FrameNumber uint32_t LE 对应触发该结果的帧号
Result uint8_t 0=NG不合格1=OK合格
Reserved[3] uint8_t[3] 填 0

5.2 MCU NG 动作

收到 Result=0NG

  • PA8 输出高电平
  • 持续 Config2D.NGioDelay(默认 200 ms后自动恢复低电平
  • NGioDelay 可通过 Config2D 配置调整1D 模式使用 Config1D.NGioDelay

外部报警装置应接在 PA8高电平有效持续时间可配置。


6. TEMP_REQ 按需截图

Server 可随时通过控制流请求当前热场快照,无需等待触发。

请求帧TYPE_CONFIG_COMMON0x20Class=CLASS_CONTROL=0x01中包含 TEMP_REQ 字段,或通过专用命令触发(具体字段由 TcpLogic 内部解析),携带 is2dRequest 标志1=请求 2D 帧0=请求 1D 帧)。

MCU 响应

  • 下一个业务循环取当前 FrameBuffer 的最新帧
  • is2d=1:执行 Preprocess_Execute,返回 ROI 裁切后的 2D 温度矩阵FrameType=0x02
  • is2d=0:返回中心行 30 个等间距采样点,时间偏移仿真 0~600 ms非真实时间序列
  • 仅在对应模式(Config2D.Enabled / Config1D.Enabled)为 1 时响应,否则忽略

7. 错误码参考

错误码 触发场景 建议处理
ERR_CRC 0x1001 帧 CRC 校验失败 检查发送数据是否正确,重发
ERR_VERSION 0x1002 协议版本不匹配(非 0x20 检查 Version 字段
ERR_LENGTH 0x1003 FrameHeader.Length 与实际帧长不符 检查帧构造逻辑
ERR_AUTH 0x2001 AuthToken 不匹配 当前版本 AuthToken 全零,不应触发
ERR_BUSY 0x2002 设备忙,拒绝处理 等待 100 ms 后重试
ERR_DEV_ID_CONFLICT 0x2003 DevID 与已注册设备冲突 检查 DevID 分配
ERR_PARAM 0x3001 配置字段值非法 检查配置结构体字段范围

8. 对接故障排查

8.1 MCU 上电后无连接

  • 检查 MCU IP 是否为 192.168.7.10Server 是否在 192.168.7.50
  • 确保 Server 在 5511 和 5512 端口上已 Listen
  • 检查以太网连接MCU 使用 1000M RGMII需 1 Gbps 交换机或兼容网卡)
  • 调试串口USART3921600会打印 TCP Connected, socket X 确认连接

8.2 握手成功但无数据帧

  • 确认已通过控制流下发 Config2DEnabled=1)或 Config1DEnabled=1
  • 查看调试串口是否打印 TRIGGER frm=N2D 模式)或 1D: internal trigger start1D 模式)
  • 若无触发,检查 TriggerTemperatureThreshold 是否过高

8.3 数据帧偶发丢失

  • 检查 Server 是否及时 ACKTCP 窗口是否足够
  • 调试串口打印 2D TX fail1D SEND ... ret=-1 表示 MCU 侧发送失败(队列满或连接异常)

8.4 温度值异常(偏高或偏低约 10 倍)

  • 确认传感器已配置为 TMP 模式(非 Y16 模式)。参见 Doc/Mini212G2预配置指南.md
  • TMP 模式输出值已是 0.1°C/LSB解析时乘以 0.1 即为摄氏度

8.5 NG 输出不动作

  • 确认发送的 DetectionResult.Result = 0NG而非 1OK
  • 检查 Config2D.NGioDelay 是否已配置0 时默认 200 ms
  • 核查 PA8 GPIO 连接是否正确

9. 相关文档

文档 内容
系统总览.md MCU 固件架构总览
QDX协议设计.md 帧结构详细说明(供深度对接参考)
TCP通信模块设计.md MCU 侧连接管理实现细节
Mini212G2预配置指南.md 传感器 TMP 模式配置