13 KiB
13 KiB
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 中按优先级判断):
InStatus != IDLE→ 等待内部指令完成LoginOk == false && LoginFlag == true && GWStatus == IDLE→ 发起注册TimingAcquisition == true && RDStatus == IDLE→ 启动传感器采集LoginOk == true && UploadFlag == true && GWStatus == IDLE && UpdateOk == true→ 上传数据LaserOnOff == true && LaserTimerCount == 0→ 激光状态处理- 全部空闲且
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 注册与数据上报时序
- 上电后
LPTimer0_ON(50)(5s)后LoginFlag=true。 APP_STATUS_ACTION检测到注册条件 →GW_STATUS_LOGIN→ToGWDevLogin()发送注册帧(Cmd=0x00)。- 网关回应注册 →
GWRevHandler置LoginOk、保存GatewayMAC→GW_STATUS_WAIT_LOGIN置LoginMess、TimingAcquisition=true。 APP_STATUS_WAIT_LOGIN置UploadFlag=true并触发采集。- 采集完成
UpdateOk=true→APP_STATUS_ACTION置GW_STATUS_UPLOAD_SENSOR→ToGWReadDataRes()发送数据帧(Cmd=0x02)。 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配置、天线开关状态。