diff --git a/docs/项目架构与工作流程分析.md b/docs/项目架构与工作流程分析.md new file mode 100644 index 0000000..dd8ad83 --- /dev/null +++ b/docs/项目架构与工作流程分析.md @@ -0,0 +1,261 @@ +# LaserTracing 项目架构与工作流程分析 + +## 1. 项目概述 + +LaserTracing(激光示踪)是基于华大 HC32L170(ARM Cortex-M0+)超低功耗 MCU 的嵌入式传感器项目。设备通过 LoRa(SX1276)无线通信接入网关,采集三维姿态角(俯仰/横滚/偏航)并定时上报,同时支持激光控制、低功耗休眠、FPO 全功率时间段等特性。 + +### 1.1 硬件组成 + +| 模块 | 型号/接口 | 用途 | +|------|-----------|------| +| MCU | HC32L170 | 主控,Cortex-M0+ | +| LoRa | SX1276 (SPI0) | 与网关无线通信 | +| 加速度计 | LSM6DSL (I2C0) | 采集加速度/陀螺仪 | +| 地磁 | MMC5983 (I2C0) | 采集磁场 | +| 激光 | LASER1~3 (GPIO) | 激光开关控制 | +| ADC | ADC (EXCH4) | 电池电压采样 | +| 调试口 | UART/RS485 | 调试命令交互 | + +### 1.2 软件版本 + +- 软件版本: `SOFTWARE_VERSION = 12` +- 硬件版本: `HARDWARE_VERSION = 11` + +## 2. 目录结构 + +``` +LaserTracing/ +├── MDK/ # Keil 工程文件 (uvprojx/uvoptx/RTE) +├── Module/ # 功能模块 +│ ├── Imu/ # IMU 姿态解算上层 +│ ├── LORA/ # SX1276 LoRa 驱动 (sx127x.c/h) +│ ├── LaserTracing_Debug/ # 调试命令模块 (UartDebug.c/h) +│ ├── MahonyAHRS/ # 姿态解算算法库 +│ ├── lsm6dsl/ # LSM6DSL 驱动 (含寄存器层) +│ └── mmc5983/ # MMC5983 驱动 +├── driver/ # HC32L170 官方外设驱动库 (inc/src) +├── mcu/ # 芯片支持包 (启动文件、FlashLoader) +├── source/ +│ ├── inc/ # 项目头文件 +│ │ ├── main.h # 应用结构体/状态机/全局声明 +│ │ ├── bsp.h # 板级定义/参数结构/外设宏 +│ │ ├── SGCP.h # 通信协议定义 +│ │ ├── Algorithm.h # 算法接口 +│ │ ├── Update.h # 升级接口 +│ │ └── UartDebug.h # 调试接口 +│ └── src/ +│ ├── main.c # 主流程/状态机/数据采集 +│ ├── bsp.c # 板级初始化/中断处理/外设封装 +│ ├── SGCP.c # 通信协议栈 (网关交互) +│ ├── Algorithm.c # 工具函数/辅助算法 +│ └── Update.c # 固件升级逻辑 +└── docs/ # 本文档 +``` + +## 3. 核心架构分层 + +### 3.1 分层结构 + +``` +┌─────────────────────────────────────────────┐ +│ 应用层 (main.c) │ +│ - AppInit/主循环/状态机/数据采集与处理 │ +├─────────────────────────────────────────────┤ +│ 协议层 (SGCP.c) │ +│ - 注册/上报/配置/激光/信号 帧处理与状态机 │ +├─────────────────────────────────────────────┤ +│ 模块层 (Module/) │ +│ - LoRa/IMU/AHRS/传感器/调试 各功能模块 │ +├─────────────────────────────────────────────┤ +│ 驱动层 (driver/ + bsp.c) │ +│ - HC32L170 外设驱动 + 板级封装 │ +└─────────────────────────────────────────────┘ +``` + +### 3.2 关键全局对象 + +- `App` (`AppDetect_t`):应用状态、传感器数据、姿态结果、配置参数、各类标志与计数器。 +- `SGCP` (`SGCP_t`):通信协议状态、网关/设备 MAC、接收缓冲区、指令状态机标志。 +- `LocalMAC` / `GatewayMAC`:本机 6 字节 MAC 与网关 MAC。 +- `LocalDataPack`:本机待上报的打包数据。 + +## 4. 工作流程分析 + +### 4.1 系统启动流程 (main) + +``` +main() + ├─ BspInit() # 时钟、GPIO、外设、中断初始化 + ├─ delay_ms(3000) # 上电等待 + ├─ AppInit() # 读参数、校验恢复默认、初始化 RTC/LPTimer/LoRa/传感器 + ├─ 打印版本信息 + └─ while(1) 主循环 + ├─ ADCLoopHandler() # 电池电压采样 + ├─ FeedDogHandler() # 看门狗喂狗 + ├─ DebugLoopHandler() # 调试命令处理 + ├─ Lsm6dslLoopHandler() # 加速度数据处理 + ├─ MMC5983LoopHandler() # 地磁数据处理 + ├─ ReadDataLoopHandler() # 数据采集状态机 + ├─ GwRevLoopHandler() # 网关收发状态机 + ├─ InRevLoopHandler() # 内部指令处理 + └─ AppLoopHandler() # 应用状态机 +``` + +### 4.2 时基中断与回调 + +| 中断 | 功能 | +|------|------| +| SysTick_CallBack (1ms) | 调用各 1mSRoutine 递减计数器 | +| RtcIRQHander (30s) | 系统定时重启、定时采集触发、周期上报、紧急上报 | +| LPTimer0IRQHander | 注册/上传重试定时器 | +| PortB_IRQHandler | LoRa DIO0(发送完成/接收完成) | +| PortC_IRQHandler | 加速度 INT1 / 地磁 INT 回调 | + +### 4.3 应用状态机 (AppLoopHandler / APP_STATUS_*) + +``` +APP_STATUS_SLEEP → APP_STATUS_ON → APP_STATUS_ACTION + │ + ┌─────────────────────────────────┼───────────────────────────────┐ + ▼ ▼ ▼ +APP_STATUS_WAIT_LOGIN (数据采集) APP_STATUS_WAIT_UPLOAD + │ 注册成功 │ 采集完成(UpdateOk) │ 上传完成/超时 + └───────▶ APP_STATUS_ACTION └───────▶ 触发上传 └──────▶ ACTION +``` + +关键转移条件(`AppLoopHandler` 中按优先级判断): +1. `InStatus != IDLE` → 等待内部指令完成 +2. `LoginOk == false && LoginFlag == true && GWStatus == IDLE` → 发起注册 +3. `TimingAcquisition == true && RDStatus == IDLE` → 启动传感器采集 +4. `LoginOk == true && UploadFlag == true && GWStatus == IDLE && UpdateOk == true` → 上传数据 +5. `LaserOnOff == true && LaserTimerCount == 0` → 激光状态处理 +6. 全部空闲且 `IsFullPowerTime() == false` → 进入休眠 (`APP_STATUS_OFF`) + +### 4.4 数据采集状态机 (ReadDataLoopHandler / READDATA_STATUS_*) + +``` +READDATA_STATUS_IDLE + └─(TimingAcquisition=true)─▶ READDATA_STATUS_UPDAING + (启动 LSM6DSL + MMC5983,置 ReadData1mSDelayCnt=2000) + └─▶ READDATA_STATUS_WAIT_UPDAING + (等待中断回调置 MagRead_EndFlag / AccRead_EndFlag 或 2s 超时) + └─▶ READDATA_STATUS_DATA_HANDLE + (IMU_Update 解算 → 存 ConvertedData → 拷入 LocalDataPack) + └─▶ READDATA_STATUS_IDLE (置 UpdateOk=true) +``` + +若任一传感器超时(未收到中断),`UpdateOk` 保持 false,本周期数据不用于上报。 + +### 4.5 注册与数据上报时序 + +1. 上电后 `LPTimer0_ON(50)`(5s)后 `LoginFlag=true`。 +2. `APP_STATUS_ACTION` 检测到注册条件 → `GW_STATUS_LOGIN` → `ToGWDevLogin()` 发送注册帧(Cmd=0x00)。 +3. 网关回应注册 → `GWRevHandler` 置 `LoginOk`、保存 `GatewayMAC` → `GW_STATUS_WAIT_LOGIN` 置 `LoginMess`、`TimingAcquisition=true`。 +4. `APP_STATUS_WAIT_LOGIN` 置 `UploadFlag=true` 并触发采集。 +5. 采集完成 `UpdateOk=true` → `APP_STATUS_ACTION` 置 `GW_STATUS_UPLOAD_SENSOR` → `ToGWReadDataRes()` 发送数据帧(Cmd=0x02)。 +6. `GW_STATUS_WAIT_UPLOAD` 等网关回应(2s 超时)。收到回应 `UploadOk=true` → 上报成功;超时则 `UploadMess=true`,由 `APP_STATUS_WAIT_UPLOAD` 计数重试,3 次失败后重新注册。 + +### 4.6 协议帧格式 (SGCP) + +网关↔设备固定帧(16 字节头): + +``` +| Header(1) | GWAddr(6) | MDAddr(6) | Cmd(1) | PayloadLen(2) | Payload(N) | CRC16(2) | +``` + +命令字(网关→设备): + +| Cmd | 含义 | +|-----|------| +| 0x00 | 设备注册 (GWTOMD_CMD_LOGIN) | +| 0x01 | 校准 (GWTOMD_CMD_CALI) | +| 0x02 | 读取/上传数据 (GWTOMD_CMD_READ_UPLOAD_SENSOR) | +| 0x05 | 设置采集时间间隔 (GWTOMD_CMD_SET_COL_TIME) | +| 0x06 | 时间同步 (GWTOMD_CMD_SYNC_TIME) | +| 0x08 | 打开/关闭激光 (GWTOMD_CMD_SET_LASER) | +| 0x09 | 信号质量查询 (GWTOMD_CMD_SIGNAL) | +| 0x0A | 设置全功率运行时间段 (GWTOMD_CMD_SET_FPO) | + +`LayoutPara_t` 参数(网关下发,10 字节 + 时间戳):CollectTime / ReportInterval / ERInterval / ERTime / FPOTimeStart / FPOTime / TimeStamp。 + +### 4.7 网关状态机 (GwRevLoopHandler / GW_STATUS_*) + +``` +GW_STATUS_IDLE + ├─▶ LOGIN → WAIT_LOGIN → IDLE # 注册流程 + ├─▶ CALI → 校准回应 # 校准 + ├─▶ SET_COL_TIME → 采集间隔回应 + ├─▶ SET_FPO → 全功率时间段回应 (0x0A) + ├─▶ SYNC_TIME → 时间同步 + ├─▶ UPLOAD_SENSOR → WAIT_UPLOAD # 上报流程 + ├─▶ LASER_STARES → 激光状态回应 + └─▶ SIGNAL → WAIT_SIGNAL → 信号质量 +``` + +### 4.8 低功耗与休眠 + +- 空闲时判断:`RDStatus==IDLE && GWStatus==IDLE && InStatus==IDLE && !TimingAcquisition && 各延时==0 && !LaserOnOff && !AttTestMode && !IsFullPowerTime()` → `APP_STATUS_OFF` → 关闭 LED → `APP_STATUS_SLEEP`。 +- `APP_STATUS_SLEEP` 中调用 `EnterDeepSleep()` 深睡眠,`WakeUpInit()` 唤醒后回 `APP_STATUS_ON`。 +- **FPO 全功率时间段**:由 `IsFullPowerTime()` 判断当前本地小时是否落在 `[FPOTimeStart, FPOTimeStart+FPOTime)` 区间内(支持跨天、0 时长表示关闭),在 FPO 时段内不进入休眠。FPOTime 默认 0,`TimeGet` 从 RTC 读取当前小时(本地时间)。 + +### 4.9 激光控制 + +- 网关下发 0x08 指令置 `SGCP.LaserOnOff`,`LaserTimerMinutes`(默认 **1 分钟**)决定自动关闭时长。 +- `GW_STATUS_LASER_STARES` 中执行 `LASER1_ON/OFF()` 并回应网关。 +- RTC 30s 中断中 `LaserTimerCount--`,归零后再次进入 `GW_STATUS_LASER_STARES` 执行关闭。 + +## 5. 通信模式配置 + +| 宏 | 值 | 说明 | +|----|----|------| +| `WORK_MODE` | 1 | 0=查询模式,1=上报模式(低功耗) | +| `SGCP_SELECT` | 1 | 0=主+子多设备,1=单主设备(当前),2=单子设备 | +| `USE_VBAT_AD` | 1 | 电池电压采样开关 | +| `USE_WDT` | 1 | 看门狗开关 | +| `USE_DEBUG` | 1 | 调试命令开关 | +| `USE_BOOTLOADER` | 0 | BootLoader 升级开关 | + +## 6. LoRa 信道配置 + +中心频率范围 **470100000 ~ 492600000 Hz**,步进 **500000 Hz**,共 **46 个信道**(CH0~CH45): + +- CH0 = 470100000,CH1 = 470600000,...,CH45 = 492600000。 +- 默认 `FREQ_CENT = CH0`;信道切换上限 `LoraSetChannel` 允许 0~45。 +- 频率范围校验(`LoraSetFreqCent` / AppInit):410000000 ~ 525000000,覆盖全部信道。 +- 可通过调试命令 `lora ch <0~45>` 配置信道。 + +## 7. 调试命令 (UartDebug) + +| 命令 | 说明 | +|------|------| +| `reg` | 手动触发注册 | +| `para` | 打印当前配置参数(含 FPO、激光状态) | +| `lpcfg CI RI EI ET` | 配置低功耗采集/上报参数 | +| `fpocfg Start Dur` | 配置全功率运行时间段(配置后自动向网关发送 0x0A 通知) | +| `lora ch/pw/bw/sf/ec/rp/fc/o` | 配置 LoRa 参数 | +| `laser` | 激光控制与定时配置 | +| `rs485` / `dch` | RS485 通道控制 / 调试通道切换 | +| `res` | 恢复出厂设置 | +| `dbg` | 调试开关控制 | + +## 8. 关键文件与职责对照 + +| 文件 | 主要职责 | +|------|----------| +| `source/src/main.c` | 主流程、应用状态机、数据采集状态机、FPO 判断、中断回调 | +| `source/src/SGCP.c` | 协议栈:帧组包/解析、网关状态机、注册/上报/配置/激光/信号处理 | +| `source/src/bsp.c` | 板级初始化、外设封装、中断处理、RTC/TimeGet/低功耗 | +| `source/inc/SGCP.h` | 协议常量、帧结构、命令字、状态机、设备数据定义 | +| `source/inc/bsp.h` | 板级宏、参数结构(LayoutPara_t 等)、外设引脚定义 | +| `source/inc/main.h` | 应用结构体、状态机枚举、宏定义 | +| `Module/LORA/sx127x.c` | LoRa 收发、信道/频率/功率配置 | +| `Module/LaserTracing_Debug/UartDebug.c` | 调试命令解析执行 | +| `Module/lsm6dsl` / `mmc5983` | 传感器驱动与数据回调 | +| `Module/MahonyAHRS` / `Imu` | 姿态解算 | + +## 9. 典型问题排查路径 + +- **注册失败/超时**:查 `GW_STATUS_WAIT_LOGIN` 超时日志、网关 MAC 是否保存、LoRa 接收是否正常。 +- **上传超时**:查 `GW_STATUS_WAIT_UPLOAD` 日志、`LocalDataPack` 是否全 0(`is_all_byte` 检查)、`UpdateOk` 是否被置位、传感器采集是否超时。 +- **无法休眠**:查 `IsFullPowerTime()` 时段判断、`InStatus/GWStatus/RDStatus` 是否处于非 IDLE、各类延时计数是否清零。 +- **LoRa 通信异常**:核对信道频率范围(470.1~492.6MHz)与网关是否一致、`FREQ_CENT`/`FreqCent` 配置、天线开关状态。 \ No newline at end of file