100
This commit is contained in:
+162
@@ -204,6 +204,115 @@ void OnConfigUpdated(const ConfigCommon_t* common, const Config2D_t* cfg2d, cons
|
||||
Preprocess_Settings_Change(cfg2d, cfg1d, common);
|
||||
}
|
||||
|
||||
## 4.6 TcpLogic_InjectTestConfig(测试模式配置注入)
|
||||
|
||||
功能:在不依赖服务器的情况下,直接向 TCP 逻辑模块注入配置参数。注入后走与服务器下发完全相同的缓存 + 回调路径。仅非 NULL 的参数会被更新。
|
||||
|
||||
原型:
|
||||
|
||||
```c
|
||||
void TcpLogic_InjectTestConfig(const ConfigCommon_t *common, const Config2D_t *cfg2d, const Config1D_t *cfg1d);
|
||||
```
|
||||
|
||||
入参:
|
||||
- `common`:通用配置指针,NULL 表示不更新
|
||||
- `cfg2d`:2D 配置指针,NULL 表示不更新
|
||||
- `cfg1d`:1D 配置指针,NULL 表示不更新
|
||||
|
||||
内部行为:
|
||||
1. 互斥锁保护下写入内部缓存
|
||||
2. 设置 `has_valid_config = 1`
|
||||
3. 触发已注册的 `ConfigUpdateCallback`
|
||||
|
||||
使用场景:
|
||||
- 测试模式(`TEST_PATTERN_MODE=1`)启动时注入默认 2D 配置,使自主触发管线无需服务器即可工作
|
||||
- 注入后若服务器连接并下发新配置,新配置会覆盖注入的默认值
|
||||
|
||||
示例:
|
||||
```c
|
||||
Config2D_t test_cfg2d;
|
||||
memset(&test_cfg2d, 0, sizeof(test_cfg2d));
|
||||
test_cfg2d.Enabled = 1;
|
||||
test_cfg2d.TriggerMode = 1; // 内部触发
|
||||
test_cfg2d.TargetWidth = 64;
|
||||
test_cfg2d.TargetHeight = 64;
|
||||
test_cfg2d.TriggerTemperatureThreshold = 800; // 80.0°C
|
||||
test_cfg2d.TriggerBurstCount = 3;
|
||||
TcpLogic_InjectTestConfig(NULL, &test_cfg2d, NULL);
|
||||
```
|
||||
|
||||
## 8. MCU 实际业务调用流程(CH32V307 实现)
|
||||
|
||||
以下为 MCU 中 main.c 的实际初始化和业务循环流程,作为第 7 节伪代码的具体实现参考:
|
||||
|
||||
```c
|
||||
// ===== 初始化阶段 (main 函数) =====
|
||||
|
||||
// 1. 硬件初始化
|
||||
USART_Printf_Init(921600);
|
||||
Config_Flash_SRAM(FLASH_128_SRAM_192); // 128K Flash + 192K SRAM
|
||||
#if !TEST_PATTERN_MODE
|
||||
DVP_Init(); // 正常模式初始化 DVP
|
||||
#endif
|
||||
TIM2_Init(); // WCHNET 10ms 定时基准
|
||||
ExtTrigger_GPIO_Init(); // PA15/EXTI15 外部触发
|
||||
NG_GPIO_Init(); // PA8 NG 输出
|
||||
|
||||
// 2. 网络初始化
|
||||
ETH_LibInit(IPAddr, GWIPAddr, IPMask, MACAddr);
|
||||
qdx_port_init();
|
||||
|
||||
// 3. 库初始化 + 回调注册
|
||||
Preprocess_Init(SENSOR_WIDTH, SENSOR_HEIGHT);
|
||||
TcpLogic_Init(MACAddr, NULL);
|
||||
TcpLogic_RegisterConfigCallback(OnConfigUpdate);
|
||||
TcpLogic_RegisterDetectionCallback(OnDetectionResult);
|
||||
TcpLogic_RegisterTempFrameRequestCallback(OnTempFrameRequest);
|
||||
|
||||
// 4. 测试模式注入默认配置
|
||||
#if TEST_PATTERN_MODE
|
||||
TcpLogic_InjectTestConfig(NULL, &test_cfg2d, NULL);
|
||||
#endif
|
||||
|
||||
// 5. 启动 TCP 引擎 + RTOS 任务
|
||||
TcpLogic_Start();
|
||||
xTaskCreate(task_wchnet_entry, "wchnet", 512, NULL, 6, NULL);
|
||||
xTaskCreate(task_business_entry, "business", 512, NULL, 5, NULL);
|
||||
xTaskCreate(task_heartbeat_entry,"hb", 256, NULL, 3, NULL);
|
||||
#if TEST_PATTERN_MODE
|
||||
xTaskCreate(task_test_pattern_entry, "testpat", 256, NULL, 4, NULL);
|
||||
#endif
|
||||
vTaskStartScheduler();
|
||||
|
||||
// ===== 业务循环 (task_business_entry) =====
|
||||
// 全部行为由运行时 Config 驱动,无编译期功能开关
|
||||
|
||||
while (1) {
|
||||
// NG 脉冲超时检查
|
||||
if (g_ng_off_time && sys_tick_ms >= g_ng_off_time)
|
||||
GPIO_ResetBits(NG_GPIO_PORT, NG_GPIO_PIN);
|
||||
|
||||
#if !TEST_PATTERN_MODE
|
||||
DVP_Task(); // 行 DMA 搬运
|
||||
#endif
|
||||
|
||||
// 辅助通道:TEMP_REQ 服务器按需截图
|
||||
if (g_temp_req_pending) {
|
||||
// → 2D: Preprocess_Execute → TcpLogic_BuildAndSendTemperatureFrame
|
||||
// → 1D: send_1d_snapshot (30点空间采样)
|
||||
}
|
||||
|
||||
// 主管线:自主触发
|
||||
if (Frame_Ready_Flag) {
|
||||
TcpLogic_GetLatestConfig(&tc, &t2, &t1);
|
||||
if (t2.Enabled)
|
||||
handle_2d_trigger(&raw, &t2, &use_buf); // 2D 状态机
|
||||
else if (t1.Enabled)
|
||||
handle_1d_trigger(&raw, &t1, &use_buf); // 1D 状态机
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Page 5
|
||||
|
||||
6. 函数调⽤时序图 (Control Flow)
|
||||
@@ -235,3 +344,56 @@ TCP 数据流返回 Defect Result (NG)
|
||||
拉⾼ DO1 定时执⾏剔除动作
|
||||
主机/中断(Main) TcpLogic (⽹络库) Preprocess (预处理库) ConfigServer (上位机)
|
||||
|
||||
# Page 7
|
||||
|
||||
## 7. 多级调试打印系统
|
||||
|
||||
### 7.1 概述
|
||||
|
||||
调试打印通过 `qdx_port.h` 中的宏体系实现,支持 **5 个级别** 和 **7 个分类**。仅需修改一个宏即可全局控制输出量:
|
||||
|
||||
```c
|
||||
#define DBG_LEVEL DBG_LEVEL_NORMAL // 修改此值控制输出详细度
|
||||
```
|
||||
|
||||
### 7.2 级别定义
|
||||
|
||||
| 值 | 宏名 | 说明 | 适用场景 |
|
||||
|---|---|---|---|
|
||||
| 0 | `DBG_LEVEL_NONE` | 完全关闭 | 量产固件 |
|
||||
| 1 | `DBG_LEVEL_ERR` | 仅错误 | 最小输出排障 |
|
||||
| 2 | `DBG_LEVEL_BRIEF` | + 服务器配置/网络事件 | **推荐日常使用** |
|
||||
| 3 | `DBG_LEVEL_NORMAL` | + 触发/数据/初始化 | 开发调试(默认) |
|
||||
| 4 | `DBG_LEVEL_VERBOSE` | + 心跳/TLV详情 | 深度调试 |
|
||||
|
||||
### 7.3 分类宏及打印级别
|
||||
|
||||
| 宏 | 级别阈值 | 前缀 | 用途 |
|
||||
|---|---|---|---|
|
||||
| `DBG_ERR` | ≥1 (ERR) | `[ERR]` | HardFault、CRC校验失败、连接失败、PP失败 |
|
||||
| `DBG_CFG` | ≥2 (BRIEF) | `[CFG]` | **服务器下发的所有配置**(Config2D/1D/Common、DevID、ACK、DetResult、TempReq) |
|
||||
| `DBG_NET` | ≥2 (BRIEF) | `[NET]` | TCP连接/断开、PHY状态、Socket事件 |
|
||||
| `DBG_TRIG` | ≥3 (NORMAL) | `[TRIG]` | 外部/内部触发、防抖、Burst启停 |
|
||||
| `DBG_DATA` | ≥3 (NORMAL) | `[DATA]` | 2D/1D帧发送结果、TEMP_REQ发送 |
|
||||
| `DBG_INIT` | ≥3 (NORMAL) | `[INIT]` | 开机初始化(传感器、DVP、WCHNET、RTOS) |
|
||||
| `DBG_HB` | ≥4 (VERBOSE) | `[HB]` | 心跳打印、TLV包头详情(高频) |
|
||||
|
||||
### 7.4 使用示例
|
||||
|
||||
```c
|
||||
DBG_ERR("CRC fail: calc=0x%04X recv=0x%04X\r\n", calc, recv);
|
||||
DBG_CFG("<< Config2D: En=%d %dx%d Trig=%d\r\n", en, w, h, trig);
|
||||
DBG_NET("[Control] Connected to %s:%d\r\n", ip, port);
|
||||
DBG_TRIG("2D ext trigger\r\n");
|
||||
DBG_DATA("2D SEND frm=%d ret=%d\r\n", frm, ret);
|
||||
DBG_INIT("Sensor: Y16 OK\r\n");
|
||||
DBG_HB("%d tick=%d frm=%d\r\n", cnt, tick, frm);
|
||||
```
|
||||
|
||||
### 7.5 各级别输出预期
|
||||
|
||||
- **NONE (0)**:静默,仅 HardFault 的 raw printf 输出
|
||||
- **ERR (1)**:错误信息 — 约 13 条打印点
|
||||
- **BRIEF (2)**:+ 服务器配置全量打印 + 网络事件 — 上位机交互一目了然
|
||||
- **NORMAL (3)**:+ 触发事件、数据发送、初始化 — 标准开发模式
|
||||
- **VERBOSE (4)**:+ 心跳(每2秒)、每个TLV包详情 — 仅深度调试使用
|
||||
+407
-286
@@ -1,24 +1,32 @@
|
||||
# CH32V307 TCPClient 模式配置与功能说明
|
||||
|
||||
> **版本**: v2.0 — 自主触发架构
|
||||
> **更新日期**: 2026-03
|
||||
> **适用代码**: main.c 自主触发架构(已移除所有 `TEST_ENABLE_*` 编译开关)
|
||||
|
||||
## 目录
|
||||
|
||||
1. [系统架构概述](#1-系统架构概述)
|
||||
2. [运行模式说明](#2-运行模式说明)
|
||||
3. [宏开关配置总表](#3-宏开关配置总表)
|
||||
4. [测试模式详解](#4-测试模式详解)
|
||||
5. [正常模式详解](#5-正常模式详解)
|
||||
6. [网络与服务器配置](#6-网络与服务器配置)
|
||||
7. [配置下发流程](#7-配置下发流程)
|
||||
8. [RTOS 任务架构](#8-rtos-任务架构)
|
||||
9. [切换模式操作指南](#9-切换模式操作指南)
|
||||
10. [常见配置场景](#10-常见配置场景)
|
||||
11. [已知注意事项](#11-已知注意事项)
|
||||
3. [编译期常量总表](#3-编译期常量总表)
|
||||
4. [自主触发架构详解](#4-自主触发架构详解)
|
||||
5. [2D 触发状态机](#5-2d-触发状态机)
|
||||
6. [1D 采集状态机](#6-1d-采集状态机)
|
||||
7. [TEMP_REQ 辅助通道](#7-temp_req-辅助通道)
|
||||
8. [测试模式详解](#8-测试模式详解)
|
||||
9. [正常模式详解](#9-正常模式详解)
|
||||
10. [网络与服务器配置](#10-网络与服务器配置)
|
||||
11. [配置下发流程](#11-配置下发流程)
|
||||
12. [RTOS 任务架构](#12-rtos-任务架构)
|
||||
13. [GPIO 引脚分配](#13-gpio-引脚分配)
|
||||
14. [功能完整性对照表](#14-功能完整性对照表)
|
||||
15. [已知注意事项](#15-已知注意事项)
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统架构概述
|
||||
|
||||
本系统基于 CH32V307WCU6 (RISC-V) 微控制器,运行 FreeRTOS 实时操作系统,通过 WCHNET TCP/IP 协议栈与上位机通信。系统支持两种运行模式:**测试模式**(软件生成模拟热成像数据)和**正常模式**(通过 DVP 接口采集 Mini212G2 红外传感器真实数据)。
|
||||
本系统基于 CH32V307WCU6 (RISC-V) 微控制器,运行 FreeRTOS 实时操作系统,通过 WCHNET TCP/IP 协议栈与上位机通信。系统行为完全由运行时服务器配置驱动——服务器下发 Config2D/Config1D 并设置 `Enabled=1` 后,MCU 自主执行触发检测和数据采集上报。
|
||||
|
||||
### 硬件资源
|
||||
|
||||
@@ -37,57 +45,63 @@
|
||||
|------|------|
|
||||
| FreeRTOS v202112.00 | 实时操作系统,Heap=16KB |
|
||||
| WCHNET | 万瑞 TCP/IP 协议栈 |
|
||||
| QDX 协议栈 | 自定义 TLV 二进制通信协议 |
|
||||
| 预处理模块 | 滑窗 ROI 搜索 + 温度统计 |
|
||||
| QDX 协议栈 | 自定义 TLV 二进制通信协议 (0x55AA, v2.0) |
|
||||
| 预处理模块 | 滑窗 ROI 搜索 + 温度统计 + 自动降尺寸 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 运行模式说明
|
||||
|
||||
系统仅保留一个编译期宏开关 `TEST_PATTERN_MODE`,控制数据来源。所有业务功能(触发、采集、NG 输出、心跳)在两种模式下均始终启用,行为由服务器运行时配置驱动。
|
||||
|
||||
### 两种模式对比
|
||||
|
||||
| 对比项 | 测试模式 (`TEST_PATTERN_MODE=1`) | 正常模式 (`TEST_PATTERN_MODE=0`) |
|
||||
|--------|------|------|
|
||||
| **数据来源** | 软件生成模拟热图 (~10 FPS) | Mini212G2 传感器 DVP/DMA 采集 |
|
||||
| **硬件依赖** | 仅需网口,无需传感器 | 需连接 Mini212G2 + DVP 线缆 |
|
||||
| **初始化** | 跳过 `Mini212G2_Init()` 和 `DVP_Init()` | 执行传感器初始化 + DVP 配置 |
|
||||
| **初始化** | 跳过 `DVP_Init()` | 执行 DVP 初始化 |
|
||||
| **帧生成** | `task_test_pattern_entry` 任务周期填充 | DVP 行中断逐行 DMA 搬运 |
|
||||
| **心跳显示** | `[HB] N tick=X TEST_MODE frm=Y` | `[HB] N tick=X dvp_frm=Y row_irq=Z` |
|
||||
| **默认配置** | 自动加载测试配置(64×64, 80°C 阈值) | 等待服务器下发,默认 1×1 |
|
||||
| **适用场景** | 软件调试、协议验证、无硬件开发 | 生产环境、实际传感器采集 |
|
||||
| **默认配置** | 自动注入测试配置(2D Enabled=1, 内部触发, 80°C) | 等待服务器下发,默认不使能 |
|
||||
| **自主触发** | ✅ 立即工作(无需服务器) | ✅ 需服务器下发 Enabled=1 后激活 |
|
||||
| **TEMP_REQ** | ✅ 可用(需对应模式 Enabled=1) | ✅ 可用 |
|
||||
| **NG GPIO** | ✅ PA8 始终初始化 | ✅ PA8 始终初始化 |
|
||||
| **外部触发 GPIO** | ✅ PA0/EXTI0 始终初始化 | ✅ PA0/EXTI0 始终初始化 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 宏开关配置总表
|
||||
## 3. 编译期常量总表
|
||||
|
||||
所有宏定义位于 `prj/TCPClient/User/main.c` 文件头部。
|
||||
|
||||
### 3.1 主模式开关
|
||||
|
||||
| 宏名 | 文件位置 | 当前值 | 说明 |
|
||||
|------|---------|--------|------|
|
||||
| `TEST_PATTERN_MODE` | main.c:18 | **1** | **主开关**:1=测试模式,0=正常模式 |
|
||||
| 宏名 | 当前值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `TEST_PATTERN_MODE` | **1** | **唯一编译开关**:1=测试模式,0=正常模式 |
|
||||
|
||||
### 3.2 功能子开关
|
||||
|
||||
| 宏名 | 当前值 | 控制功能 | 依赖条件 |
|
||||
|------|--------|---------|---------|
|
||||
| `TEST_ENABLE_HEARTBEAT` | **1** | 周期心跳调试打印(2秒间隔) | 无 |
|
||||
| `TEST_ENABLE_TRIGGER` | **0** | 内部触发 + 连拍上传 | 需配合阈值配置 |
|
||||
| `TEST_ENABLE_NG_GPIO` | **0** | PA8 NG GPIO 脉冲输出 | 需硬件连接 |
|
||||
| `TEST_ENABLE_TEMP_REQ` | **1** | 服务器按需帧请求响应 | 需服务器发送请求 |
|
||||
| `TEST_ENABLE_TCP_SEND` | **1** | TCP 数据通道发送 | 需网络连接 |
|
||||
|
||||
### 3.3 其他编译期常量
|
||||
### 3.2 业务常量
|
||||
|
||||
| 宏名 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| `KEEPALIVE_ENABLE` | 1 | TCP KeepAlive 保持(20s 探测) |
|
||||
| `DEFAULT_BURST_COUNT` | 3 | 默认连拍帧数 |
|
||||
| `DEFAULT_BURST_INTERVAL_MS` | 200 | 默认连拍帧间隔 (ms) |
|
||||
| `DEFAULT_BURST_COUNT` | 3 | 服务器未配置时的默认连拍帧数 |
|
||||
| `DEFAULT_BURST_INTERVAL_MS` | 200 | 服务器未配置时的默认连拍间隔 (ms) |
|
||||
| `MAX_TCP_PAYLOAD_SIZE` | 10240 | TCP 发送缓冲区大小 (字节) |
|
||||
| `TEST_FPS_DELAY_MS` | 100 | 测试模式帧间隔 (~10 FPS) |
|
||||
| `TEST_1D_POINTS` | 30 | 1D 模式采样点数 |
|
||||
| `KEEPALIVE_ENABLE` | 1 | TCP KeepAlive(20s 空闲 / 15s 探测 / 9 次) |
|
||||
| `TEST_FPS_DELAY_MS` | 100 | 测试模式帧生成间隔 (~10 FPS) |
|
||||
| `SNAPSHOT_1D_POINTS` | 30 | TEMP_REQ 1D 空间采样点数 |
|
||||
| `MAX_1D_POINTS` | 512 | 1D 采集缓冲最大样本数 |
|
||||
| `NG_PULSE_MS` | 200 | NG 脉冲默认宽度(服务器可通过 NGioDelay 覆盖) |
|
||||
|
||||
### 3.3 GPIO 引脚宏
|
||||
|
||||
| 宏名 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| `EXT_TRIG_GPIO_PORT` | GPIOA | 外部触发输入端口 |
|
||||
| `EXT_TRIG_GPIO_PIN` | GPIO_Pin_15 | PA15 |
|
||||
| `EXT_TRIG_EXTI_LINE` | EXTI_Line15 | 外部中断线 |
|
||||
| `NG_GPIO_PORT` | GPIOA | NG 输出端口 |
|
||||
| `NG_GPIO_PIN` | GPIO_Pin_8 | PA8 |
|
||||
|
||||
### 3.4 传感器相关宏 (dvp.h)
|
||||
|
||||
@@ -104,15 +118,222 @@
|
||||
|
||||
| 宏名 | 当前值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `SENSOR_USE_USART3` | 0 | 启用后必须为 1(USART2 不可用) |
|
||||
| `SENSOR_UART_ENABLE` | **0 (已禁用)** | MCU UART 配置已禁用,传感器通过 USB 预配置 |
|
||||
| `SENSOR_UART_BAUD` | 115200 | 传感器 UART 波特率(未使用) |
|
||||
| `SENSOR_UART_ENABLE` | **0 (已禁用)** | 传感器通过 USB 预配置 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 测试模式详解
|
||||
## 4. 自主触发架构详解
|
||||
|
||||
### 4.1 启用方式
|
||||
### 4.1 核心设计原则
|
||||
|
||||
系统的所有业务行为由运行时服务器配置驱动,不再使用编译期功能开关:
|
||||
|
||||
```
|
||||
服务器下发 Config2D (Enabled=1) → MCU 自主执行 2D 触发/连拍/上报
|
||||
服务器下发 Config1D (Enabled=1) → MCU 自主执行 1D 采集/上报
|
||||
两者互斥:Config2D.Enabled 优先级高于 Config1D.Enabled
|
||||
```
|
||||
|
||||
### 4.2 主循环逻辑流程
|
||||
|
||||
```
|
||||
task_business_entry (优先级 5, 2ms 轮询)
|
||||
│
|
||||
├── [1] NG 脉冲超时检查 → 到期则拉低 PA8
|
||||
│
|
||||
├── [2] DVP_Task() (仅正常模式)
|
||||
│ ├── 行 DMA 完成 → 复制到 FrameBuffer
|
||||
│ └── 最后一行 → Frame_Ready_Flag=1
|
||||
│
|
||||
├── [3] TEMP_REQ 辅助通道(服务器按需截图)
|
||||
│ ├── 前提:对应模式 Enabled=1
|
||||
│ ├── is2D=1 → Preprocess_Execute() → TCP 发送 (frameType=0x02)
|
||||
│ └── is2D=0 → send_1d_snapshot() → 30 点空间采样
|
||||
│
|
||||
└── [4] 自主触发主管线
|
||||
│ 前提:Frame_Ready_Flag=1 && TcpLogic_GetLatestConfig OK
|
||||
│
|
||||
├── Config2D.Enabled=1 → handle_2d_trigger()
|
||||
│ (2D 触发状态机:消抖 → 延迟 → 连拍)
|
||||
│
|
||||
└── Config1D.Enabled=1 → handle_1d_trigger()
|
||||
(1D 采集状态机:IDLE → DEBOUNCE → COLLECTING)
|
||||
```
|
||||
|
||||
### 4.3 回调注册
|
||||
|
||||
| 回调 | 注册函数 | 触发时机 | 处理 |
|
||||
|------|---------|---------|------|
|
||||
| `OnConfigUpdate` | `TcpLogic_RegisterConfigCallback` | 服务器下发配置 | → `Preprocess_Settings_Change()` |
|
||||
| `OnDetectionResult` | `TcpLogic_RegisterDetectionCallback` | 服务器返回检测结果 (resultStatus=0 为 NG) | → PA8 NG 脉冲 |
|
||||
| `OnTempFrameRequest` | `TcpLogic_RegisterTempFrameRequestCallback` | 服务器请求截图 | → 设置 `g_temp_req_pending` |
|
||||
|
||||
---
|
||||
|
||||
## 5. 2D 触发状态机
|
||||
|
||||
### 5.1 状态机流程
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ IDLE │
|
||||
│ 等待触发 │
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
│ TriggerMode=0 │ TriggerMode=1
|
||||
│ (外部触发) │ (内部触发)
|
||||
▼ ▼
|
||||
PA0/EXTI0 上升沿 Preprocess_CheckInternalTrigger2D()
|
||||
│ │ (TriggerRoi 区域 Max/Avg > Threshold)
|
||||
▼ │
|
||||
┌──────────────┐ │
|
||||
│ DEBOUNCE │ │
|
||||
│ DebounceMs │ │
|
||||
└──────┬───────┘ │
|
||||
│ │
|
||||
└─────────┬───────────────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ DELAY │
|
||||
│ DelayMs │
|
||||
└──────┬───────┘
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ BURST │──┐
|
||||
│ 发送第1帧 │ │ 剩余 BurstCount-1 帧
|
||||
└──────────────┘ │ 间隔 InternalIntervalMs
|
||||
▲ │
|
||||
└──────────┘
|
||||
│
|
||||
▼
|
||||
Burst 完成 → 回到 IDLE
|
||||
```
|
||||
|
||||
### 5.2 关键 Config2D 字段
|
||||
|
||||
| 字段 | 类型 | 2D 触发中的作用 |
|
||||
|------|------|----------------|
|
||||
| `Enabled` | u8 | 1=启用 2D 管线 |
|
||||
| `TriggerMode` | u8 | 0=外部(GPIO), 1=内部(温度) |
|
||||
| `TriggerDebounceIntervalMs` | u16 | 外部触发消抖等待 (ms) |
|
||||
| `TriggerDelayMs` | u16 | 触发确认后延迟采集 (ms) |
|
||||
| `TriggerBurstCount` | u8 | 连拍帧数 |
|
||||
| `TriggerInternalIntervalMs` | u16 | 连拍帧间隔 (ms) |
|
||||
| `TriggerCondition` | u8 | 内部触发判定:0=平均温度, 1=最大温度 |
|
||||
| `TriggerTemperatureThreshold` | i16 | 内部触发温度阈值 (0.1°C/LSB) |
|
||||
| `TriggerRoiX/Y/W/H` | u16×4 | 内部触发检测区域 |
|
||||
| `TargetWidth` / `TargetHeight` | u16 | 预处理输出尺寸 |
|
||||
| `NGioDelay` | u16 | NG 脉冲宽度 (ms) |
|
||||
|
||||
### 5.3 2D 帧发送路径
|
||||
|
||||
```
|
||||
handle_2d_trigger() → start_2d_burst()
|
||||
→ do_2d_capture_send()
|
||||
→ Preprocess_Execute(raw, tx_buf, &meta) // 滑窗 ROI 搜索
|
||||
→ TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 0x01, 1)
|
||||
// frameType=TRIGGER, is2D=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 1D 采集状态机
|
||||
|
||||
### 6.1 状态机流程
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ S1D_IDLE │ (RunMode 必须=1)
|
||||
│ 等待触发 │
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
│ TriggerType=0 │ TriggerType=1
|
||||
│ (外部触发) │ (内部触发)
|
||||
▼ ▼
|
||||
PA0/EXTI0 上升沿 前置环形缓冲(3样本)
|
||||
│ 连续3个 ≥ TriggerTempLimit
|
||||
▼ │
|
||||
┌───────────────┐ │
|
||||
│ S1D_DEBOUNCE │ │
|
||||
│ HighTimerLimit │ │
|
||||
└──────┬────────┘ │
|
||||
│ │
|
||||
└─────────┬───────────────┘
|
||||
▼
|
||||
┌────────────────┐
|
||||
│ S1D_COLLECTING │
|
||||
│ 逐帧采集温度点 │
|
||||
│ (中心行最大值) │
|
||||
└───────┬────────┘
|
||||
│
|
||||
┌────────┼────────┐
|
||||
│ 停止条件1 │ 停止条件2
|
||||
│ BufferSize 满 │ 已触发 + NgCountLimit 连续冷点
|
||||
│ │
|
||||
└────────┬────────┘
|
||||
▼
|
||||
切片 [LSizeStart, -RSizeStart]
|
||||
│
|
||||
▼
|
||||
send_1d_collection() → TCP 发送
|
||||
│
|
||||
▼
|
||||
回到 S1D_IDLE
|
||||
```
|
||||
|
||||
### 6.2 1D 温度采样方式
|
||||
|
||||
每个 DVP 帧产生一个温度样本:取中心行所有像素的最大温度值(`get_1d_sample()`)。
|
||||
|
||||
### 6.3 内部触发预环形缓冲
|
||||
|
||||
内部触发模式维护长度为 3 的环形缓冲:
|
||||
- 每帧写入一个样本到环形缓冲
|
||||
- 当 3 个样本全部 ≥ `TriggerTempLimit` → 进入 COLLECTING 状态
|
||||
- 环形缓冲内容(最旧在前)写入采集数组前 3 位
|
||||
- 从第 4 位起继续采集
|
||||
|
||||
### 6.4 关键 Config1D 字段
|
||||
|
||||
| 字段 | 类型 | 1D 采集中的作用 |
|
||||
|------|------|----------------|
|
||||
| `Enabled` | u8 | 1=启用 1D 管线 |
|
||||
| `RunMode` | u8 | 0=STOP, 1=RUN |
|
||||
| `TriggerType` | u8 | 0=外部(GPIO), 1=内部(温度) |
|
||||
| `BufferSize` | u16 | 单次采集最大样本数(停止条件) |
|
||||
| `TriggerTempLimit` | i16 | 触发/采集温度阈值 (0.1°C/LSB) |
|
||||
| `HighTimerLimit` | u16 | 外部触发消抖时间 (ms) |
|
||||
| `NgCountLimit` | u8 | 连续冷点数→停止采集 |
|
||||
| `LSizeStart` | u16 | 切片左起始偏移 |
|
||||
| `RSizeStart` | u16 | 切片右侧移除点数 |
|
||||
|
||||
### 6.5 1D 数据打包格式
|
||||
|
||||
每个样本点 4 字节 (Little-Endian):
|
||||
|
||||
| 偏移 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| 0-1 | u16 LE | TimeOffset (距采集开始的毫秒偏移) |
|
||||
| 2-3 | u16 LE | Temperature (0.1°C/LSB) |
|
||||
|
||||
---
|
||||
|
||||
## 7. TEMP_REQ 辅助通道
|
||||
|
||||
TEMP_REQ 是服务器主动请求的按需截图通道,与自主触发管线独立工作:
|
||||
|
||||
- **2D 截图**:`Preprocess_Execute()` → 滑窗搜索 → 发送 `frameType=0x02`(MASKED)
|
||||
- **1D 截图**:`send_1d_snapshot()` → 从中心行等间距采样 30 点 → 发送
|
||||
|
||||
前提:对应模式 `Enabled=1`,否则请求被忽略并打印 `TEMP_REQ ignored`。
|
||||
|
||||
---
|
||||
|
||||
## 8. 测试模式详解
|
||||
|
||||
### 8.1 启用方式
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 1
|
||||
@@ -120,7 +341,7 @@
|
||||
|
||||
编译烧录即可,**无需连接任何传感器硬件**,仅需以太网连接。
|
||||
|
||||
### 4.2 测试图案
|
||||
### 8.2 测试图案
|
||||
|
||||
系统自动循环生成 4 种测试图案(256×192 Y16 格式):
|
||||
|
||||
@@ -133,65 +354,50 @@
|
||||
|
||||
总周期:40 帧 ≈ 4 秒循环一次。
|
||||
|
||||
### 4.3 默认配置参数
|
||||
### 8.3 自动注入测试配置
|
||||
|
||||
测试模式启动时自动加载以下配置(无需服务器下发即可工作):
|
||||
测试模式启动时通过 `TcpLogic_InjectTestConfig()` 注入以下配置(走标准缓存+回调路径):
|
||||
|
||||
```
|
||||
TargetWidth = 64 # 预处理输出宽度
|
||||
TargetHeight = 64 # 预处理输出高度
|
||||
TriggerRoiX = 0 # 触发检测区域起点 X
|
||||
TriggerRoiY = 0 # 触发检测区域起点 Y
|
||||
TriggerRoiW = 256 # 触发检测区域宽度(全幅)
|
||||
TriggerRoiH = 192 # 触发检测区域高度(全幅)
|
||||
TriggerCondition = 1 # 触发条件:1=最大温度
|
||||
TriggerTemperatureThreshold = 800 # 80.0°C (0.1°C/LSB)
|
||||
TriggerBurstCount = 3 # 连拍帧数
|
||||
TriggerInternalIntervalMs = 200 # 连拍间隔 (ms)
|
||||
NGioDelay = 200 # NG 脉冲宽度 (ms)
|
||||
Config2D:
|
||||
Enabled = 1 # 自动启用 2D 管线
|
||||
TriggerMode = 1 # 内部触发(温度检测)
|
||||
TargetWidth = 64 # 预处理输出 64×64
|
||||
TargetHeight = 64
|
||||
TriggerRoiX/Y = 0, 0 # 全幅扫描
|
||||
TriggerRoiW/H = 256, 192
|
||||
TriggerCondition = 1 # 最大温度
|
||||
TriggerTemperatureThreshold = 800 # 80.0°C
|
||||
TriggerBurstCount = 3 # 3 帧连拍
|
||||
TriggerInternalIntervalMs = 200
|
||||
NGioDelay = 200
|
||||
```
|
||||
|
||||
> **注意**:如果服务器连接后下发了 Config2D,将覆盖上述默认配置。
|
||||
> **注入路径**:`TcpLogic_InjectTestConfig()` → 内部缓存 + `has_valid_config=1` → 触发 `OnConfigUpdate` 回调 → `Preprocess_Settings_Change()`。与服务器下发配置走完全相同的路径。
|
||||
|
||||
### 4.4 测试模式数据流
|
||||
### 8.4 启动串口输出示例
|
||||
|
||||
```
|
||||
task_test_pattern_entry (优先级 4, 100ms 周期)
|
||||
│ 生成 256×192 Y16 测试图案
|
||||
│ 写入 FrameBuffer[]
|
||||
│ 设置 Frame_Ready_Flag=1
|
||||
▼
|
||||
task_business_entry (优先级 5)
|
||||
├── 检查 g_temp_req_pending (服务器请求)
|
||||
│ ├── is2D=1 → Preprocess_Execute() → 滑窗搜索 → 发送 2D 帧
|
||||
│ └── is2D=0 → send_1d_frame_from_raw() → 采样中心行 → 发送 1D 帧
|
||||
│
|
||||
└── 检查 Frame_Ready_Flag (仅 TRIGGER 启用时)
|
||||
└── Preprocess_CheckInternalTrigger2D()
|
||||
└── 触发 → 连拍发送
|
||||
```
|
||||
|
||||
### 4.5 启动串口输出示例
|
||||
|
||||
```
|
||||
TCPClient Test
|
||||
TCPClient
|
||||
SystemClk:144000000
|
||||
=== Feature Switches ===
|
||||
PATTERN=1 TRIGGER=0 NG_GPIO=0 TEMP_REQ=1 TCP_SEND=1 HB=1
|
||||
TEST_PATTERN=1
|
||||
UserByte: c0
|
||||
=== TEST PATTERN MODE === No sensor/DVP hardware needed
|
||||
net version:1c
|
||||
WCHNET_LibInit Success
|
||||
Test default config loaded: trigger thresh=800 ROI=full burst=3
|
||||
Test config injected: En=1 TrigMode=Internal thresh=800 Tgt=64x64 burst=3
|
||||
[HB] 0 tick=1010 TEST_MODE frm=9
|
||||
[HB] 1 tick=3010 TEST_MODE frm=29
|
||||
2D internal trigger
|
||||
TRIGGER frm=21
|
||||
2D SEND frm=21 64x64 ret=0
|
||||
Burst start: 3 frames, interval=200 ms
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 正常模式详解
|
||||
## 9. 正常模式详解
|
||||
|
||||
### 5.1 启用方式
|
||||
### 9.1 启用方式
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 0
|
||||
@@ -199,9 +405,9 @@ Test default config loaded: trigger thresh=800 ROI=full burst=3
|
||||
|
||||
需要:
|
||||
1. Mini212G2 传感器正确连接 DVP 接口
|
||||
2. 传感器已通过 USB 或 UART 预配置为 CMOS/DVP Y16 输出
|
||||
2. 传感器已通过 USB 预配置为 CMOS/DVP Y16 输出
|
||||
|
||||
### 5.2 硬件连接
|
||||
### 9.2 硬件连接
|
||||
|
||||
#### DVP 引脚定义
|
||||
|
||||
@@ -231,20 +437,7 @@ Test default config loaded: trigger thresh=800 ROI=full burst=3
|
||||
|
||||
> 注意:启用 USART3 传感器通信会占用 printf 调试端口,需通过 JTAG 调试。
|
||||
|
||||
### 5.3 传感器配置选项
|
||||
|
||||
修改 `mini212g2.h`:
|
||||
|
||||
```c
|
||||
// 当前状态:MCU UART 配置已禁用(#if 0)
|
||||
// 模组已通过 USB 预配置,无需 MCU 配置
|
||||
|
||||
// 如需重新启用 MCU UART 配置,将 mini212g2.h 中的 #if 0 改为 #if 1
|
||||
// 仅可使用 USART3 (PB10/PB11),USART2 引脚已被占用
|
||||
// ⚠ 启用后 printf 串口不可用,需通过 JTAG 调试
|
||||
```
|
||||
|
||||
### 5.4 正常模式数据流
|
||||
### 9.3 正常模式数据流
|
||||
|
||||
```
|
||||
DVP 硬件中断 (DVP_IRQHandler)
|
||||
@@ -257,40 +450,23 @@ task_business_entry (优先级 5)
|
||||
│ ├── 复制 DMA 行缓冲 → FrameBuffer[line_idx]
|
||||
│ └── 最后一行 → Frame_Ready_Flag=1
|
||||
▼
|
||||
├── 检查 g_temp_req_pending (服务器请求)
|
||||
│ ├── is2D=1 → Preprocess_Execute() → 发送
|
||||
│ └── is2D=0 → 1D 采样 → 发送
|
||||
├── [TEMP_REQ] 服务器按需截图
|
||||
│
|
||||
└── 检查 Frame_Ready_Flag (TRIGGER 启用时)
|
||||
└── Preprocess_CheckInternalTrigger2D()
|
||||
└── [自主触发] Config2D.Enabled → 2D 状态机
|
||||
Config1D.Enabled → 1D 状态机
|
||||
```
|
||||
|
||||
### 5.5 正常模式注意事项
|
||||
### 9.4 正常模式注意事项
|
||||
|
||||
- **无默认预处理参数**:正常模式不加载测试默认配置,`Preprocess_Init()` 仅设置 `TargetWidth=1, TargetHeight=1`。必须等服务器下发 Config2D 后才能获取正确的目标尺寸。
|
||||
- **传感器初始化检查**:可通过 JTAG 查看 `sensor_init_ok` / `sensor_init_fail` 变量确认初始化结果。
|
||||
- **帧率取决于传感器**:Mini212G2 在 DVP 模式下的帧率由传感器内部配置决定,不通过软件控制。
|
||||
|
||||
### 5.6 启动串口输出示例(预期)
|
||||
|
||||
```
|
||||
TCPClient Test
|
||||
SystemClk:144000000
|
||||
=== Feature Switches ===
|
||||
PATTERN=0 TRIGGER=0 NG_GPIO=0 TEMP_REQ=1 TCP_SEND=1 HB=1
|
||||
UserByte: c0
|
||||
[DVP] Init done CR0=0x2C CR1=0x04 ROW=1 COL=512
|
||||
[DVP] DMA_BUF0=0x200XXXXX DMA_BUF1=0x200XXXXX
|
||||
net version:1c
|
||||
WCHNET_LibInit Success
|
||||
[HB] 0 tick=1010 dvp_frm=0 row_irq=0
|
||||
```
|
||||
- **无默认配置**:正常模式不注入测试配置,`Preprocess_Init()` 仅设置 `TargetWidth=1, TargetHeight=1`。必须等服务器下发 Config2D/Config1D 后才能工作。
|
||||
- **传感器初始化**:模组已通过 USB 预配置,`mini212g2.h` 中 UART 配置已关闭。
|
||||
- **帧率取决于传感器**:Mini212G2 在 DVP 模式下的帧率由传感器内部配置决定。
|
||||
|
||||
---
|
||||
|
||||
## 6. 网络与服务器配置
|
||||
## 10. 网络与服务器配置
|
||||
|
||||
### 6.1 MCU 网络参数
|
||||
### 10.1 MCU 网络参数
|
||||
|
||||
定义位置:`main.c`
|
||||
|
||||
@@ -301,7 +477,7 @@ WCHNET_LibInit Success
|
||||
| 子网掩码 | 255.255.255.0 | C 类子网 |
|
||||
| MAC 地址 | 由芯片自动获取 | 硬件 MAC |
|
||||
|
||||
### 6.2 服务器连接参数
|
||||
### 10.2 服务器连接参数
|
||||
|
||||
定义位置:`qdx_tcp_logic.c`
|
||||
|
||||
@@ -311,47 +487,62 @@ WCHNET_LibInit Success
|
||||
| `CONTROL_PORT` | 5511 | 控制通道端口 |
|
||||
| `DATA_PORT` | 5512 | 数据通道端口 |
|
||||
|
||||
> **修改方法**:直接编辑 `qdx_tcp_logic.c` 中的常量值,重新编译。
|
||||
|
||||
### 6.3 TCP KeepAlive
|
||||
### 10.3 TCP KeepAlive
|
||||
|
||||
```c
|
||||
#define KEEPALIVE_ENABLE 1 // main.c
|
||||
// 探测配置: 20s 空闲后每 15s 探测一次,最多 9 次
|
||||
```
|
||||
|
||||
### 10.4 TCP 内部参数
|
||||
|
||||
| 参数 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| `HEARTBEAT_INTERVAL_MS` | 2000 | 心跳发送间隔 |
|
||||
| `SERVER_TIMEOUT_MS` | 6000 | 服务器超时断连 |
|
||||
| `RECONNECT_DELAY_MS` | 3000 | 断连后重连等待 |
|
||||
| `MAX_FRAGMENT_PAYLOAD` | 1400 | 分片最大载荷 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 配置下发流程
|
||||
## 11. 配置下发流程
|
||||
|
||||
### 7.1 TLV 配置类型
|
||||
### 11.1 TLV 消息类型
|
||||
|
||||
| TLV Type | 名称 | 说明 |
|
||||
|----------|------|------|
|
||||
| 0x20 | TYPE_CONFIG_COMMON | 通用配置(模式、严格标记等) |
|
||||
| 0x22 | TYPE_CONFIG_2D | 2D 配置(目标尺寸、触发、连拍等) |
|
||||
| 0x23 | TYPE_CONFIG_1D | 1D 配置 |
|
||||
| TLV Type | 名称 | 方向 | 说明 |
|
||||
|----------|------|------|------|
|
||||
| 0x01 | TYPE_HANDSHAKE | ↔ | 握手(UUID、版本) |
|
||||
| 0x02 | TYPE_HEARTBEAT | ↔ | 心跳(上行/下行) |
|
||||
| 0x05 | TYPE_DEVID_ASSIGN | ← | 设备 ID 分配(触发重连) |
|
||||
| 0x10 | TYPE_TEMP_FRAME | ← | 请求温度帧(TEMP_REQ) |
|
||||
| 0x20 | TYPE_CONFIG_COMMON | ← | 通用配置 |
|
||||
| 0x22 | TYPE_CONFIG_2D | ← | 2D 配置 |
|
||||
| 0x23 | TYPE_CONFIG_1D | ← | 1D 配置 |
|
||||
| 0x30 | TYPE_ACK_PAYLOAD | ← | ACK 响应 |
|
||||
| 0x40 | TYPE_DETECTION_RESULT | ← | 检测结果(OK/NG) |
|
||||
|
||||
### 7.2 Config2D 关键字段
|
||||
### 11.2 Config2D 关键字段
|
||||
|
||||
| 字段 | 偏移 | 类型 | 说明 |
|
||||
|------|------|------|------|
|
||||
| Width | 4 | u16 LE | 设备/传感器分辨率宽度(仅标记,不影响预处理) |
|
||||
| Height | 6 | u16 LE | 设备/传感器分辨率高度(仅标记,不影响预处理) |
|
||||
| **TargetWidth** | **23** | **u16 LE** | **预处理输出宽度(直接控制帧大小)** |
|
||||
| **TargetHeight** | **25** | **u16 LE** | **预处理输出高度(直接控制帧大小)** |
|
||||
| Fps | 8 | u16 LE | 帧率 |
|
||||
| TriggerCondition | 27 | u8 | 0=平均, 1=最大 |
|
||||
| TriggerTemperatureThreshold | 28 | u16 LE | 触发温度阈值 (0.1°C/LSB) |
|
||||
| Enabled | 0 | u8 | **使能开关** |
|
||||
| Width | 4 | u16 LE | 设备分辨率宽度(仅标记) |
|
||||
| Height | 6 | u16 LE | 设备分辨率高度(仅标记) |
|
||||
| **TargetWidth** | **23** | **u16 LE** | **预处理输出宽度** |
|
||||
| **TargetHeight** | **25** | **u16 LE** | **预处理输出高度** |
|
||||
| TriggerMode | 21 | u8 | 0=外部, 1=内部 |
|
||||
| TriggerCondition | 37 | u8 | 0=平均, 1=最大 |
|
||||
| TriggerTemperatureThreshold | 28 | i16 LE | 触发阈值 (0.1°C/LSB) |
|
||||
| TriggerBurstCount | 30 | u8 | 连拍帧数 |
|
||||
| TriggerInternalIntervalMs | 31 | u16 LE | 连拍帧间隔 (ms) |
|
||||
| TriggerRoiX/Y/W/H | 33-40 | u16 LE ×4 | 触发检测 ROI 区域 |
|
||||
| TriggerInternalIntervalMs | 31 | u16 LE | 连拍间隔 (ms) |
|
||||
| TriggerDebounceIntervalMs | 35 | u16 LE | 外部触发消抖 (ms) |
|
||||
| TriggerDelayMs | 23 | u16 LE | 触发后延迟 (ms) |
|
||||
| TriggerRoiX/Y/W/H | 33-40 | u16 LE ×4 | 内部触发检测 ROI |
|
||||
| NGioDelay | 41 | u16 LE | NG 脉冲宽度 (ms) |
|
||||
|
||||
> **重要**:Width/Height 与 TargetWidth/TargetHeight 是两组不同的字段!
|
||||
> - `Width/Height`:设备分辨率标记(偏移 4-7),**不影响预处理**
|
||||
> - `TargetWidth/TargetHeight`:预处理实际输出尺寸(偏移 23-26),**直接决定帧数据大小**
|
||||
> **重要**:`Width/Height` 与 `TargetWidth/TargetHeight` 是两组不同的字段!前者仅做标识,后者直接控制帧大小。
|
||||
|
||||
### 7.3 缓冲区容量约束
|
||||
### 11.3 缓冲区容量约束
|
||||
|
||||
```
|
||||
MAX_TCP_PAYLOAD_SIZE = 10240 字节
|
||||
@@ -360,189 +551,119 @@ HeadOffset = 64 字节(协议头预留)
|
||||
最大像素数 = 10176 / 2 = 5088 像素
|
||||
|
||||
推荐安全目标尺寸:
|
||||
64 × 64 = 4096 像素 = 8192 字节 ✓ (< 10176)
|
||||
71 × 71 = 5041 像素 = 10082 字节 ✓ (< 10176)
|
||||
72 × 72 = 5184 像素 = 10368 字节 ✗ (> 10176,会触发降尺寸)
|
||||
64 × 64 = 4096 像素 = 8192 字节 ✓
|
||||
71 × 71 = 5041 像素 = 10082 字节 ✓
|
||||
72 × 72 = 5184 像素 = 10368 字节 ✗ (触发降尺寸)
|
||||
```
|
||||
|
||||
### 7.4 自动降尺寸保护
|
||||
### 11.4 自动降尺寸保护
|
||||
|
||||
当服务器下发的 TargetWidth × TargetHeight × 2 超过可用缓冲区时,MCU 会自动等比减半目标尺寸直到适合:
|
||||
TargetWidth × TargetHeight × 2 超过可用缓冲区时,自动等比减半:
|
||||
|
||||
```
|
||||
示例:服务器设 TargetWidth=185, TargetHeight=70
|
||||
185 × 70 × 2 = 25,900 > 10,176 → 减半
|
||||
93 × 35 × 2 = 6,510 < 10,176 → 使用 93×35
|
||||
日志输出:PP: target clamped 185x70 -> 93x35 (buf=10176)
|
||||
示例:服务器设 185×70 → 185×70×2=25900 > 10176 → 减半 → 93×35
|
||||
日志:PP: target clamped 185x70 -> 93x35 (buf=10176)
|
||||
```
|
||||
|
||||
### 7.5 配置传递链
|
||||
### 11.5 配置传递链
|
||||
|
||||
```
|
||||
服务器 TCP 下发 TLV
|
||||
→ qdx_tcp_logic.c: parse_and_dispatch_tlv()
|
||||
→ 反序列化 → cached_cfg2d / cached_cfg1d / cached_common
|
||||
→ 反序列化 → cached_cfg{2d,1d,common}
|
||||
→ OnConfigUpdate() 回调
|
||||
→ Preprocess_Settings_Change() 互斥锁更新
|
||||
→ 下次 Preprocess_Execute() 使用新配置
|
||||
→ 下次帧处理使用新配置
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. RTOS 任务架构
|
||||
## 12. RTOS 任务架构
|
||||
|
||||
| 任务名 | 优先级 | 栈 (words) | 条件 | 功能 |
|
||||
|--------|--------|-----------|------|------|
|
||||
| `wchnet` | 6 (最高) | 512 | 始终创建 | WCHNET 协议栈轮询 |
|
||||
| `business` | 5 | 512 | `TEST_ENABLE_TCP_SEND=1` | DVP/预处理/发送主循环 |
|
||||
| `testpat` | 4 | 256 | `TEST_PATTERN_MODE=1` | 测试图案生成 |
|
||||
| `hb` | 3 (最低) | 256 | `TEST_ENABLE_HEARTBEAT=1` | 心跳调试打印 |
|
||||
| TcpLogic 内部 | - | - | 始终创建 | 管理线程 (连接/心跳) |
|
||||
|
||||
> 测试模式创建 4 个任务,正常模式创建 3 个(无 testpat)。
|
||||
| `wchnet` | 6 (最高) | 512 | 始终创建 | WCHNET 协议栈轮询 (5ms) |
|
||||
| `business` | 5 | 512 | 始终创建 | DVP + 触发状态机 + 发送 |
|
||||
| `testpat` | 4 | 256 | `TEST_PATTERN_MODE=1` | 测试图案生成 (~10 FPS) |
|
||||
| `hb` | 3 (最低) | 256 | 始终创建 | 心跳调试打印 (2s) |
|
||||
| TcpLogic 内部 | - | - | 始终创建 | 管理线程 (连接/心跳/重连) |
|
||||
|
||||
---
|
||||
|
||||
## 9. 切换模式操作指南
|
||||
## 13. GPIO 引脚分配
|
||||
|
||||
### 9.1 从测试模式 → 正常模式
|
||||
|
||||
1. **修改宏**:打开 `prj/TCPClient/User/main.c`,将:
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 1
|
||||
```
|
||||
改为:
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 0
|
||||
```
|
||||
|
||||
2. **检查传感器配置**:当前模组已通过 USB 预配置,`mini212g2.h` 中 UART 配置已用 `#if 0` 关闭,无需修改。如需重新启用,将 `#if 0` 改为 `#if 1`。
|
||||
|
||||
3. **检查功能开关**:根据需要启用/禁用各子功能:
|
||||
```c
|
||||
#define TEST_ENABLE_TRIGGER 1 // 启用内部触发
|
||||
#define TEST_ENABLE_NG_GPIO 1 // 启用 NG 输出(需接 PA8)
|
||||
```
|
||||
|
||||
4. **编译烧录**:使用 MRS IDE 编译并烧录。
|
||||
|
||||
### 9.2 从正常模式 → 测试模式
|
||||
|
||||
1. **修改宏**:`TEST_PATTERN_MODE` 改为 `1`
|
||||
2. **无需断开传感器**:测试模式跳过所有硬件初始化,传感器接线不影响
|
||||
3. **编译烧录**
|
||||
|
||||
### 9.3 功能开关独立配置
|
||||
|
||||
各功能子开关在两种模式下均可独立启用/禁用,无互相依赖:
|
||||
|
||||
| 开关组合 | 行为 |
|
||||
|---------|------|
|
||||
| PATTERN=1, TRIGGER=1 | 测试模式 + 内部触发连拍(测试热点图案会触发) |
|
||||
| PATTERN=1, TRIGGER=0, TEMP_REQ=1 | 测试模式 + 服务器按需请求(当前配置) |
|
||||
| PATTERN=0, TRIGGER=1, TEMP_REQ=1 | 正常模式 + 自动触发 + 服务器请求(完整功能) |
|
||||
| PATTERN=0, TRIGGER=0, TEMP_REQ=1 | 正常模式 + 仅服务器请求(最简运行) |
|
||||
| TCP_SEND=0 | 禁用 business 任务,系统仅运行网络协议但不处理/发送帧 |
|
||||
| GPIO | 功能 | 方向 | 配置 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| PA15 | 外部触发输入 | 输入 | 下拉 + EXTI15 上升沿 | 2D/1D 共用(互斥) |
|
||||
| PA8 | NG 输出 | 推挽输出 | 低速 2MHz | 检测 NG 时脉冲拉高 |
|
||||
| PA4-PA6, PA9-PA10, PB3, PB8-PB9 | DVP 数据线 | 输入 | 浮空 | 仅正常模式使用 |
|
||||
| PC8, PC9, PC11 | DVP HSYNC/VSYNC/PCLK | 输入 | - | 仅正常模式使用 |
|
||||
| PA2, PA3 | **已占用** | - | - | USART2,不可用 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 常见配置场景
|
||||
## 14. 功能完整性对照表
|
||||
|
||||
### 场景 A:纯软件协议调试(无硬件)
|
||||
### 协议规范 vs MCU 实现
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 1
|
||||
#define TEST_ENABLE_HEARTBEAT 1
|
||||
#define TEST_ENABLE_TRIGGER 0
|
||||
#define TEST_ENABLE_NG_GPIO 0
|
||||
#define TEST_ENABLE_TEMP_REQ 1
|
||||
#define TEST_ENABLE_TCP_SEND 1
|
||||
```
|
||||
|
||||
**适用**:验证 TLV 协议、握手流程、Config 下发、帧分片发送等。
|
||||
|
||||
### 场景 B:测试内部触发 + 连拍
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 1
|
||||
#define TEST_ENABLE_TRIGGER 1 // ← 打开
|
||||
#define TEST_ENABLE_NG_GPIO 0
|
||||
#define TEST_ENABLE_TEMP_REQ 1
|
||||
#define TEST_ENABLE_TCP_SEND 1
|
||||
```
|
||||
|
||||
**适用**:验证 80°C 触发阈值、3 帧连拍、连拍间隔。热点和棋盘格图案会触发。
|
||||
|
||||
### 场景 C:正常模式完整功能
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 0
|
||||
#define TEST_ENABLE_TRIGGER 1
|
||||
#define TEST_ENABLE_NG_GPIO 1 // ← PA8 接报警
|
||||
#define TEST_ENABLE_TEMP_REQ 1
|
||||
#define TEST_ENABLE_TCP_SEND 1
|
||||
```
|
||||
|
||||
**适用**:生产运行,传感器实时采集 + 自动触发 + NG 报警 + 服务器请求。
|
||||
|
||||
### 场景 D:正常模式最小功能验证
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 0
|
||||
#define TEST_ENABLE_TRIGGER 0
|
||||
#define TEST_ENABLE_NG_GPIO 0
|
||||
#define TEST_ENABLE_TEMP_REQ 1 // 仅响应服务器请求
|
||||
#define TEST_ENABLE_TCP_SEND 1
|
||||
```
|
||||
|
||||
**适用**:验证传感器数据采集 + 网络发送,无自动触发逻辑干扰。
|
||||
|
||||
### 场景 E:网络连接诊断
|
||||
|
||||
```c
|
||||
#define TEST_PATTERN_MODE 1
|
||||
#define TEST_ENABLE_HEARTBEAT 1
|
||||
#define TEST_ENABLE_TRIGGER 0
|
||||
#define TEST_ENABLE_NG_GPIO 0
|
||||
#define TEST_ENABLE_TEMP_REQ 0 // 关闭帧请求
|
||||
#define TEST_ENABLE_TCP_SEND 0 // 关闭 business 任务
|
||||
```
|
||||
|
||||
**适用**:仅测试 TCP 连接/断开/重连,不涉及数据帧处理。心跳打印确认系统活跃。
|
||||
| 协议功能 | 实现状态 | 备注 |
|
||||
|---------|---------|------|
|
||||
| 握手 (Handshake) | ✅ | UUID + HW/FW 版本 |
|
||||
| 心跳 (Heartbeat) | ✅ | 2s 间隔,6s 超时断连 |
|
||||
| 设备 ID 分配 (DevID Assign) | ✅ | 触发自动重连 |
|
||||
| Config Common/2D/1D 下发 | ✅ | 解析+缓存+回调 |
|
||||
| ACK 响应 | ✅ | 发送+接收 |
|
||||
| TEMP_REQ 截图 | ✅ | 2D 预处理 / 1D 空间采样 |
|
||||
| Detection Result | ✅ | NG → PA8 脉冲 |
|
||||
| 2D 外部触发 | ✅ | GPIO → 消抖 → 延迟 → 连拍 |
|
||||
| 2D 内部触发 | ✅ | ROI Max/Avg → 延迟 → 连拍 |
|
||||
| 1D 外部触发 | ✅ | GPIO → 消抖 → 采集 → 切片 |
|
||||
| 1D 内部触发 | ✅ | 3 样本预环形 → 采集 → 切片 |
|
||||
| 温度矩阵分片发送 | ✅ | 每片 ≤1400 字节 |
|
||||
| TCP KeepAlive | ✅ | 20s/15s/9次 |
|
||||
| CRC16-MODBUS 校验 | ✅ | 每帧校验 |
|
||||
| IsLive 实时流 | ❌ | MCU 资源不足,触发场景不需要 |
|
||||
| Training 训练模式 | ❌ | 服务器端完成 |
|
||||
| SyncTime 时间同步 | ❌ | 协议已定义 (0x03),未解析 |
|
||||
| StatusEvent 状态上报 | ❌ | 服务器通过心跳判断在线 |
|
||||
| Alarm GPIO | ❌ | 结构体有字段,硬件未接线 |
|
||||
| 1D StartPointsToRemove / ReferenceLength / TimerCLimit | ❌ | 已解析到结构体,业务逻辑未使用 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 已知注意事项
|
||||
## 15. 已知注意事项
|
||||
|
||||
### 11.1 温度单位
|
||||
### 15.1 温度单位
|
||||
|
||||
系统统一使用 **0.1°C/LSB**:
|
||||
- 温度值 350 = 35.0°C
|
||||
- 温度值 900 = 90.0°C
|
||||
- `TEMP_RAW(deg_c) = (uint16_t)(deg_c * 10)`
|
||||
|
||||
### 11.2 TriggerTemperatureThreshold 值
|
||||
### 15.2 Config2D 字段区分
|
||||
|
||||
温度阈值使用 0.1°C/LSB 单位,与系统所有温度值一致。当前测试默认 `TriggerTemperatureThreshold = 800`(80.0°C),测试热点图案 90.0°C(值 900)可正常触发。
|
||||
- **Width / Height**:设备分辨率标识(如 256×192),不影响 MCU 预处理
|
||||
- **TargetWidth / TargetHeight**:预处理实际输出尺寸,**必须正确设置**
|
||||
|
||||
### 11.3 服务器 Config2D 字段区分
|
||||
### 15.3 正常模式默认目标尺寸
|
||||
|
||||
- **Width / Height**(偏移 4-7):设备分辨率标识(如 256×192),不影响 MCU 预处理
|
||||
- **TargetWidth / TargetHeight**(偏移 23-26):预处理输出目标尺寸,**必须正确设置**
|
||||
`TargetWidth=1, TargetHeight=1`(最小默认),必须等服务器下发 Config2D 后才能正常输出。
|
||||
|
||||
如果服务器只设了 Width/Height=64×64 而未设 TargetWidth/TargetHeight,MCU 仍会使用超大目标尺寸(或上次缓存值),导致 `PP fail ret=-3` 或触发自动降尺寸。
|
||||
### 15.4 IP 与端口硬编码
|
||||
|
||||
### 11.4 正常模式默认目标尺寸
|
||||
|
||||
正常模式启动时 `TargetWidth=1, TargetHeight=1`(最小默认),必须等服务器下发 Config2D 后才会更新为正确值。测试模式自动加载 64×64。
|
||||
|
||||
### 11.5 IP 与端口硬编码
|
||||
|
||||
当前网络参数(IP、端口)为编译期常量,更改需修改源码并重新编译:
|
||||
网络参数为编译期常量,更改需修改源码并重新编译:
|
||||
- MCU IP:`main.c` → `IPAddr[]`
|
||||
- 服务器 IP:`qdx_tcp_logic.c` → `SERVER_IP`
|
||||
- 端口号:`qdx_tcp_logic.c` → `CONTROL_PORT` / `DATA_PORT`
|
||||
|
||||
### 11.6 printf 限制
|
||||
### 15.5 printf 限制
|
||||
|
||||
使用 newlib-nano,仅支持 `%d, %x, %s` 格式。所有 `uint32_t` 变量必须强制转换 `(int)` 后打印,否则可能 HardFault。不支持 `%u, %lu, %f`。
|
||||
使用 newlib-nano,仅支持 `%d, %x, %s` 格式。所有 `uint32_t` 必须 `(int)` 强转后打印,否则 HardFault。不支持 `%u, %lu, %f`。
|
||||
|
||||
### 15.6 双缓冲发送
|
||||
|
||||
系统使用 A/B 交替 `TcpTxBuffer_t`,避免发送过程中缓冲区被覆盖。`use_buffer_A` 标志在每次发送后翻转。
|
||||
|
||||
### 15.7 2D/1D 互斥
|
||||
|
||||
主循环中 `Config2D.Enabled` 优先级高于 `Config1D.Enabled`。若两者同时 Enabled=1,仅 2D 管线运行。
|
||||
|
||||
Reference in New Issue
Block a user