4.2 KiB
4.2 KiB
编码实现 - AMOLED 显示与字模驱动 (Docs/60_coding/mod-lcd.md)
本文件对应 Truly AMOLED 驱动与图文渲染的具体编码实现细节。
1. 对应代码源文件
- Drivers/lcd.c (LCD 初始化、SPI 数据写、画图画字函数)
- Drivers/lcd.h (管脚接口与画图画字声明)
- Drivers/lcd_font.h (ASCII 8x16 点阵字模与图标数据)
2. 关键代码片段与逻辑实现
2.1 局部窗口设置 (X 轴偏移量修正)
在 lcd.c 中配置窗口时,需要将坐标对齐到 Truly AMOLED (RM69310) 在 120x240 面板下的实际 GRAM 范围,加入 X 轴 4 像素的偏移,Y 轴无偏移:
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 的时钟页面刷新中,获取当前百分比及充电状态,动态绘制到状态栏:
void UI_ShowClockPage(SystemState state, u8 hour, u8 min) {
char bat_str[10];
u8 bat_val = Read_Battery_Percent();
bit charging = Is_Charging();
LCD_Clear(COLOR_BLACK);
// 充电状态判定与百分比字符串格式化
if (charging) {
if (bat_val >= 100) {
bat_str[0] = '1'; bat_str[1] = '0'; bat_str[2] = '0'; bat_str[3] = '%'; bat_str[4] = '+'; bat_str[5] = '';
} else {
bat_str[0] = '0' + (bat_val / 10);
bat_str[1] = '0' + (bat_val % 10);
bat_str[2] = '%';
bat_str[3] = '+';
bat_str[4] = '';
}
LCD_ShowString(60, 24, bat_str, COLOR_GRAY, COLOR_BLACK);
} else {
if (bat_val >= 100) {
bat_str[0] = '1'; bat_str[1] = '0'; bat_str[2] = '0'; bat_str[3] = '%'; bat_str[4] = '';
} else {
bat_str[0] = '0' + (bat_val / 10);
bat_str[1] = '0' + (bat_val % 10);
bat_str[2] = '%';
bat_str[3] = '';
}
LCD_ShowString(76, 24, bat_str, COLOR_GRAY, COLOR_BLACK);
}
LCD_ShowImage(82, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK);
}
2.3 对码确认二步微调界面渲染实现
在 main.c 中通过判断 confirm_edit_focus 的值动态渲染闪烁选框:
void UI_ShowPairConfirmPage(u8 edit_focus, u8 type, u8 selected_suffix) {
char num_buf[10];
LCD_Clear(COLOR_BLACK);
LCD_ShowStringCentered(40, "v RECU", COLOR_GREEN, COLOR_BLACK);
// 步骤1:渲染传感器类型
if (edit_focus == 0) {
// 类型处于编辑状态,左右加选框或括号
char type_buf[20];
type_buf[0] = '[';
type_buf[1] = ' ';
strcpy(&type_buf[2], sensor_prefixes[type]);
strcat(type_buf, " ]");
LCD_ShowStringCentered(90, type_buf, COLOR_CYAN, COLOR_BLACK);
} else {
// 锁定显示
LCD_ShowStringCentered(90, sensor_prefixes[type], COLOR_WHITE, COLOR_BLACK);
}
// 渲染位图图标
LCD_ShowImage(44, 120, 32, 32, sensor_icons[type], COLOR_WHITE, COLOR_BLACK);
// 步骤2:渲染数字序号
num_buf[0] = '[';
num_buf[1] = ' ';
num_buf[2] = ' ';
num_buf[3] = '0' + (selected_suffix / 10);
num_buf[4] = '0' + (selected_suffix % 10);
num_buf[5] = ' ';
num_buf[6] = ' ';
num_buf[7] = ']';
num_buf[8] = '';
if (edit_focus == 1) {
// 序号处于编辑状态,高亮显示
LCD_ShowStringCentered(180, num_buf, COLOR_CYAN, COLOR_BLACK);
} else {
// 灰度非编辑状态显示
LCD_ShowStringCentered(180, num_buf, COLOR_GRAY, COLOR_BLACK);
}
}