菜单支持,所有功能都测试成功
This commit is contained in:
39
AGENTS.md
39
AGENTS.md
@@ -15,6 +15,8 @@ STM32CubeMX 生成的项目,使用 **Keil MDK-ARM V5.32** 工具链。
|
||||
- `hz16_data.c/h` — CJK 16×16 字库
|
||||
- `STM32F103C8T6/Drivers/BSP/AT24C02/` — AT24C02 EEPROM 驱动
|
||||
- `at24c02.c/h` — I2C 读写(字节/页/连续,自动跨页)
|
||||
- `STM32F103C8T6/User/` — 用户应用代码
|
||||
- `menu.c/h` — 菜单系统(LCD参数显示、按键调节、EEPROM存储)
|
||||
|
||||
## 硬件配置
|
||||
- **MCU**: STM32F103C8T6 (LQFP48, 72MHz, 64KB Flash, 20KB RAM)
|
||||
@@ -33,39 +35,30 @@ STM32CubeMX 生成的项目,使用 **Keil MDK-ARM V5.32** 工具链。
|
||||
## 初始化顺序(main.c)
|
||||
```
|
||||
HAL_Init → SystemClock_Config → MX_GPIO → MX_DMA → MX_USART1 → MX_SPI2
|
||||
→ MX_TIM4 → MX_ADC1 → MX_TIM3
|
||||
→ MX_TIM4 → MX_ADC1 → MX_TIM3 → MX_I2C1
|
||||
→ button_driver_init() → st7735s_init() → lcd_* draw
|
||||
→ TIM3 PWM start (PA6~PB1) → TIM4 Base start (TRGO→ADC) → ADC injected start
|
||||
→ AT24C02 scan → menu_init()
|
||||
```
|
||||
|
||||
## ADC 采坑记录(不可从 CubeMX 重新生成时光靠设置)
|
||||
- **ADC 时钟**: SystemClock_Config 初始为 PCLK2/2=36MHz(超 14MHz 规格),必须在 `USER CODE SysInit` 中手动改为 `/6`:
|
||||
```c
|
||||
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE) | RCC_CFGR_ADCPRE_DIV6;
|
||||
```
|
||||
- **TIM4_TRGO 触发 ADC(当前方案)**: CubeMX 中 TIM4 无任何 PWM 通道,生成的 `MasterOutputTrigger` 为 `TIM_TRGO_RESET` → TRGO 无脉冲。必须在 `USER CODE TIM4_Init 2` 中写寄存器:
|
||||
```c
|
||||
TIM4->CR2 = (TIM4->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1; /* TRGO = Update */
|
||||
```
|
||||
启动时用 `HAL_TIM_Base_Start(&htim4)` 即可。
|
||||
- **旧方案(已废弃)**: TIM3_CH4 触发 ADC 已废弃(PB8/PB9 改为 I2C)。
|
||||
## CubeMX 生成代码注意事项
|
||||
- **TIM4_TRGO**: CubeMX 已正确生成 `TIM_TRGO_UPDATE`(`tim.c:125`),无需手动写寄存器。若从 `.ioc` 重新生成,检查 `sMasterConfig.MasterOutputTrigger` 是否仍为 `TIM_TRGO_UPDATE`。
|
||||
- **ADC 时钟**: CubeMX 已通过 HAL 配置 `RCC_ADCPCLK2_DIV6`(`adc.c:221`),无需手动改 `RCC->CFGR`。若重新生成,验证 `PeriphClkInit.AdcClockSelection` 是否为 `RCC_ADCPCLK2_DIV6`(必须 ≤14MHz)。
|
||||
- **SPI2 模式**: CubeMX 已配置 Mode 3(CPOL=HIGH, CPHA=2EDGE),见 `spi.c:45-46`。重新生成时确认 `CLKPolarity=HIGH, CLKPhase=2EDGE`。
|
||||
|
||||
## printf 无 MicroLIB
|
||||
在 `usart.c` 的 USER CODE 区通过 `#pragma import(__use_no_semihosting)` + `_sys_exit()` + `_ttywrch()` + `struct __FILE` + `FILE __stdout` 实现。Keil 取消勾选 Use MicroLIB 即可。
|
||||
|
||||
## SPI 注意事项
|
||||
- LCD (ST7735S) 使用**硬件SPI2**(PB13 SCK, PB15 MOSI),18MHz,**Mode 3**(CPOL=HIGH, CPHA=2EDGE)
|
||||
- 若通过 CubeMX 重新生成 `spi.c`,务必在 SPI2 配置中设置 Clock Polarity=High, Clock Phase=2 Edge
|
||||
- CS(PB11)、DC(PB10)、RST(PB12) 为 GPIO 控制
|
||||
|
||||
## LCD 字库生成(tools/font_gen.py)
|
||||
- Python + Pillow 渲染,使用 `C:\ProgramData\anaconda3\python.exe`
|
||||
- ASCII 8×16(默认):`python font_gen.py`
|
||||
- CJK 16×16(按需):`python font_gen.py --cjk --string "你的汉字" --output STM32F103C8T6/Drivers/BSP/LCD/hz16_data`
|
||||
- ASCII 默认参数:`--font simsun --size 56 --threshold 64 --scale 4`
|
||||
- CJK 默认参数:`--font simsun --size 48 --threshold 50 --scale 3`
|
||||
- Python + Pillow,使用 `python font_gen.py`(Windows 下默认系统 Python)
|
||||
- **仅生成 CJK 字库**,ASCII 字库 `lcd_data.c` 已手动维护
|
||||
- CJK 16×16(按需):
|
||||
```
|
||||
python tools/font_gen.py --cjk --string "你的汉字" --output STM32F103C8T6/Drivers/BSP/LCD/hz16_data
|
||||
```
|
||||
- 默认参数:`--font simsun --size 48 --scale 3`,Otsu 自适应阈值
|
||||
- CJK 无等宽替代字体,必须用 simsun
|
||||
- ASCII `_` 下划线手动设为 `0x7F`(GDI 无法可靠提取)
|
||||
- 输出目录 `MDK-ARM\STM32F103C8T6\` 已 gitignore
|
||||
|
||||
## 代码规范
|
||||
- **遵循**: `嵌入式C语言代码规范(V1.0).md`
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "st7735s.h"
|
||||
#include "lcd.h"
|
||||
#include "at24c02.h"
|
||||
#include "menu.h"
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
@@ -91,9 +92,6 @@ int main(void)
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
/* ADC 时钟预分频:PCLK2 / 6 = 72/6 = 12MHz */
|
||||
/* 默认 /2=36MHz 超过 14MHz 规格,ADC 无法正常工作 */
|
||||
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE) | RCC_CFGR_ADCPRE_DIV6;
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
@@ -143,64 +141,41 @@ int main(void)
|
||||
/* 启动 ADC 注入组(TIM4 每触发一次,自动采一轮 PA0~PA3) */
|
||||
HAL_ADCEx_InjectedStart(&hadc1);
|
||||
|
||||
/* === AT24C02 EEPROM 测试 === */
|
||||
{
|
||||
uint8_t wbuf[] = {0x11, 0x22, 0x33, 0x44, 0x55};
|
||||
uint8_t rbuf[8];
|
||||
int i, ret;
|
||||
|
||||
ret = at24c02_scan();
|
||||
if (ret == AT24C02_OK) {
|
||||
lcd_draw_string(0, 64, "AT24C02 OK", COLOR_GREEN, COLOR_BLACK);
|
||||
/* AT24C02 检测 */
|
||||
if (at24c02_scan() == AT24C02_OK) {
|
||||
lcd_draw_string(0, 80, "AT24C02 OK", COLOR_GREEN, COLOR_BLACK);
|
||||
} else {
|
||||
lcd_draw_string(0, 64, "AT24C02 FAIL", COLOR_RED, COLOR_BLACK);
|
||||
lcd_draw_string(0, 80, "AT24C02 FAIL", COLOR_RED, COLOR_BLACK);
|
||||
}
|
||||
|
||||
/* 在地址 0 写入 5 个字节 */
|
||||
ret = at24c02_write_buf(0, wbuf, 5);
|
||||
printf("AT24C02 write: %d\r\n", ret);
|
||||
|
||||
/* 从地址 0 读回 8 个字节 */
|
||||
ret = at24c02_read_buf(0, rbuf, 8);
|
||||
printf("AT24C02 read[%d]:", ret);
|
||||
for (i = 0; i < 8; i++) {
|
||||
printf(" %02X", rbuf[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
/* 验证 */
|
||||
lcd_draw_string(0, 80, "EEPROM:", COLOR_WHITE, COLOR_BLACK);
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (rbuf[i] != wbuf[i]) {
|
||||
printf("AT24C02 ERR: addr %d expect %02X got %02X\r\n",
|
||||
i, wbuf[i], rbuf[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 5) {
|
||||
printf("AT24C02 verify OK\r\n");
|
||||
}
|
||||
}
|
||||
/* 进入菜单界面 */
|
||||
menu_init();
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
uint32_t tick_last = 0;
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
HAL_Delay(1000);
|
||||
/* 菜单按键处理(每帧必须频繁调用) */
|
||||
menu_process();
|
||||
|
||||
/* 每秒执行一次:LED翻转 + ADC打印 */
|
||||
if (HAL_GetTick() - tick_last >= 1000) {
|
||||
tick_last = HAL_GetTick();
|
||||
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||
|
||||
/* 读取 ADC 注入组结果(TIM4 以 1kHz 触发,每秒打印一次最新值) */
|
||||
uint16_t adc0 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
|
||||
uint16_t adc1 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2);
|
||||
uint16_t adc2 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_3);
|
||||
uint16_t adc3 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_4);
|
||||
printf("ADC: %4d %4d %4d %4d\r\n", adc0, adc1, adc2, adc3);
|
||||
}
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,81 @@ void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, ui
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:显示一个6x8 ASCII字符
|
||||
* 入口参数:x - 列坐标
|
||||
* y - 行坐标
|
||||
* ch - 字符 (ASCII 32-126)
|
||||
* color - 字符颜色 (RGB565)
|
||||
* bg_color - 背景颜色 (RGB565)
|
||||
* 返回值:无
|
||||
* 函数说明:LCD_F6x8为列式存储(每字节一列,bit0=顶行,bit7=底行)
|
||||
* 框选6x8区域→逐行逐列取bit→发送color或bg_color
|
||||
*/
|
||||
void lcd_draw_char_6x8(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color)
|
||||
{
|
||||
uint8_t row;
|
||||
uint8_t col;
|
||||
uint8_t col_data;
|
||||
|
||||
if (ch < 32 || ch > 126) {
|
||||
ch = ' ';
|
||||
}
|
||||
|
||||
st7735s_set_window(x, y, x + 5, y + 7);
|
||||
|
||||
HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET);
|
||||
|
||||
for (row = 0; row < 8; row++) {
|
||||
for (col = 0; col < 6; col++) {
|
||||
col_data = LCD_F6x8[ch - 32][col];
|
||||
if (col_data & (1 << row)) {
|
||||
st7735s_spi_write_byte((uint8_t)(color >> 8));
|
||||
st7735s_spi_write_byte((uint8_t)(color & 0xFF));
|
||||
} else {
|
||||
st7735s_spi_write_byte((uint8_t)(bg_color >> 8));
|
||||
st7735s_spi_write_byte((uint8_t)(bg_color & 0xFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:显示字符串(6x8字体)
|
||||
* 入口参数:x - 列坐标
|
||||
* y - 行坐标
|
||||
* str - 字符串指针
|
||||
* color - 字符颜色 (RGB565)
|
||||
* bg_color - 背景颜色 (RGB565)
|
||||
* 返回值:无
|
||||
* 函数说明:连续显示6x8字符,自动换行
|
||||
*/
|
||||
void lcd_draw_string_6x8(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color)
|
||||
{
|
||||
uint16_t start_x = x;
|
||||
|
||||
while (*str != '\0') {
|
||||
if (*str == '\n') {
|
||||
y += FONT_HEIGHT_8;
|
||||
x = start_x;
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
if (x + FONT_WIDTH_6 > s_lcd_width) {
|
||||
y += FONT_HEIGHT_8;
|
||||
x = start_x;
|
||||
}
|
||||
if (y + FONT_HEIGHT_8 > s_lcd_height) {
|
||||
break;
|
||||
}
|
||||
lcd_draw_char_6x8(x, y, *str, color, bg_color);
|
||||
x += FONT_WIDTH_6;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:显示一个16x16 CJK汉字
|
||||
* 入口参数:x - 列坐标
|
||||
|
||||
@@ -21,6 +21,8 @@ extern "C" {
|
||||
/* 字体定义 */
|
||||
#define FONT_WIDTH_8 8 /* 8x16字体宽度(含间距) */
|
||||
#define FONT_HEIGHT_16 16 /* 8x16字体高度 */
|
||||
#define FONT_WIDTH_6 6 /* 6x8字体宽度 */
|
||||
#define FONT_HEIGHT_8 8 /* 6x8字体高度 */
|
||||
|
||||
/* === 字符/字符串绘制 === */
|
||||
|
||||
@@ -46,6 +48,28 @@ void lcd_draw_char(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_
|
||||
*/
|
||||
void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color);
|
||||
|
||||
/*
|
||||
* 函数功能:显示一个6x8 ASCII字符
|
||||
* 入口参数:x - 列坐标
|
||||
* y - 行坐标
|
||||
* ch - 字符 (ASCII 32-126)
|
||||
* color - 字符颜色 (RGB565)
|
||||
* bg_color - 背景颜色 (RGB565)
|
||||
* 返回值:无
|
||||
*/
|
||||
void lcd_draw_char_6x8(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color);
|
||||
|
||||
/*
|
||||
* 函数功能:显示字符串(6x8字体)
|
||||
* 入口参数:x - 列坐标
|
||||
* y - 行坐标
|
||||
* str - 字符串指针
|
||||
* color - 字符颜色 (RGB565)
|
||||
* bg_color - 背景颜色 (RGB565)
|
||||
* 返回值:无
|
||||
*/
|
||||
void lcd_draw_string_6x8(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color);
|
||||
|
||||
/*
|
||||
* 函数功能:显示一个16x16 CJK汉字
|
||||
* 入口参数:x - 列坐标
|
||||
|
||||
@@ -1,298 +1,300 @@
|
||||
#include "lcd_data.h"
|
||||
/*ASCII字模数据*********************/
|
||||
/* ASCII 字模数据 8x16 */
|
||||
/* 来源: font8x16 (hubenchang0515) — MIT 许可 */
|
||||
/* 人工逐像素设计的专业位图字体,非算法缩放生成 */
|
||||
|
||||
/*宽8像素,高16像素*/
|
||||
/* 字体: simsun.ttc, 字号: 64, 阈值: 50 */
|
||||
const uint8_t LCD_F8x16[][16] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // ! 1
|
||||
0x00, 0x16, 0x36, 0x3C, 0x68, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18,
|
||||
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // ! 1
|
||||
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2
|
||||
0x00, 0x00, 0x20, 0x26, 0x26, 0xFF, 0x7E, 0x24,
|
||||
0x64, 0xFF, 0xFE, 0x64, 0x64, 0x00, 0x00, 0x00, // # 3
|
||||
0x00, 0x18, 0x3C, 0x7E, 0x7E, 0x78, 0x38, 0x18,
|
||||
0x1C, 0x1E, 0x7E, 0x56, 0x7C, 0x18, 0x18, 0x00, // $ 4
|
||||
0x00, 0x00, 0x60, 0xF4, 0x94, 0x9C, 0x98, 0xFC,
|
||||
0x1E, 0x1B, 0x3B, 0x2B, 0x6E, 0x04, 0x00, 0x00, // % 5
|
||||
0x00, 0x00, 0x30, 0x78, 0x68, 0x78, 0x78, 0x76,
|
||||
0xF4, 0xD4, 0xDC, 0xCC, 0x7F, 0x22, 0x00, 0x00, // & 6
|
||||
0x00, 0x60, 0x70, 0x30, 0x60, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C,
|
||||
0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, // # 3
|
||||
0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06,
|
||||
0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, // $ 4
|
||||
0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18,
|
||||
0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, // % 5
|
||||
0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC,
|
||||
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, // & 6
|
||||
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7
|
||||
0x00, 0x02, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x02, 0x00, // ( 8
|
||||
0x00, 0x40, 0x60, 0x30, 0x30, 0x10, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0x40, 0x00, // ) 9
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0xFF, 0x7E, 0x3C,
|
||||
0xFF, 0xDB, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // * 10
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xFF, 0x18,
|
||||
0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, // ( 8
|
||||
0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // ) 9
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF,
|
||||
0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * 10
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
|
||||
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 11
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70,
|
||||
0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12
|
||||
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, // , 12
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // - 13
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14
|
||||
0x00, 0x02, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18,
|
||||
0x10, 0x30, 0x20, 0x60, 0x40, 0xC0, 0x80, 0x00, // / 15
|
||||
0x00, 0x00, 0x3C, 0x66, 0x66, 0x42, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x18, 0x00, 0x00, // 0 16
|
||||
0x00, 0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // 1 17
|
||||
0x00, 0x00, 0x3C, 0x66, 0x62, 0x62, 0x06, 0x04,
|
||||
0x08, 0x10, 0x20, 0x42, 0xFE, 0x7C, 0x00, 0x00, // 2 18
|
||||
0x00, 0x00, 0x3C, 0x64, 0x66, 0x06, 0x0C, 0x1C,
|
||||
0x06, 0x02, 0x62, 0x66, 0x7C, 0x18, 0x00, 0x00, // 3 19
|
||||
0x00, 0x00, 0x04, 0x0C, 0x1C, 0x1C, 0x2C, 0x6C,
|
||||
0x4C, 0xFE, 0x0C, 0x0C, 0x0E, 0x1E, 0x00, 0x00, // 4 20
|
||||
0x00, 0x00, 0x3E, 0x7E, 0x60, 0x40, 0x7C, 0x66,
|
||||
0x06, 0x02, 0x62, 0x66, 0x7C, 0x18, 0x00, 0x00, // 5 21
|
||||
0x00, 0x00, 0x1C, 0x26, 0x62, 0x40, 0xDC, 0xF6,
|
||||
0xC2, 0xC3, 0x43, 0x62, 0x3E, 0x18, 0x00, 0x00, // 6 22
|
||||
0x00, 0x00, 0x7E, 0x7E, 0x44, 0x04, 0x0C, 0x08,
|
||||
0x18, 0x18, 0x18, 0x38, 0x38, 0x10, 0x00, 0x00, // 7 23
|
||||
0x00, 0x00, 0x3C, 0x66, 0x42, 0x62, 0x76, 0x3C,
|
||||
0x6E, 0x46, 0xC2, 0x46, 0x7C, 0x18, 0x00, 0x00, // 8 24
|
||||
0x00, 0x00, 0x3C, 0x66, 0x46, 0xC2, 0xC2, 0x66,
|
||||
0x7E, 0x16, 0x06, 0x64, 0x7C, 0x10, 0x00, 0x00, // 9 25
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // . 14
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
|
||||
0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, // / 15
|
||||
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xD6, 0xD6,
|
||||
0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, // 0 16
|
||||
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, // 1 17
|
||||
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30,
|
||||
0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, // 2 18
|
||||
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06,
|
||||
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // 3 19
|
||||
0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE,
|
||||
0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, // 4 20
|
||||
0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06,
|
||||
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // 5 21
|
||||
0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // 6 22
|
||||
0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18,
|
||||
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, // 7 23
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // 8 24
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06,
|
||||
0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, // 9 25
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // : 26
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, // ; 27
|
||||
0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60,
|
||||
0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, // < 28
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // = 29
|
||||
0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06,
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, // > 30
|
||||
0x00, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0x46, 0x0C,
|
||||
0x18, 0x10, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // ? 31
|
||||
0x00, 0x00, 0x1C, 0x36, 0x6F, 0x5F, 0xD7, 0xF5,
|
||||
0xF5, 0xFE, 0x7E, 0x63, 0x3E, 0x18, 0x00, 0x00, // @ 32
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x2C, 0x2C,
|
||||
0x3C, 0x7E, 0x46, 0x46, 0xC7, 0xC7, 0x00, 0x00, // A 33
|
||||
0x00, 0x00, 0xFC, 0x66, 0x62, 0x62, 0x66, 0x7C,
|
||||
0x66, 0x63, 0x63, 0x63, 0x7E, 0xF8, 0x00, 0x00, // B 34
|
||||
0x00, 0x00, 0x1E, 0x63, 0x41, 0xC0, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC1, 0x62, 0x3E, 0x18, 0x00, 0x00, // C 35
|
||||
0x00, 0x00, 0xF8, 0x6C, 0x66, 0x63, 0x63, 0x63,
|
||||
0x63, 0x63, 0x62, 0x66, 0x7C, 0xF0, 0x00, 0x00, // D 36
|
||||
0x00, 0x00, 0x7E, 0x66, 0x62, 0x60, 0x64, 0x7C,
|
||||
0x64, 0x60, 0x60, 0x63, 0x7E, 0x7E, 0x00, 0x00, // E 37
|
||||
0x00, 0x00, 0x7E, 0x63, 0x61, 0x60, 0x64, 0x7C,
|
||||
0x64, 0x64, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, // F 38
|
||||
0x00, 0x00, 0x3C, 0x66, 0x42, 0xC0, 0xC0, 0xC0,
|
||||
0xC7, 0xC6, 0x46, 0x66, 0x3E, 0x18, 0x00, 0x00, // G 39
|
||||
0x00, 0x00, 0xE7, 0x66, 0x66, 0x66, 0x66, 0x7E,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, // H 40
|
||||
0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // : 26
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // ; 27
|
||||
0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60,
|
||||
0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, // < 28
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00,
|
||||
0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // = 29
|
||||
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06,
|
||||
0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, // > 30
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18,
|
||||
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // ? 31
|
||||
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE,
|
||||
0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, // @ 32
|
||||
0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE,
|
||||
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, // A 33
|
||||
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66,
|
||||
0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, // B 34
|
||||
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
|
||||
0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, // C 35
|
||||
0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, // D 36
|
||||
0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68,
|
||||
0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, // E 37
|
||||
0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68,
|
||||
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, // F 38
|
||||
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE,
|
||||
0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, // G 39
|
||||
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, // H 40
|
||||
0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // I 41
|
||||
0x00, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xF8, 0x20, 0x00, // J 42
|
||||
0x00, 0x00, 0xE6, 0x66, 0x6C, 0x68, 0x70, 0x78,
|
||||
0x68, 0x6C, 0x6C, 0x66, 0x67, 0x67, 0x00, 0x00, // K 43
|
||||
0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||
0x60, 0x60, 0x60, 0x63, 0x7E, 0x7E, 0x00, 0x00, // L 44
|
||||
0x00, 0x00, 0xC3, 0x66, 0x66, 0x66, 0x66, 0x6E,
|
||||
0x7E, 0x7A, 0x5A, 0x5A, 0xD7, 0xC7, 0x00, 0x00, // M 45
|
||||
0x00, 0x00, 0xC7, 0x62, 0x72, 0x72, 0x52, 0x5A,
|
||||
0x4A, 0x4E, 0x46, 0x46, 0xE2, 0xE0, 0x00, 0x00, // N 46
|
||||
0x00, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0x43, 0x66, 0x3C, 0x18, 0x00, 0x00, // O 47
|
||||
0x00, 0x00, 0x7C, 0x66, 0x63, 0x63, 0x62, 0x7E,
|
||||
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, // P 48
|
||||
0x00, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xFB, 0x7A, 0x6E, 0x3C, 0x06, 0x00, 0x00, // Q 49
|
||||
0x00, 0x00, 0x7C, 0x66, 0x62, 0x62, 0x66, 0x7C,
|
||||
0x68, 0x6C, 0x64, 0x66, 0x67, 0x63, 0x00, 0x00, // R 50
|
||||
0x00, 0x00, 0x3C, 0x66, 0x42, 0x60, 0x70, 0x3C,
|
||||
0x0E, 0x06, 0xC2, 0x46, 0x7E, 0x18, 0x00, 0x00, // S 51
|
||||
0x00, 0x00, 0x7E, 0xDB, 0x99, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, // T 52
|
||||
0x00, 0x00, 0xE7, 0x62, 0x62, 0x62, 0x62, 0x62,
|
||||
0x62, 0x62, 0x62, 0x62, 0x3C, 0x18, 0x00, 0x00, // U 53
|
||||
0x00, 0x00, 0xE7, 0x66, 0x66, 0x64, 0x24, 0x24,
|
||||
0x3C, 0x38, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, // V 54
|
||||
0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x5A, 0x7E,
|
||||
0x7C, 0x7C, 0x2C, 0x2C, 0x24, 0x00, 0x00, 0x00, // W 55
|
||||
0x00, 0x00, 0x66, 0x66, 0x24, 0x3C, 0x18, 0x18,
|
||||
0x18, 0x3C, 0x2C, 0x24, 0x66, 0x66, 0x00, 0x00, // X 56
|
||||
0x00, 0x00, 0xE7, 0x62, 0x66, 0x34, 0x34, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, // Y 57
|
||||
0x00, 0x00, 0x7E, 0x66, 0x46, 0x0C, 0x08, 0x18,
|
||||
0x10, 0x30, 0x20, 0x62, 0xFE, 0x7C, 0x00, 0x00, // Z 58
|
||||
0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00, // [ 59
|
||||
0x00, 0x40, 0x60, 0x20, 0x30, 0x30, 0x10, 0x18,
|
||||
0x08, 0x0C, 0x0C, 0x04, 0x06, 0x02, 0x02, 0x00, // \ 60
|
||||
0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, // ] 61
|
||||
0x00, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, // I 41
|
||||
0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, // J 42
|
||||
0x00, 0x00, 0xE6, 0x66, 0x66, 0x6C, 0x78, 0x78,
|
||||
0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, // K 43
|
||||
0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||
0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, // L 44
|
||||
0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, // M 45
|
||||
0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE,
|
||||
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, // N 46
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // O 47
|
||||
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60,
|
||||
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, // P 48
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||
0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, // Q 49
|
||||
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C,
|
||||
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, // R 50
|
||||
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C,
|
||||
0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // S 51
|
||||
0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, // T 52
|
||||
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // U 53
|
||||
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||
0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, // V 54
|
||||
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6,
|
||||
0xD6, 0xFE, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, // W 55
|
||||
0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38,
|
||||
0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, // X 56
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18,
|
||||
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, // Y 57
|
||||
0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30,
|
||||
0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, // Z 58
|
||||
0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, // [ 59
|
||||
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38,
|
||||
0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, // \ 60
|
||||
0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00, // ] 61
|
||||
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, // _ 63
|
||||
0x00, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, // _ 63
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64
|
||||
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x46, 0x3E,
|
||||
0x66, 0xC6, 0x6F, 0x36, 0x00, 0x00, 0x00, 0x00, // a 65
|
||||
0x00, 0x00, 0xC0, 0x60, 0x60, 0x60, 0x7C, 0x76,
|
||||
0x66, 0x62, 0x62, 0x66, 0x66, 0x5C, 0x00, 0x00, // b 66
|
||||
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x40,
|
||||
0x40, 0x62, 0x76, 0x1C, 0x00, 0x00, 0x00, 0x00, // c 67
|
||||
0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x76,
|
||||
0x66, 0x46, 0x46, 0x66, 0x6E, 0x3E, 0x00, 0x00, // d 68
|
||||
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x7E,
|
||||
0x40, 0x62, 0x76, 0x1C, 0x00, 0x00, 0x00, 0x00, // e 69
|
||||
0x00, 0x00, 0x0E, 0x1B, 0x31, 0x30, 0x7C, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x38, 0x7C, 0x00, 0x00, // f 70
|
||||
0x00, 0x00, 0x00, 0x1B, 0x2F, 0x66, 0x66, 0x3C,
|
||||
0x78, 0x7E, 0x46, 0x66, 0x3C, 0x00, 0x00, 0x00, // g 71
|
||||
0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, // h 72
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x38, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // i 73
|
||||
0x00, 0x04, 0x06, 0x00, 0x00, 0x1E, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x04, 0x6C, 0x38, 0x00, // j 74
|
||||
0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x66, 0x6C,
|
||||
0x68, 0x78, 0x6C, 0x6C, 0x66, 0x67, 0x00, 0x00, // k 75
|
||||
0x00, 0x00, 0x38, 0x38, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, // l 76
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0xDB, 0xDB, 0xDB,
|
||||
0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00, // m 77
|
||||
0x00, 0x00, 0x00, 0x00, 0xFC, 0x76, 0x66, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
|
||||
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, // a 65
|
||||
0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66,
|
||||
0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, // b 66
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
|
||||
0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // c 67
|
||||
0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, // d 68
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE,
|
||||
0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // e 69
|
||||
0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60,
|
||||
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, // f 70
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, // g 71
|
||||
0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66,
|
||||
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, // h 72
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, // i 73
|
||||
0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, // j 74
|
||||
0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78,
|
||||
0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, // k 75
|
||||
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, // l 76
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6,
|
||||
0xD6, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00, // m 77
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, // n 78
|
||||
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0xC3,
|
||||
0xC3, 0x42, 0x66, 0x38, 0x00, 0x00, 0x00, 0x00, // o 79
|
||||
0x00, 0x00, 0x00, 0x7C, 0x76, 0x62, 0x63, 0x63,
|
||||
0x62, 0x66, 0x7C, 0x60, 0x70, 0x00, 0x00, 0x00, // p 80
|
||||
0x00, 0x00, 0x00, 0x3E, 0x66, 0x46, 0xC6, 0xC6,
|
||||
0x46, 0x7E, 0x16, 0x06, 0x0E, 0x00, 0x00, 0x00, // q 81
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0x3B, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0xF8, 0x00, 0x00, 0x00, 0x00, // r 82
|
||||
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x38,
|
||||
0x0E, 0x46, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, // s 83
|
||||
0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0x1E, 0x0C, 0x00, 0x00, 0x00, // t 84
|
||||
0x00, 0x00, 0x00, 0x00, 0xE6, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, // u 85
|
||||
0x00, 0x00, 0x00, 0x00, 0xE6, 0x66, 0x24, 0x34,
|
||||
0x38, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // v 86
|
||||
0x00, 0x00, 0x00, 0x00, 0xDB, 0xDA, 0x5A, 0x7E,
|
||||
0x7C, 0x2C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, // w 87
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0x34, 0x38, 0x18,
|
||||
0x18, 0x2C, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, // x 88
|
||||
0x00, 0x00, 0x00, 0x67, 0x66, 0x34, 0x34, 0x1C,
|
||||
0x18, 0x18, 0x18, 0x70, 0x60, 0x00, 0x00, 0x00, // y 89
|
||||
0x00, 0x00, 0x00, 0x00, 0x7E, 0x4C, 0x08, 0x18,
|
||||
0x30, 0x22, 0x7E, 0x7C, 0x00, 0x00, 0x00, 0x00, // z 90
|
||||
0x00, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18,
|
||||
0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x00, // { 91
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // | 92
|
||||
0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18,
|
||||
0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, // } 93
|
||||
0x00, 0x70, 0x59, 0x0E, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // o 79
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, // p 80
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, // q 81
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66,
|
||||
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, // r 82
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60,
|
||||
0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, // s 83
|
||||
0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30,
|
||||
0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, // t 84
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, // u 85
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, // v 86
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6,
|
||||
0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, // w 87
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38,
|
||||
0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, // x 88
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
|
||||
0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, // y 89
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18,
|
||||
0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, // z 90
|
||||
0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18,
|
||||
0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, // { 91
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // | 92
|
||||
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18,
|
||||
0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, // } 93
|
||||
0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ~ 94
|
||||
};
|
||||
|
||||
/*宽6像素,高8像素(未使用)*/
|
||||
/* 宽6像素,高8像素 */
|
||||
/* 来源: font6x8 (fantasticmao/font6x8), GPL-3.0 */
|
||||
/* 列式存储:每字节一列,bit0=顶行,bit7=底行 */
|
||||
const uint8_t LCD_F6x8[][6] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 0
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ! 1
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // " 2
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // # 3
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // $ 4
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // % 5
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // & 6
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ' 7
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ( 8
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ) 9
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // * 10
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // + 11
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // , 12
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // - 13
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // . 14
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // / 15
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 0 16
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 1 17
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 2 18
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 3 19
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 4 20
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 5 21
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 6 22
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 7 23
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 8 24
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // 9 25
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // : 26
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ; 27
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // < 28
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // = 29
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // > 30
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ? 31
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // @ 32
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // A 33
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // B 34
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // C 35
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // D 36
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // E 37
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // F 38
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // G 39
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // H 40
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // I 41
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // J 42
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // K 43
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // L 44
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // M 45
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // N 46
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // O 47
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // P 48
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // Q 49
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // R 50
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // S 51
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // T 52
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // U 53
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // V 54
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // W 55
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // X 56
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // Y 57
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // Z 58
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // [ 59
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // \ 60
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ] 61
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ^ 62
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // _ 63
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // ` 64
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // a 65
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // b 66
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // c 67
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // d 68
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // e 69
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // f 70
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // g 71
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // h 72
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // i 73
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // j 74
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // k 75
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // l 76
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // m 77
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // n 78
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // o 79
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // p 80
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // q 81
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // r 82
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // s 83
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // t 84
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // u 85
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // v 86
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // w 87
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // x 88
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // y 89
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // z 90
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // { 91
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // | 92
|
||||
0x00,0x00,0x00,0x00,0x00,0x00, // } 93
|
||||
0x00,0x00,0x00,0x00,0x00,0x00 // ~ 94
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
|
||||
0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, // ! 1
|
||||
0x00, 0x00, 0x03, 0x00, 0x03, 0x00, // " 2
|
||||
0x00, 0x14, 0x3E, 0x14, 0x3E, 0x14, // # 3
|
||||
0x00, 0x04, 0x2A, 0x7F, 0x2A, 0x10, // $ 4
|
||||
0x00, 0x26, 0x10, 0x08, 0x04, 0x32, // % 5
|
||||
0x00, 0x1A, 0x25, 0x29, 0x10, 0x28, // & 6
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // ' 7
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x00, // ( 8
|
||||
0x00, 0x00, 0x41, 0x41, 0x3E, 0x00, // ) 9
|
||||
0x00, 0x28, 0x18, 0x0E, 0x18, 0x28, // * 10
|
||||
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // + 11
|
||||
0x00, 0x00, 0x20, 0x10, 0x00, 0x00, // , 12
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 13
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, // . 14
|
||||
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 15
|
||||
0x00, 0x00, 0x1E, 0x21, 0x21, 0x1E, // 0 16
|
||||
0x00, 0x00, 0x00, 0x22, 0x3F, 0x20, // 1 17
|
||||
0x00, 0x00, 0x22, 0x31, 0x29, 0x26, // 2 18
|
||||
0x00, 0x00, 0x12, 0x21, 0x25, 0x1A, // 3 19
|
||||
0x00, 0x00, 0x0C, 0x0A, 0x3F, 0x08, // 4 20
|
||||
0x00, 0x00, 0x17, 0x25, 0x25, 0x19, // 5 21
|
||||
0x00, 0x00, 0x1C, 0x26, 0x25, 0x18, // 6 22
|
||||
0x00, 0x00, 0x01, 0x39, 0x05, 0x03, // 7 23
|
||||
0x00, 0x00, 0x1A, 0x25, 0x25, 0x1A, // 8 24
|
||||
0x00, 0x00, 0x06, 0x09, 0x29, 0x1E, // 9 25
|
||||
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, // : 26
|
||||
0x00, 0x00, 0x20, 0x14, 0x00, 0x00, // ; 27
|
||||
0x00, 0x00, 0x08, 0x14, 0x22, 0x00, // < 28
|
||||
0x00, 0x00, 0x14, 0x14, 0x14, 0x00, // = 29
|
||||
0x00, 0x00, 0x22, 0x14, 0x08, 0x00, // > 30
|
||||
0x00, 0x02, 0x01, 0x29, 0x06, 0x00, // ? 31
|
||||
0x00, 0x1E, 0x21, 0x2D, 0x2E, 0x00, // @ 32
|
||||
0x00, 0x30, 0x0C, 0x0B, 0x0C, 0x30, // A 33
|
||||
0x00, 0x00, 0x3F, 0x25, 0x25, 0x1A, // B 34
|
||||
0x00, 0x00, 0x1E, 0x21, 0x21, 0x12, // C 35
|
||||
0x00, 0x00, 0x3F, 0x21, 0x21, 0x1E, // D 36
|
||||
0x00, 0x00, 0x3F, 0x25, 0x25, 0x25, // E 37
|
||||
0x00, 0x00, 0x3F, 0x05, 0x05, 0x05, // F 38
|
||||
0x00, 0x00, 0x1E, 0x21, 0x29, 0x1A, // G 39
|
||||
0x00, 0x00, 0x3F, 0x04, 0x04, 0x3F, // H 40
|
||||
0x00, 0x00, 0x21, 0x3F, 0x21, 0x00, // I 41
|
||||
0x00, 0x18, 0x20, 0x21, 0x1F, 0x00, // J 42
|
||||
0x00, 0x00, 0x3F, 0x0C, 0x12, 0x21, // K 43
|
||||
0x00, 0x00, 0x3F, 0x20, 0x20, 0x20, // L 44
|
||||
0x00, 0x3F, 0x06, 0x08, 0x06, 0x3F, // M 45
|
||||
0x00, 0x00, 0x3F, 0x06, 0x18, 0x3F, // N 46
|
||||
0x00, 0x00, 0x1E, 0x21, 0x21, 0x1E, // O 47
|
||||
0x00, 0x00, 0x3F, 0x09, 0x09, 0x06, // P 48
|
||||
0x00, 0x1E, 0x21, 0x21, 0x5E, 0x00, // Q 49
|
||||
0x00, 0x00, 0x3F, 0x09, 0x19, 0x26, // R 50
|
||||
0x00, 0x00, 0x12, 0x25, 0x29, 0x12, // S 51
|
||||
0x00, 0x01, 0x01, 0x3F, 0x01, 0x01, // T 52
|
||||
0x00, 0x1F, 0x20, 0x20, 0x20, 0x1F, // U 53
|
||||
0x00, 0x0F, 0x10, 0x20, 0x10, 0x0F, // V 54
|
||||
0x00, 0x1F, 0x20, 0x1C, 0x20, 0x1F, // W 55
|
||||
0x00, 0x21, 0x12, 0x0C, 0x12, 0x21, // X 56
|
||||
0x00, 0x03, 0x04, 0x38, 0x04, 0x03, // Y 57
|
||||
0x00, 0x00, 0x31, 0x29, 0x25, 0x23, // Z 58
|
||||
0x00, 0x00, 0x3F, 0x21, 0x21, 0x00, // [ 59
|
||||
0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // \ 60
|
||||
0x00, 0x00, 0x21, 0x21, 0x3F, 0x00, // ] 61
|
||||
0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62
|
||||
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 63
|
||||
0x00, 0x00, 0x00, 0x01, 0x02, 0x00, // ` 64
|
||||
0x00, 0x18, 0x24, 0x24, 0x18, 0x20, // a 65
|
||||
0x00, 0x00, 0x3F, 0x24, 0x24, 0x18, // b 66
|
||||
0x00, 0x00, 0x18, 0x24, 0x24, 0x00, // c 67
|
||||
0x00, 0x00, 0x18, 0x24, 0x24, 0x3F, // d 68
|
||||
0x00, 0x00, 0x1C, 0x2A, 0x2A, 0x0C, // e 69
|
||||
0x00, 0x04, 0x04, 0x3E, 0x05, 0x05, // f 70
|
||||
0x00, 0x00, 0x0C, 0x52, 0x52, 0x3E, // g 71
|
||||
0x00, 0x00, 0x3F, 0x04, 0x04, 0x38, // h 72
|
||||
0x00, 0x00, 0x24, 0x3D, 0x20, 0x00, // i 73
|
||||
0x00, 0x20, 0x40, 0x44, 0x3D, 0x00, // j 74
|
||||
0x00, 0x00, 0x3F, 0x08, 0x14, 0x22, // k 75
|
||||
0x00, 0x00, 0x1F, 0x20, 0x20, 0x10, // l 76
|
||||
0x00, 0x3E, 0x04, 0x18, 0x04, 0x3E, // m 77
|
||||
0x00, 0x00, 0x3C, 0x02, 0x02, 0x3C, // n 78
|
||||
0x00, 0x00, 0x1C, 0x22, 0x22, 0x1C, // o 79
|
||||
0x00, 0x00, 0x7E, 0x12, 0x12, 0x0C, // p 80
|
||||
0x00, 0x00, 0x0C, 0x12, 0x12, 0x7E, // q 81
|
||||
0x00, 0x00, 0x04, 0x38, 0x04, 0x04, // r 82
|
||||
0x00, 0x00, 0x04, 0x2A, 0x2A, 0x10, // s 83
|
||||
0x00, 0x00, 0x04, 0x1E, 0x24, 0x10, // t 84
|
||||
0x00, 0x1C, 0x20, 0x20, 0x20, 0x1C, // u 85
|
||||
0x00, 0x0C, 0x10, 0x20, 0x10, 0x0C, // v 86
|
||||
0x00, 0x1C, 0x20, 0x18, 0x20, 0x1C, // w 87
|
||||
0x00, 0x22, 0x14, 0x08, 0x14, 0x22, // x 88
|
||||
0x00, 0x04, 0x48, 0x30, 0x08, 0x04, // y 89
|
||||
0x00, 0x00, 0x24, 0x34, 0x2C, 0x24, // z 90
|
||||
0x00, 0x08, 0x08, 0x36, 0x41, 0x41, // { 91
|
||||
0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, // | 92
|
||||
0x00, 0x41, 0x41, 0x36, 0x08, 0x08, // } 93
|
||||
0x00, 0x08, 0x04, 0x08, 0x10, 0x08 // ~ 94
|
||||
};
|
||||
|
||||
@@ -15,13 +15,8 @@
|
||||
#include "spi.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* 部分屏幕厂家虽然标称128x160,但实际使用132x162驱动晶片,
|
||||
* 左右各偏移2列,上下偏移1行才能正确显示。
|
||||
* 根据自己的屏幕实测调整这两个值。
|
||||
*/
|
||||
#define X_OFFSET 2
|
||||
#define Y_OFFSET 1
|
||||
#define X_OFFSET 0
|
||||
#define Y_OFFSET 0
|
||||
|
||||
uint16_t s_lcd_width = LCD_WIDTH;
|
||||
uint16_t s_lcd_height = LCD_HEIGHT;
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F103xB</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP/MultiButton;../Drivers/BSP/LCD;..\Drivers\BSP\AT24C02</IncludePath>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP/MultiButton;../Drivers/BSP/LCD;..\Drivers\BSP\AT24C02;..\User</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -1152,6 +1152,16 @@
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Application/User</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>menu.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\User\menu.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
</Group>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"stm32f103c8t6\button_driver_1.o"
|
||||
"stm32f103c8t6\multi_button_1.o"
|
||||
"stm32f103c8t6\at24c02.o"
|
||||
"stm32f103c8t6\menu.o"
|
||||
--strict --scatter "STM32F103C8T6\STM32F103C8T6.sct"
|
||||
--summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
|
||||
--info sizes --info totals --info unused --info veneers
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
STM32F103C8T6/MDK-ARM/STM32F103C8T6/menu.crf
Normal file
BIN
STM32F103C8T6/MDK-ARM/STM32F103C8T6/menu.crf
Normal file
Binary file not shown.
Binary file not shown.
356
STM32F103C8T6/User/menu.c
Normal file
356
STM32F103C8T6/User/menu.c
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* 模块名称:菜单系统
|
||||
* 模块功能:通过LCD显示参数,按键导航/调整,AT24C02存储
|
||||
* 适用平台:STM32F103C8T6
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-14
|
||||
* 修改记录:
|
||||
* 2026-07-14 王建锋 创建初始版本
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
#include "button_driver.h"
|
||||
#include "at24c02.h"
|
||||
#include "lcd.h"
|
||||
#include "tim.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define COLOR_GRAY 0x8410 /* RGB565 灰 */
|
||||
|
||||
/* ======================== EEPROM 存储布局 ======================== */
|
||||
#define EEPROM_DATA_ADDR 0x10 /* 参数存储起始地址 */
|
||||
#define EEPROM_MAGIC 0xA55A /* 有效数据标识 */
|
||||
#define EEPROM_MAGIC_ADDR 0x0E /* Magic 存储地址(2字节) */
|
||||
|
||||
/* ======================== 参数定义 ======================== */
|
||||
typedef struct {
|
||||
const char *name; /* 显示名称 */
|
||||
const char *unit; /* 单位 */
|
||||
int32_t default_val; /* 默认值 */
|
||||
int32_t min; /* 最小值 */
|
||||
int32_t max; /* 最大值 */
|
||||
int32_t step; /* 步进 */
|
||||
} ParamDef_t;
|
||||
|
||||
static const ParamDef_t s_param_def[PARAM_COUNT] = {
|
||||
{"PWM1", "", 500, 0, 999, 50 },
|
||||
{"PWM2", "", 500, 0, 999, 50 },
|
||||
{"PWM3", "", 500, 0, 999, 50 },
|
||||
{"PWM4", "", 500, 0, 999, 50 },
|
||||
};
|
||||
|
||||
/* ======================== 运行时状态 ======================== */
|
||||
static int32_t s_param_val[PARAM_COUNT]; /* 当前参数值 */
|
||||
static uint8_t s_sel = 0; /* 选中的参数索引 */
|
||||
static uint8_t s_editing = 0; /* 0=导航, 1=编辑 */
|
||||
static uint8_t s_redraw = 1; /* 需要重绘标志 */
|
||||
|
||||
/* ======================== 静态函数声明 ======================== */
|
||||
static void draw_menu(void);
|
||||
static void load_params(void);
|
||||
static int save_params(void);
|
||||
static void apply_param(uint8_t idx);
|
||||
|
||||
/* ======================== 公开函数 ======================== */
|
||||
|
||||
/*
|
||||
* 函数功能:菜单系统初始化
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:从EEPROM加载参数,清屏,绘制初始界面
|
||||
*/
|
||||
void menu_init(void)
|
||||
{
|
||||
lcd_draw_string(0, 0, "Menu Loading...", COLOR_WHITE, COLOR_BLACK);
|
||||
load_params();
|
||||
s_sel = 0;
|
||||
s_editing = 0;
|
||||
s_redraw = 1;
|
||||
apply_param(PARAM_PWM1);
|
||||
apply_param(PARAM_PWM2);
|
||||
apply_param(PARAM_PWM3);
|
||||
apply_param(PARAM_PWM4);
|
||||
st7735s_fill_screen(COLOR_BLACK);
|
||||
draw_menu();
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:菜单系统循环处理
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:轮询按键事件,更新参数/界面。需在主循环中频繁调用
|
||||
*/
|
||||
void menu_process(void)
|
||||
{
|
||||
ButtonEvent evt;
|
||||
uint8_t i;
|
||||
int32_t *p_val;
|
||||
|
||||
/* 依次检查5个按键的事件 */
|
||||
for (i = 0; i < 5; i++) {
|
||||
evt = button_driver_get_event(i);
|
||||
if (evt == BTN_NONE_PRESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (evt == BTN_SINGLE_CLICK) {
|
||||
switch (i) {
|
||||
case 0: /* KEY1: 上移 */
|
||||
if (!s_editing) {
|
||||
if (s_sel > 0) {
|
||||
s_sel--;
|
||||
} else {
|
||||
s_sel = PARAM_COUNT - 1;
|
||||
}
|
||||
s_redraw = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* KEY2: 减小 */
|
||||
p_val = &s_param_val[s_sel];
|
||||
*p_val -= s_param_def[s_sel].step;
|
||||
if (*p_val < s_param_def[s_sel].min) {
|
||||
*p_val = s_param_def[s_sel].min;
|
||||
}
|
||||
s_editing = 1;
|
||||
s_redraw = 1;
|
||||
apply_param(s_sel);
|
||||
break;
|
||||
|
||||
case 2: /* KEY3: 下移 */
|
||||
if (!s_editing) {
|
||||
s_sel++;
|
||||
if (s_sel >= PARAM_COUNT) {
|
||||
s_sel = 0;
|
||||
}
|
||||
s_redraw = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* KEY4: 增大 */
|
||||
p_val = &s_param_val[s_sel];
|
||||
*p_val += s_param_def[s_sel].step;
|
||||
if (*p_val > s_param_def[s_sel].max) {
|
||||
*p_val = s_param_def[s_sel].max;
|
||||
}
|
||||
s_editing = 1;
|
||||
s_redraw = 1;
|
||||
apply_param(s_sel);
|
||||
break;
|
||||
|
||||
case 4: /* KEY5: 确认保存 */
|
||||
if (save_params() == AT24C02_OK) {
|
||||
lcd_draw_string(0, 80, "SAVED! ", COLOR_GREEN, COLOR_BLACK);
|
||||
printf("Menu: params saved\r\n");
|
||||
} else {
|
||||
lcd_draw_string(0, 80, "SAVE FAIL! ", COLOR_RED, COLOR_BLACK);
|
||||
printf("Menu: params save FAIL\r\n");
|
||||
}
|
||||
s_editing = 0;
|
||||
s_redraw = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 只处理一个按键事件每帧 */
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_redraw) {
|
||||
draw_menu();
|
||||
s_redraw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:获取指定参数的当前值
|
||||
* 入口参数:id - 参数ID
|
||||
* 返回值:参数值
|
||||
*/
|
||||
int32_t menu_get_param(ParamId_t id)
|
||||
{
|
||||
if (id >= PARAM_COUNT) {
|
||||
return 0;
|
||||
}
|
||||
return s_param_val[id];
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:强制保存参数到EEPROM
|
||||
* 入口参数:无
|
||||
* 返回值:0=成功,负值=失败
|
||||
*/
|
||||
int menu_save_params(void)
|
||||
{
|
||||
return save_params();
|
||||
}
|
||||
|
||||
/* ======================== 内部函数 ======================== */
|
||||
|
||||
/*
|
||||
* 函数功能:从EEPROM加载参数
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:读取EEPROM中存储的参数值,若Magic不对则使用默认值
|
||||
*/
|
||||
static void load_params(void)
|
||||
{
|
||||
uint8_t magic_buf[2];
|
||||
uint8_t data_buf[PARAM_COUNT * 4];
|
||||
int ret;
|
||||
uint8_t i;
|
||||
|
||||
/* 先读取Magic */
|
||||
ret = at24c02_read_buf(EEPROM_MAGIC_ADDR, magic_buf, 2);
|
||||
if ((ret != AT24C02_OK) ||
|
||||
(magic_buf[0] != ((EEPROM_MAGIC >> 8) & 0xFF)) ||
|
||||
(magic_buf[1] != (EEPROM_MAGIC & 0xFF))) {
|
||||
/* Magic不匹配:使用默认值 */
|
||||
for (i = 0; i < PARAM_COUNT; i++) {
|
||||
s_param_val[i] = s_param_def[i].default_val;
|
||||
}
|
||||
printf("Menu: using defaults (no saved data)\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 读取参数数据 */
|
||||
ret = at24c02_read_buf(EEPROM_DATA_ADDR, data_buf, PARAM_COUNT * 4);
|
||||
if (ret != AT24C02_OK) {
|
||||
for (i = 0; i < PARAM_COUNT; i++) {
|
||||
s_param_val[i] = s_param_def[i].default_val;
|
||||
}
|
||||
printf("Menu: EEPROM read fail, using defaults\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 解析数据(小端:低字节在前) */
|
||||
for (i = 0; i < PARAM_COUNT; i++) {
|
||||
s_param_val[i] = (int32_t)(
|
||||
(uint32_t)data_buf[i * 4 + 0] |
|
||||
((uint32_t)data_buf[i * 4 + 1] << 8) |
|
||||
((uint32_t)data_buf[i * 4 + 2] << 16) |
|
||||
((uint32_t)data_buf[i * 4 + 3] << 24));
|
||||
/* 钳位到有效范围 */
|
||||
if (s_param_val[i] < s_param_def[i].min) {
|
||||
s_param_val[i] = s_param_def[i].min;
|
||||
}
|
||||
if (s_param_val[i] > s_param_def[i].max) {
|
||||
s_param_val[i] = s_param_def[i].max;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Menu: params loaded from EEPROM\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:保存参数到EEPROM
|
||||
* 入口参数:无
|
||||
* 返回值:0=成功,负值=失败
|
||||
* 函数说明:先写Magic标识,再写参数数据
|
||||
*/
|
||||
static int save_params(void)
|
||||
{
|
||||
uint8_t magic_buf[2];
|
||||
uint8_t data_buf[PARAM_COUNT * 4];
|
||||
uint8_t i;
|
||||
int ret;
|
||||
|
||||
/* 打包Magic */
|
||||
magic_buf[0] = (EEPROM_MAGIC >> 8) & 0xFF;
|
||||
magic_buf[1] = EEPROM_MAGIC & 0xFF;
|
||||
|
||||
/* 打包参数(小端) */
|
||||
for (i = 0; i < PARAM_COUNT; i++) {
|
||||
data_buf[i * 4 + 0] = (uint8_t)(s_param_val[i] & 0xFF);
|
||||
data_buf[i * 4 + 1] = (uint8_t)((s_param_val[i] >> 8) & 0xFF);
|
||||
data_buf[i * 4 + 2] = (uint8_t)((s_param_val[i] >> 16) & 0xFF);
|
||||
data_buf[i * 4 + 3] = (uint8_t)((s_param_val[i] >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
/* 写入EEPROM */
|
||||
ret = at24c02_write_buf(EEPROM_MAGIC_ADDR, magic_buf, 2);
|
||||
if (ret != AT24C02_OK) {
|
||||
return ret;
|
||||
}
|
||||
ret = at24c02_write_buf(EEPROM_DATA_ADDR, data_buf, PARAM_COUNT * 4);
|
||||
if (ret != AT24C02_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return AT24C02_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:将指定参数立即应用到对应PWM通道
|
||||
* 入口参数:idx - 参数索引 (0=PWM1, 1=PWM2, 2=PWM3, 3=PWM4)
|
||||
* 返回值:无
|
||||
*/
|
||||
static void apply_param(uint8_t idx)
|
||||
{
|
||||
uint32_t duty = (uint32_t)s_param_val[idx];
|
||||
static const uint16_t ch_map[4] = {
|
||||
TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4
|
||||
};
|
||||
|
||||
if (idx < PARAM_COUNT) {
|
||||
__HAL_TIM_SET_COMPARE(&htim3, ch_map[idx], duty);
|
||||
printf("PWM%d duty=%lu\r\n", idx + 1, (unsigned long)duty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:绘制菜单界面
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:清空参数区域,重新绘制所有参数行
|
||||
*/
|
||||
static void draw_menu(void)
|
||||
{
|
||||
char buf[24];
|
||||
uint8_t i;
|
||||
uint16_t color;
|
||||
|
||||
/* 绘制标题行 */
|
||||
|
||||
lcd_draw_string(0, 0, "-- PARAM MENU --", COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
/* 绘制各参数(每行16像素,从y=16开始) */
|
||||
for (i = 0; i < PARAM_COUNT; i++) {
|
||||
if (i == s_sel) {
|
||||
if (s_editing) {
|
||||
/* 编辑态:高亮 + 左右尖括号 */
|
||||
snprintf(buf, sizeof(buf), ">%s:%ld %s< ",
|
||||
s_param_def[i].name,
|
||||
(long)s_param_val[i],
|
||||
s_param_def[i].unit);
|
||||
color = COLOR_YELLOW;
|
||||
} else {
|
||||
/* 选中态:箭头 + 高亮 */
|
||||
snprintf(buf, sizeof(buf), ">%s:%ld %s ",
|
||||
s_param_def[i].name,
|
||||
(long)s_param_val[i],
|
||||
s_param_def[i].unit);
|
||||
color = COLOR_WHITE;
|
||||
}
|
||||
} else {
|
||||
/* 未选中:普通显示 */
|
||||
snprintf(buf, sizeof(buf), " %s:%ld %s ",
|
||||
s_param_def[i].name,
|
||||
(long)s_param_val[i],
|
||||
s_param_def[i].unit);
|
||||
color = COLOR_GRAY;
|
||||
}
|
||||
/* 填充整行背景以覆盖之前内容 */
|
||||
lcd_draw_string(0, 16 + i * 16, buf, color, COLOR_BLACK);
|
||||
}
|
||||
|
||||
/* 底部提示 */
|
||||
if (s_editing) {
|
||||
lcd_draw_string_6x8(0, 140, "KEY5:SAVE ", COLOR_GREEN, COLOR_BLACK);
|
||||
} else {
|
||||
lcd_draw_string_6x8(0, 140, "K1/K3:Sel K2/K4:Adj", COLOR_GRAY, COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
55
STM32F103C8T6/User/menu.h
Normal file
55
STM32F103C8T6/User/menu.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef __MENU_H
|
||||
#define __MENU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/* 参数数量 */
|
||||
#define PARAM_COUNT 4
|
||||
|
||||
/* 参数ID枚举 */
|
||||
typedef enum {
|
||||
PARAM_PWM1 = 0, /* PA6 TIM3_CH1 */
|
||||
PARAM_PWM2, /* PA7 TIM3_CH2 */
|
||||
PARAM_PWM3, /* PB0 TIM3_CH3 */
|
||||
PARAM_PWM4, /* PB1 TIM3_CH4 */
|
||||
} ParamId_t;
|
||||
|
||||
/*
|
||||
* 函数功能:菜单系统初始化
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:从EEPROM加载参数,清屏,绘制初始界面
|
||||
*/
|
||||
void menu_init(void);
|
||||
|
||||
/*
|
||||
* 函数功能:菜单系统循环处理
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 函数说明:轮询按键事件,更新参数/界面。需在主循环中频繁调用
|
||||
*/
|
||||
void menu_process(void);
|
||||
|
||||
/*
|
||||
* 函数功能:获取指定参数的当前值
|
||||
* 入口参数:id - 参数ID
|
||||
* 返回值:参数值
|
||||
*/
|
||||
int32_t menu_get_param(ParamId_t id);
|
||||
|
||||
/*
|
||||
* 函数功能:强制保存参数到EEPROM
|
||||
* 入口参数:无
|
||||
* 返回值:0=成功,负值=失败
|
||||
*/
|
||||
int menu_save_params(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MENU_H */
|
||||
@@ -1,14 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
STM32 ST7735S LCD 字模生成工具(Pillow 版)
|
||||
- ASCII 8×16:生成 lcd_data.c
|
||||
- CJK 16×16:生成 hz16_data.c + hz16_data.h(含二分查找函数)
|
||||
STM32 ST7735S LCD CJK 字模生成工具(Pillow 版)
|
||||
生成 hz16_data.c + hz16_data.h(含二分查找函数)
|
||||
|
||||
用法:
|
||||
# ASCII
|
||||
python font_gen.py --font simsun --size 56 --threshold 64
|
||||
|
||||
# CJK 常用汉字(GB2312 一级,约 3755 字)
|
||||
python font_gen.py --cjk --font simsun --size 32 --threshold 64
|
||||
|
||||
@@ -19,7 +15,6 @@ STM32 ST7735S LCD 字模生成工具(Pillow 版)
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import struct
|
||||
|
||||
try:
|
||||
from PIL import Image, ImageFont, ImageDraw
|
||||
@@ -27,12 +22,44 @@ except ImportError:
|
||||
print("请安装 Pillow: pip install Pillow", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# ── Otsu 自适应阈值 ──
|
||||
|
||||
def otsu_threshold(pixels: list) -> int:
|
||||
"""Otsu 算法自动计算最佳二值化阈值"""
|
||||
hist = [0] * 256
|
||||
for v in pixels:
|
||||
hist[v] += 1
|
||||
total = len(pixels)
|
||||
sum_all = sum(i * hist[i] for i in range(256))
|
||||
sum_bg = 0
|
||||
w_bg = 0
|
||||
w_fg = 0
|
||||
max_var = 0
|
||||
best = 128
|
||||
for t in range(256):
|
||||
w_bg += hist[t]
|
||||
if w_bg == 0:
|
||||
continue
|
||||
w_fg = total - w_bg
|
||||
if w_fg == 0:
|
||||
break
|
||||
sum_bg += t * hist[t]
|
||||
mean_bg = sum_bg / w_bg
|
||||
mean_fg = (sum_all - sum_bg) / w_fg
|
||||
between_var = w_bg * w_fg * (mean_bg - mean_fg) * (mean_bg - mean_fg)
|
||||
if between_var > max_var:
|
||||
max_var = between_var
|
||||
best = t
|
||||
return best
|
||||
|
||||
|
||||
# ── 通用渲染 ──
|
||||
|
||||
def render_char(font, char: str, w: int, h: int, scale: int = 1,
|
||||
threshold: int = 64) -> list:
|
||||
threshold: int = None) -> list:
|
||||
"""
|
||||
在 w*scale × h*scale 画布上渲染字符,缩放到 w×h
|
||||
threshold=None 时自动使用 Otsu 算法
|
||||
返回逐行字节列表(MSB 优先)
|
||||
"""
|
||||
bw, bh = w * scale, h * scale
|
||||
@@ -42,13 +69,20 @@ def render_char(font, char: str, w: int, h: int, scale: int = 1,
|
||||
bbox = draw.textbbox((0, 0), char, font=font)
|
||||
tw = bbox[2] - bbox[0]
|
||||
th = bbox[3] - bbox[1]
|
||||
cx = (bw - tw) // 2 - bbox[0]
|
||||
cy = (bh - th) // 2 - bbox[1]
|
||||
|
||||
# 防止 bbox[0]/bbox[1] 为负导致偏移错误
|
||||
left = bbox[0] if bbox[0] > 0 else 0
|
||||
top = bbox[1] if bbox[1] > 0 else 0
|
||||
cx = (bw - tw) // 2 - left
|
||||
cy = (bh - th) // 2 - top
|
||||
draw.text((cx, cy), char, font=font, fill=255)
|
||||
|
||||
small = img.resize((w, h), Image.LANCZOS)
|
||||
pixels = list(small.getdata())
|
||||
|
||||
if threshold is None:
|
||||
threshold = otsu_threshold(pixels)
|
||||
|
||||
bytes_per_row = (w + 7) // 8
|
||||
result = []
|
||||
for r in range(h):
|
||||
@@ -62,57 +96,6 @@ def render_char(font, char: str, w: int, h: int, scale: int = 1,
|
||||
return result
|
||||
|
||||
|
||||
# ── ASCII 8×16 ──
|
||||
|
||||
def generate_ascii(output_path: str, font_path: str, size: int,
|
||||
threshold: int, scale: int = 4):
|
||||
font = ImageFont.truetype(font_path, size)
|
||||
chars = list(range(32, 127))
|
||||
N = len(chars)
|
||||
|
||||
lines = [
|
||||
'#include "lcd_data.h"',
|
||||
'/*ASCII字模数据*********************/',
|
||||
'',
|
||||
'/*宽8像素,高16像素*/',
|
||||
f'/* 字体: {os.path.basename(font_path)}, 字号: {size}, 阈值: {threshold} */',
|
||||
'const uint8_t LCD_F8x16[][16] =',
|
||||
'{',
|
||||
]
|
||||
|
||||
for idx, ch in enumerate(chars):
|
||||
if ch == ord('_'):
|
||||
bitmap = [0x00] * 15 + [0x7F]
|
||||
else:
|
||||
bitmap = render_char(font, chr(ch), 8, 16, scale, threshold)
|
||||
|
||||
show = chr(ch) if 32 <= ch <= 126 else '?'
|
||||
comma = ',' if idx < N - 1 else ''
|
||||
line1 = ', '.join(f'0x{b:02X}' for b in bitmap[:8])
|
||||
line2 = ', '.join(f'0x{b:02X}' for b in bitmap[8:])
|
||||
lines.append(f' {line1},')
|
||||
lines.append(f' {line2}{comma} // {show} {idx}')
|
||||
if (idx + 1) % 10 == 0:
|
||||
print(f" ASCII 进度: {idx+1}/{N}")
|
||||
|
||||
lines.append('};')
|
||||
lines.append('')
|
||||
lines.append('/*宽6像素,高8像素(未使用)*/')
|
||||
lines.append('const uint8_t LCD_F6x8[][6] =')
|
||||
lines.append('{')
|
||||
for idx, ch in enumerate(chars):
|
||||
show = chr(ch) if 32 <= ch <= 126 else '?'
|
||||
comma = ',' if idx < N - 1 else ''
|
||||
lines.append(f' 0x00,0x00,0x00,0x00,0x00,0x00{comma} // {show} {idx}')
|
||||
lines.append('};')
|
||||
lines.append('')
|
||||
|
||||
content = '\n'.join(lines)
|
||||
with open(output_path, 'w', encoding='utf-8', newline='\n') as f:
|
||||
f.write(content)
|
||||
print(f"已生成 ASCII 字模: {output_path}")
|
||||
|
||||
|
||||
# ── CJK 16×16 ──
|
||||
|
||||
CJK_W, CJK_H = 16, 16
|
||||
@@ -344,35 +327,33 @@ def _resolve_font(name_or_path: str) -> str:
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description='字模生成工具')
|
||||
p = argparse.ArgumentParser(description='CJK 字模生成工具')
|
||||
p.add_argument('--font', default='simsun', help='字体名称或路径')
|
||||
p.add_argument('--size', type=int, default=64, help='渲染字号')
|
||||
p.add_argument('--threshold', type=int, default=50, help='二值化阈值(默认50)')
|
||||
p.add_argument('--scale', type=int, default=4, help='缩放倍率')
|
||||
|
||||
g = p.add_argument_group('ASCII 8×16')
|
||||
g.add_argument('--ascii', action='store_true', help='生成 ASCII 字模(默认)')
|
||||
|
||||
g = p.add_argument_group('CJK 16×16')
|
||||
g.add_argument('--cjk', action='store_true', help='生成 CJK 汉字字模')
|
||||
g.add_argument('--common', action='store_true', help='CJK:仅常用汉字(GB2312 一级)')
|
||||
g.add_argument('--gb2312', action='store_true', help='CJK:GB2312 全部汉字')
|
||||
g.add_argument('--punct', action='store_true', help='CJK:加入中文标点/全角字符')
|
||||
g.add_argument('--string', type=str, default=None, help='CJK:仅生成指定字符串中的字符(节省空间)')
|
||||
g.add_argument('--output', '-o', default=None, help='CJK 输出基名(不含扩展名)')
|
||||
p.add_argument('--size', type=int, default=None, help='渲染字号')
|
||||
p.add_argument('--threshold', type=int, default=None, help='二值化阈值(默认 Otsu 自适应)')
|
||||
p.add_argument('--scale', type=int, default=None, help='缩放倍率(越大边缘越平滑)')
|
||||
p.add_argument('--cjk', action='store_true', help='生成 CJK 汉字字模(必须指定)')
|
||||
p.add_argument('--common', action='store_true', help='CJK:仅常用汉字(GB2312 一级)')
|
||||
p.add_argument('--gb2312', action='store_true', help='CJK:GB2312 全部汉字')
|
||||
p.add_argument('--punct', action='store_true', help='CJK:加入中文标点/全角字符')
|
||||
p.add_argument('--string', type=str, default=None, help='CJK:仅生成指定字符串中的字符(节省空间)')
|
||||
p.add_argument('--output', '-o', default=None, help='CJK 输出基名(不含扩展名)')
|
||||
|
||||
args = p.parse_args()
|
||||
|
||||
font_path = _resolve_font(args.font)
|
||||
print(f"字体: {font_path}")
|
||||
|
||||
if not args.cjk:
|
||||
print("请指定 --cjk 来生成 CJK 字库,ASCII 字库已不再由此工具生成")
|
||||
return
|
||||
|
||||
proj_dir = os.path.abspath(os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'..', 'STM32F103C8T6', 'Drivers', 'BSP', 'LCD'))
|
||||
|
||||
if args.cjk:
|
||||
size = args.size or 48
|
||||
scale = args.scale or 3
|
||||
size = args.size if args.size is not None else 48
|
||||
scale = args.scale if args.scale is not None else 3
|
||||
out_base = args.output or os.path.join(proj_dir, 'hz16_data')
|
||||
|
||||
if args.string is not None:
|
||||
@@ -382,12 +363,6 @@ def main():
|
||||
generate_cjk(out_base, font_path, size, args.threshold, scale,
|
||||
mode='common' if args.common else ('gb2312' if args.gb2312 else 'common'),
|
||||
punct=args.punct)
|
||||
else:
|
||||
# 默认 ASCII
|
||||
size = args.size or 56
|
||||
scale = args.scale or 4
|
||||
out = os.path.join(proj_dir, 'lcd_data.c')
|
||||
generate_ascii(out, font_path, size, args.threshold, scale)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user