Files
stc32g128k/Docs/30_architecture/main.md

171 lines
12 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)
本章节定义手环的系统软硬件架构设计,包括引脚分配、基于事件驱动的 APP 框架微内核设计、事件生命周期流转机制以及持久化数据存储结构。
---
## 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 模式 | 连接外设与功能描述 |
| :--- | :--- | :--- | :--- | :--- |
| **Pin 1** | `P1.0` | `TXD` | 推挽输出 | 串口 1 (UART1) 发送脚 |
| **Pin 2** | `P1.1` | `RXD` | 高阻输入 | 串口 1 (UART1) 接收脚 |
| **Pin 4** | `P1.5` | `+3.3V` | 电源 | 屏幕/系统 3.3V 逻辑供电 |
| **Pin 5** | `P1.6` | `+3.3V` | 电源 | 屏幕/系统 3.3V 逻辑供电 |
| **Pin 6** | `P1.7` | `TP_RST` | 推挽输出 | 触摸屏复位脚 (NC) |
| **Pin 8** | `UCAP` | `TP_INT` | 输入中断 | 触摸屏中断唤醒脚 (NC) |
| **Pin 9** | `P5.4` | `SPI_SDO` | 推挽输出 | Truly AMOLED 屏幕 SPI 串行数据输出 (MISO) |
| **Pin 10** | `Vcc` | `SPI_CS` | 推挽输出 | Truly AMOLED 屏幕 SPI 片选信号 (CS) |
| **Pin 11** | `VREF+` | `SPI_CLK` | 推挽输出 | Truly AMOLED 屏幕 SPI 串行时钟信号 (SCL) |
| **Pin 12** | `GND` | `SPI_SDI` | 推挽输出 | Truly AMOLED 屏幕 SPI 串行数据输入 (MOSI/SDA) |
| **Pin 13** | `P3.0` | `SPI_DCX` | 推挽输出 | Truly AMOLED 屏幕 SPI 数据/指令选择脚 (D/C) |
| **Pin 14** | `P3.1` | `DIS_RST` | 推挽输出 | Truly AMOLED 屏幕复位控制脚 (RESET) |
| **Pin 19** | `P3.6` | `KEY_DOWN` | 高阻输入 + 上拉 | 侧边按键 ▼ (下移),按下为低电平 |
| **Pin 20** | `P3.7` | `KEY_CONFIRM` | 高阻输入 + 上拉 | 侧边按键 ■ (确认/菜单),按下为低电平 |
| **Pin 21** | `P2.0` | `KEY_UP` | 高阻输入 + 上拉 | 侧边按键 ▲ (上移),按下为低电平 |
| **Pin 22** | `P2.1` | `BAT_ADC` | 模拟输入 | 电池电压采样输入端口,对应硬件 ADC 通道 9 (A9) |
| **Pin 23** | `P2.2` | `DET` | 高阻输入 | USB 插入充电检测引脚,高电平代表正在充电 |
| **Pin 24** | `P2.3` | `KEY_SOS` | 高阻输入 + 上拉 | 上部并联 SOS 求救按键,按下为低电平 |
| **Pin 25** | `P2.4` | `MOTOR_PWM` | 推挽输出 | 连接振动马达驱动电路。高电平震动,低电平静止 |
| **Pin 27** | `P2.6` | `LED_RGB` | SPI MOSI | WS2812B 级联双幻彩灯珠 DIN 控制信号 |
| **Pin 28** | `P2.7` | `SHUT` | 推挽输出 | OLED 供电芯片 SGM3833 控制引脚。高电平开启供电,低电平切断 |
| **Pin 29** | `P0.0` | `RF_RX_DATA` | 输入中断 | LR690L 433MHz 射频接收芯片数据输出脚 (INT0/INT2) |
| **Pin 30** | `P0.1` | `RF_TX` | 推挽输出 | LR690L 射频芯片发射使能控制引脚 |
| **Pin 31** | `P0.2` | `RF_RX` | 推挽输出 | LR690L 射频芯片接收使能控制引脚 |
| **Pin 32** | `P0.3` | `RF_TX_DAT` | 推挽输出 | LR690L 射频芯片发射调制数据输入引脚 |
---
## 2. 软件事件驱动 APP 框架 (Event-Driven App-Framework)
手环软件系统摒弃了传统的单线程前后台大循环设计,采用分层明确的 **事件驱动式 APP 框架** 架构。
### 2.1 五层软件架构模型
```mermaid
graph TD
%% 5层立体依赖结构
subgraph LayerApps ["1. 应用业务层 (Applications)"]
ActiveApp["当前活跃应用 (Foreground App)"]
BgApp["后台监测应用 (Background App)"]
end
subgraph LayerAppMgr ["2. 应用管理层 (APP Management)"]
AppManager["APP 管理器 (StartApp / CloseApp)"]
Lifecycle["生命周期调度机"]
end
subgraph LayerEvent ["3. 事件总线层 (Event Layer)"]
EventDispatcher["事件分配器 (Event Dispatcher)"]
EventQueue["事件环形缓冲区 (EventQueue)"]
end
subgraph LayerDrivers ["4. 中断与驱动层 (Drivers)"]
ExtInt["外部中断 (KEY按键扫描 / RF解码)"]
TimeInt["时钟中断 (Timer1 1ms时基)"]
ADC_Drv["ADC 电量采集"]
LCD_Drv["LCD 屏幕绘制驱动"]
end
subgraph LayerHW ["5. 硬件实体层 (STC32 HW)"]
MCU["STC32G 单片机核心"]
end
%% 单向数据与控制交互
LayerHW ===> LayerDrivers
LayerDrivers ===>|异步推送事件| LayerEvent
LayerEvent ===>|事件分发路由| LayerAppMgr
LayerAppMgr ===>|生命周期回调与分发| LayerApps
LayerApps ===>|调用显示/报警动作| LayerDrivers
```
---
## 3. 应用生命周期机制 (APP Lifecycle)
手环中运行的各个子功能页面(如时钟、菜单、对码、布防)均被抽象为独立的 **App 实例**。每个 App 必须注册并实现以下生命周期回调接口:
```c
typedef struct {
u8 app_id; // 应用程序 ID
void (*OnStart)(void); // 启动回调:应用切入前台,加载资源、初始化显示
void (*onRun)(void); // 循环回调:主循环轮询轮空调用,执行非阻塞业务逻辑
void (*onClose)(void); // 关闭回调:应用退出前台,保存状态、清理外设
void (*onEvent)(KeyEvent evt); // 事件回调:接收并消耗来自事件层的系统事件
} WristbandApp;
```
### 3.1 活跃应用切换逻辑 (APP Switch)
1. 当调用 `StartApp(target_app_id)` 时:
* 触发当前活跃应用的 `onClose()` 接口,执行现场保存及关屏/停振等外设清理。
* 更新活跃应用指针指向新 App。
* 触发新活跃应用的 `OnStart()` 接口,执行初始画面的绘制(置 `Redraw = 1`)。
2. 在主循环中,系统不断执行当前活跃应用的 `onRun()` 接口,以维护非阻塞的页面动画或等待超时逻辑。
---
## 4. 事件采集、缓冲与流转机制 (Event Bus)
事件总线层是实现前后台解耦的核心。
```mermaid
graph LR
%% 事件的产生与消耗流转
HW_Sig["物理引脚状态跳变"] -->|电平变化中断| Driver["驱动中断 ISR"]
Driver -->|消抖/自适应解调| Packer["封装统一事件 (KeyEvent)"]
Packer -->|Key_Push_Event| Queue["Event Ring Buffer (环形队列)"]
Queue -->|Key_Pop_Event| MainLoop["MainLoop 轮询读取"]
MainLoop -->|事件分发| AppMgr["APP 管理器"]
AppMgr -->|onEvent(evt) 回调| ActiveApp["当前活跃 App 实例"]
```
### 4.1 环形事件缓冲区 (EventQueue)
为防止高速按键或多输入源并发导致事件丢失,系统建立一个深度为 4 级的环形事件队列。按键消抖模块与 RF 模块作为 **事件产生者** 将数据推送至队列:
* **按键事件产生**Timer1 定时器每 10ms 中断扫描物理引脚,判定有效按键后执行 `Key_Push_Event(KEY_UP_SHORT)`
* **RF 事件产生**LR690L 接收中断触发,解码线程还原 24 位载波包,识别到配对传感器动作,推送对应防区事件。
* **事件路由**:主循环轮询事件队列,若队列非空,`Key_Pop_Event()` 读出事件并分配给当前活跃应用的 `onEvent(evt)` 执行特异化响应。
---
## 5. 持久化配置数据库架构
手环配对防区数据存储在 STC32G 内置 Flash 的第 254 扇区:
* **物理存储地址**`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;
```
---
## 6. 核心业务事件输入输出 (I/O) 架构明细表
手环核心事件在整个框架中的端到端流动及消耗链路如下:
| 事件名称 | 输入源 (触发条件与参数) | 事件总线流转 (产生端 -> 分发端) | 活跃 APP 消费处理 (逻辑响应与动作) |
| :--- | :--- | :--- | :--- |
| **按键操作事件**<br>`KEY_EVENT` | **源**Pin 19/20/21 下降沿中断。<br>**参数**:▲/▼/■ (短按/长按)。 | **产生**`KEY` 驱动 10ms 中断消抖扫描包装。<br>**分发**`Key_Push_Event` 压入队列,主循环读出并传入活跃 App。 | **待机应用**:长按确认键 3 秒,调用 `StartApp(APP_MENU)`<br>**菜单应用**:短按 ▲/▼ 键移动高亮焦点;短按确认键调用 `StartApp` 进入对应子设置应用。 |
| **主动求救事件**<br>`SOS_ACTIVE_EVENT` | **源**Pin 24 (`P2.3`) SOS 物理键拉低。 | **产生**:检测到低电平,直接压入事件队列 `KEY_SOS_ACTIVE`<br>**分发**主循环捕获APP 管理器强制抢占调用 `StartApp(APP_SOS)`。 | **SOS报警应用**<br>1. 显示AMOLED 亮起 `SOS EMIS`<br>2. 灯效WS2812B 红色交替闪烁 (50ms)<br>3. 马达:开启间歇长振 (振1000ms停200ms)<br>4. 射频启动发送线程周期性2s发射手环 Factory ID 及 `0x08` (SOS) 包。 |
| **无线对码捕获事件**<br>`RF_PAIR_RECV_EVENT` | **源**Pin 29 沿变化中断。<br>**参数**EV1527 24位对码信号。 | **产生**RF 驱动解调同步头并还原二进制码字。<br>**分发**:包装为 `RF_PAIR_EVENT` 传入事件队列,主循环分发。 | **配对应用**<br>1. 状态:跳转进入 `STATE_PAIR_CONFIRM` (微调保存页)<br>2. 显示:只读显示自动识别的传感器类型及大图标;<br>3. 马达:短振 300ms 提醒成功;<br>4. 交互:通过按键微调序号并写入 Flash 数据库。 |
| **传感器入侵警报事件**<br>`RF_ALARM_RECV_EVENT` | **源**Pin 29 沿变化中断。<br>**参数**:传感器物理地址 + 4位状态码。 | **产生**RF 驱动还原码字。<br>**分发**:主循环比对 Flash 数据库匹配槽位成功,触发防区报警事件。 | **警报应用**:若该防区为 ZONE 0 (24h) 或处于已布防APP管理器启动 `StartApp(APP_ALARM)`<br>1. 显示AMOLED 刷红边框与对应大图标,显示入侵警报文字;<br>2. 灯效:同步闪烁该防区专属色彩;<br>3. 马达:输出对应防区的特定异步振动波形。 |
| **系统自动休眠事件**<br>`AUTO_SLEEP_EVENT` | **源**:软件时钟计时 `inactivity_timer >= 1000` (10s)。 | **产生**Timer1 中断秒分频累加。<br>**分发**:触发超时休眠事件,分发至当前应用。 | **所有非警报应用**:执行 `onClose()` $
ightarrow$ 调用 PM 模块拉低 `SHUT=0`Pin 28彻底切断屏幕供电 $
ightarrow$ 配置 GPIO 变化中断和无线唤醒源 $
ightarrow$ 执行 `PCON|=0x02` 进入停机休眠。 |
| **中断唤醒系统事件**<br>`SYSTEM_WAKEUP_EVENT` | **源**GPIO 按键下降沿或无线信号变化触发硬件唤醒。 | **产生**MCU 瞬间恢复时钟,执行唤醒 ISR。<br>**分发**:自动触发系统重构事件。 | **系统底层**:优先拉高 `SHUT=1` 开启 SGM3833 供电 $
ightarrow$ **阻塞强延时 50ms 避开浪涌** $
ightarrow$ 完整重新配置 RM69310 屏幕控制器 $
ightarrow$ 调用 `StartApp(APP_CLOCK)` 恢复时钟显示状态。 |
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->