feat: initial commit for stc32g12k128 wristband firmware

This commit is contained in:
2026-07-06 11:10:43 +08:00
commit ee8b8bfe15
40 changed files with 80064 additions and 0 deletions

465
Drivers/lcd.c Normal file
View File

@@ -0,0 +1,465 @@
#include "lcd.h"
#include "lcd_font.h"
#include "../App/config.h"
#include "intrins.h"
// RM69310 屏幕接口引脚
sbit LCD_RST = P1^0; // 硬件复位
sbit LCD_DCX = P1^1; // 数据/命令选择
sbit LCD_SDI = P1^4; // SPI 数据输入 (MOSI)
sbit LCD_SCL = P1^5; // SPI 时钟 (SCLK)
sbit LCD_CS = P1^6; // SPI 片选 (CS)
// SGM3833 电源芯片控制脚
sbit SGM_CTRL = P3^4;
// External delay functions defined in main.c
extern void Delay_ms(u16 ms);
extern void Delay10us(void);
void SGM_SendPulse(u8 pulse_cnt)
{
u8 i;
SGM_CTRL = 0;
Delay_ms(5); // 确保进入关断/复位状态 (tOFF)
SGM_CTRL = 1;
Delay_ms(5); // 确保充分初始化 (tINIT >= 300us)
for(i = 0; i < pulse_cnt; i++)
{
SGM_CTRL = 0;
Delay10us();
SGM_CTRL = 1;
Delay10us();
}
SGM_CTRL = 1;
Delay_ms(5); // 确保数据稳定存储 (tSTORE >= 80us)
}
void SPI_SendData(u8 dat)
{
u8 i;
for(i = 0; i < 8; i++)
{
LCD_SCL = 0;
if(dat & 0x80)
LCD_SDI = 1;
else
LCD_SDI = 0;
_nop_();
LCD_SCL = 1;
_nop_();
dat <<= 1;
}
}
void WriteComm(u8 cmd)
{
LCD_CS = 0;
LCD_DCX = 0; // 命令模式
SPI_SendData(cmd);
LCD_CS = 1;
}
void WriteData(u8 dat)
{
LCD_CS = 0;
LCD_DCX = 1; // 数据模式
SPI_SendData(dat);
LCD_CS = 1;
}
void LCD_Reset(void)
{
LCD_RST = 1;
Delay_ms(10);
LCD_RST = 0;
Delay_ms(20);
LCD_RST = 1;
Delay_ms(120);
}
void LCD_Init(void)
{
// Configure LCD pins as push-pull output
P1M1 &= ~((1<<0) | (1<<1) | (1<<4) | (1<<5) | (1<<6));
P1M0 |= ((1<<0) | (1<<1) | (1<<4) | (1<<5) | (1<<6));
// Configure P3.4 (SGM_CTRL) as push-pull output
P3M1 &= ~(1 << 4);
P3M0 |= (1 << 4);
SGM_CTRL = 1;
LCD_CS = 1;
LCD_SCL = 1;
LCD_RST = 1;
LCD_DCX = 1;
LCD_Reset();
// 寄存器配置(源自 Truly 信利官方初始化配置)
WriteComm(0xFE);WriteData(0x01);
WriteComm(0x04);WriteData(0xa0); // SPI write ram enable
WriteComm(0x05);WriteData(0x70); // 128RGB
WriteComm(0x06);WriteData(0x3C); // NL = 240 line
WriteComm(0x25);WriteData(0x06); // normal mode: gamma1
WriteComm(0x26);WriteData(0x80); // T1A = 280
WriteComm(0x27);WriteData(0x12); // normal mode VBP = 12
WriteComm(0x28);WriteData(0x12); // normal mode VFP = 8
WriteComm(0x2A);WriteData(0x06); // idle mode: gamma1
WriteComm(0x2B);WriteData(0x80); // T1B = 280
WriteComm(0x2D);WriteData(0x12); // idle mode VBP = 12
WriteComm(0x2F);WriteData(0x12); // idle mode VFP = 8
WriteComm(0x37);WriteData(0x0C); // precharge to VGSP
WriteComm(0x6D);WriteData(0x18); // skip frame VGMP and VGSP regulator off
WriteComm(0x29);WriteData(0x01); // normal mode skip frame off
WriteComm(0x30);WriteData(0x43); // idle mode skip frame = 60/2 = 30Hz
WriteComm(0x0E);WriteData(0x83); // AVDD = 5.6V normal mode
WriteComm(0x0F);WriteData(0x83); // AVDD = 5.6V idle mode
WriteComm(0x10);WriteData(0x71); // AVDD = 3xVCI
WriteComm(0x11);WriteData(0xb3); // VCL = -2xVCI
WriteComm(0x12);WriteData(0xb3); // VCL = -2xVCI
WriteComm(0x13);WriteData(0x80); // VGH = AVDD normal mode
WriteComm(0x14);WriteData(0x80); // VGH = AVDD idle mode
WriteComm(0x15);WriteData(0x81); // VGL = VCL - VCI normal mode
WriteComm(0x16);WriteData(0x81); // VGL = VCL - VCI idle mode
WriteComm(0x18);WriteData(0x66); // VGHR = 6V normal/idle mode
WriteComm(0x19);WriteData(0x44); // VGLR = -6V normal/idle mode
WriteComm(0x1E);WriteData(0x02); // Switch EQ on
WriteComm(0x5B);WriteData(0x10); // VREFN5 on
WriteComm(0x62);WriteData(0x19); // VREFN5 = -3V normal mode
WriteComm(0x63);WriteData(0x19); // VREFN5 = -3V idle mode
WriteComm(0x70);WriteData(0x55); // display off SD to AVDD
WriteComm(0x1D);WriteData(0x02); // Switch EQ on
WriteComm(0x89);WriteData(0x18); // VGMP = 5.5V
WriteComm(0x8A);WriteData(0xb9); // VGSP = 2V
WriteComm(0x8B);WriteData(0x01); // VGMP VGSP high byte
WriteComm(0x8C);WriteData(0x10); // VGMP = 5.4V
WriteComm(0x8D);WriteData(0x90); // VGSP = 2V
WriteComm(0x8E);WriteData(0x01); // VGMP VGSP high byte
WriteComm(0x6E);WriteData(0x0A); // MIPI interface off
WriteComm(0x6A);WriteData(0x05); // MUX
WriteComm(0x3A);WriteData(0x08); // T1_sd
WriteComm(0x3B);WriteData(0x00); // Tp_sd
WriteComm(0x3D);WriteData(0x16); // Th_sd
WriteComm(0x3F);WriteData(0x27); // Tsw_sd
WriteComm(0x40);WriteData(0x0F); // Thsw_sd
WriteComm(0x41);WriteData(0x0D); // Thsd_sd
WriteComm(0x42);WriteData(0x14); // Mux 142536
WriteComm(0x43);WriteData(0x41);
WriteComm(0x44);WriteData(0x25);
WriteComm(0x45);WriteData(0x52);
WriteComm(0x46);WriteData(0x36);
WriteComm(0x47);WriteData(0x63);
WriteComm(0x48);WriteData(0x14);
WriteComm(0x49);WriteData(0x41);
WriteComm(0x4A);WriteData(0x25);
WriteComm(0x4B);WriteData(0x52);
WriteComm(0x4C);WriteData(0x36);
WriteComm(0x4D);WriteData(0x63);
WriteComm(0x4E);WriteData(0x14); // Data R1R2G1G2B1B2
WriteComm(0x4F);WriteData(0x41);
WriteComm(0x50);WriteData(0x25);
WriteComm(0x51);WriteData(0x52);
WriteComm(0x52);WriteData(0x36);
WriteComm(0x53);WriteData(0x63);
WriteComm(0x54);WriteData(0x14);
WriteComm(0x55);WriteData(0x41);
WriteComm(0x56);WriteData(0x25);
WriteComm(0x57);WriteData(0x52);
WriteComm(0x58);WriteData(0x36);
WriteComm(0x59);WriteData(0x63);
WriteComm(0x66);WriteData(0x90); // idle mode internal power
WriteComm(0x67);WriteData(0x40); // internal power delay 1 frame off
WriteComm(0x72);WriteData(0x1A); // internal OVDD = 4.6V
WriteComm(0x73);WriteData(0x07); // internal OVSS = -2V
WriteComm(0x74);WriteData(0x0C); // OVDD power from AVDD
WriteComm(0x6A);WriteData(0x3D); // swire 61=0x3D pulse
WriteComm(0x6B);WriteData(0x29); // swire 41=0x29 pulse
WriteComm(0xFE);WriteData(0x04);
WriteComm(0x5E);WriteData(0x01);
WriteComm(0x5F);WriteData(0xB8);
WriteComm(0x60);WriteData(0xBB);
WriteComm(0x61);WriteData(0xBB);
WriteComm(0x62);WriteData(0xBB);
WriteComm(0x76);WriteData(0xBB);
WriteComm(0x77);WriteData(0x3B);
WriteComm(0x78);WriteData(0x92);
WriteComm(0x79);WriteData(0xBB);
WriteComm(0x7A);WriteData(0xBB);
WriteComm(0x00);WriteData(0xDC); // SN_CK1
WriteComm(0x01);WriteData(0x00);
WriteComm(0x02);WriteData(0x02);
WriteComm(0x03);WriteData(0x00);
WriteComm(0x04);WriteData(0x08);
WriteComm(0x05);WriteData(0x01);
WriteComm(0x06);WriteData(0x70);
WriteComm(0x07);WriteData(0x0A);
WriteComm(0x08);WriteData(0x00);
WriteComm(0x09);WriteData(0xDC); // SN_CK2
WriteComm(0x0a);WriteData(0x00);
WriteComm(0x0b);WriteData(0x02);
WriteComm(0x0C);WriteData(0x00);
WriteComm(0x0D);WriteData(0x08);
WriteComm(0x0E);WriteData(0x00);
WriteComm(0x0F);WriteData(0x70);
WriteComm(0x10);WriteData(0x0A);
WriteComm(0x11);WriteData(0x00);
WriteComm(0x12);WriteData(0xCC); // EM_CK1
WriteComm(0x13);WriteData(0x00);
WriteComm(0x14);WriteData(0x02);
WriteComm(0x15);WriteData(0x00);
WriteComm(0x16);WriteData(0x20);
WriteComm(0x17);WriteData(0x00);
WriteComm(0x18);WriteData(0x28);
WriteComm(0x19);WriteData(0x26);
WriteComm(0x1A);WriteData(0x00);
WriteComm(0x1B);WriteData(0xCC); // EM_CK2
WriteComm(0x1C);WriteData(0x00);
WriteComm(0x1D);WriteData(0x02);
WriteComm(0x1E);WriteData(0x00);
WriteComm(0x1F);WriteData(0x20);
WriteComm(0x20);WriteData(0x01);
WriteComm(0x21);WriteData(0x28);
WriteComm(0x22);WriteData(0x26);
WriteComm(0x23);WriteData(0x00);
WriteComm(0x4C);WriteData(0x89); // SN_STV
WriteComm(0x4D);WriteData(0x00);
WriteComm(0x4E);WriteData(0x01);
WriteComm(0x4F);WriteData(0x00);
WriteComm(0x50);WriteData(0x01);
WriteComm(0x51);WriteData(0xBB);
WriteComm(0x52);WriteData(0xBB);
WriteComm(0x53);WriteData(0xCA); // EM_STV
WriteComm(0x54);WriteData(0x00);
WriteComm(0x55);WriteData(0x03);
WriteComm(0x56);WriteData(0x00);
WriteComm(0x58);WriteData(0x00);
WriteComm(0x59);WriteData(0x00);
WriteComm(0x65);WriteData(0x45); // 04
WriteComm(0x66);WriteData(0x0C); // 03
WriteComm(0x67);WriteData(0x00); // 10
WriteComm(0xFE);WriteData(0x01); // ID
WriteComm(0xE5);WriteData(0x00);
WriteComm(0xE6);WriteData(0x10);
WriteComm(0xE7);WriteData(0x31);
WriteComm(0xFE);WriteData(0x00); // 切换到 Page 0
WriteComm(0xC4);WriteData(0x80);
WriteComm(0x2A);WriteData(0x00);WriteData(0x04);WriteData(0x00);WriteData(0x7B); // 设置列
// 显式设置 16 位像素格式 (COLMOD = 0x75)
WriteComm(0x3A);WriteData(0x75);
WriteComm(0x11);WriteData(0x00); // 退出睡眠
Delay_ms(150);
WriteComm(0x29);WriteData(0x00); // 开启显示
Delay_ms(20);
}
void LCD_SetWindow(u16 x_start, u16 x_end, u16 y_start, u16 y_end)
{
WriteComm(0x2A);
WriteData((u8)(x_start >> 8));
WriteData((u8)(x_start & 0xFF));
WriteData((u8)(x_end >> 8));
WriteData((u8)(x_end & 0xFF));
WriteComm(0x2B);
WriteData((u8)(y_start >> 8));
WriteData((u8)(y_start & 0xFF));
WriteData((u8)(y_end >> 8));
WriteData((u8)(y_end & 0xFF));
}
void LCD_Clear(u16 color)
{
u16 i, j;
LCD_SetWindow(4, 123, 0, 239);
WriteComm(0x2C);
for(i = 0; i < 120; i++)
{
for(j = 0; j < 240; j++)
{
WriteData((u8)(color >> 8));
WriteData((u8)(color & 0xFF));
}
}
}
void LCD_FillRect(u16 x, u16 y, u16 w, u16 h, u16 color)
{
u16 i, count;
u8 ch = (u8)(color >> 8);
u8 cl = (u8)(color & 0xFF);
LCD_SetWindow(x + 4, x + w - 1 + 4, y, y + h - 1);
WriteComm(0x2C);
count = w * h;
for(i = 0; i < count; i++)
{
WriteData(ch);
WriteData(cl);
}
}
void LCD_DrawRectBorder(u16 x, u16 y, u16 w, u16 h, u16 color)
{
LCD_FillRect(x, y, w, 1, color);
LCD_FillRect(x, y + h - 1, w, 1, color);
LCD_FillRect(x, y, 1, h, color);
LCD_FillRect(x + w - 1, y, 1, h, color);
}
void LCD_DrawMonoBitmap(u16 x, u16 y, u16 w, u16 h, unsigned char code *bmp, u16 color, u16 bg_color)
{
u16 r, c;
u16 byte_width = (w + 7) / 8;
u8 ch = (u8)(color >> 8);
u8 cl = (u8)(color & 0xFF);
u8 bgh = (u8)(bg_color >> 8);
u8 bgl = (u8)(bg_color & 0xFF);
LCD_SetWindow(x + 4, x + w - 1 + 4, y, y + h - 1);
WriteComm(0x2C);
for(r = 0; r < h; r++)
{
for(c = 0; c < w; c++)
{
u16 byte_idx = r * byte_width + (c / 8);
u8 bit_shift = 7 - (c % 8);
if(bmp[byte_idx] & (1 << bit_shift))
{
WriteData(ch);
WriteData(cl);
}
else
{
WriteData(bgh);
WriteData(bgl);
}
}
}
}
void LCD_ShowChar8x16(u16 x, u16 y, char ch, u16 color, u16 bg_color)
{
u8 r, c;
u8 char_idx = ch - 0x20;
u8 f_h = (u8)(color >> 8);
u8 f_l = (u8)(color & 0xFF);
u8 b_h = (u8)(bg_color >> 8);
u8 b_l = (u8)(bg_color & 0xFF);
if(ch < 0x20 || ch > 0x7E) return;
LCD_SetWindow(x + 4, x + 8 - 1 + 4, y, y + 16 - 1);
WriteComm(0x2C);
for(r = 0; r < 16; r++)
{
u8 line = FONT_8x16[char_idx][r];
for(c = 0; c < 8; c++)
{
if(line & (0x80 >> c))
{
WriteData(f_h);
WriteData(f_l);
}
else
{
WriteData(b_h);
WriteData(b_l);
}
}
}
}
void LCD_ShowString(u16 x, u16 y, char *str, u16 color, u16 bg_color)
{
while(*str)
{
LCD_ShowChar8x16(x, y, *str, color, bg_color);
x += 8;
str++;
}
}
void LCD_ShowStringCentered(u16 y, char *str, u16 color, u16 bg_color)
{
u16 len = 0;
char *p = str;
while(*p++) len++;
if(len * 8 >= 120)
LCD_ShowString(0, y, str, color, bg_color);
else
LCD_ShowString((120 - len * 8) / 2, y, str, color, bg_color);
}
void LCD_ShowChar16x32(u16 x, u16 y, char ch, u16 color, u16 bg_color)
{
u8 r, c, i, j;
u8 char_idx = ch - 0x20;
u8 f_h = (u8)(color >> 8);
u8 f_l = (u8)(color & 0xFF);
u8 b_h = (u8)(bg_color >> 8);
u8 b_l = (u8)(bg_color & 0xFF);
if(ch < 0x20 || ch > 0x7E) return;
LCD_SetWindow(x + 4, x + 16 - 1 + 4, y, y + 32 - 1);
WriteComm(0x2C);
for(r = 0; r < 16; r++)
{
u8 line = FONT_8x16[char_idx][r];
for(i = 0; i < 2; i++)
{
for(c = 0; c < 8; c++)
{
u8 val_bit = (line & (0x80 >> c));
for(j = 0; j < 2; j++)
{
if(val_bit)
{
WriteData(f_h);
WriteData(f_l);
}
else
{
WriteData(b_h);
WriteData(b_l);
}
}
}
}
}
}
void LCD_ShowString16x32(u16 x, u16 y, char *str, u16 color, u16 bg_color)
{
while(*str)
{
LCD_ShowChar16x32(x, y, *str, color, bg_color);
x += 16;
str++;
}
}
void LCD_ShowString16x32Centered(u16 y, char *str, u16 color, u16 bg_color)
{
u16 len = 0;
char *p = str;
while(*p++) len++;
if(len * 16 >= 120)
LCD_ShowString16x32(0, y, str, color, bg_color);
else
LCD_ShowString16x32((120 - len * 16) / 2, y, str, color, bg_color);
}

