4 Commits

Author SHA1 Message Date
YuanHongbin e849f719a7 docs: 新增激光示踪参数文档(电池容量/传感器参数/LoRa频率等整机参数汇总) 2026-09-08 15:31:05 +08:00
YuanHongbin 706eb1247e feat: LoRa中心频率改为470.1~492.6MHz(46信道), 激光默认关闭时间改为1分钟, 软件版本升至13
- sx127x.h: CH0~CH45中心频率改为470100000~492600000, 步进500000; FREQ_CENT/USE_LORA_CH扩展至CH45
- sx127x.c: LoraSetChannel信道上限16->45; LoraSetFreqCent频率校验改为470.1~492.6MHz; 移除BOM
- main.c: LoraFreq频率校验同步改为470.1~492.6MHz; 激光默认关闭时间10分钟->1分钟
- UartDebug.c: lora帮助文本信道范围更新为0~45
- main.h: 软件版本12->13
- docs: 更新软件版本号与LoRa频率范围说明
- MDK: 调试器配置更新
2026-09-01 19:14:32 +08:00
YuanHongbin c417d124a0 docs: 新增项目架构与工作流程分析文档 2026-09-01 19:06:16 +08:00
YuanHongbin f239690002 feat: 新增全功率运行时间段(FPO)功能
- bsp.h: LayoutPara_t 新增 FPOTimeStart/FPOTime 字段, 移除BOM, 声明TimeGet
- main.h: 声明 IsFullPowerTime
- main.c: 新增 IsFullPowerTime() 判断函数(支持跨天), 睡眠条件加FPO检查, AppInit中FPO参数初始化与校验
- SGCP.h: 新增 GWTOMD_CMD_SET_FPO=0x0A, GW_STATUS_SET_FPO 枚举, 声明 ToGWSetFPORes
- SGCP.c: 实现 ToGWSetFPORes() 回应帧, GWTOMD_CMD_SET_FPO 接收处理(校验/存Flash), 两个GwRevLoopHandler新增GW_STATUS_SET_FPO case
- UartDebug.c: 新增 fpocfg 调试命令(配置后向网关发送0x0A通知), para输出FPO信息, DEBUG_CMD_CNT 17->18
- bsp.c: TimeGet 去除UTC+8偏移(RTC已存本地时间)
2026-08-17 10:36:33 +08:00
12 changed files with 698 additions and 56 deletions
+24 -7
View File
@@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>12</nTsel> <nTsel>6</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@@ -114,7 +114,7 @@
<tDlgDll></tDlgDll> <tDlgDll></tDlgDll>
<tDlgPa></tDlgPa> <tDlgPa></tDlgPa>
<tIfile></tIfile> <tIfile></tIfile>
<pMon>BIN\CMSIS_AGDI.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry> <SetRegEntry>
@@ -135,7 +135,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>JL2CM3</Key> <Key>JL2CM3</Key>
<Name>-U4294967295 -O78 -S1 -ZTIFSpeedSel10000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8027 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0FlashHC32L17X_128K.FLM -FS00 -FL020000 -FP0($$Device:HC32L170JATA$Flash\FlashHC32L17X_128K.FLM)</Name> <Name>-U12345678 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8027 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0FlashHC32L17X_128K.FLM -FS00 -FL020000 -FP0($$Device:HC32L170JATA$Flash\FlashHC32L17X_128K.FLM)</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@@ -411,7 +411,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>12</nTsel> <nTsel>6</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@@ -422,7 +422,7 @@
<tDlgDll></tDlgDll> <tDlgDll></tDlgDll>
<tDlgPa></tDlgPa> <tDlgPa></tDlgPa>
<tIfile></tIfile> <tIfile></tIfile>
<pMon>BIN\CMSIS_AGDI.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry> <SetRegEntry>
@@ -443,7 +443,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>JL2CM3</Key> <Key>JL2CM3</Key>
<Name>-U4294967295 -O78 -S1 -ZTIFSpeedSel10000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8027 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0FlashHC32L17X_128K.FLM -FS00 -FL020000 -FP0($$Device:HC32L170JATA$Flash\FlashHC32L17X_128K.FLM)</Name> <Name>-U12345678 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8027 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0FlashHC32L17X_128K.FLM -FS00 -FL020000 -FP0($$Device:HC32L170JATA$Flash\FlashHC32L17X_128K.FLM)</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@@ -461,7 +461,24 @@
<Name></Name> <Name></Name>
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>255</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>0</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>0</BreakIfRCount>
<Filename>..\source\inc\bsp.h</Filename>
<ExecCommand></ExecCommand>
<Expression></Expression>
</Bp>
</Breakpoint>
<WatchWindow1> <WatchWindow1>
<Ww> <Ww>
<count>0</count> <count>0</count>
+3 -3
View File
@@ -1,4 +1,4 @@
#include "sx127x.h" #include "sx127x.h"
#include "ddl.h" #include "ddl.h"
#include "UartDebug.h" #include "UartDebug.h"
@@ -622,7 +622,7 @@ void Sx1276RxRetValue(void)
bool LoraSetChannel(uint8_t Channel) bool LoraSetChannel(uint8_t Channel)
{ {
if(Channel > 16) if(Channel > 45)
return false; return false;
LoRaPara.ucChannel = Channel; LoRaPara.ucChannel = Channel;
return true; return true;
@@ -667,7 +667,7 @@ bool LoraSetRegPreamble(uint8_t RegPreamble)
} }
bool LoraSetFreqCent(uint32_t FreqCent) bool LoraSetFreqCent(uint32_t FreqCent)
{ {
if(FreqCent < 410000000 || FreqCent > 525000000) if(FreqCent < 470100000ul || FreqCent > 492600000ul)
return false; return false;
LoRaPara.dwFreqHz = FreqCent; LoRaPara.dwFreqHz = FreqCent;
return true; return true;
+118 -13
View File
@@ -756,19 +756,54 @@ typedef struct {
#endif #endif
/* /*
中心频率配置:433100000ul + 200000*N 中心频率配置:470100000ul ~ 492600000ul,步进500000
*/ */
#define CH0 (433100000ul + 0) //测试频率 #define CH0 (470100000ul) //出厂默认频率
#define CH1 (433100000ul + 200000) #define CH1 (470600000ul)
#define CH2 (433100000ul + 400000) #define CH2 (471100000ul)
#define CH3 (433100000ul + 600000) #define CH3 (471600000ul)
#define CH4 (433100000ul + 800000) #define CH4 (472100000ul)
#define CH5 (433100000ul + 1000000) #define CH5 (472600000ul)
#define CH6 (433100000ul + 1200000) #define CH6 (473100000ul)
#define CH7 (433100000ul + 1400000) #define CH7 (473600000ul)
#define CH8 (433100000ul + 1600000) #define CH8 (474100000ul)
#define CH9 (433100000ul + 1800000) #define CH9 (474600000ul)
#define CH10 (433100000ul + 2000000) #define CH10 (475100000ul)
#define CH11 (475600000ul)
#define CH12 (476100000ul)
#define CH13 (476600000ul)
#define CH14 (477100000ul)
#define CH15 (477600000ul)
#define CH16 (478100000ul)
#define CH17 (478600000ul)
#define CH18 (479100000ul)
#define CH19 (479600000ul)
#define CH20 (480100000ul)
#define CH21 (480600000ul)
#define CH22 (481100000ul)
#define CH23 (481600000ul)
#define CH24 (482100000ul)
#define CH25 (482600000ul)
#define CH26 (483100000ul)
#define CH27 (483600000ul)
#define CH28 (484100000ul)
#define CH29 (484600000ul)
#define CH30 (485100000ul)
#define CH31 (485600000ul)
#define CH32 (486100000ul)
#define CH33 (486600000ul)
#define CH34 (487100000ul)
#define CH35 (487600000ul)
#define CH36 (488100000ul)
#define CH37 (488600000ul)
#define CH38 (489100000ul)
#define CH39 (489600000ul)
#define CH40 (490100000ul)
#define CH41 (490600000ul)
#define CH42 (491100000ul)
#define CH43 (491600000ul)
#define CH44 (492100000ul)
#define CH45 (492600000ul)
#if (USE_LORA_CH == 0) #if (USE_LORA_CH == 0)
#define FREQ_CENT CH0 #define FREQ_CENT CH0
@@ -792,10 +827,80 @@ typedef struct {
#define FREQ_CENT CH9 #define FREQ_CENT CH9
#elif (USE_LORA_CH == 10) #elif (USE_LORA_CH == 10)
#define FREQ_CENT CH10 #define FREQ_CENT CH10
#elif (USE_LORA_CH == 11)
#define FREQ_CENT CH11
#elif (USE_LORA_CH == 12)
#define FREQ_CENT CH12
#elif (USE_LORA_CH == 13)
#define FREQ_CENT CH13
#elif (USE_LORA_CH == 14)
#define FREQ_CENT CH14
#elif (USE_LORA_CH == 15)
#define FREQ_CENT CH15
#elif (USE_LORA_CH == 16)
#define FREQ_CENT CH16
#elif (USE_LORA_CH == 17)
#define FREQ_CENT CH17
#elif (USE_LORA_CH == 18)
#define FREQ_CENT CH18
#elif (USE_LORA_CH == 19)
#define FREQ_CENT CH19
#elif (USE_LORA_CH == 20)
#define FREQ_CENT CH20
#elif (USE_LORA_CH == 21)
#define FREQ_CENT CH21
#elif (USE_LORA_CH == 22)
#define FREQ_CENT CH22
#elif (USE_LORA_CH == 23)
#define FREQ_CENT CH23
#elif (USE_LORA_CH == 24)
#define FREQ_CENT CH24
#elif (USE_LORA_CH == 25)
#define FREQ_CENT CH25
#elif (USE_LORA_CH == 26)
#define FREQ_CENT CH26
#elif (USE_LORA_CH == 27)
#define FREQ_CENT CH27
#elif (USE_LORA_CH == 28)
#define FREQ_CENT CH28
#elif (USE_LORA_CH == 29)
#define FREQ_CENT CH29
#elif (USE_LORA_CH == 30)
#define FREQ_CENT CH30
#elif (USE_LORA_CH == 31)
#define FREQ_CENT CH31
#elif (USE_LORA_CH == 32)
#define FREQ_CENT CH32
#elif (USE_LORA_CH == 33)
#define FREQ_CENT CH33
#elif (USE_LORA_CH == 34)
#define FREQ_CENT CH34
#elif (USE_LORA_CH == 35)
#define FREQ_CENT CH35
#elif (USE_LORA_CH == 36)
#define FREQ_CENT CH36
#elif (USE_LORA_CH == 37)
#define FREQ_CENT CH37
#elif (USE_LORA_CH == 38)
#define FREQ_CENT CH38
#elif (USE_LORA_CH == 39)
#define FREQ_CENT CH39
#elif (USE_LORA_CH == 40)
#define FREQ_CENT CH40
#elif (USE_LORA_CH == 41)
#define FREQ_CENT CH41
#elif (USE_LORA_CH == 42)
#define FREQ_CENT CH42
#elif (USE_LORA_CH == 43)
#define FREQ_CENT CH43
#elif (USE_LORA_CH == 44)
#define FREQ_CENT CH44
#elif (USE_LORA_CH == 45)
#define FREQ_CENT CH45
#endif #endif
#if !defined FREQ_CENT #if !defined FREQ_CENT
#define FREQ_CENT (433100000ul + 0)//200000 #define FREQ_CENT (470100000ul)//500000
#endif #endif
#if !defined FREQ_DEV #if !defined FREQ_DEV
#define FREQ_DEV 1000000ul #define FREQ_DEV 1000000ul
+69 -2
View File
@@ -12,7 +12,7 @@
#if (USE_DEBUG != 0) #if (USE_DEBUG != 0)
#define DEBUG_CMD_CNT 17 #define DEBUG_CMD_CNT 18
const DBGFunType DebugFun[DEBUG_CMD_CNT]; const DBGFunType DebugFun[DEBUG_CMD_CNT];
volatile DebugChannel_e gDebugChannel = DBG_CH_RS485_1;//上电默认调试口 volatile DebugChannel_e gDebugChannel = DBG_CH_RS485_1;//上电默认调试口
@@ -214,6 +214,10 @@ static void DebugCmdGetPara(int argc, char *argv[])
DBG_LOG("Lora: ch %d, rp %d, fc %d\r\n", App.Para.Lora.ucChannel, App.Para.Lora.RegPreamble, App.Para.Lora.FreqCent); DBG_LOG("Lora: ch %d, rp %d, fc %d\r\n", App.Para.Lora.ucChannel, App.Para.Lora.RegPreamble, App.Para.Lora.FreqCent);
DBG_LOG("LpCfg: CI:%dsec, RI:%dmin, EI:%dmin, ET:%dmin\r\n", DBG_LOG("LpCfg: CI:%dsec, RI:%dmin, EI:%dmin, ET:%dmin\r\n",
App.Para.Layout.CollectTime*30, App.Para.Layout.ReportInterval/2, App.Para.Layout.ERInterval/2, App.Para.Layout.ERTime/2); App.Para.Layout.CollectTime*30, App.Para.Layout.ReportInterval/2, App.Para.Layout.ERInterval/2, App.Para.Layout.ERTime/2);
DBG_LOG("FpoCfg: Start:%02d:00, Dur:%dh, End:%02d:00, %s\r\n",
App.Para.Layout.FPOTimeStart, App.Para.Layout.FPOTime,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24,
(IsFullPowerTime() == true) ? "FullPower" : "LowPower");
DBG_LOG("Laser: %s, AutoOff: %dmin\r\n", DBG_LOG("Laser: %s, AutoOff: %dmin\r\n",
(SGCP.LaserOnOff == true) ? "ON" : "OFF", SGCP.LaserTimerMinutes); (SGCP.LaserOnOff == true) ? "ON" : "OFF", SGCP.LaserTimerMinutes);
struct tm *stime; struct tm *stime;
@@ -558,7 +562,7 @@ static void DebugLoraConfig(int argc, char *argv[])
if(strcmp(argv[1], "?") == 0) { if(strcmp(argv[1], "?") == 0) {
DBG_LOG("Debug Cmd: lora arg1 arg2\r\n"); DBG_LOG("Debug Cmd: lora arg1 arg2\r\n");
DBG_LOG(" brief --> Configure Lora parameters.\r\n"); DBG_LOG(" brief --> Configure Lora parameters.\r\n");
DBG_LOG(" arg1 --> ch: Channel--para=(0~16)\r\n"); DBG_LOG(" arg1 --> ch: Channel--para=(0~45)\r\n");
DBG_LOG(" pw: Power--para=(0~20)\r\n"); DBG_LOG(" pw: Power--para=(0~20)\r\n");
DBG_LOG(" bw: SignalBw--para=(0~9)\r\n"); DBG_LOG(" bw: SignalBw--para=(0~9)\r\n");
DBG_LOG(" sf: SpreadFactor--para=(6~12)\r\n"); DBG_LOG(" sf: SpreadFactor--para=(6~12)\r\n");
@@ -739,6 +743,58 @@ static void DebugCmdLPConfig(int argc, char *argv[])
DBG_LOG("The low-power device is configured.\r\n"); DBG_LOG("The low-power device is configured.\r\n");
} }
/***************************************************************************************** /*****************************************************************************************
* 函数名称: DebugCmdFPOConfig
* 功能描述: 全功率运行时间段配置
* 参 数: argc, 输入参数数量
argv, 输入参数
* 返 回 值: 无
*****************************************************************************************/
static void DebugCmdFPOConfig(int argc, char *argv[])
{
DBG_LOG("\r\n");
if(argc < 2)
return;
if(strcmp(argv[1], "?") == 0) {
DBG_LOG("Debug Cmd: fpocfg arg1 arg2\r\n");
DBG_LOG(" brief --> Configure full-power work period.\r\n");
DBG_LOG(" arg1 --> Full-power work start hour. (0~23 hour)\r\n");
DBG_LOG(" arg2 --> Full-power work duration. (0~24 hour, 0=off)\r\n\r\n");
return;
}
if(argc < 3)
return;
uint8_t FPOTimeStart = (uint8_t)atoi(argv[1]);
uint8_t FPOTime = (uint8_t)atoi(argv[2]);
if(FPOTimeStart > 23) {
DBG_LOG("FPOTimeStart Para Error! (0~23)\r\n");
return;
}
if(FPOTime > 24) {
DBG_LOG("FPOTime Para Error! (0~24)\r\n");
return;
}
App.Para.Layout.FPOTimeStart = FPOTimeStart;
App.Para.Layout.FPOTime = FPOTime;
SAVE_APP_PARA((uint32_t *)&App.Para);
DBG_LOG("The full-power work period is configured. Start:%02d:00, Dur:%dh, End:%02d:00\r\n",
App.Para.Layout.FPOTimeStart, App.Para.Layout.FPOTime,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24);
if(SGCP.LoginOk)
{
ToGWSetFPORes();
DBG_LOG("FPO config update sent to gateway.\r\n");
}
else
{
DBG_LOG("Gateway not logged in, skip sending FPO config update.\r\n");
}
}
/*****************************************************************************************
* 函数名称: DebugLaserConfig * 函数名称: DebugLaserConfig
* 功能描述: 激光控制 * 功能描述: 激光控制
* 参 数: argc, 输入参数数量 * 参 数: argc, 输入参数数量
@@ -1062,6 +1118,16 @@ void DebugCmdHelp(int argc, char *argv[])
} }
DebugCmdLPConfig(argc1, argv1); DebugCmdLPConfig(argc1, argv1);
memset(Data, 0x00, 10);
len = strlen("fpocfg ?\0");
memcpy(Data, "fpocfg ?\0", len);
token = strtok(Data, " "); // 假设分隔符是空格
for(argc1 = 0; (token != NULL && argc1 < 10); argc1++) {
argv1[argc1] = token;
token = strtok(NULL, " ");
}
DebugCmdFPOConfig(argc1, argv1);
memset(Data, 0x00, 10); memset(Data, 0x00, 10);
len = strlen("laser ?\0"); len = strlen("laser ?\0");
memcpy(Data, "laser ?\0", len); memcpy(Data, "laser ?\0", len);
@@ -1134,6 +1200,7 @@ const DBGFunType DebugFun[DEBUG_CMD_CNT] = {
"rs485", DebugCmdRS485Ctrl, "rs485", DebugCmdRS485Ctrl,
"lora", DebugLoraConfig, "lora", DebugLoraConfig,
"lpcfg", DebugCmdLPConfig, "lpcfg", DebugCmdLPConfig,
"fpocfg", DebugCmdFPOConfig,
"laser", DebugLaserConfig, "laser", DebugLaserConfig,
"res", DebugCmdRestoreFactory, "res", DebugCmdRestoreFactory,
"dch", DebugCmdChannel, "dch", DebugCmdChannel,
+261
View File
@@ -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 = 13`
- 硬件版本: `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):470100000 ~ 492600000,覆盖全部信道。
- 可通过调试命令 `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` 配置、天线开关状态。
+3
View File
@@ -98,6 +98,7 @@ typedef enum {
GW_STATUS_CALI, GW_STATUS_CALI,
GW_STATUS_READ_SENSOR, GW_STATUS_READ_SENSOR,
GW_STATUS_SET_COL_TIME, GW_STATUS_SET_COL_TIME,
GW_STATUS_SET_FPO,//设置全功率运行时间段
GW_STATUS_SYNC_TIME, GW_STATUS_SYNC_TIME,
GW_STATUS_UPLOAD_SENSOR,//主动上报模式时会使用该状态 GW_STATUS_UPLOAD_SENSOR,//主动上报模式时会使用该状态
GW_STATUS_WAIT_UPLOAD,//主动上报模式时会使用该状态 GW_STATUS_WAIT_UPLOAD,//主动上报模式时会使用该状态
@@ -125,6 +126,7 @@ typedef enum {
GWTOMD_CMD_LOGIN = 0x00, //0x00,设备注册 GWTOMD_CMD_LOGIN = 0x00, //0x00,设备注册
GWTOMD_CMD_CALI = 0x01, //0x01, 校准指令 GWTOMD_CMD_CALI = 0x01, //0x01, 校准指令
GWTOMD_CMD_READ_UPLOAD_SENSOR = 0x02, //0x02,读取数据指令or上传数据指令 GWTOMD_CMD_READ_UPLOAD_SENSOR = 0x02, //0x02,读取数据指令or上传数据指令
GWTOMD_CMD_SET_FPO = 0x0A, //0x0A, 设置全功率运行时间段(低功耗设备)
GWTOMD_CMD_SET_COL_TIME = 0x05, //0x05,设置采集时间间隔 GWTOMD_CMD_SET_COL_TIME = 0x05, //0x05,设置采集时间间隔
GWTOMD_CMD_SYNC_TIME = 0x06, //0x06,时间同步 GWTOMD_CMD_SYNC_TIME = 0x06, //0x06,时间同步
GWTOMD_CMD_SET_LASER = 0x08,//打开or关闭激光 GWTOMD_CMD_SET_LASER = 0x08,//打开or关闭激光
@@ -281,6 +283,7 @@ typedef struct {
extern SGCP_t SGCP; extern SGCP_t SGCP;
void SGCP1mSRoutine(void); void SGCP1mSRoutine(void);
void ToGWSetFPORes(void);
void GwRevLoopHandler(void); void GwRevLoopHandler(void);
void MasRevLoopHandler(void); void MasRevLoopHandler(void);
+4 -1
View File
@@ -1,4 +1,4 @@
#ifndef _BSP_H #ifndef _BSP_H
#define _BSP_H #define _BSP_H
#include <stdint.h> #include <stdint.h>
@@ -225,6 +225,8 @@ typedef struct {
uint16_t ReportInterval; //上报时间间隔,设置范围,30*N秒,10<=N<=1440(默认1200秒,N=40) uint16_t ReportInterval; //上报时间间隔,设置范围,30*N秒,10<=N<=1440(默认1200秒,N=40)
uint8_t ERInterval; //紧急上报时间间隔,设置范围,30*N秒,2<=N<=10(默认120秒,N=4) uint8_t ERInterval; //紧急上报时间间隔,设置范围,30*N秒,2<=N<=10(默认120秒,N=4)
uint8_t ERTime; //紧急上报时长,设置范围,30*N秒,20<=N<=240(默认1200秒,N=40) uint8_t ERTime; //紧急上报时长,设置范围,30*N秒,20<=N<=240(默认1200秒,N=40)
uint8_t FPOTimeStart; //每天全功率工作时间起始点时间,设置范围0~23小时整点时间(默认0点整)
uint8_t FPOTime; //每天全功率工作时间时长,设置范围0~24小时(默认0小时)
uint32_t TimeStamp; //网关返回RTC时间戳 uint32_t TimeStamp; //网关返回RTC时间戳
}__attribute__((packed))LayoutPara_t,*LayoutPara;//上位机下发的配置参数 }__attribute__((packed))LayoutPara_t,*LayoutPara;//上位机下发的配置参数
@@ -279,6 +281,7 @@ uint32_t GetSysTick(void);
void delay_ms(uint32_t ms); void delay_ms(uint32_t ms);
void Delay(uint32_t time); void Delay(uint32_t time);
void RTCInit(uint8_t sec); void RTCInit(uint8_t sec);
void TimeGet(struct tm *cTime);
void LPTimer0_ON(uint16_t _100ms); void LPTimer0_ON(uint16_t _100ms);
void LPTimer0_OFF(void); void LPTimer0_OFF(void);
void WakeUpInit(void); void WakeUpInit(void);
+2 -1
View File
@@ -5,7 +5,7 @@
#include "Update.h" #include "Update.h"
#include "Imu.h" #include "Imu.h"
#define SOFTWARE_VERSION 12 //软件版本 #define SOFTWARE_VERSION 13 //软件版本
#define HARDWARE_VERSION 11 //硬件版本 #define HARDWARE_VERSION 11 //硬件版本
#define MAIN_DBG_LOG(...) { if(MainDispEn) DBG_LOG(__VA_ARGS__);} #define MAIN_DBG_LOG(...) { if(MainDispEn) DBG_LOG(__VA_ARGS__);}
@@ -107,6 +107,7 @@ extern AppDetect_t App;
void MainDBGOnOff(bool OnOff); void MainDBGOnOff(bool OnOff);
void DataDBGOnOff(bool OnOff); void DataDBGOnOff(bool OnOff);
bool IsFullPowerTime(void);
#endif #endif
+117
View File
@@ -652,6 +652,46 @@ SGCP.GWRS485Rx.sCmdMDToGW = (GWTOMD_CMD_M)GFHeader->Cmd;
#endif #endif
} }
/**
*******************************************************************************
** \brief 网关设置全功率运行时间段指令回应
**
** \param 无(回显已配置的 FPOTimeStart 与 FPOTime,与接收格式一致)
**
** \retval 无
******************************************************************************/
void ToGWSetFPORes(void)
{
uint8_t Pack[256];
uint16_t Crc16;
uint8_t Len;
GatewayFrameHeader GFHeader = (GatewayFrameHeader)Pack;
GFHeader->Header = 0x7B;
memcpy(&GFHeader->GWAddr[0], &GatewayMAC[0], sizeof(GFHeader->GWAddr));
memcpy(&GFHeader->MDAddr[0], &LocalMAC[0], sizeof(GFHeader->MDAddr));
GFHeader->Cmd = GWTOMD_CMD_SET_FPO;
GFHeader->PayloadLen = 2;
Len = sizeof(GatewayFrameHeader_t);
Pack[Len++] = App.Para.Layout.FPOTimeStart;
Pack[Len++] = App.Para.Layout.FPOTime;
Crc16 = CRC_Modbus(CRC16_BASE, Pack, Len);
Pack[Len++] = Crc16 & 0x00ff;
Pack[Len++] = (Crc16 >> 8) & 0x00ff;
SGCP.GWRS485Rx.sCmdMDToGW = (GWTOMD_CMD_M)GFHeader->Cmd;
#if(SGCP_SELECT == 1 || SGCP_SELECT == 2)
Sx1276LoRaSendBuffer(Pack, Len);
#endif
#if(SGCP_SELECT == 3)
LPUart0SendArray(Pack, Len);
#endif
}
/** /**
******************************************************************************* *******************************************************************************
** \brief 网关时间同步指令回应 ** \brief 网关时间同步指令回应
@@ -1007,6 +1047,46 @@ static void GWRevHandler(void)
} }
break;} break;}
case GWTOMD_CMD_SET_FPO:{
if(SGCP.LoginOk == true)
{
uint8_t Start = PayLoad[0];
uint8_t Duration = PayLoad[1];
if(Start > 23)
{
DBG_LOG("FPOTimeStart Err\r\n");
if(SGCP.GWStatus == GW_STATUS_WAIT_UPLOAD)
{
SGCP.UploadOk = true;
SGCP.NextGWStatus = GW_STATUS_IDLE;
}
return;
}
if(Duration > 24)
{
DBG_LOG("FPOTime Err\r\n");
if(SGCP.GWStatus == GW_STATUS_WAIT_UPLOAD)
{
SGCP.UploadOk = true;
SGCP.NextGWStatus = GW_STATUS_IDLE;
}
return;
}
if(SGCP.GWStatus == GW_STATUS_WAIT_UPLOAD)
{
SGCP.UploadOk = true;
SGCP.NextGWStatus = GW_STATUS_SET_FPO;
}
else
{
SGCP.GWStatus = GW_STATUS_SET_FPO;
}
App.Para.Layout.FPOTimeStart = Start;
App.Para.Layout.FPOTime = Duration;
SAVE_APP_PARA((uint32_t *)&App.Para);
}
break;}
case GWTOMD_CMD_SET_COL_TIME:{ case GWTOMD_CMD_SET_COL_TIME:{
if(SGCP.LoginOk == true) if(SGCP.LoginOk == true)
{ {
@@ -1471,6 +1551,25 @@ void GwRevLoopHandler(void)
SGCP.GW1mSDelayCnt = 5000; SGCP.GW1mSDelayCnt = 5000;
break;} break;}
case GW_STATUS_SET_FPO:{
PrintfMess();
if(SGCP.BroadCmd == true)
{
SGCP.BroadCmd = false;
DBG_LOG("Broad FPO Set as %02d:00 ~ %02d:00\r\n", App.Para.Layout.FPOTimeStart,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24);
}
else
{
ToGWSetFPORes();
DBG_LOG("Alone FPO Set as %02d:00 ~ %02d:00\r\n", App.Para.Layout.FPOTimeStart,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24);
}
SGCP.GWStatus = GW_STATUS_WAIT_SUBIDLE;
SGCP.NextSubStatus = SUB_STATUS_BROADCAST_SET_COLTIME;
SGCP.GW1mSDelayCnt = 5000;
break;}
case GW_STATUS_SYNC_TIME:{ case GW_STATUS_SYNC_TIME:{
PrintfMess(); PrintfMess();
if(SGCP.BroadCmd == true) if(SGCP.BroadCmd == true)
@@ -1795,6 +1894,24 @@ void GwRevLoopHandler(void)
SGCP.GWStatus = GW_STATUS_IDLE; SGCP.GWStatus = GW_STATUS_IDLE;
break;} break;}
case GW_STATUS_SET_FPO:{
PrintfMess();
if(SGCP.BroadCmd == true)
{
SGCP.BroadCmd = false;
DBG_LOG("Broad FPO Set as %02d:00 ~ %02d:00\r\n", App.Para.Layout.FPOTimeStart,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24);
}
else
{
ToGWSetFPORes();
DBG_LOG("Alone FPO Set as %02d:00 ~ %02d:00\r\n", App.Para.Layout.FPOTimeStart,
(App.Para.Layout.FPOTimeStart + App.Para.Layout.FPOTime) % 24);
}
/*GWRevHandler函数中已经缓存了接收到的全功率运行时间段*/
SGCP.GWStatus = GW_STATUS_IDLE;
break;}
case GW_STATUS_SYNC_TIME:{ case GW_STATUS_SYNC_TIME:{
PrintfMess(); PrintfMess();
if(SGCP.BroadCmd == true) if(SGCP.BroadCmd == true)
+1 -1
View File
@@ -647,7 +647,7 @@ void TimeGet(struct tm *cTime)
cTime->tm_year = BCDToDec(RtcDateTime.u8Year) + 100; cTime->tm_year = BCDToDec(RtcDateTime.u8Year) + 100;
cTime->tm_mon = BCDToDec(RtcDateTime.u8Month) - 1; cTime->tm_mon = BCDToDec(RtcDateTime.u8Month) - 1;
cTime->tm_mday = BCDToDec(RtcDateTime.u8Day); cTime->tm_mday = BCDToDec(RtcDateTime.u8Day);
cTime->tm_hour = BCDToDec(RtcDateTime.u8Hour) + 8; cTime->tm_hour = BCDToDec(RtcDateTime.u8Hour);
cTime->tm_min = BCDToDec(RtcDateTime.u8Minute); cTime->tm_min = BCDToDec(RtcDateTime.u8Minute);
cTime->tm_sec = BCDToDec(RtcDateTime.u8Second); cTime->tm_sec = BCDToDec(RtcDateTime.u8Second);
cTime->tm_isdst = 0; cTime->tm_isdst = 0;
+41 -4
View File
@@ -132,12 +132,15 @@ static void AppInit(void)
App.Para.Layout.ReportInterval = 40; App.Para.Layout.ReportInterval = 40;
App.Para.Layout.ERInterval = 4; App.Para.Layout.ERInterval = 4;
App.Para.Layout.ERTime = 40; App.Para.Layout.ERTime = 40;
App.Para.Layout.FPOTime = 0;
App.Para.Layout.FPOTimeStart = 0;
} }
if(App.Para.BLPara.LoraFreq < 410000000 || App.Para.BLPara.LoraFreq > 525000000) if(App.Para.BLPara.LoraFreq < 470100000ul || App.Para.BLPara.LoraFreq > 492600000ul)
App.Para.BLPara.LoraFreq = CH0; App.Para.BLPara.LoraFreq = CH0;
App.Para.Lora.FreqCent = App.Para.BLPara.LoraFreq; App.Para.Lora.FreqCent = App.Para.BLPara.LoraFreq;
SX1276LoRaWriteFreq(App.Para.Lora.FreqCent); //Lora频率:433100000ul + 200000*N SX1276LoRaWriteFreq(App.Para.Lora.FreqCent); //Lora频率:470100000ul + 500000*N
if(App.Para.Rs485Ch1.Addr > 16 || App.Para.Rs485Ch1.Addr < 1){ if(App.Para.Rs485Ch1.Addr > 16 || App.Para.Rs485Ch1.Addr < 1){
App.Para.Rs485Ch1.Addr = 1; App.Para.Rs485Ch1.Addr = 1;
@@ -157,8 +160,14 @@ static void AppInit(void)
if(App.Para.Layout.ERTime > 240 || App.Para.Layout.ERTime < 20) { if(App.Para.Layout.ERTime > 240 || App.Para.Layout.ERTime < 20) {
App.Para.Layout.ERTime = 40; App.Para.Layout.ERTime = 40;
} }
if(App.Para.Layout.FPOTimeStart > 23 || App.Para.Layout.FPOTimeStart < 0) {
App.Para.Layout.FPOTimeStart = 0;
}
if(App.Para.Layout.FPOTime > 24 || App.Para.Layout.FPOTime < 0) {
App.Para.Layout.FPOTime = 0;
}
if(App.Para.LaserTimerMinutes < 0 || App.Para.LaserTimerMinutes > 240) if(App.Para.LaserTimerMinutes < 0 || App.Para.LaserTimerMinutes > 240)
App.Para.LaserTimerMinutes = 10; App.Para.LaserTimerMinutes = 1;
SGCP.LaserTimerMinutes = App.Para.LaserTimerMinutes; SGCP.LaserTimerMinutes = App.Para.LaserTimerMinutes;
SAVE_APP_PARA((uint32_t *)&App.Para); SAVE_APP_PARA((uint32_t *)&App.Para);
@@ -316,6 +325,33 @@ static void ReadDataLoopHandler(void)
} }
} }
bool IsFullPowerTime(void)
{
uint8_t Duration = App.Para.Layout.FPOTime;
uint8_t Start = App.Para.Layout.FPOTimeStart;
uint8_t Hour;
struct tm cTime;
if(Duration == 0)
return false;
TimeGet(&cTime);
Hour = (uint8_t)(cTime.tm_hour % 24);
if(Start + Duration <= 24)
{
if(Hour >= Start && Hour < Start + Duration)
return true;
}
else
{
uint8_t WrapEnd = Start + Duration - 24;
if(Hour >= Start || Hour < WrapEnd)
return true;
}
return false;
}
static void AppLoopHandler(void) static void AppLoopHandler(void)
{ {
switch(App.Status) { switch(App.Status) {
@@ -385,7 +421,8 @@ static void AppLoopHandler(void)
&& App.TD1mSDelayCnt == 0 && App.TD1mSDelayCnt == 0
&& App.ReadData1mSDelayCnt == 0 && App.ReadData1mSDelayCnt == 0
&& SGCP.LaserOnOff == false && SGCP.LaserOnOff == false
&& App.AttTestMode == false) && App.AttTestMode == false
&& IsFullPowerTime() == false)
{ {
//App.Status = APP_STATUS_ACTION; //App.Status = APP_STATUS_ACTION;
App.Status = APP_STATUS_OFF; App.Status = APP_STATUS_OFF;
+31
View File
@@ -0,0 +1,31 @@
设备前述:建议长时间供电,送检样机不需要进入低功耗,避免设备重复性差的问题。
该版本为低功耗版本,采用12V供电,休眠电流380uA,工作电流18mA
硬件版本记录:HV4.x系列
==>>Crack_Left_HV4.0 and Crack_Right_HV4.0
1、H7233-1:LDO,输出稳定的3.3V,最大输入15V
2、HC32L170JATA-LQ48:设备的MCU主控芯片
3、LSM6DSLTR:六轴加速度芯片
4、MMC5983MA:三轴地磁芯片
5、MAX3471EUA+:串口转485芯片
6、Ra-02:LORA通信芯片
硬件版本变更记录:
Crack_Left_HV4.0 ==> Crack_Left_HV4.1 Release 2024-06-21
Crack_Right_HV4.0 ==> Crack_Right_HV4.1 Release 2024-06-21
1、调整了主副板FPC母座位置
==> Crack_Left_HV4.0 Release 2024-06-12
==> Crack_Right_HV4.0 Release 2024-06-12
1、板框改大
2、连接座子换成5P+4P的FPC座子
3、传感器中断脚修改
代码版本变更记录:
CrackUnit_Active_SV1.0 ==>> CrackUnit_Active_SV1.1 Release 2024-08-08
1、使用了MMC5983中断引脚,修复了驱动bug
2、修复了均值滤波函数bug
==>>CrackUnit_Active_SV1.0 Release 2024-08-01
该版本为低功耗版本