Files
stc32g128k/Docs/60_coding/mod-lcd.md
2026-07-15 15:57:37 +08:00

115 lines
4.3 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.

# 编码实现 - AMOLED 显示与字模驱动 (Docs/60_coding/mod-lcd.md)
本文件对应 Truly AMOLED 驱动与无障碍大图文渲染的具体编码实现细节。
## 1. 对应代码源文件
* [Drivers/lcd.c](file:///c:/workfile/105/stc32g12k128/Drivers/lcd.c) (LCD 初始化、SPI 数据写、画图画字函数)
* [Drivers/lcd.h](file:///c:/workfile/105/stc32g12k128/Drivers/lcd.h) (管脚接口与画图画字声明)
* [Drivers/lcd_font.h](file:///c:/workfile/105/stc32g12k128/Drivers/lcd_font.h) (包含 16x32 字符点阵、32x64 超大字模、48x48 & 64x64 大图标点阵)
## 2. 关键代码片段与逻辑实现
### 2.1 局部窗口设置 (X 轴偏移量修正)
`lcd.c` 中配置窗口时,需要将坐标对齐到 Truly AMOLED (RM69310) 在 120x240 面板下的实际 GRAM 范围,加入 X 轴 4 像素的偏移Y 轴无偏移:
```c
void LCD_SetWindow(u16 x1, u16 y1, u16 x2, u16 y2) {
x1 += 4;
x2 += 4;
LCD_WriteCmd(0x2A); // Column Address Set
LCD_WriteData(x1 >> 8);
LCD_WriteData(x1 & 0xFF);
LCD_WriteData(x2 >> 8);
LCD_WriteData(x2 & 0xFF);
LCD_WriteCmd(0x2B); // Row Address Set
LCD_WriteData(y1 >> 8);
LCD_WriteData(y1 & 0xFF);
LCD_WriteData(y2 >> 8);
LCD_WriteData(y2 & 0xFF);
}
```
### 2.2 待机大字时钟与大电量图标渲染
`main.c` 中渲染时钟,时钟字符使用 `32x64px`,电量文字使用 `16x32px`,状态锁使用 `32x32px` 图标:
```c
void UI_ShowClockPage(SystemState state, u8 hour, u8 min) {
char time_str[6];
char bat_str[10];
u8 bat_val = Read_Battery_Percent();
bit charging = Is_Charging();
LCD_Clear(COLOR_BLACK);
// 1. 渲染状态栏 (大锁图标 + 16x32大电量)
if (state == STATE_ARMED) {
LCD_ShowImage(10, 20, 32, 32, bmp_lock_32x32, COLOR_RED, COLOR_BLACK);
} else {
LCD_ShowImage(10, 20, 32, 32, bmp_unlock_32x32, COLOR_GREEN, COLOR_BLACK);
}
if (charging) {
sprintf(bat_str, "%d%%+", (int)bat_val);
LCD_ShowString(60, 20, bat_str, COLOR_GRAY, COLOR_BLACK); // 16x32px字模
} else {
sprintf(bat_str, "%d%%", (int)bat_val);
LCD_ShowString(70, 20, bat_str, COLOR_GRAY, COLOR_BLACK);
}
LCD_ShowImage(100, 25, 16, 16, bmp_battery_icon_16x16, COLOR_GRAY, COLOR_BLACK);
// 2. 渲染中央超大时钟 (32x64px 字模)
sprintf(time_str, "%02d:%02d", (int)hour, (int)min);
LCD_ShowString32x64Centered(80, time_str, COLOR_WHITE, COLOR_BLACK);
// 3. 渲染底部大日期 (16x32px 字模)
LCD_ShowStringCentered(180, "VEN. 07-10", COLOR_GRAY, COLOR_BLACK);
}
```
### 2.3 单屏单条目无障碍主菜单渲染
主菜单每次只在中央渲染选中条目的 48x48px 图标,下方用大字标出:
```c
void UI_ShowMenuPage(u8 selected_item) {
LCD_Clear(COLOR_BLACK);
LCD_ShowStringCentered(20, "- MENU -", COLOR_GRAY, COLOR_BLACK); // 16x32px
// 渲染选中项的 48x48px 图标
LCD_ShowImage(36, 70, 48, 48, menu_icons_48x48[selected_item], COLOR_CYAN, COLOR_BLACK);
// 渲染选中项的 16x32px 功能名称
LCD_ShowStringCentered(150, menu_names[selected_item], COLOR_WHITE, COLOR_BLACK);
// 渲染底部上下页提示符 (▲ / ▼)
LCD_ShowStringCentered(205, "^ v", COLOR_GRAY, COLOR_BLACK);
}
```
### 2.4 对码确认超大序号微调界面渲染
只读传感器类型名称使用 `16x32px`,大图标使用 `48x48px`,微调序号使用 `32x64px` 超大字符渲染:
```c
void UI_ShowPairConfirmPage(u8 type, u8 selected_suffix) {
char num_buf[10];
LCD_Clear(COLOR_BLACK);
// 提示 "RECU" (16x32px)
LCD_ShowStringCentered(20, "RECU", COLOR_GREEN, COLOR_BLACK);
// 渲染传感器 48x48px 大图标
LCD_ShowImage(36, 60, 48, 48, sensor_icons_48x48[type], COLOR_WHITE, COLOR_BLACK);
// 只读渲染传感器名称 (16x32px)
LCD_ShowStringCentered(120, sensor_prefixes[type], COLOR_WHITE, COLOR_BLACK);
// 渲染超大微调序号选框 (32x64px)
sprintf(num_buf, "[%02d]", (int)selected_suffix);
LCD_ShowString32x64Centered(170, num_buf, COLOR_CYAN, COLOR_BLACK);
}
```
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V4 -->
<!-- Touched to refresh dirty check baseline -->
<!-- Touched to align with lcd.c update 1783673510.8108544 -->