51
Drivers/lcd.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef __LCD_H__
#define __LCD_H__
#include "../App/config.h"
#include "stc32g.h"
// Color Constants (RGB565)
#define COLOR_BLACK 0x0000
#define COLOR_WHITE 0xFFFF
#define COLOR_CYAN 0x073F
#define COLOR_RED 0xF800
#define COLOR_GREEN 0x07E0
#define COLOR_BLUE 0x001F
#define COLOR_GRAY 0x5AEB
#define COLOR_AMBER 0xFDC0
// Public screen functions
void SGM_SendPulse(u8 pulse_cnt);
void LCD_Reset(void);
void LCD_Init(void);
void LCD_SetWindow(u16 x_start, u16 x_end, u16 y_start, u16 y_end);
void LCD_Clear(u16 color);
// Drawing Primitives
void LCD_FillRect(u16 x, u16 y, u16 w, u16 h, u16 color);
void LCD_DrawRectBorder(u16 x, u16 y, u16 w, u16 h, u16 color);
void LCD_DrawMonoBitmap(u16 x, u16 y, u16 w, u16 h, unsigned char code *bmp, u16 color, u16 bg_color);
void LCD_ShowChar8x16(u16 x, u16 y, char ch, u16 color, u16 bg_color);
void LCD_ShowString(u16 x, u16 y, char *str, u16 color, u16 bg_color);
void LCD_ShowStringCentered(u16 y, char *str, u16 color, u16 bg_color);
void LCD_ShowChar16x32(u16 x, u16 y, char ch, u16 color, u16 bg_color);
void LCD_ShowString16x32(u16 x, u16 y, char *str, u16 color, u16 bg_color);
void LCD_ShowString16x32Centered(u16 y, char *str, u16 color, u16 bg_color);
// Font and Bitmap externs (defined in lcd_font.h via lcd.c)
extern unsigned char code FONT_8x16[95][16];
extern unsigned char code bmp_battery_20x10[];
extern unsigned char code bmp_lock_16x16[];
extern unsigned char code bmp_unlock_16x16[];
extern unsigned char code bmp_radar_32x32_f1[];
extern unsigned char code bmp_radar_32x32_f2[];
extern unsigned char code bmp_radar_32x32_f3[];
extern unsigned char code bmp_confirm_lock_32x32[];
extern unsigned char code bmp_checkmark_32x32[];
extern unsigned char code bmp_cross_32x32[];
extern unsigned char code bmp_door_32x32[];
extern unsigned char code bmp_siren_32x32[];
#endif

