From 039029ab2001ad6db3dad9878183f9fa3bfdead1 Mon Sep 17 00:00:00 2001 From: zouhaitao Date: Thu, 9 Jul 2026 18:42:00 +0800 Subject: [PATCH] docs: optimize all module breakdown files with architect-level details --- Docs/50_module-breakdown/mod-key.md | 56 ++++++++++--------- Docs/50_module-breakdown/mod-lcd.md | 50 ++++++++--------- Docs/50_module-breakdown/mod-led.md | 37 ++++++++----- Docs/50_module-breakdown/mod-motor.md | 36 +++++++----- Docs/50_module-breakdown/mod-power.md | 40 ++++++++------ Docs/50_module-breakdown/mod-rf.md | 45 +++++++++------ Docs/50_module-breakdown/mod-sys.md | 79 ++++++++++++--------------- 7 files changed, 183 insertions(+), 160 deletions(-) diff --git a/Docs/50_module-breakdown/mod-key.md b/Docs/50_module-breakdown/mod-key.md index 441d353..8d23769 100644 --- a/Docs/50_module-breakdown/mod-key.md +++ b/Docs/50_module-breakdown/mod-key.md @@ -1,47 +1,49 @@ -# 模块拆分 - 按键扫描与事件判定 (Docs/50_module-breakdown/mod-key.md) +# 模块拆分 - 按键输入消抖与判定 (Docs/50_module-breakdown/mod-key.md) -本模块描述按键状态消抖、长按和短按计时判定。支持 5 个物理按键到手环事件的映射。 +本模块描述物理按键输入的检测、电平消抖、长按计时以及多事件防丢处理。 ## 1. 模块职责说明 * **职责范围**: - 1. 在 1ms 定时器中断中建立 10ms 扫描计时周期。 - 2. 对 5 个物理按键进行引脚电平扫描: - * 侧边:`KEY_UP` SW1 (▲), `KEY_DOWN` SW2 (▼), `KEY_CONFIRM` (■) - * 上部:`KEY_SOS1` (SOS 1), `KEY_SOS2` (SOS 2) - 3. 实现消抖检测(连续 20ms 检测到电平稳定才认定按键动作)。 - 4. 对上部双 SOS 按键进行逻辑并联处理,保证按下任意一个均能触发求救。 - 5. 对按住不放的行为进行计时累加,判定长按: - * 长按 **确认键 (CONFIRM / ■)** 达 3 秒触发主菜单选择界面或退出当前页面。 - * 侧边 **▼ 键** 长按达 2 秒产生长按退出/消除警报事件。 - * SOS 按键(SOS1 / SOS2)长按或短按,只要是非报警状态,一律触发 `KEY_SOS_ACTIVE` 本地报警呼救事件。 - 6. 将按键判定结果转换为 `KeyEvent` 并注入按键事件缓冲区 `key_event_buf`。 + 1. 在系统上电时,将按键引脚 `P0.1~P0.5` 配置为**高阻输入且开启内部上拉电阻**(STC32G P0M0/P0M1/P0PU 寄存器配置)。 + 2. 实现每 10ms 一次的硬件消抖滤波(采用 3 次扫描连续一致判定法,滤波时间约 20-30ms)。 + 3. 支持侧边 ▲/▼ 键、确认键 ■,以及上部双并联 SOS 键的独立状态判定。 + 4. 对上部双 SOS 按键进行逻辑并联处理:只要任意一个按键拉低,即视为 SOS 触发。 + 5. **长按计时判定**: + * 长按 **确认键 (■)** 达 3 秒(300 个时基单位)触发主菜单切换或子页面放弃退出。 + * 长按 **▼ 键** 达 2 秒(200 个时基单位)触发报警清除或 IPC 绑定退出。 + 6. **防丢事件缓冲队列 (Ring Buffer)**: + * 为了防止高频按键或同时按下时发生丢键,本模块维护一个深度为 4 级的环形事件队列。按键扫描判定出的 `KeyEvent` 压入队列,主循环通过出队机制依次消费。 + +--- ## 2. 数据结构定义 -### 按键事件枚举 (KeyEvent) +### 2.1 按键事件枚举 (KeyEvent) ```c typedef enum { KEY_EVENT_NONE, - KEY_UP_SHORT, - KEY_DOWN_SHORT, - KEY_DOWN_LONG, // 长按 ▼ 2 秒解除警报/退出绑定 + KEY_UP_SHORT, // ▲ 键短按 + KEY_DOWN_SHORT, // ▼ 键短按 + KEY_DOWN_LONG, // ▼ 键长按 2 秒 (清除报警/退出) KEY_CONFIRM_CLICK, // ■ 确认键短按 - KEY_CONFIRM_LONG, // ■ 确认键长按(3秒进入/退出菜单/退出绑定) - KEY_SOS_ACTIVE // SOS键活动 (短按或长按,跳转至发送 SOS 报警) + KEY_CONFIRM_LONG, // ■ 确认键长按 3 秒 (菜单切换) + KEY_SOS_ACTIVE // SOS 键触发 (不分长短按,秒级响应) } KeyEvent; ``` +--- + ## 3. 接口与函数说明 +* `void Key_Init(void)`:配置 `P0.1~P0.5` 的 `P0M1=0x00`, `P0M0=0x00`(高阻模式),并设置 `P0PU = 0x3E` 使能上拉电阻。 * `void Key_Scan_Process(void)`: - 在 Timer 1 ISR 中每 10ms 调度一次。 - * 读取 `KEY_UP`, `KEY_DOWN`, `KEY_CONFIRM`, `KEY_SOS1`, `KEY_SOS2` 的 GPIO 逻辑电平。 - * 计算并联 SOS 状态:`is_sos_pressed = (KEY_SOS1 == 0) || (KEY_SOS2 == 0)`。 - * 如果发现按键电平状态改变,进行计数消抖。 - * 如果按住不放,累加计时计数器(`key_up_hold`, `key_down_hold`, `key_confirm_hold`, `key_sos_hold`)。 - * 检测到 `key_confirm_hold >= 300` 达 3 秒时,注入 `KEY_CONFIRM_LONG` 中断事件。 - * 检测到 `key_down_hold >= 200` 达 2 秒时,注入 `KEY_DOWN_LONG` 中断事件。 - * 检测到并联 SOS 被按下时,注入 `KEY_SOS_ACTIVE` 事件。 + 在 Timer 1 10ms 中断分频中调用。 + * 读取引脚逻辑状态,并利用移位寄存器滤波判定。 + * 并联 SOS 状态:`sos_pressed = (KEY_SOS1 == 0) || (KEY_SOS2 == 0)`。 + * 累加各按键的计数器:`key_up_hold`, `key_down_hold`, `key_confirm_hold`, `key_sos_hold`。 + * 达到长按阈值时将对应事件写入环形队列。 +* `bit Key_Push_Event(KeyEvent evt)`:将事件压入环形事件队列。若满则丢弃,返回 0。 +* `KeyEvent Key_Pop_Event(void)`:主循环调用,从事件队列中读取未消费的事件。若空返回 `KEY_EVENT_NONE`。 diff --git a/Docs/50_module-breakdown/mod-lcd.md b/Docs/50_module-breakdown/mod-lcd.md index 4c91417..eeb66d4 100644 --- a/Docs/50_module-breakdown/mod-lcd.md +++ b/Docs/50_module-breakdown/mod-lcd.md @@ -1,37 +1,33 @@ -# 模块拆分 - AMOLED 显示与字模驱动 (Docs/50_module-breakdown/mod-lcd.md) +# 模块拆分 - AMOLED 显示与无障碍渲染 (Docs/50_module-breakdown/mod-lcd.md) -本模块管理 0.95寸 Truly AMOLED 屏幕引脚、电平控制、SPI 传输和无障碍大字/大图标渲染(分辨率为 120x240 像素)。 +本模块管理 Truly 0.95寸 AMOLED 屏的底层 SPI 通信、窗口控制、以及无障碍(A11y)超大字体和图标的渲染。 ## 1. 模块职责说明 * **职责范围**: - 1. 提供底层的 SPI 单向命令/数据通道。 - 2. 控制 `SGM_CTRL` 供电管脚以使能 SGM3833 PMIC。 - 3. 支持屏幕窗口配置,实现底层清屏与局部像素写入。 - 4. 读取 `lcd_font.h` 库,在指定坐标绘制 16x32 大字符、32x64 超大字符与 48x48/64x64 超大单色位图。 - 5. 实现各业务状态屏幕无障碍(A11y)画面绘制与水平垂直居中对齐。 + 1. 管理 RM69310 控制器通信,提供单向 SPI 指令/数据写操作。 + 2. 提供 `SGM_CTRL`(引脚 `P3.4`)控制,配合低功耗模块实现屏幕 PMIC 的上电与彻底断电。 + 3. **物理窗口偏置处理**:Truly 120x240 AMOLED 屏的 GRAM X 轴起始位置有 **+4 像素的偏置**,设置显示窗口时必须进行偏移修正:`LCD_SetWindow(x1 + 4, x2 + 4, y1, y2)`。 + 4. **无障碍大字排版(A11y)渲染**: + * 取消任何小于 16x32px 的微缩文本。 + * 时间显示使用 **32x64px** 超大点阵。 + * 防区图标使用 **48x48px** 或 **64x64px** 超大单色位图。 + * 在 120 像素宽的屏幕内,应用水平居中公式:`X_start = (120 - len * char_width) / 2`。 + 5. **单页集中展示逻辑**:控制各菜单页面和子修改页面在屏幕中只显示单焦点,避免多行小字杂乱堆叠。 -## 2. 底层显示接口 +--- -* `void LCD_Init(void)`:初始化 LCD 引脚,置 `SGM_CTRL = 1` 使能 SGM3833 供电,并发送 RM69310 AMOLED 控制器的初始化寄存器配置序列。 -* `void LCD_WriteCmd(u8 cmd)`:拉低 `LCD_RS` 发送 SPI 命令。 -* `void LCD_WriteData(u8 dat)`:拉高 `LCD_RS` 发送 SPI 数据。 -* `void LCD_SetWindow(u16 x1, u16 y1, u16 x2, u16 y2)`:设置局部像素绘制范围,适配 Truly 120x240 竖屏对齐(处理 X 轴偏移量 +4)。 -* `void LCD_Clear(u16 color)`:将整块屏幕刷写为特定背景色。 +## 2. 接口与函数说明 -## 3. 图文绘制与 UI 渲染 - -* `void LCD_ShowChar(u16 x, u16 y, char c, u16 fc, u16 bc)`:绘制字符。 -* `void LCD_ShowStringCentered(u16 y, char *str, u16 fc, u16 bc)`:在 120 像素宽屏幕上水平居中绘制 16x32px 宽的大字符串。 -* `void LCD_ShowString32x64Centered(u16 y, char *str, u16 fc, u16 bc)`:在 120 像素宽屏幕上水平居中绘制超大 (32x64px) 数字。 -* `void LCD_ShowImage(u16 x, u16 y, u16 w, u16 h, const u8 *img, u16 fc, u16 bc)`:在指定区域绘制单色位图(支持 32x32, 48x48, 64x64 格式)。 -* `void UI_ShowClockPage(SystemState state, u8 hour, u8 min)`:渲染时钟待机页面(120 宽大字版布局,32x64 走时时间,电量大图标)。 -* `void UI_ShowMenuPage(u8 selected_item)`:渲染无障碍主选择菜单,单页单大图标(48x48px)与大文字(16x32px)。 -* `void UI_ShowSetTimePage(u8 editing_field, u16 current_value)`:渲染大字单参数设定页面(如调整 `HEURE` 时的超大数值显示)。 -* `void UI_ShowArmDisarmSelectPage(u8 current_selection)`:渲染大图文布撤防手动切换界面。 -* `void UI_ShowAlarmPage(char *sensor_name, u8 zone)`:渲染防区告警页面,显示 64x64px 超大传感器图标、16x32px 闪烁文字与 4px 粗警告边框。 -* `void UI_ShowPairSearchPage(void)`:渲染对码等待搜索状态(含 64x64px 雷达图标)。 -* `void UI_ShowPairConfirmPage(u8 type, u8 selected_suffix)`:渲染对码序号微调页。类型与 48x48px 图标只读,序号 `[ selected_suffix ]` 以 32x64px 超大字模闪烁显示。 -* `void UI_ShowBindingPage(void)`:渲染与 IPC 绑定对码界面,含 48x48px 摄像头大图标与 16x32px 发送提示,底部显示 Factory ID。 +* `void LCD_Init(void)`:配置 `P1.1~P1.6` 控制线为推挽输出模式,并在拉高 `SGM_CTRL` 稳定后,发送 RM69310 初始化寄存器指令序列。 +* `void LCD_WriteCmd(u8 cmd)`:拉低 `LCD_RS` 选择命令寄存器,通过 SPI 发送字节。 +* `void LCD_WriteData(u8 dat)`:拉高 `LCD_RS` 选择数据寄存器,通过 SPI 发送字节。 +* `void LCD_SetWindow(u16 x1, u16 y1, u16 x2, u16 y2)`:设置局部像素刷写范围,物理 X 坐标必须强制加 4 像素。 +* `void LCD_Clear(u16 color)`:清屏为指定底色(常态使用全黑以节省功耗)。 +* `void LCD_ShowChar16x32(u16 x, u16 y, char c, u16 fc, u16 bc)`:在指定坐标绘制标准无障碍大字符(16x32点阵)。 +* `void LCD_ShowChar32x64(u16 x, u16 y, char c, u16 fc, u16 bc)`:在指定坐标绘制超大数字字符(32x64点阵)。 +* `void LCD_ShowImage(u16 x, u16 y, u16 w, u16 h, const u8 *img, u16 fc, u16 bc)`:渲染指定单色位图(支持 32x32/48x48/64x64/80x80 图标规格)。 +* `void LCD_ShowStringCentered(u16 y, char *str, u16 fc, u16 bc)`:16x32 规格字符串居中渲染,单行限制最多 7 个字符。 +* `void LCD_ShowString32x64Centered(u16 y, char *str, u16 fc, u16 bc)`:32x64 规格超大字符串居中渲染(如时钟显示)。 diff --git a/Docs/50_module-breakdown/mod-led.md b/Docs/50_module-breakdown/mod-led.md index 06015bb..ce9efe8 100644 --- a/Docs/50_module-breakdown/mod-led.md +++ b/Docs/50_module-breakdown/mod-led.md @@ -1,19 +1,22 @@ # 模块拆分 - WS2812B 可编程 RGB 灯效 (Docs/50_module-breakdown/mod-led.md) -本模块描述可编程幻彩 RGB 灯珠(WS2812B/FCOB-2.7)的单线级联数据流驱动与报警色彩反馈。 +本模块管理双级联幻彩 RGB 灯珠(WS2812B/FCOB-2.7)的硬件 SPI 通道、防抖抗噪切换以及指示闪烁逻辑。 ## 1. 模块职责说明 * **职责范围**: - 1. 在系统启动时,配置 WS2812 的物理输出引脚 `P2.3` (MOSI)。 - 2. 支持一上一下级联(Daisy-chained)的双 WS2812B/FCOB-2.7 灯珠驱动。上灯的 DOUT 串行连接至下灯的 DIN。 - 3. 提供高速的硬件 SPI 发送驱动,配合 LUT 查表展宽算法,连续发送 48-bit (24-bit × 2) 的 GRB 级联数据流,输出满足单线纳秒级精度的 WS2812 时序波形,使两个灯珠同步亮起相同的颜色。 - 4. 在硬件 SPI 传输 48位灯效数据时,采取临时关闭中断并把复用的 `P2.5` 配置为高阻输入的隔离防噪处理。 - 5. 维护软件定时闪烁状态机,提供报警状态下的指示灯颜色与特定频率闪烁效果。 + 1. 管理物理引脚 `P2.3`(复用硬件 SPI 的 MOSI)作为单线纳秒级高速数据流输出。 + 2. 实现对级联的两个 RGB 灯珠(上灯 DOUT 串接下灯 DIN)输出相同的 24-bit × 2 色彩数据。 + 3. **硬件 SPI 复用防噪隔离处理**: + 由于单片机引脚紧缺,SPI 引脚与马达控制可能存在轻微高频串扰。在每次发送 48-bit (GRB) 灯光控制字之前,**必须临时关闭全局中断 (EA=0)**,并将马达引脚配置为高阻输入以彻底隔离噪声。发送完成后立即恢复引脚模式并使能全局中断 (EA=1)。 + 4. **软件异步闪烁控制**: + 在 1ms 中断中自增计时器,控制报警状态下不同防区灯光的异步闪烁(500ms 亮、500ms 灭,或本地 SOS 下的 50ms 红光快速交替爆闪)。 + +--- ## 2. LED 报警色彩矩阵 -根据 7 种不同的外部传感器类型及本地主动求救,亮起对应的 LED 灯: +根据防区传感器类型及报警动作亮起指示灯: * **门磁/窗磁 (PORTE)**:红色闪烁。 * **PIR 人体红外 (PIR)**:橙色闪烁。 * **烟雾传感器 (FUMEE)**:绿色闪烁。 @@ -21,14 +24,20 @@ * **气体泄漏 (GAZ)**:紫色闪烁。 * **水浸传感器 (INOND.)**:黄色闪烁。 * **振动传感器 (VIBRA.)**:青色闪烁。 -* **本地主动 SOS**:红色快速交替闪烁。 +* **本地主动 SOS**:双红灯以 50ms 周期高速交替闪烁。 + +--- ## 3. 接口与函数说明 -* `void WS2812_Init(void)`:配置 `P2.3` 引脚为推挽输出模式。 -* `void WS2812_Write24Bit(u8 g, u8 r, u8 b)`:使用硬件 SPI 方式串行发送 24-bit 颜色数据给级联灯珠。发送前后进行 `P2.5` 引脚高阻/推挽切换屏蔽马达时钟抖动。 -* `void WS2812_Reset(void)`:发送大于 80us 的低电平复位脉冲使颜色锁存生效。 -* `void LED_Set_Color(u8 g, u8 r, u8 b)`:立即设置 RGB 灯亮起特定颜色。 -* `void LED_Flash_Process(void)`:在 1ms 定时器中断中累加,控制报警状态下指示灯的交替闪烁(如 500ms 亮、500ms 灭)。 +* `void WS2812_Init(void)`:初始化物理引脚 `P2.3` 状态,复用硬件 SPI 通道,配置时钟展宽 LUT 码表。 +* `void WS2812_WriteRGB(u8 led1_g, u8 led1_r, u8 led1_b, u8 led2_g, u8 led2_r, u8 led2_b)`: + 1. 临时保存并拉低 `EA = 0`。 + 2. 切换 `P2.5` (MOTOR) 引脚为高阻输入以防共地噪声。 + 3. 通过 SPI 控制寄存器高速连发 48 字节的时序宽展码,驱动两个灯珠亮起对应颜色。 + 4. 发送完毕后发送 >80us 的低电平复位脉冲。 + 5. 恢复马达引脚为推挽输出,并还原 `EA`。 +* `void LED_Set_Color(u8 g, u8 r, u8 b)`:同步设置双级联灯亮起特定颜色。 +* `void LED_Flash_Process(void)`:在 1ms 中断中调用,控制指示灯处于交替爆闪或间歇闪烁的状态机更新。 - + diff --git a/Docs/50_module-breakdown/mod-motor.md b/Docs/50_module-breakdown/mod-motor.md index 3056481..a2f1ced 100644 --- a/Docs/50_module-breakdown/mod-motor.md +++ b/Docs/50_module-breakdown/mod-motor.md @@ -1,32 +1,40 @@ -# 模块拆分 - 振动马达驱动与反馈 (Docs/50_module-breakdown/mod-motor.md) +# 模块拆分 - 振动马达异步驱动与反馈 (Docs/50_module-breakdown/mod-motor.md) -本模块描述手环告警与按键反馈的振动马达驱动逻辑。手环通过控制特定的振动时长与周期,向用户提供直观的物理触觉告警反馈。 +本模块描述振动马达引脚的开关控制、异步时间片脉冲时序生成以及针对不同防区的特定振动波形。 ## 1. 模块职责说明 * **职责范围**: - 1. 系统初始化时,将马达控制管脚 `P2.5` 配置为推挽输出模式。 - 2. 提供底层的开关控制,使能或禁止马达供电(高电平振动,低电平静止)。 - 3. 在 1ms 中断(Timer 1)中执行异步振动控制时序(Pulse Process),实现不阻塞 CPU 的各种复杂振动波形(如短振、长振、连续多次振动)。 - 4. 根据接收到的 7 类传感器报警类型或本地主动 SOS 呼救状态,自动触发对应的振动模式。 + 1. 系统初始化时配置马达引脚 `P2.5` 为推挽输出模式,默认输出低电平(马达静止)。 + 2. **非阻塞异步脉冲处理**: + 为防止马达振动时间(几百毫秒)阻塞 CPU 的业务循环与射频解码,本模块将马达动作拆分为多个电平交替状态段。利用 Timer 1 (1ms 中断) 异步扣减阶段计数器,实现不占用 CPU 资源的精细振动波形。 + 3. 配合系统状态机,在按键点击时输出 50ms 极短触觉反馈,在防区入侵报警时根据类型输出对应的振动指征,在本地主动 SOS 状态下输出连续不断的重度警示振动。 + +--- ## 2. 振动模式设计 (周期 5 秒) +* **按键操作反馈**:1 次极短振动 50ms。 * **门磁/窗磁 (PORTE)**:1 次短振 300ms。 * **PIR 红外 (PIR)**:2 次短振 300ms (间隔 200ms)。 * **烟雾传感器 (FUMEE)**:3 次短振 200ms (间隔 150ms)。 * **紧急按钮 (URGENCE)**:1 次长振 800ms。 * **气体泄漏 (GAZ)**:4 次短振 200ms (间隔 100ms)。 * **水浸传感器 (INOND.)**:2 次长振 600ms (间隔 300ms)。 -* **振动传感器 (VIBRA.)**:连续 3 次短振 150ms (间隔 100ms)。 -* **本地主动 SOS**:持续性间歇长振(振 1000ms,停 200ms 循环)。 +* **振动传感器 (VIBRA.)**:连续 3 次极短振动 150ms (间隔 100ms)。 +* **本地主动 SOS**:持续间歇重度长振(振 1000ms,停 200ms 循环)。 + +--- ## 3. 接口与函数说明 -* `void Motor_Init(void)`:初始化配置引脚 `P2.5` 为推挽输出,默认输出低电平(马达静止)。 -* `void Motor_Set_State(bit state)`:立即开关马达(直接写入 `P2.5` 引脚)。 -* `void Motor_Start_Alarm_Pattern(u8 pattern_type)`:传入传感器类型,装载对应的振动计数器和阶段标志,启动异步振动模式。 -* `void Motor_Pulse_Process(void)`:在 1ms 中断中调用(通常每 10ms 调度一次),更新振动时间计数器,切换各阶段电平以输出指定波形。 -* `void Motor_Stop(void)`:清空所有计数器并立即关闭马达,用以清除告警。 +* `void Motor_Init(void)`:配置引脚 `P2.5` 的 `P2M1=0x00`, `P2M0=0x20`(推挽输出),默认输出 `MOTOR = 0`。 +* `void Motor_Set_State(bit state)`:硬开关控制引脚 `P2.5` 的电平。 +* `void Motor_Start_Pattern(u8 pattern_type)`:装载对应类型的马达振动计数器,开启异步振动状态机。 +* `void Motor_Pulse_Process(void)`: + 在 Timer 1 的 10ms 中断分频中被调用: + * 根据装载的波形,扣减当前阶段维持的毫秒数。 + * 当计数器归零时,切换 `MOTOR` 引脚电平并转入下一个电平维持段。 +* `void Motor_Stop(void)`:清空所有计数器,拉低 `MOTOR = 0`,强行中止当前振动。 - + diff --git a/Docs/50_module-breakdown/mod-power.md b/Docs/50_module-breakdown/mod-power.md index a788399..5bb8c26 100644 --- a/Docs/50_module-breakdown/mod-power.md +++ b/Docs/50_module-breakdown/mod-power.md @@ -1,28 +1,34 @@ -# 模块拆分 - 电源与供电管理 (Docs/50_module-breakdown/mod-power.md) +# 模块拆分 - 极低功耗与电源管理 (Docs/50_module-breakdown/mod-power.md) -本模块负责手环的供电管理以及低功耗休眠/唤醒逻辑。 +本模块描述手环的低功耗管理、AMOLED 供电 PMIC 控制以及中断睡眠/唤醒时序。 ## 1. 模块职责说明 * **职责范围**: - 1. 系统初始化时使能 SGM3833 PMIC 供电(拉高 `SGM_CTRL = 1`),使 OLED 屏正常工作。 - 2. 维护低功耗状态机。当系统检测到连续 10 秒无任何按键操作时,执行关屏、拉低 `SGM_CTRL = 0` 彻底切断 **SGM3833** 供电、挂起外设,使单片机进入 Power-Down(停机模式)。 - 3. 配置外部中断:将 5 个按键的 GPIO 口和 LR690L 433MHz 芯片的接收中断引脚配置为唤醒中断源,使手环在处于 Power-Down 挂起状态下能被瞬间唤醒。 - 4. 唤醒后,第一时间拉高 `SGM_CTRL = 1` 恢复 OLED 电源,延时等待 PMIC 稳定后,重新驱动显示并恢复常规时钟计时。 + 1. 在系统上电时使能 SGM3833 升压芯片,为 OLED 屏提供稳定的显示电源。 + 2. **低功耗决策判定**: + 当主系统处于非警报状态,且连续 10 秒(`inactivity_timer >= 1000`)无任何按键或无线包事件时,判定系统进入 `STATE_SLEEP` 极低功耗睡眠。 + 3. **彻底切断 PMIC**: + 为消除 OLED 的静态负压漏电流,休眠前拉低 `SGM_CTRL = 0`,使 SGM3833 彻底断电。 + 4. **睡眠挂起配置**: + 使能 `INT2`(外部中断 2,接射频接收引脚)以及 P0 口引脚电平变化中断,然后将 STC32G 写入 `PCON |= 0x02` 进入停机(Power-Down)挂起状态,关闭主高频振荡时钟,全板功耗降至微安级。 + 5. **安全唤醒重初始化时序**: + 发生按键或无线信号中断时,CPU 瞬间被唤醒。由于升压 PMIC 的输入电容充电及负压稳压需要时间,唤醒后**严禁立即写屏**。必须首先拉高 `SGM_CTRL = 1`,接着**软件强行阻塞延时 50ms**,等电网稳定后,再次完整初始化 RM69310 的寄存器参数,最后恢复待机屏幕重绘。 -## 2. 接口与函数设计 +--- -* `void Power_Init(void)`: - 1. 配置 `SGM_CTRL`(物理引脚 `P3.4`)为推挽输出模式。 - 2. 设置 `SGM_CTRL = 1` 开启 SGM3833 OLED 供电芯片。 +## 2. 接口与函数说明 + +* `void Power_Init(void)`:配置 `P3.4` (SGM_CTRL) 为推挽输出,默认输出高电平 `SGM_CTRL = 1`。 * `void Enter_Low_Power_Sleep(void)`: - 1. 发送命令关闭 RM69310 AMOLED 屏幕显示。 - 2. 拉低 `SGM_CTRL = 0` 关闭 SGM3833 升压/负压芯片。 - 3. 允许按键引脚中断与 433MHz 射频接收中断。 - 4. 写入 `PCON |= 0x02`(或 MCU 挂起控制位 `PD = 1`)使 CPU 进入深度睡眠 Power-Down 模式。 + 1. 向 RM69310 屏幕控制器发送关闭显示命令(寄存器 0x28)。 + 2. 拉低 `SGM_CTRL = 0` 彻底切断 PMIC。 + 3. 配置并使能按键端口中断与 RF 中断。 + 4. 执行 `PCON |= 0x02` 挂起 CPU。 * `void Wakeup_Restore(void)`: - 1. 拉高 `SGM_CTRL = 1` 开启 SGM3833 供电芯片。 - 2. 延时约 50ms 等待电压稳定。 - 3. 重新初始化 RM69310 屏幕控制器并恢复正常显示。 + 1. 拉高 `SGM_CTRL = 1` 开启 SGM3833 供电。 + 2. 执行 `delay_ms(50)` 阻塞式等待电平平稳,过滤冲击电流。 + 3. 调用 `LCD_Init()` 重新对 RM69310 进行整套初始化配置,恢复写屏 GRAM 通道。 + 4. 状态机切回 `STATE_CLOCK` 并置 `Redraw = 1`。 diff --git a/Docs/50_module-breakdown/mod-rf.md b/Docs/50_module-breakdown/mod-rf.md index a24dfa3..59eec6b 100644 --- a/Docs/50_module-breakdown/mod-rf.md +++ b/Docs/50_module-breakdown/mod-rf.md @@ -1,30 +1,39 @@ # 模块拆分 - 自适应 RF 解码与发射 (Docs/50_module-breakdown/mod-rf.md) -本模块管理射频芯片 GPIO 初始化、433MHz EV1527 解调接收(宽限时序比值算法)与射频打包主动发射。 +本模块描述 LR690L 433MHz 射频物理收发的控制、自适应宽限时间比值解码机制以及对码/呼救编码包的发射。 ## 1. 模块职责说明 * **职责范围**: - 1. 初始化射频接收和发射控制引脚。 - 2. 对射频输入引脚进行高低电平时序轮询解码,计算其高低电平比值,实现自适应 EV1527 24位数据解码。 - 3. 在特定系统请求下(例如发送 SOS 呼救或与 IPC 对码绑定),主动通过发射引脚发出 EV1527 编码帧。 -* **自适应比值解调机制**: - 不依赖死宽度的微秒延迟。检测同步头低电平(时间在 1500~60000us 之间)与高电平时间(时间在 50~2500us 之间),算出两者的时序比例。 - * 以 `31` 作为低电平对高电平的时钟倍率基准(高低比值支持在 `15` 到 `48` 倍范围)。 - * 计算出每 bit 的标准时钟周期 `T = low_time / 31`,根据此动态 `T` 进行后续 24 个数据位(高/低电平宽度)的比值反解。 + 1. 配置射频芯片接收 GPIO 与发射 GPIO 的电平方向。 + 2. **自适应比值解调算法**: + EV1527 协议数据速率变化范围较宽。本模块采用自适应宽度比值解调机制: + * 捕获到一个低电平维持时间介于 1500us~60000us 之间的脉冲,判定为同步前导头。 + * 抓取该帧的标准时钟周期基准 `T = low_time / 31`(前导低电平占 31 个时钟周期 T,允许 T 的宽度随环境在宽限范围内自适应计算)。 + * 连续捕获 24 位宽数据:每个 bit 的电平变化依据其高低电平的宽幅比例(1:3 对应 0,3:1 对应 1)反解出对应的数据位。 + 3. 解析出 24 位载波包:前 20 位为无线探测器的出厂唯一地址码(Address Code),后 4 位为状态数据码(Data Code)。 + 4. **数据包主动发送**: + 将手环 Factory ID 编码为一帧 EV1527 数据,通过物理发射引脚输出同步头及 24 位调制波形,连发多遍以确保 IPC 接收质量。 -## 2. 接口与函数说明 +--- -* `void RF_Init(void)`:配置射频芯片引脚方向,初始化控制端口电平。 +## 2. 业务状态射频数据编码定义 + +* **对码绑定发送 (LIAISON IPC)**: + * 数据码固定为 **`0x01`** (0001),源地址为手环 20-bit 出厂 Factory ID,周期性连续发射。 +* **本地主动 SOS 呼救 (SOS EMIS)**: + * 数据码固定为 **`0x08`** (1000),源地址为手环 20-bit 出厂 Factory ID,以 2 秒为周期循环向外发射。 +* **传感器自动识别对码**: + * 手环被动接收 433MHz 对码信号。若捕获成功,状态机直接**依据后 4 位数据码的数据值自动判断识别传感器的设备类型**(如门磁为 `0x01`,红外为 `0x02`),直接跳转到对码微调序号页,类型与大图标只读高亮。 + +--- + +## 3. 接口与函数说明 + +* `void RF_Init(void)`:初始化射频物理端口,使能 INT2 (接收脚的沿中断)。 * `bit EV1527_Decode(u32 *out_addr, u8 *out_type)`: - 进行射频接收包解码尝试。 - * 首先通过计数检测大于 `1500us` 的同步低电平前导信号。 - * 自适应计算时钟基准 `T`。 - * 连续接收 24 位宽数据:如果某个数据位的高电平比低电平长,则认为该位为 `1`;反之为 `0`。 - * 正常解码成功将 20 位地址存入 `out_addr`,后 4 位数据存入 `out_type` 并返回 `1`;否则返回 `0`。 + 主循环轮询调用。如果捕获到合法同步头且成功解调出 24 位数据流,则输出 `out_addr` 和 `out_type` 并返回 1,否则返回 0。 * `void EV1527_Transmit(u32 addr, u8 data_code)`: - 主动发射一帧数据。生成同步头,并按 `1` 码(高电平 3T, 低电平 1T)或 `0` 码(高电平 1T, 低电平 3T)依次驱动发射引脚电平,持续多帧以确保接收方捕获。 - * 该函数被手环用作向 IPC 摄像头主动对码绑定(`data_code = 0x01`)。 - * 该函数也用于手环主动发射 SOS 紧急呼救包(`data_code = 0x08`),此时传入手环自身的出厂固定 ID `bracelet_factory_id`。 + 主动发射数据。连发至少 5 遍,每遍间歇 20ms,产生满足 T 基准的同步码头、`1` 码时序(高 3T 低 1T)和 `0` 码时序(高 1T 低 3T)。 diff --git a/Docs/50_module-breakdown/mod-sys.md b/Docs/50_module-breakdown/mod-sys.md index 47ad52c..4be8bde 100644 --- a/Docs/50_module-breakdown/mod-sys.md +++ b/Docs/50_module-breakdown/mod-sys.md @@ -1,67 +1,60 @@ -# 模块拆分 - 系统核心控制与存储 (Docs/50_module-breakdown/mod-sys.md) +# 模块拆分 - 系统状态机与 IAP 数据库 (Docs/50_module-breakdown/mod-sys.md) -本模块定义手环系统的生命周期、状态机、时间计数器、定时中断调度器以及断电保存数据库模块。 +本模块描述手环的核心生命周期调度器、业务状态机、软件 RTC 时钟,以及持久化防区配置 Flash 扇区读写。 ## 1. 模块职责说明 * **职责范围**: - 1. 驱动系统主状态机运转(`current_state`)。 - 2. 提供 RTC 软时钟维护(`current_hour`, `current_min`, `current_sec`)。 - 3. 利用 Timer 1 产生 1ms 定时器中断,作为按键消抖、LED闪烁、马达脉冲及超时休眠计数器的调度时基。 - 4. 维护无按键操作计时器 `inactivity_timer`,计满 10 秒后触发系统进入 `STATE_SLEEP`。 - 5. 实现 IAP 读写底层函数,对防区数据库进行存取与读取。 - 6. 读取并管理手环出厂固定唯一的 `bracelet_factory_id`,作为主动射频发送的数据源地址。 + 1. 驱动核心 SystemState 状态迁移,为其他所有外设(显示、指示灯、振动、无线)提供全局状态指示。 + 2. 提供基于软件计数分频的高可靠 RTC 时钟(维护日历:时、分、秒、年、月、日)。 + 3. 利用 Timer 1 产生主 1ms 系统滴答,自增休眠超时计时器 `inactivity_timer`。 + 4. **持久化 IAP 配置数据库管理**: + 利用 STC32G 内部 Flash 闪存的第 254 扇区(地址:`0xFE0000`)实现数据库的掉电不丢失存储。最大支持 16 个传感器槽位,提供写入、删除、检索和配置防区类别的全套数据库处理接口。 + 5. 管理出厂固定唯一的 `bracelet_factory_id`(通过读取芯片全球唯一硬 UID 进行哈希映射生成,20位有效)。 + +--- ## 2. 数据结构定义 -### 2.1 传感器插槽结构体 (Sensor_Slot) +### 2.1 传感器槽位信息结构体 (Sensor_Slot) ```c typedef struct { - u8 is_used; // 0x01:已使用,其它:空闲 - u8 addr[3]; // 24位 EV1527 对码物理地址 - u8 type; // 传感器类型 (0~6) - u8 zone; // 防区类别 (0: 永久防区, 1: 可撤布防区) - char name_gbk[16]; // 法语自定义名字(前缀+两位数序号,如 PORTE 02) + u8 is_used; // 0x01: 有效配置槽位,其它: 空闲槽位 + u8 addr[3]; // 24位对码 EV1527 传感器无线物理地址 + u8 type; // 传感器类型:0(门磁), 1(红外), 2(烟感), 3(紧急), 4(气体), 5(水浸), 6(振动) + u8 zone; // 防区类别:0(永久防区 - 24h), 1(普通可撤布防区) + char name_gbk[16]; // 法语防区名称,拼装格式为 "[预设前缀] [微调序号]" (如 PORTE 02) } Sensor_Slot; ``` -### 2.2 系统状态列 (SystemState) +### 2.2 系统核心状态枚举 (SystemState) ```c typedef enum { - STATE_CLOCK, // 常态时钟待机 - STATE_SLEEP, // 低功耗休眠 - STATE_MENU, // 主选择菜单 - STATE_SET_TIME, // 时间日期设置 - STATE_PAIR_SEARCH, // 对码等待搜寻 + STATE_CLOCK, // 时钟常态待机(大字走时与电量大图标) + STATE_SLEEP, // 彻底关屏断电深度睡眠(主时钟暂停,挂起 CPU) + STATE_MENU, // 主选择菜单(单大条目卡片式循环切换) + STATE_SET_TIME, // 时间日期微调修改(单大参数显示) + STATE_PAIR_SEARCH, // 对码雷达搜寻等待 STATE_PAIR_CONFIRM, // 序号微调与保存确认 - STATE_ARM_DISARM_SELECT, // 手动选择布撤防设定 - STATE_IPC_BIND, // IPC 对码发射绑定 - STATE_ALARMING, // 被动防区报警响应 - STATE_SOS_EMITTED // 本地主动发射 SOS 呼救状态 + STATE_ARM_DISARM_SELECT, // 系统手动布撤防更改 + STATE_IPC_BIND, // 对码绑定发射 + STATE_ALARMING, // 收到传感器警报响应(高频爆闪与间歇振动) + STATE_SOS_EMITTED // 本地主动发射 SOS 求救 } SystemState; ``` -## 3. 模块接口说明 +--- -### 3.1 定时与时钟函数 -* `void Timer1_Init(void)`:配置 Timer 1 作为 1ms 中断源,并使能全局中断。 -* `void Timer1_Isr(void) interrupt 3`:ISR 中断处理。自增时间滴答,并在主循环处于非休眠时自增 `inactivity_timer` 超时计时器。自增 RTC(时/分/秒/日/月/年)并维护其他任务定时。 +## 3. 接口与函数说明 -### 3.2 IAP 数据库存储接口 -* `void Load_Database(void)`:从 Flash 扇区 `0xFE0000` 读取 16 组传感器配置载入内存的 `sensor_list`。 -* `void Save_Database(void)`:擦除 Flash 扇区并将内存中的 `sensor_list` 写入 Flash。 -* `void Add_Sensor(u32 addr, u8 type, u8 suffix_idx)`:向 `sensor_list` 添加传感器信息,将其名字拼装为 `[前缀] [suffix_idx]`,并自动调用 `Save_Database()`。 -* `bit Check_Sensor_ID(u32 addr, u8 *out_slot_index)`:在数据库中检索该地址码,若存在则返回它的槽位索引。 - -### 3.3 系统初始化与全局 ID 获取 * `void System_Init(void)`: - 1. 初始化单片机系统寄存器(WTST, EAXFR 等)。 - 2. 读取 STC32G 硬件全球唯一 ID (UID) 生成 `bracelet_factory_id`。 - 3. 载入数据库并配置 Timer1 和外设 GPIO 状态。 - -### 3.4 电池与充电检测接口 -* `u16 Get_ADC_Result(u8 channel)`:底层 ADC 数据采集函数。 -* `u8 Read_Battery_Percent(void)`:读取通道 8 (`P0.0`) 并返回 0%~100% 的电量。 -* `bit Is_Charging(void)`:读取 `P2.7` 返回是否处于充电状态。 + 配置单片机寄存器(使能 FCON,开启扩展 SFR,调整外部 RAM 模式)。读取内置全球唯一 UID 拼装 Factory ID。初始化 Timer 1 开启 1ms 时基,载入 Flash 数据库。 +* `void Timer1_Init(void)`:配置 Timer 1 中断,提供 1ms 精度的时基回调。 +* `void Timer1_Isr(void) interrupt 3`: + 中断服务函数。累加 `inactivity_timer`;更新 RTC(秒/分/时/日/月/年)数值;分频驱动马达状态机和 RGB 闪烁标志。 +* `void Load_Database(void)`:读取 `0xFE0000` Flash 扇区数据至内存缓冲槽。 +* `void Save_Database(void)`:通过 STC IAP 命令擦除 `0xFE0000` 扇区,并将缓冲槽内的 16 组数据完整写回。 +* `void Add_Sensor(u32 addr, u8 type, u8 suffix_idx)`:向空闲槽位添加新传感器。根据 `type` 索引获取设备名称前缀(如 `PORTE` 或 `PIR`),拼装为 `[前缀] [suffix_idx]`,存入槽位并执行 `Save_Database()` 持久化。 +* `bit Check_Sensor_ID(u32 addr, u8 *out_slot_index)`:在数据库中查寻地址码,若匹配则返回槽位索引,作为警报时的名称提取依据。