修正1.14寸屏幕垂直偏置并添加自动清屏以清除开机噪声;修正新硬件射频收发引脚对调,低功耗唤醒中断重定向至P3.6中断16;添加一键串口收发诊断测试指令,并临时屏蔽SOS物理按键

This commit is contained in:
Antigravity IDE
2026-07-17 19:43:02 +08:00
parent 7cbd83c40b
commit 47bcd252b2
12 changed files with 609 additions and 822 deletions

139
App/ui.c
View File

@@ -38,8 +38,8 @@ void UI_ShowClockPage(SystemState state, u8 hour, u8 min)
}
// ====== 绘制右上角电池电量 ======
LCD_ShowString(62, 24, "85%", COLOR_GRAY, COLOR_BLACK); // 静态测试显示 85% 字符
LCD_DrawMonoBitmap(92, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK); // 渲染 20x10 电池外廓和格数
LCD_ShowString(77, 24, "85%", COLOR_GRAY, COLOR_BLACK); // 静态测试显示 85% 字符并移动至右上角
LCD_DrawMonoBitmap(107, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK); // 渲染 20x10 电池并移动至右上角
// ====== 绘制中部时间 "HH:MM" ======
time_str[0] = '0' + (hour / 10); // 小时十位
@@ -77,7 +77,7 @@ void UI_ShowPairMenuPage(u8 selected_index)
}
// 渲染当前选中的高亮中间项
LCD_DrawRectBorder(8, 110, 104, 28, COLOR_CYAN); // 青色对齐外框
LCD_DrawRectBorder(15, 110, 104, 28, COLOR_CYAN); // 青色对齐外框 (在 135px 宽度下居中)
LCD_ShowStringCentered(118, menu_items[selected_index], COLOR_CYAN, COLOR_BLACK);
// 渲染下方相邻项 (如果当前选择的不是最后一行)
@@ -98,13 +98,13 @@ void UI_ShowPairWaitPage(u8 frame_index)
// 绘制头部 "APPAIRAGE" (对码中)
LCD_ShowStringCentered(35, "APPAIRAGE", COLOR_GRAY, COLOR_BLACK);
// 根据 Timer1 节拍算得的帧号,切换渲染雷达的 3 种点阵图形,形成扩散动态视觉
// 根据 Timer1 节拍算得的帧号,切换渲染雷达的 3 种点阵图形,形成扩散动态视觉 (在 135px 下居中 X = 51)
if (frame_index == 0)
LCD_DrawMonoBitmap(44, 75, 32, 32, bmp_radar_32x32_f1, COLOR_CYAN, COLOR_BLACK);
LCD_DrawMonoBitmap(51, 75, 32, 32, bmp_radar_32x32_f1, COLOR_CYAN, COLOR_BLACK);
else if (frame_index == 1)
LCD_DrawMonoBitmap(44, 75, 32, 32, bmp_radar_32x32_f2, COLOR_CYAN, COLOR_BLACK);
LCD_DrawMonoBitmap(51, 75, 32, 32, bmp_radar_32x32_f2, COLOR_CYAN, COLOR_BLACK);
else
LCD_DrawMonoBitmap(44, 75, 32, 32, bmp_radar_32x32_f3, COLOR_CYAN, COLOR_BLACK);
LCD_DrawMonoBitmap(51, 75, 32, 32, bmp_radar_32x32_f3, COLOR_CYAN, COLOR_BLACK);
// 绘制状态描述
LCD_ShowStringCentered(165, "RECHERCHE", COLOR_WHITE, COLOR_BLACK); // 法语: 搜寻中
@@ -124,24 +124,24 @@ void UI_ShowPairConfirmPage(u8 type, u8 zone_index)
// 顶部显示捕获回馈标志 "v RECU" (法语: 信号已接收)
LCD_ShowStringCentered(32, "v RECU", COLOR_GREEN, COLOR_BLACK);
// 在上部居中绘制设备类别所对应的图形
// 在上部居中绘制设备类别所对应的图形 (135px 下居中 X = 51)
if (type == 0) {
LCD_DrawMonoBitmap(44, 55, 32, 32, bmp_door_32x32, COLOR_WHITE, COLOR_BLACK); // 门磁图标
LCD_DrawMonoBitmap(51, 55, 32, 32, bmp_door_32x32, COLOR_WHITE, COLOR_BLACK); // 门磁图标
} else if (type == 2 || type == 3) {
LCD_DrawMonoBitmap(44, 55, 32, 32, bmp_siren_32x32, COLOR_WHITE, COLOR_BLACK); // 警号喇叭图标
LCD_DrawMonoBitmap(51, 55, 32, 32, bmp_siren_32x32, COLOR_WHITE, COLOR_BLACK); // 警号喇叭图标
} else {
LCD_DrawMonoBitmap(44, 55, 32, 32, bmp_confirm_lock_32x32, COLOR_WHITE, COLOR_BLACK); // 锁型常规图标
LCD_DrawMonoBitmap(51, 55, 32, 32, bmp_confirm_lock_32x32, COLOR_WHITE, COLOR_BLACK); // 锁型常规图标
}
// 渲染传感器类型的文字
LCD_ShowStringCentered(105, sensor_names_fr[type], COLOR_WHITE, COLOR_BLACK);
// 绘制一个青色边框,在中间以 16x32 大号字体展示当前防区号 (如 "01", "12")
LCD_DrawRectBorder(15, 140, 90, 44, COLOR_CYAN);
// 绘制一个青色边框,在中间以 16x32 大号字体展示当前防区号 (在 135px 下居中 X=22, 宽度 90)
LCD_DrawRectBorder(22, 140, 90, 44, COLOR_CYAN);
zone_str[0] = '0' + (zone_index / 10);
zone_str[1] = '0' + (zone_index % 10);
zone_str[2] = '\0';
LCD_ShowString16x32(44, 146, zone_str, COLOR_CYAN, COLOR_BLACK); // 渲染两位防区编号
LCD_ShowString16x32(51, 146, zone_str, COLOR_CYAN, COLOR_BLACK); // 渲染两位防区编号 (135px 下居中 X = 51)
// 底部提示按键动作
LCD_ShowStringCentered(215, "CONFIRMER", COLOR_GRAY, COLOR_BLACK); // 法语: 短按以确认保存
@@ -153,8 +153,8 @@ void UI_ShowPairConfirmPage(u8 type, u8 zone_index)
void UI_ShowPairSuccessPage(void)
{
LCD_Clear(COLOR_BLACK);
// 渲染 32x32 对勾图标
LCD_DrawMonoBitmap(44, 75, 32, 32, bmp_checkmark_32x32, COLOR_GREEN, COLOR_BLACK);
// 渲染 32x32 对勾图标 (135px 下居中 X = 51)
LCD_DrawMonoBitmap(51, 75, 32, 32, bmp_checkmark_32x32, COLOR_GREEN, COLOR_BLACK);
LCD_ShowStringCentered(145, "SUCCES", COLOR_GREEN, COLOR_BLACK); // 法语: 成功
LCD_ShowStringCentered(180, "ENREGISTRE", COLOR_GRAY, COLOR_BLACK); // 法语: 配置已保存
}
@@ -166,8 +166,8 @@ void UI_ShowPairSuccessPage(void)
void UI_ShowPairFailPage(u8 is_timeout)
{
LCD_Clear(COLOR_BLACK);
// 渲染 32x32 红色叉号图标
LCD_DrawMonoBitmap(44, 75, 32, 32, bmp_cross_32x32, COLOR_RED, COLOR_BLACK);
// 渲染 32x32 红色叉号图标 (135px 下居中 X = 51)
LCD_DrawMonoBitmap(51, 75, 32, 32, bmp_cross_32x32, COLOR_RED, COLOR_BLACK);
LCD_ShowStringCentered(145, "ECHEC", COLOR_RED, COLOR_BLACK); // 法语: 失败
if (is_timeout) {
LCD_ShowStringCentered(180, "DELAI DEPASSE", COLOR_GRAY, COLOR_BLACK); // 法语: 对码超时
@@ -189,17 +189,17 @@ void UI_ShowAlarmPage(u8 type, u8 zone_index)
char zone_info[20];
LCD_Clear(COLOR_BLACK);
// 绘制双重红色爆闪粗边界框 (配合 ms_tick 在 AlarmApp 中亮灭闪烁)
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
LCD_DrawRectBorder(6, 6, 108, 228, COLOR_RED);
// 绘制双重红色爆闪粗边界框 (在新宽 135px 下对称扩展)
LCD_DrawRectBorder(4, 4, 127, 232, COLOR_RED);
LCD_DrawRectBorder(6, 6, 123, 228, COLOR_RED);
// 绘制报警设备的图形
// 绘制报警设备的图形 (135px 下居中 X = 51)
if (type == 0) {
LCD_DrawMonoBitmap(44, 50, 32, 32, bmp_door_32x32, COLOR_RED, COLOR_BLACK); // 门磁报警
LCD_DrawMonoBitmap(51, 50, 32, 32, bmp_door_32x32, COLOR_RED, COLOR_BLACK); // 门磁报警
} else if (type == 2 || type == 3) {
LCD_DrawMonoBitmap(44, 50, 32, 32, bmp_siren_32x32, COLOR_RED, COLOR_BLACK); // 烟感/燃气报警
LCD_DrawMonoBitmap(51, 50, 32, 32, bmp_siren_32x32, COLOR_RED, COLOR_BLACK); // 烟感/燃气报警
} else {
LCD_DrawMonoBitmap(44, 50, 32, 32, bmp_confirm_lock_32x32, COLOR_RED, COLOR_BLACK); // 其他防区报警
LCD_DrawMonoBitmap(51, 50, 32, 32, bmp_confirm_lock_32x32, COLOR_RED, COLOR_BLACK); // 其他防区报警
}
// 拼接字符串: "设备类型名 两位防区号"
@@ -227,19 +227,19 @@ void UI_ShowSosPage(void)
{
LCD_Clear(COLOR_BLACK);
// 绘制红白双层紧急警示框
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
LCD_DrawRectBorder(5, 5, 110, 230, COLOR_RED);
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_WHITE);
// 绘制红白双层紧急警示框 (在新宽 135px 下对称扩展)
LCD_DrawRectBorder(4, 4, 127, 232, COLOR_RED);
LCD_DrawRectBorder(5, 5, 125, 230, COLOR_RED);
LCD_DrawRectBorder(8, 8, 119, 224, COLOR_WHITE);
// ====== 用画点和填充矩形函数像素级绘制精细的警徽灯架 ======
LCD_FillRect(44, 45, 32, 2, COLOR_RED); // 警灯顶部
LCD_FillRect(48, 47, 24, 12, COLOR_RED); // 警灯红色灯罩
LCD_FillRect(40, 59, 40, 4, COLOR_GRAY); // 警灯灰色底座
LCD_FillRect(57, 51, 6, 6, COLOR_WHITE); // 中间高亮光影
LCD_FillRect(58, 36, 4, 6, COLOR_RED); // 发射的垂直红色闪光
LCD_FillRect(46, 38, 4, 4, COLOR_RED); // 左侧散射闪光
LCD_FillRect(70, 38, 4, 4, COLOR_RED); // 右侧散射闪光
// ====== 用画点和填充矩形函数像素级绘制精细的警徽灯架 (在新宽 135px 下整体右移 7 像素) ======
LCD_FillRect(51, 45, 32, 2, COLOR_RED); // 警灯顶部
LCD_FillRect(55, 47, 24, 12, COLOR_RED); // 警灯红色灯罩
LCD_FillRect(47, 59, 40, 4, COLOR_GRAY); // 警灯灰色底座
LCD_FillRect(64, 51, 6, 6, COLOR_WHITE); // 中间高亮光影
LCD_FillRect(65, 36, 4, 6, COLOR_RED); // 发射的垂直红色闪光
LCD_FillRect(53, 38, 4, 4, COLOR_RED); // 左侧散射闪光
LCD_FillRect(77, 38, 4, 4, COLOR_RED); // 右侧散射闪光
// 绘制求救中法文字样
LCD_ShowStringCentered(120, "SOS", COLOR_RED, COLOR_BLACK);
@@ -257,11 +257,11 @@ void UI_ShowBindingPage(u32 addr)
LCD_Clear(COLOR_BLACK);
// ====== 像素级拼装绘制一个青色网络摄像头简图 ======
LCD_DrawRectBorder(36, 46, 32, 26, COLOR_CYAN); // 相机主体框
LCD_FillRect(44, 56, 6, 6, COLOR_CYAN); // 镜头光圈点
LCD_FillRect(68, 48, 2, 22, COLOR_CYAN); // 右侧红外指示圈
LCD_FillRect(70, 50, 2, 18, COLOR_CYAN); // 镜头固定翼 1
LCD_FillRect(72, 52, 2, 14, COLOR_CYAN); // 镜头固定翼 2
LCD_DrawRectBorder(43, 46, 32, 26, COLOR_CYAN); // 相机主体框 (135px 下居中等比右移 X = 43)
LCD_FillRect(51, 56, 6, 6, COLOR_CYAN); // 镜头光圈点 (135px 下居中等比右移 X = 51)
LCD_FillRect(75, 48, 2, 22, COLOR_CYAN); // 右侧红外指示圈 (135px 下居中等比右移 X = 75)
LCD_FillRect(77, 50, 2, 18, COLOR_CYAN); // 镜头固定翼 1 (135px 下居中等比右移 X = 77)
LCD_FillRect(79, 52, 2, 14, COLOR_CYAN); // 镜头固定翼 2 (135px 下居中等比右移 X = 79)
LCD_ShowStringCentered(120, "LIAISON", COLOR_WHITE, COLOR_BLACK); // 法语: 连接/绑定
LCD_ShowStringCentered(155, "ENVOI EN COURS", COLOR_CYAN, COLOR_BLACK); // 法语: 发送对码帧中
@@ -294,46 +294,46 @@ void UI_ShowBindingPage(u32 addr)
* @brief 渲染显示设置主菜单界面
* @param selected_index 当前菜单高亮行索引 (0:时钟修改, 1:对码匹配, 2:摄像机绑定)
* @details 在顶部和底部绘制向上/向下箭头提示滑轮,中部绘制选中项的大几何图形,
* 并在下方打印对应的法文字串描述。
* 并在下方打印对应的法文字串描述。
*/
void UI_ShowMainMenu(u8 selected_index)
{
LCD_Clear(COLOR_BLACK);
// ====== 绘制顶部的向上箭头三角标记 ======
LCD_FillRect(58, 20, 4, 2, COLOR_GRAY);
LCD_FillRect(56, 22, 8, 2, COLOR_GRAY);
LCD_FillRect(54, 24, 12, 2, COLOR_GRAY);
// ====== 绘制顶部的向上箭头三角标记 (在 135px 宽度下居中) ======
LCD_FillRect(65, 20, 4, 2, COLOR_GRAY);
LCD_FillRect(63, 22, 8, 2, COLOR_GRAY);
LCD_FillRect(61, 24, 12, 2, COLOR_GRAY);
if (selected_index == 0)
{
// 菜单 0时间修改设置。中部绘制一个青色闹钟样式
LCD_DrawRectBorder(44, 70, 32, 32, COLOR_CYAN); // 闹钟外圈
LCD_FillRect(59, 76, 2, 10, COLOR_CYAN); // 闹钟时针
LCD_FillRect(59, 85, 8, 2, COLOR_CYAN); // 闹钟分针
// 菜单 0时间修改设置。中部绘制一个青色闹钟样式 (135px 下居中 X = 51)
LCD_DrawRectBorder(51, 70, 32, 32, COLOR_CYAN); // 闹钟外圈
LCD_FillRect(66, 76, 2, 10, COLOR_CYAN); // 闹钟时针
LCD_FillRect(66, 85, 8, 2, COLOR_CYAN); // 闹钟分针
LCD_ShowStringCentered(150, "1. HORLOGE", COLOR_WHITE, COLOR_BLACK); // 法语: 时钟/时间修改
}
else if (selected_index == 1)
{
// 菜单 1无线对码匹配。中部绘制一个青色同心圆雷达波纹图形
LCD_DrawMonoBitmap(44, 70, 32, 32, bmp_radar_32x32_f3, COLOR_CYAN, COLOR_BLACK);
// 菜单 1无线对码匹配。中部绘制一个青色同心圆雷达波纹图形 (135px 下居中 X = 51)
LCD_DrawMonoBitmap(51, 70, 32, 32, bmp_radar_32x32_f3, COLOR_CYAN, COLOR_BLACK);
LCD_ShowStringCentered(150, "2. APPAIRAGE", COLOR_WHITE, COLOR_BLACK); // 法语: 配对
}
else if (selected_index == 2)
{
// 菜单 2网络摄像机绑定。中部绘制一个相机/联通关系图
LCD_DrawRectBorder(44, 74, 20, 16, COLOR_CYAN);
LCD_FillRect(52, 80, 4, 4, COLOR_CYAN);
LCD_FillRect(64, 76, 2, 12, COLOR_CYAN);
LCD_FillRect(66, 78, 2, 8, COLOR_CYAN);
LCD_FillRect(68, 80, 2, 4, COLOR_CYAN);
// 菜单 2网络摄像机绑定。中部绘制一个相机/联通关系图 (135px 下居中等比右移 X = 57)
LCD_DrawRectBorder(57, 74, 20, 16, COLOR_CYAN);
LCD_FillRect(65, 80, 4, 4, COLOR_CYAN);
LCD_FillRect(77, 76, 2, 12, COLOR_CYAN);
LCD_FillRect(79, 78, 2, 8, COLOR_CYAN);
LCD_FillRect(81, 80, 2, 4, COLOR_CYAN);
LCD_ShowStringCentered(150, "3. LIAISON", COLOR_WHITE, COLOR_BLACK); // 法语: 摄像机绑定
}
// ====== 绘制底部的向下箭头三角标记 ======
LCD_FillRect(54, 210, 12, 2, COLOR_GRAY);
LCD_FillRect(56, 212, 8, 2, COLOR_GRAY);
LCD_FillRect(58, 214, 4, 2, COLOR_GRAY);
// ====== 绘制底部的向下箭头三角标记 (在 135px 宽度下居中) ======
LCD_FillRect(61, 210, 12, 2, COLOR_GRAY);
LCD_FillRect(63, 212, 8, 2, COLOR_GRAY);
LCD_FillRect(65, 214, 4, 2, COLOR_GRAY);
}
/**
@@ -354,8 +354,9 @@ void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
LCD_FillRect(17, 15, 8, 2, COLOR_GREEN);
LCD_FillRect(25, 17, 2, 6, COLOR_GREEN);
LCD_ShowString(62, 24, "85%", COLOR_GRAY, COLOR_BLACK);
LCD_DrawMonoBitmap(92, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK);
// 移动电池百分比和图标到 135px 右上角
LCD_ShowString(77, 24, "85%", COLOR_GRAY, COLOR_BLACK);
LCD_DrawMonoBitmap(107, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK);
// ====== 处理调节项一:小时的消隐/显示逻辑 ======
if (selection == 1 && !blink_on)
@@ -370,10 +371,10 @@ void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
time_str[1] = '0' + (hour % 10);
}
time_str[2] = '\0';
LCD_ShowString16x32(12, 100, time_str, COLOR_CYAN, COLOR_BLACK); // 采用青色特大字描绘小时
LCD_ShowString16x32(23, 100, time_str, COLOR_CYAN, COLOR_BLACK); // 采用青色特大字描绘小时 (在 135px 下整体居中 X = 23)
// 绘制中间冒号
LCD_ShowString16x32(48, 98, ":", COLOR_WHITE, COLOR_BLACK);
// 绘制中间冒号 (在 135px 下整体居中 X = 59)
LCD_ShowString16x32(59, 98, ":", COLOR_WHITE, COLOR_BLACK);
// ====== 处理调节项二:分钟的消隐/显示逻辑 ======
if (selection == 2 && !blink_on)
@@ -388,7 +389,7 @@ void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
time_str[1] = '0' + (min % 10);
}
time_str[2] = '\0';
LCD_ShowString16x32(64, 100, time_str, COLOR_CYAN, COLOR_BLACK); // 采用青色特大字描绘分钟
LCD_ShowString16x32(75, 100, time_str, COLOR_CYAN, COLOR_BLACK); // 采用青色特大字描绘分钟 (在 135px 下整体居中 X = 75)
// 补齐底部的固定辅助元素
LCD_ShowStringCentered(150, "AM", COLOR_WHITE, COLOR_BLACK);