261 lines
13 KiB
Markdown
261 lines
13 KiB
Markdown
# 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` 配置、天线开关状态。 |