284
Drivers/lcd_font.h Normal file
View File

@@ -0,0 +1,284 @@
#ifndef __FONT_H__
#define __FONT_H__
// 1. Horizontal Battery Icon (20x10 pixels)
// Width: 20 pixels (3 bytes per row), Height: 10 rows
unsigned char code bmp_battery_20x10[30] = {
0xFF, 0xFF, 0x00, // ####################..
0x80, 0x00, 0x80, // #..................#
0xBF, 0xFB, 0x80, // ##.###############.#
0xBF, 0xFB, 0xE0, // ##.###############.###
0xBF, 0xFB, 0xE0, // ##.###############.###
0xBF, 0xFB, 0xE0, // ##.###############.###
0xBF, 0xFB, 0xE0, // ##.###############.###
0xBF, 0xFB, 0x80, // ##.###############.#
0x80, 0x00, 0x80, // #..................#
0xFF, 0xFF, 0x00 // ####################..
};
// 2. Lock Icon (16x16 pixels)
// Width: 16 pixels (2 bytes per row), Height: 16 rows
unsigned char code bmp_lock_16x16[32] = {
0x07, 0xE0, // ######
0x0C, 0x30, // ## ##
0x18, 0x18, // ## ##
0x18, 0x18, // ## ##
0x18, 0x18, // ## ##
0xFF, 0xFF, // ################
0xFF, 0xFF, // ################
0xE7, 0xE7, // ### ###### ###
0xE7, 0xE7, // ### ###### ###
0xE1, 0x87, // ### #### ###
0xE1, 0x87, // ### #### ###
0xE7, 0xE7, // ### ###### ###
0xE7, 0xE7, // ### ###### ###
0xFF, 0xFF, // ################
0xFF, 0xFF, // ################
0x00, 0x00 //
};
// 3. Unlock Icon (16x16 pixels)
// Width: 16 pixels (2 bytes per row), Height: 16 rows
unsigned char code bmp_unlock_16x16[32] = {
0x07, 0xE0, // ######
0x0C, 0x30, // ## ##
0x18, 0x00, // ##
0x18, 0x00, // ##
0x18, 0x00, // ##
0xFF, 0xFF, // ################
0xFF, 0xFF, // ################
0xE7, 0xE7, // ### ###### ###
0xE7, 0xE7, // ### ###### ###
0xE1, 0x87, // ### #### ###
0xE1, 0x87, // ### #### ###
0xE7, 0xE7, // ### ###### ###
0xE7, 0xE7, // ### ###### ###
0xFF, 0xFF, // ################
0xFF, 0xFF, // ################
0x00, 0x00 //
};
// 4. Radar Icon Frame 1 (32x32 pixels, 4 bytes per row)
unsigned char code bmp_radar_32x32_f1[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x10, 0x08, 0x00,
0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x07, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 5. Radar Icon Frame 2
unsigned char code bmp_radar_32x32_f2[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xE0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x40, 0x02, 0x00,
0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
0x00, 0x40, 0x02, 0x00, 0x00, 0x47, 0xE2, 0x00, 0x00, 0x48, 0x12, 0x00, 0x00, 0x50, 0x0A, 0x00,
0x00, 0x50, 0x0A, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, 0x48, 0x12, 0x00, 0x00, 0x47, 0xE2, 0x00,
0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
0x00, 0x40, 0x02, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x07, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 6. Radar Icon Frame 3 (Complete circles)
unsigned char code bmp_radar_32x32_f3[128] = {
0x00, 0x07, 0xE0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x40, 0x02, 0x00,
0x00, 0x87, 0xE1, 0x00, 0x01, 0x18, 0x18, 0x80, 0x02, 0x20, 0x04, 0x40, 0x04, 0x40, 0x02, 0x20,
0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20,
0x04, 0x40, 0x02, 0x20, 0x04, 0x47, 0xE2, 0x20, 0x04, 0x48, 0x12, 0x20, 0x04, 0x50, 0x0A, 0x20,
0x04, 0x50, 0x0A, 0x20, 0x04, 0x50, 0x0A, 0x20, 0x04, 0x48, 0x12, 0x20, 0x04, 0x47, 0xE2, 0x20,
0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20, 0x04, 0x40, 0x02, 0x20,
0x04, 0x40, 0x02, 0x20, 0x02, 0x20, 0x04, 0x40, 0x01, 0x18, 0x18, 0x80, 0x00, 0x87, 0xE1, 0x00,
0x00, 0x40, 0x02, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x07, 0xE0, 0x00
};
// 7. Checkmark Icon (32x32 pixels)
unsigned char code bmp_checkmark_32x32[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0xF0, 0x00, 0x00, 0x3F, 0xFC, 0x00,
0x00, 0xF8, 0x1F, 0x00, 0x01, 0xC0, 0x03, 0x80,
0x03, 0x80, 0x01, 0xC0, 0x07, 0x00, 0x00, 0xE0,
0x0E, 0x00, 0x00, 0x70, 0x0C, 0x00, 0x00, 0x30,
0x18, 0x00, 0x02, 0x18, 0x18, 0x00, 0x07, 0x18,
0x38, 0x00, 0x0E, 0x1C, 0x30, 0x00, 0x1C, 0x0C,
0x30, 0x20, 0x38, 0x0C, 0x30, 0x70, 0x70, 0x0C,
0x30, 0x38, 0xE0, 0x0C, 0x30, 0x1D, 0xC0, 0x0C,
0x30, 0x0F, 0x80, 0x0C, 0x38, 0x07, 0x00, 0x1C,
0x18, 0x02, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18,
0x0C, 0x00, 0x00, 0x30, 0x0E, 0x00, 0x00, 0x70,
0x07, 0x00, 0x00, 0xE0, 0x03, 0x80, 0x01, 0xC0,
0x01, 0xC0, 0x03, 0x80, 0x00, 0xF8, 0x1F, 0x00,
0x00, 0x3F, 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 8. Cross Icon (32x32 pixels)
unsigned char code bmp_cross_32x32[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0xF0, 0x00, 0x00, 0x3F, 0xFC, 0x00,
0x00, 0xF8, 0x1F, 0x00, 0x01, 0xC0, 0x03, 0x80,
0x03, 0x80, 0x01, 0xC0, 0x07, 0x00, 0x00, 0xE0,
0x0E, 0x00, 0x00, 0x70, 0x0C, 0x00, 0x00, 0x30,
0x18, 0x10, 0x08, 0x18, 0x18, 0x38, 0x1C, 0x18,
0x38, 0x1C, 0x38, 0x1C, 0x30, 0x0E, 0x70, 0x0C,
0x30, 0x07, 0xE0, 0x0C, 0x30, 0x03, 0xC0, 0x0C,
0x30, 0x03, 0xC0, 0x0C, 0x30, 0x07, 0xE0, 0x0C,
0x30, 0x0E, 0x70, 0x0C, 0x38, 0x1C, 0x38, 0x1C,
0x18, 0x38, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x18,
0x0C, 0x00, 0x00, 0x30, 0x0E, 0x00, 0x00, 0x70,
0x07, 0x00, 0x00, 0xE0, 0x03, 0x80, 0x01, 0xC0,
0x01, 0xC0, 0x03, 0x80, 0x00, 0xF8, 0x1F, 0x00,
0x00, 0x3F, 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 9. Door Icon (32x32 pixels)
unsigned char code bmp_door_32x32[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0x7C, 0xF0, 0x0F, 0x00, 0x7C, 0xF0, 0x0F, 0x00, 0x7C, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 10. Siren Icon (32x32 pixels)
unsigned char code bmp_siren_32x32[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00,
0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00,
0x06, 0x01, 0x80, 0x60, 0x07, 0x01, 0x80, 0xE0,
0x03, 0x81, 0x81, 0xC0, 0x01, 0xC0, 0x03, 0x80,
0x00, 0xE0, 0x07, 0x00, 0x00, 0x60, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7C, 0x0F, 0xF0, 0x3E, 0x00, 0x1F, 0xF8, 0x00,
0x00, 0x3F, 0xFC, 0x00, 0x00, 0x7F, 0xFE, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00,
0x01, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x80,
0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xC0,
0x03, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xC0,
0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 11. Unlocked Padlock Icon (32x32 pixels, for confirmation page)
unsigned char code bmp_confirm_lock_32x32[128] = {
0x00, 0x03, 0xC0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1C, 0x38, 0x00, 0x00, 0x38, 0x1C, 0x00,
0x00, 0x30, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
0x00, 0x30, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0,
0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x03, 0xC0, 0xF0,
0x0F, 0x03, 0xC0, 0xF0, 0x0F, 0x03, 0xC0, 0xF0, 0x0F, 0x03, 0xC0, 0xF0, 0x0F, 0x01, 0x80, 0xF0,
0x0F, 0x01, 0x80, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0,
0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Standard ASCII 8x16 Font Library
// 95 printable characters (0x20 to 0x7E)
// Each character takes 16 bytes.
unsigned char code FONT_8x16[95][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20 Space
{0x00,0x00,0x0C,0x1C,0x1C,0x1C,0x0C,0x0C,0x08,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00}, // 0x21 !
{0x00,0x00,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x22 "
{0x00,0x00,0x24,0x24,0x7E,0x24,0x24,0x7E,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00}, // 0x23 #
{0x00,0x00,0x08,0x1C,0x2A,0x0A,0x0A,0x1C,0x28,0x28,0x2A,0x1C,0x08,0x00,0x00,0x00}, // 0x24 $
{0x00,0x00,0x62,0x94,0x98,0x68,0x10,0x26,0x49,0x49,0x26,0x00,0x00,0x00,0x00,0x00}, // 0x25 %
{0x00,0x00,0x00,0x0C,0x12,0x12,0x0C,0x15,0x22,0x22,0x1D,0x00,0x00,0x00,0x00,0x00}, // 0x26 &
{0x00,0x00,0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x27 '
{0x00,0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,0x00}, // 0x28 (
{0x00,0x00,0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x00,0x00}, // 0x29 )
{0x00,0x00,0x00,0x08,0x2A,0x1C,0x08,0x1C,0x2A,0x08,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2A *
{0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00}, // 0x2B +
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x08,0x10,0x00,0x00}, // 0x2C ,
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2D -
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00}, // 0x2E .
{0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00}, // 0x2F /
{0x00,0x00,0x1C,0x22,0x22,0x26,0x2A,0x32,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x30 0
{0x00,0x00,0x08,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x31 1
{0x00,0x00,0x1C,0x22,0x22,0x04,0x08,0x10,0x20,0x22,0x3F,0x00,0x00,0x00,0x00,0x00}, // 0x32 2
{0x00,0x00,0x1C,0x22,0x02,0x06,0x18,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x33 3
{0x00,0x00,0x02,0x06,0x0A,0x12,0x22,0x7F,0x02,0x02,0x07,0x00,0x00,0x00,0x00,0x00}, // 0x34 4
{0x00,0x00,0x3F,0x20,0x20,0x3C,0x22,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x35 5
{0x00,0x00,0x1C,0x22,0x20,0x3C,0x22,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x36 6
{0x00,0x00,0x3F,0x22,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00}, // 0x37 7
{0x00,0x00,0x1C,0x22,0x22,0x1C,0x22,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x38 8
{0x00,0x00,0x1C,0x22,0x22,0x22,0x22,0x1E,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x39 9
{0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00}, // 0x3A :
{0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x0C,0x0C,0x08,0x10,0x00,0x00,0x00}, // 0x3B ;
{0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00,0x00,0x00}, // 0x3C <
{0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3D =
{0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x00,0x00,0x00}, // 0x3E >
{0x00,0x00,0x1C,0x22,0x22,0x02,0x04,0x08,0x08,0x00,0x08,0x08,0x00,0x00,0x00,0x00}, // 0x3F ?
{0x00,0x00,0x1C,0x22,0x4A,0x56,0x52,0x52,0x4C,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x40 @
{0x00,0x00,0x08,0x14,0x22,0x22,0x3E,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x41 A
{0x00,0x00,0x3C,0x22,0x22,0x3C,0x22,0x22,0x22,0x22,0x3C,0x00,0x00,0x00,0x00,0x00}, // 0x42 B
{0x00,0x00,0x1C,0x22,0x20,0x20,0x20,0x20,0x20,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x43 C
{0x00,0x00,0x38,0x24,0x22,0x22,0x22,0x22,0x22,0x24,0x38,0x00,0x00,0x00,0x00,0x00}, // 0x44 D
{0x00,0x00,0x3E,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x3E,0x00,0x00,0x00,0x00,0x00}, // 0x45 E
{0x00,0x00,0x3E,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00}, // 0x46 F
{0x00,0x00,0x1C,0x22,0x20,0x20,0x27,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x47 G
{0x00,0x00,0x22,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x48 H
{0x00,0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x49 I
{0x00,0x00,0x0E,0x02,0x02,0x02,0x02,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x4A J
{0x00,0x00,0x22,0x24,0x28,0x30,0x20,0x30,0x28,0x24,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x4B K
{0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3E,0x00,0x00,0x00,0x00,0x00}, // 0x4C L
{0x00,0x00,0x22,0x36,0x2A,0x2A,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x4D M
{0x00,0x00,0x22,0x32,0x2A,0x26,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x4E N
{0x00,0x00,0x1C,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x4F O
{0x00,0x00,0x3C,0x22,0x22,0x3C,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00}, // 0x50 P
{0x00,0x00,0x1C,0x22,0x22,0x22,0x22,0x2A,0x24,0x22,0x1D,0x00,0x00,0x00,0x00,0x00}, // 0x51 Q
{0x00,0x00,0x3C,0x22,0x22,0x3C,0x28,0x24,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x52 R
{0x00,0x00,0x1C,0x22,0x20,0x1C,0x02,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x53 S
{0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x54 T
{0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x55 U
{0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x56 V
{0x00,0x00,0x22,0x22,0x22,0x2A,0x2A,0x2A,0x2A,0x14,0x14,0x00,0x00,0x00,0x00,0x00}, // 0x57 W
{0x00,0x00,0x22,0x22,0x14,0x08,0x08,0x08,0x14,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x58 X
{0x00,0x00,0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x59 Y
{0x00,0x00,0x3E,0x02,0x04,0x08,0x10,0x20,0x20,0x20,0x3E,0x00,0x00,0x00,0x00,0x00}, // 0x5A Z
{0x00,0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00,0x00,0x00,0x00,0x00}, // 0x5B [
{0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00}, // 0x5C Backslash
{0x00,0x00,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3C,0x00,0x00,0x00,0x00,0x00}, // 0x5D ]
{0x00,0x00,0x08,0x14,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x5E ^
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00}, // 0x5F _
{0x00,0x00,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x60 `
{0x00,0x00,0x00,0x00,0x1C,0x02,0x1E,0x22,0x22,0x26,0x1F,0x00,0x00,0x00,0x00,0x00}, // 0x61 a
{0x00,0x00,0x20,0x20,0x3C,0x22,0x22,0x22,0x22,0x22,0x3C,0x00,0x00,0x00,0x00,0x00}, // 0x62 b
{0x00,0x00,0x00,0x00,0x1C,0x22,0x20,0x20,0x20,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x63 c
{0x00,0x00,0x02,0x02,0x1E,0x22,0x22,0x22,0x22,0x22,0x1E,0x00,0x00,0x00,0x00,0x00}, // 0x64 d
{0x00,0x00,0x00,0x00,0x1C,0x22,0x3E,0x20,0x20,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x65 e
{0x00,0x00,0x0E,0x10,0x10,0x3C,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00}, // 0x66 f
{0x00,0x00,0x00,0x00,0x1E,0x22,0x22,0x22,0x1E,0x02,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x67 g
{0x00,0x00,0x20,0x20,0x3C,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x68 h
{0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x69 i
{0x00,0x00,0x02,0x00,0x06,0x02,0x02,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x6A j
{0x00,0x00,0x20,0x20,0x22,0x24,0x28,0x30,0x28,0x24,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x6B k
{0x00,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x6C l
{0x00,0x00,0x00,0x00,0x3A,0x2A,0x2A,0x2A,0x2A,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x6D m
{0x00,0x00,0x00,0x00,0x2E,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x6E n
{0x00,0x00,0x00,0x00,0x1C,0x22,0x22,0x22,0x22,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x6F o
{0x00,0x00,0x00,0x00,0x3C,0x22,0x22,0x3C,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00}, // 0x70 p
{0x00,0x00,0x00,0x00,0x1E,0x22,0x22,0x1E,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00}, // 0x71 q
{0x00,0x00,0x00,0x00,0x2E,0x12,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00}, // 0x72 r
{0x00,0x00,0x00,0x00,0x1E,0x20,0x1C,0x02,0x02,0x22,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x73 s
{0x00,0x00,0x08,0x08,0x3E,0x08,0x08,0x08,0x08,0x08,0x04,0x00,0x00,0x00,0x00,0x00}, // 0x74 t
{0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x26,0x1F,0x00,0x00,0x00,0x00,0x00}, // 0x75 u
{0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x76 v
{0x00,0x00,0x00,0x00,0x22,0x22,0x2A,0x2A,0x2A,0x14,0x14,0x00,0x00,0x00,0x00,0x00}, // 0x77 w
{0x00,0x00,0x00,0x00,0x22,0x14,0x08,0x08,0x14,0x22,0x22,0x00,0x00,0x00,0x00,0x00}, // 0x78 x
{0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x1E,0x02,0x1C,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x79 y
{0x00,0x00,0x00,0x00,0x3E,0x04,0x08,0x10,0x20,0x20,0x3E,0x00,0x00,0x00,0x00,0x00}, // 0x7A z
{0x00,0x00,0x06,0x08,0x08,0x08,0x10,0x08,0x08,0x08,0x06,0x00,0x00,0x00,0x00,0x00}, // 0x7B {
{0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x7C |
{0x00,0x00,0x60,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x60,0x00,0x00,0x00,0x00,0x00}, // 0x7D }
{0x00,0x00,0x00,0x12,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0x7E ~
};
#endif

288
Drivers/rf.c Normal file
View File

@@ -0,0 +1,288 @@
#include "rf.h"
#include "../App/config.h"
#include "intrins.h"
// ATR5179 射频开关控制脚
sbit RF_TX = P2^0; // V1 控制端 (1: 选通天线到 TX 路径)
sbit RF_RX = P3^7; // V2 控制端 (1: 选通天线到 RX 路径)
// 射频数据与控制引脚
sbit RF_TX_DAT = P3^6; // LT4455 数据输入 (DIN)
sbit RF_RX_DATA = P2^1; // LR690L 数据输出 (DATA)
sbit SHUT = P2^2; // LR690L 休眠脚 (0:工作, 1:休眠)
// External functions defined in main.c
extern void Delay_us(u16 us);
extern void Delay_ms(u16 ms);
extern u16 GetTimer0_Safe(void);
extern void Uart_SendString(char *s);
extern void Uart_SendHex4(u8 val);
extern void Uart_SendHex8(u8 val);
extern void Uart_SendHex16(u16 val);
extern void Uart_SendHex20(u32 val);
extern void Uart_SendByte(u8 dat);
void RF_Init(void)
{
// P2.0 (RF_TX) 和 P2.2 (SHUT) 配置为推挽输出P2.1 (RF_RX_DATA) 配置为双向口/输入
P2M1 &= ~((1 << 0) | (1 << 1) | (1 << 2));
P2M0 &= ~(1 << 1);
P2M0 |= ((1 << 0) | (1 << 2));
// P3.6 (RF_TX_DAT), P3.7 (RF_RX) 配置为推挽输出
P3M1 &= ~((1 << 6) | (1 << 7));
P3M0 |= ((1 << 6) | (1 << 7));
RF_TX = 0;
SHUT = 1; // 默认关闭接收芯片
RF_RX = 0;
RF_TX_DAT = 0;
}
void RF_SetMode(u8 mode)
{
if (mode == 0) // Sleep/Idle
{
SHUT = 1; // LR690L Sleep
RF_RX = 0; // 断开接收天线
RF_TX = 0; // 断开发射天线
}
else if (mode == 1) // Rx Mode
{
SHUT = 0; // LR690L 工作
RF_RX = 1; // 天线切至接收端
RF_TX = 0;
}
else if (mode == 2) // Tx Mode
{
SHUT = 1; // LR690L 睡眠
RF_RX = 0;
RF_TX = 1; // 天线切至发射端
}
}
void EV1527_TxFrame(u32 addr, u8 dat)
{
u8 i;
// 1. 同步脉冲: 1T 高电平 + 31T 低电平
RF_TX_DAT = 1;
Delay_us(320);
RF_TX_DAT = 0;
Delay_us(9920);
// 2. 20位地址码 (MSB first)
for (i = 0; i < 20; i++)
{
if ((addr >> (19 - i)) & 1)
{
// 逻辑 1: 3T 高电平 + 1T 低电平
RF_TX_DAT = 1;
Delay_us(960);
RF_TX_DAT = 0;
Delay_us(320);
}
else
{
// 逻辑 0: 1T 高电平 + 3T 低电平
RF_TX_DAT = 1;
Delay_us(320);
RF_TX_DAT = 0;
Delay_us(960);
}
}
// 3. 4位数据码 (MSB first)
for (i = 0; i < 4; i++)
{
if ((dat >> (3 - i)) & 1)
{
// 逻辑 1: 3T 高电平 + 1T 低电平
RF_TX_DAT = 1;
Delay_us(960);
RF_TX_DAT = 0;
Delay_us(320);
}
else
{
// 逻辑 0: 1T 高电平 + 3T 低电平
RF_TX_DAT = 1;
Delay_us(320);
RF_TX_DAT = 0;
Delay_us(960);
}
}
}
void EV1527_Transmit(u32 addr, u8 dat)
{
u8 r;
for (r = 0; r < 25; r++) // 增加到 25 帧(约 340ms
{
EV1527_TxFrame(addr, dat);
}
}
u16 GetPulseDuration(u8 state, u16 timeout_us)
{
u16 timeout_ticks = (u16)((u32)timeout_us * (MAIN_Fosc / 1000000UL) / 12UL);
TL0 = 0;
TH0 = 0;
TR0 = 1; // 启动定时器0
while (RF_RX_DATA == state)
{
if (GetTimer0_Safe() > timeout_ticks)
{
TR0 = 0;
return 0; // 超时
}
}
TR0 = 0;
return (u16)((u32)GetTimer0_Safe() * 12UL / (MAIN_Fosc / 1000000UL)); // 返回微秒数
}
bit EV1527_Decode(u32 *out_addr, u8 *out_data)
{
u16 high_time, low_time;
u8 i;
u32 addr = 0;
u8 dat = 0;
u16 T;
u16 idata raw_h[24];
u16 idata raw_l[24];
// 1. 同步头捕获: 必须是低电平状态之后变高电平开始
if (RF_RX_DATA == 0)
{
u16 wait_cnt = 0;
while (RF_RX_DATA == 0)
{
Delay_us(10);
wait_cnt++;
if (wait_cnt > 3000) // 30ms 超时
return 0;
}
}
// 测量同步头高电平时间 (放宽至 2500us)
high_time = GetPulseDuration(1, 2500);
if (high_time < 50 || high_time > 2500)
return 0;
// 测量同步头低电平时间 (放宽至 60000us)
low_time = GetPulseDuration(0, 60000);
if (low_time < 1500 || low_time > 60000)
return 0;
// 计算高低电平时间之比。对于标准 EV1527低电平是高电平的 31 倍。
// 放宽比例范围为 15 到 48以应对各种不同的遥控器电阻。
{
u32 ratio = (u32)low_time / high_time;
if (ratio < 15 || ratio > 48)
return 0;
}
// 估算基准脉冲周期 T = low_time / 31
T = low_time / 31;
if (T == 0) T = 1;
// 2. 连续抓取 24 个数据脉冲
for (i = 0; i < 24; i++)
{
u16 wait_cnt = 0;
// 等待下一个数据脉冲的上升沿 (如果当前是低电平,等待它变高)
while (RF_RX_DATA == 0)
{
Delay_us(5);
wait_cnt++;
if (wait_cnt > 1000) // 5ms 超时
{
return 0; // 解码失败
}
}
// 测量高电平持续时间和低电平持续时间
raw_h[i] = GetPulseDuration(1, 5000);
if (raw_h[i] == 0) return 0;
raw_l[i] = GetPulseDuration(0, 5000);
if (raw_l[i] == 0) return 0;
}
// 3. 将抓到的全部 24 位脉冲数据无条件输出到串口 (缩短输出信息以防止阻塞接收)
Uart_SendString("Captured: Sync H=");
Uart_SendHex16(high_time);
Uart_SendString("us, L=");
Uart_SendHex16(low_time);
Uart_SendString("us, T=");
Uart_SendHex16(T);
Uart_SendString("us\r\n");
// 4. 组合成 24 位地址与数据,使用自适应阈值:如果高电平时间比低电平时间长,判定为 1反之为 0
for (i = 0; i < 24; i++)
{
if (raw_h[i] > raw_l[i])
{
if (i < 20) addr = (addr << 1) | 1;
else dat = (dat << 1) | 1;
}
else
{
if (i < 20) addr = (addr << 1);
else dat = (dat << 1);
}
}
*out_addr = addr;
*out_data = dat;
// 串口打印解码结果方便现场调试
Uart_SendString("Decoded ADDR: 0x");
Uart_SendHex20(addr);
Uart_SendString(", DATA: 0x");
Uart_SendHex4(dat);
Uart_SendString("\r\n");
return 1;
}
void Loopback_Test(void)
{
u16 match_count = 0;
u16 i;
SHUT = 0; // 使能接收芯片
RF_RX = 1; // 选通天线到接收端
RF_TX = 0; // 发送侧断开
Delay_ms(100);
Uart_SendString("Starting RF Loopback Self-Test...\r\n");
for (i = 0; i < 100; i++)
{
RF_TX_DAT = 1;
Delay_us(500);
if (RF_RX_DATA == 1) match_count++;
RF_TX_DAT = 0;
Delay_us(500);
if (RF_RX_DATA == 0) match_count++;
}
Uart_SendString("Loopback Match Count: ");
Uart_SendHex16(match_count);
Uart_SendString("/200\r\n");
if (match_count > 150)
{
Uart_SendString("Result: PASS! Transmitter is emitting RF, and Receiver is picking it up!\r\n");
}
else
{
Uart_SendString("Result: FAIL! No RF signal detected. Check hardware.\r\n");
}
SHUT = 1;
RF_RX = 0;
}

16
Drivers/rf.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef __RF_H__
#define __RF_H__
#include "../App/config.h"
#include "stc32g.h"
// Public RF functions
void RF_Init(void);
void RF_SetMode(u8 mode); // mode: 0=Sleep, 1=Rx, 2=Tx
void EV1527_TxFrame(u32 addr, u8 dat);
void EV1527_Transmit(u32 addr, u8 dat);
u16 GetPulseDuration(u8 state, u16 timeout_us);
bit EV1527_Decode(u32 *out_addr, u8 *out_data);
void Loopback_Test(void);
#endif

1487
Drivers/stc32g.h Normal file

File diff suppressed because it is too large Load Diff