Files
stc32g128k/Docs/30_architecture/main.md

265 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构设计说明书 (Docs/30_architecture/main.md)
本章节定义手环的系统软硬件架构设计,包括引脚分配、核心状态机迁移关系、持久化数据存储结构以及软件分层框架与主循环调度流程。
---
## 1. 硬件原理图与引脚分配架构
手环的完整电路连接设计参见以下 KiCad 硬件工程文件:
* **硬件原理图**[text.kicad_sch](file:///c:/workfile/105/stc32g12k128/Hardware/text.kicad_sch)
* **PCB 布局图**[text.kicad_pcb](file:///c:/workfile/105/stc32g12k128/Hardware/text.kicad_pcb)
主控芯片采用 **STC32G12K128**(工作频率 24.0 MHz单周期 8051 内核32位乘除法器
显示端采用 **Truly 0.95寸 AMOLED 屏幕**,物理分辨率为 **120x240 像素**,控制芯片为 **RM69310**
### 1.1 GPIO 物理映射表
| 引脚号 | 引脚名称 | IO 模式 | 连接外设与功能描述 |
| :--- | :--- | :--- | :--- |
| **P0.0** | `BAT_ADC` | 模拟输入 | 电池电压采样输入端口,对应硬件 ADC 通道 8 (A8) |
| **P0.1** | `KEY_UP` | 高阻输入+上拉 | 侧边按键 ▲ (上移),按下为低电平 |
| **P0.2** | `KEY_SOS1` | 高阻输入+上拉 | 上部按键 SOS 1按下为低电平 |
| **P0.3** | `KEY_DOWN` | 高阻输入+上拉 | 侧边按键 ▼ (下移),按下为低电平 |
| **P0.4** | `KEY_CONFIRM`| 高阻输入+上拉 | 侧边按键 ■ (确认),按下为低电平 |
| **P0.5** | `KEY_SOS2` | 高阻输入+上拉 | 上部按键 SOS 2按下为低电平 |
| **P1.1** | `LCD_RST` | 推挽输出 | LCD 屏幕复位引脚 |
| **P1.3** | `LCD_RS` | 推挽输出 | LCD 屏幕 SPI 数据/命令寄存器选择 (D/C) |
| **P1.4** | `LCD_CS` | 推挽输出 | LCD 屏幕 SPI 片选信号 |
| **P1.5** | `LCD_SCL` | 推挽输出 | LCD 屏幕 SPI 时钟信号 |
| **P1.6** | `LCD_SDA` | 推挽输出 | LCD 屏幕 SPI 数据信号 |
| **P2.3** | `WS2812_DI` | SPI MOSI | 连接可编程双级联 RGB 灯珠的 DIN 信号输入 |
| **P2.5** | `MOTOR` | 推挽输出 | 连接振动马达驱动电路。高电平震动,低电平静止 |
| **P2.7** | `USB_DET` | 高阻输入 | USB 插入充电检测引脚,高电平代表正在充电 |
| **P3.4** | `SGM_CTRL` | 推挽输出 | OLED 供电芯片 SGM3833 控制引脚。高电平使能,低电平关闭 |
---
## 2. 软件核心业务状态机
系统包含 10 个业务状态,其状态迁移关系如下图所示:
```mermaid
stateDiagram-v2
[*] --> STATE_CLOCK
%% 休眠与唤醒
STATE_CLOCK --> STATE_SLEEP : 10秒无操作超时
STATE_SLEEP --> STATE_CLOCK : 中断唤醒 (按键/无线信号)
%% 主选择菜单迁移
STATE_CLOCK --> STATE_MENU : CONFIRM 长按 3 秒
STATE_MENU --> STATE_CLOCK : CONFIRM 长按 3 秒 / 10秒无操作超时
STATE_MENU --> STATE_SLEEP : 10秒无操作超时
%% 子设置页面迁移
STATE_MENU --> STATE_SET_TIME : 选中 "1. DATE/HEURE" + 确认键单击
STATE_SET_TIME --> STATE_CLOCK : 保存退出 / 10秒无操作超时
STATE_MENU --> STATE_PAIR_SEARCH : 选中 "2. APPAIRAGE" + 确认键单击
STATE_PAIR_SEARCH --> STATE_PAIR_CONFIRM : 捕获 433MHz 传感器数据
STATE_PAIR_CONFIRM --> STATE_CLOCK : CONFIRM/SOS 确认并保存配置
STATE_PAIR_SEARCH --> STATE_MENU : 长按 ▼ 键退出
STATE_MENU --> STATE_ARM_DISARM_SELECT : 选中 "3. ARM/DISARM" + 确认键单击
STATE_ARM_DISARM_SELECT --> STATE_CLOCK : 选择完成并返回
STATE_MENU --> STATE_IPC_BIND : 选中 "4. LIAISON IPC" + 确认键单击
STATE_IPC_BIND --> STATE_CLOCK : 发射结束 / 确认键长按 3s 退出 / ▼键长按 2s 退出
%% 报警迁移
STATE_CLOCK --> STATE_SOS_EMITTED : 按下上部任意 SOS 键 (点击/长按)
STATE_SLEEP --> STATE_SOS_EMITTED : 中断唤醒直接报警
STATE_SOS_EMITTED --> STATE_CLOCK : 按任意键/超时退出
STATE_CLOCK --> STATE_ALARMING : 捕获已配对传感器报警 (ZONE 0 或布防下的 ZONE 1)
STATE_ALARMING --> STATE_CLOCK : 按任意键/超时退出
```
### 2.1 低功耗设计与唤醒架构
为实现超低功耗,系统在 `STATE_SLEEP` 状态下使用以下硬件与软件协同设计:
1. **彻底切断 PMIC**:拉低 `SGM_CTRL = 0`,使 SGM3833 停止工作,彻底消除 Truly AMOLED 屏的负压静态功耗。
2. **休眠配置**:允许 P0 口电平变化中断与射频接收引脚的中断使能。
3. **进入停机**:将单片机挂起写入 `PCON |= 0x02` 进入停机模式,关闭主时钟。
4. **中断唤醒**:按键按下或 LR690L 接收到载波变化时,触发中断唤醒 MCUISR 立即拉高 `SGM_CTRL = 1` 并延时约 50ms 重新初始化 RM69310 屏幕控制器以恢复显示。
---
## 3. 持久化配置数据库架构
为了确保配对数据掉电不丢失,手环使用内置 IAP 读写 Flash 扇区:
* **物理存储扇区**`0xFE0000` (末尾扇区,大小为 512 字节)。
* **数据库容量**:共 16 组传感器配置槽位。
* **存储结构定义**
```c
typedef struct {
u8 is_used; // 有效标志 (0x01: 有效, 其它: 空闲)
u8 addr[3]; // 24位射频物理地址 (EV1527)
u8 type; // 传感器类型 (0: 门磁, 1: 红外, 2: 烟感, 3: 紧急, 4: 气体, 5: 水浸, 6: 振动)
u8 zone; // 防区类别 (0: 永久防区, 1: 普通可撤布防区)
char name_gbk[16]; // 法语自定义防区名称 (格式化为: [名前缀] [两位序号])
} Sensor_Slot;
```
---
## 4. 软件层级架构与核心代码框架
软件系统采用 **非阻塞** 的三层级模块化架构设计:
```mermaid
graph TD
subgraph Layer3 [应用层 (APP)]
MainScheduler[主循环轮询 & 喂狗]
SysStateMachine[SystemState 业务状态机]
SoftRTC[软件 RTC 计时器]
end
subgraph Layer2 [外设驱动层 (DRV)]
AMOLED[RM69310 AMOLED 屏幕绘制]
RF[LR690L 编解码 & 过滤 0x08 SOS 信号]
KEY[按键消抖 & 长按长计时]
PM[低功耗休眠与唤醒]
LED[WS2812B 级联双彩灯时序]
MOTOR[振动马达脉冲时序]
end
subgraph Layer1 [硬件抽象与时基层 (HW)]
Timer1[Timer 1 中断 (1ms 滴答)]
ADC[12位电压采集]
Flash[IAP 读写]
GPIO[数字 I/O 与电平中断]
end
Layer1 --> Layer2
Layer2 --> Layer3
```
### 4.1 核心主程序调度框架 (main.c)
主程序采用完全解耦的时间片轮询加事件触发的非阻塞循环结构:
```c
#include "config.h"
// 全局状态变量
SystemState current_state;
u16 inactivity_timer;
u32 rx_addr;
u8 rx_type;
void main(void) {
// 1. 初始化底层硬件与外设驱动
System_Init();
Power_Init(); // SGM_CTRL 默认拉高工作
LCD_Init(); // Truly AMOLED 初始化
RF_Init(); // LR690L 接收中断与发射初始化
WS2812_Init(); // 双级联彩灯初始化
Motor_Init(); // 马达脉冲时序初始化
ADC_Init(); // 电池采样初始化
// 2. 载入持久化数据配置
Load_Database();
// 3. 初始化软件状态与计时器
current_state = STATE_CLOCK;
inactivity_timer = 0;
Redraw = 1;
// 开启全局中断
EA = 1;
// 4. 核心主循环轮询调度
while (1) {
// A. 轮询射频接收
if (EV1527_Decode(&rx_addr, &rx_type)) {
inactivity_timer = 0; // 重置休眠计数
Process_RF_Event(rx_addr, rx_type);
}
// B. 轮询并消耗按键事件
if (key_event_buf != KEY_EVENT_NONE) {
KeyEvent evt = key_event_buf;
key_event_buf = KEY_EVENT_NONE; // 清空事件
inactivity_timer = 0; // 重置休眠计数
Process_System_Event(evt);
}
// C. 超时低功耗检测判定
if (inactivity_timer >= 1000) { // 10秒无操作
inactivity_timer = 0;
current_state = STATE_SLEEP;
// 执行硬件关屏断电并让单片机进入深度休眠
Enter_Low_Power_Sleep();
// 被外部中断唤醒后从此处开始继续向下运行,执行电源与显示恢复
Wakeup_Restore();
current_state = STATE_CLOCK;
Redraw = 1;
}
// D. 屏幕刷新渲染调度
if (Redraw) {
Redraw = 0; // 清除标志
Render_UI_Screen(current_state);
}
// E. 喂狗操作
WDT_CONTR = 0x17;
}
}
```
---
## 5. 模块间输入/输出事件与流转处理消耗图
为了使各功能模块Drivers & App交互逻辑清晰可见下表整理了各模块产生的事件源输入及其被消费输出的处理链路
### 5.1 模块输入/输出事件矩阵
| 模块名称 | 输入源 (触发源) | 产生/发出事件 | 输出消费对象 (消费处理) |
| :--- | :--- | :--- | :--- |
| **按键模块 (KEY)** | 物理引脚P0.1~P0.5)电平状态改变 | `KeyEvent`<br>- `KEY_UP_SHORT` / `KEY_DOWN_SHORT`<br>- `KEY_DOWN_LONG` (长按▼ 2秒)<br>- `KEY_CONFIRM_CLICK`<br>- `KEY_CONFIRM_LONG` (长按■ 3秒)<br>- `KEY_SOS_SHORT` / `KEY_SOS_LONG` (SOS键短按或长按) | 写入全局事件缓冲队列 `key_event_buf`。由 **APP 应用状态机** 读出后用于控制页面导航、退出告警或启动对码。 |
| **无线射频 (RF)** | LR690L 433MHz 载波信号接收(输入电平变化) | `RFEvent` (包含 `rx_addr``rx_type`) | 传递至 **APP 状态机**`Process_RF_Event` 进行报警分发。 |
| **状态机 (APP)** | 消耗 `key_event_buf``RFEvent` | `SysState` 业务状态跳转及动作指令 | 1. 改变 `current_state` 并设置 `Redraw = 1`<br>2. 调度 **LED****MOTOR** 开启报警灯效/马达振动;<br>3. 写入 **IAP Flash 数据库** 配对记录;<br>4. 调用 **RF** 发送 `0x01` (IPC对码) 或 `0x08` (主动SOS)。 |
| **显示模块 (LCD)** | 状态机重绘请求 `Redraw == 1` | SPI 串行像素显示数据流 | 驱动 **Truly AMOLED** 渲染当前状态所对应的时钟、主菜单、对码、时间设定或报警画面。 |
| **供电管理 (POWER)**| 1. `inactivity_timer >= 1000` (10秒超时)<br>2. 中断唤醒信号 (GPIO/INT2) | 电源电平控制及停机状态 | 1. **进入休眠**:发出关屏指令 $
ightarrow$ 拉低 `SGM_CTRL = 0` $
ightarrow$ 执行停机挂起(主循环暂停在 `Enter_Low_Power_Sleep` 内);<br>2. **唤醒恢复**:拉高 `SGM_CTRL = 1` $
ightarrow$ 延时 50ms $
ightarrow$ 重新初始化 RM69310 屏幕控制器(主循环恢复运行并在待机页重新走时)。 |
| **彩灯模块 (LED)** | 状态机调用报警指示请求 | SPI 48-bit 灯珠级联控制字 | 向两颗级联的 WS2812B 发送颜色数据(报警时交替闪烁,配对时常亮)。 |
| **马达模块 (MOTOR)**| 状态机请求按键反馈/告警振动 | IO 电平状态控制字 (P2.5) | 定时驱动 `P2.5` 引脚电平产生不同振动波形(如短振、长振、间歇循环振动)。 |
### 5.2 事件流转与消费链路拓扑
手环系统的输入事件(按键中断与无线载波中断)在主循环中的处理与消耗流转关系如下:
```mermaid
flowchart TD
%% 硬件输入事件
PinKey[物理按键按下 / 下降沿] -->|P0.1-P0.5 端口中断| ISR_Port0[Port0 中断 ISR]
Carrier[433MHz 射频载波信号] -->|INT2 中断| ISR_INT2[INT2 唤醒中断 ISR]
%% 中断服务层 (ISR)
ISR_Port0 -->|唤醒系统并每10ms扫描| KeyScan[消抖与长短按判定]
ISR_INT2 -->|唤醒系统并使能软解码| RFDecode[EV1527 自适应比值解码]
%% 事件过滤与缓冲层
KeyScan -->|判定有效按键事件| BufKey[写入 key_event_buf 缓冲区]
RFDecode --> ProcessRF[生成合法传感器 RFEvent]
%% APP 状态机消费处理
BufKey -->|主循环读取并重置| SM_Key[消费按键事件]
ProcessRF -->|主循环调用并比对配置| SM_RF[消费已配对防区报警]
SM_Key -->|CONFIRM 长按 3s| StateMenu[切入 STATE_MENU 并 Redraw=1]
SM_Key -->|子页面确认操作| StateSub[执行配对/布防/时间设定并 IAP 写入]
SM_Key -->|点击/长按 SOS 键| EmitSOS[调用 RF 主动发射 0x08 SOS 信号]
SM_Key -->|告警状态任意键| ClearAlarm[清除本地报警状态并退回时钟]
SM_RF -->|匹配成功且处于布防| LocalAlarm[触发 LED 交替闪烁 & 马达间歇振动]
%% 显示与控制响应
StateMenu -->|Redraw == 1| LcdPaint[Truly AMOLED 屏幕局部像素重绘]
StateSub -->|Redraw == 1| LcdPaint
LocalAlarm -->|Redraw == 1| LcdPaint
EmitSOS -->|Redraw == 1| LcdPaint
```