diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f74ecc6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Build output +build/ +*.elf +*.hex +*.bin +*.map + +# IDE/Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db diff --git a/Core/Inc/config.h b/Core/Inc/config.h new file mode 100644 index 0000000..4775512 --- /dev/null +++ b/Core/Inc/config.h @@ -0,0 +1,98 @@ +/***************************************************************** + * 萝莉3代遥控器 - 硬件引脚配置 + * MCU: STM32F103RBT6 (LQFP64) + * + * 引脚编码: (port << 8) | pin + * port: 0=GPIOA, 1=GPIOB, 2=GPIOC, 3=GPIOD + * pin: 0-15 + * + * 示例: PA0=0x000, PB1=0x101, PC2=0x202 + *****************************************************************/ +#ifndef CONFIG_H +#define CONFIG_H + +/* ================================================================ + * ADC 输入引脚 (16通道) + * ADC_IN0~15 可在 OLED 菜单中配置映射通道、混控 + * 支持自动检测按键/ADC 输入类型 + * ================================================================ */ +#define ADC_IN0 0x200 /* PC0 - ADC12_IN10 */ +#define ADC_IN1 0x201 /* PC1 - ADC12_IN11 */ +#define ADC_IN2 0x202 /* PC2 - ADC12_IN12 */ +#define ADC_IN3 0x203 /* PC3 - ADC12_IN13 */ +#define ADC_IN4 0x000 /* PA0 - ADC12_IN0 */ +#define ADC_IN5 0x001 /* PA1 - ADC12_IN1 */ +#define ADC_IN6 0x002 /* PA2 - ADC12_IN2 */ +#define ADC_IN7 0x003 /* PA3 - ADC12_IN3 */ +#define ADC_IN8 0x004 /* PA4 - ADC12_IN4 */ +#define ADC_IN9 0x005 /* PA5 - ADC12_IN5 */ +#define ADC_IN10 0x006 /* PA6 - ADC12_IN6 */ +#define ADC_IN11 0x007 /* PA7 - ADC12_IN7 */ +#define ADC_IN12 0x204 /* PC4 - ADC12_IN14 */ +#define ADC_IN13 0x205 /* PC5 - ADC12_IN15 */ +#define ADC_IN14 0x100 /* PB0 - ADC12_IN8 */ +#define ADC_IN15 0x101 /* PB1 - ADC12_IN9 */ + +/* ================================================================ + * OLED 屏幕 (128x64 SSD1306, 硬件 I2C) + * ================================================================ */ +#define OLED_SDA 0x10B /* PB11 - I2C2_SDA */ +#define OLED_SCL 0x10A /* PB10 - I2C2_SCL */ + +/* ================================================================ + * 操作按键 (上拉输入, 按下低电平) + * 上/下/确认/返回 + * 确认长按 -> 高频头配置页 + * 返回长按 -> 主页值/回传切换 + * ================================================================ */ +#define KEY_IN1 0x10C /* PB12 - 上 */ +#define KEY_IN2 0x10D /* PB13 - 下 */ +#define KEY_IN3 0x10E /* PB14 - 确认/菜单 */ +#define KEY_IN4 0x10F /* PB15 - 返回/回传 */ + +/* ================================================================ + * PWM 输出 (TIM4 CH3/CH4) + * 可配置为: WS2812 / LED 呼吸灯 / 振动电机 + * ================================================================ */ +#define PWM_OUT1 0x108 /* PB8 - TIM4_CH3 */ +#define PWM_OUT2 0x109 /* PB9 - TIM4_CH4 */ + +/* ================================================================ + * LED 状态指示灯 + * LED_OUT1: 系统状态 - 开机常亮 + * LED_OUT2: NRF24L01 状态 - 未连接慢闪/配对快闪/已连接常亮 + * LED_OUT3: CRFS 状态 - 未连接慢闪/配对快闪/已连接常亮 + * ================================================================ */ +#define LED_OUT1 0x206 /* PC6 */ +#define LED_OUT2 0x207 /* PC7 */ +#define LED_OUT3 0x208 /* PC8 */ + +/* ================================================================ + * NRF24L01+ 2.4G 无线模块 (硬件 SPI1) + * 默认开启,可在 OLED 菜单中关闭 + * ================================================================ */ +#define NRF24L01_CE 0x107 /* PB7 - 输出 */ +#define NRF24L01_CSN 0x106 /* PB6 - 输出 (SPI 片选) */ +#define NRF24L01_SCK 0x103 /* PB3 - SPI1_SCK */ +#define NRF24L01_MOSI 0x105 /* PB5 - SPI1_MOSI */ +#define NRF24L01_MISO 0x104 /* PB4 - SPI1_MISO */ +#define NRF24L01_IRQ 0x302 /* PD2 - 外部中断 */ + +/* ================================================================ + * 串口 + * UART1: 可选接收外部 SBUS 信号 (OLED 菜单中开启) + * UART3: 发送 CRFS 信号 (OLED 菜单中开启) + * ================================================================ */ +#define RX1 0x00A /* PA10 - USART1_RX */ +#define TX1 0x009 /* PA9 - USART1_TX */ +#define RX3 0x20B /* PC11 - USART3_RX */ +#define TX3 0x20A /* PC10 - USART3_TX */ + +/* ================================================================ + * USB (虚拟 HID Joystick) + * 连接电脑自动识别为飞行模拟器外设 + * ================================================================ */ +#define USB_DM 0x00B /* PA11 - USB_DM */ +#define USB_DP 0x00C /* PA12 - USB_DP */ + +#endif /* CONFIG_H */ diff --git a/Core/Inc/input.h b/Core/Inc/input.h new file mode 100644 index 0000000..9ac54d5 --- /dev/null +++ b/Core/Inc/input.h @@ -0,0 +1,61 @@ +/** + * 按键输入与 ADC 读取模块 + * 按键: PB12(上), PB13(下), PB14(确认), PB15(返回) - 上拉输入, 按下低电平 + * ADC: 16通道 (ADC_IN0~15), 使用 ADC2 扫描 + */ +#ifndef INPUT_H +#define INPUT_H + +#include "main.h" +#include "adc.h" +#include "config.h" + +/* 按键定义 */ +#define KEY_UP 0 +#define KEY_DOWN 1 +#define KEY_OK 2 +#define KEY_BACK 3 +#define KEY_NONE 0xFF + +/* 按键状态 */ +#define KEY_STATE_IDLE 0 +#define KEY_STATE_PRESS 1 +#define KEY_STATE_HOLD 2 /* 长按 */ +#define KEY_STATE_RELEASE 3 + +/* 长按阈值 (ms) */ +#define KEY_LONG_PRESS_MS 800 +#define KEY_POWER_OFF_MS 2000 + +/* ADC 通道数 */ +#define ADC_CHANNEL_COUNT 16 + +/* ADC 原始值范围 */ +#define ADC_RAW_MIN 0 +#define ADC_RAW_MAX 4095 + +/* 函数声明 */ +void Input_Init(void); +void Input_Scan(void); /* 每 10ms 调用一次 */ + +/* 按键查询 */ +uint8_t Input_GetKey(void); /* 返回当前按下的键 (单次) */ +uint8_t Input_GetKeyState(uint8_t key); /* 获取按键状态 */ +uint8_t Input_IsKeyPressed(uint8_t key); /* 是否刚按下 */ +uint8_t Input_IsKeyHeld(uint8_t key); /* 是否长按 */ +uint8_t Input_IsKeyReleased(uint8_t key); /* 是否刚释放 */ + +/* ADC 读取 */ +uint16_t Input_GetADC(uint8_t ch); /* 读取指定通道原始值 */ +uint16_t Input_GetADC_Percent(uint8_t ch); /* 读取百分比 0-1000 */ +void Input_ReadAllADC(void); /* 读取所有 ADC 通道 */ + +/* ADC 值存储 (用于通道映射) */ +extern uint16_t adc_values[ADC_CHANNEL_COUNT]; +extern uint8_t key_values[4]; /* 按键数字值 (0/1) */ + +/* 引脚编码解码 */ +GPIO_TypeDef* Config_GetPort(uint16_t pin_code); +uint16_t Config_GetPin(uint16_t pin_code); + +#endif /* INPUT_H */ diff --git a/Core/Inc/menu.h b/Core/Inc/menu.h new file mode 100644 index 0000000..43b2c48 --- /dev/null +++ b/Core/Inc/menu.h @@ -0,0 +1,86 @@ +/** + * 菜单系统与 UI 交互 + * 基于 OLED 128x64 的层级菜单 + * 支持: 模型选择、高频头配置、通道映射、混控、PWM驱动、首页设置 + */ +#ifndef MENU_H +#define MENU_H + +#include "main.h" +#include "oled.h" +#include "input.h" +#include "storage.h" +#include "pwm_out.h" +#include "nrf24l01.h" + +/* 页面 ID */ +#define PAGE_HOME 0 +#define PAGE_MAIN_MENU 1 +#define PAGE_MODEL_LIST 2 +#define PAGE_MODEL_NEW 3 +#define PAGE_MODEL_EDIT 4 +#define PAGE_CHANNEL_MAP 5 +#define PAGE_MIXER 6 +#define PAGE_MIXER_EDIT 7 +#define PAGE_TELEM 8 +#define PAGE_RF_CONFIG 9 +#define PAGE_NRF_CONFIG 10 +#define PAGE_CRFS_CONFIG 11 +#define PAGE_PWM_CONFIG 12 +#define PAGE_HOME_SET 13 +#define PAGE_BIND 14 +#define PAGE_RF_QUICK 15 + +/* 菜单项最大数 */ +#define MENU_MAX_ITEMS 10 + +/* 菜单项结构 */ +typedef struct { + const char *text; + uint8_t target_page; + void (*action)(void); /* 可选回调 */ +} MenuItem_t; + +/* 页面上下文 */ +typedef struct { + uint8_t page_id; + uint8_t cursor; /* 当前选中项 */ + uint8_t scroll_offset; /* 滚动偏移 */ + uint8_t item_count; + MenuItem_t items[MENU_MAX_ITEMS]; + uint8_t edit_idx; /* 编辑模式下的索引 */ + uint8_t edit_value; /* 编辑值 */ + char edit_str[16]; /* 编辑字符串 */ + uint8_t edit_str_len; +} Page_t; + +/* 函数声明 */ +void Menu_Init(void); +void Menu_Run(void); /* 主循环调用 */ + +/* 页面渲染 */ +void Menu_DrawHome(void); +void Menu_DrawMainMenu(void); +void Menu_DrawModelList(void); +void Menu_DrawModelNew(void); +void Menu_DrawChannelMap(void); +void Menu_DrawMixer(void); +void Menu_DrawMixerEdit(void); +void Menu_DrawRFConfig(void); +void Menu_DrawNRFConfig(void); +void Menu_DrawCRFSConfig(void); +void Menu_DrawPWMConfig(void); +void Menu_DrawHomeSet(void); +void Menu_DrawBind(void); +void Menu_DrawRFQuick(void); + +/* 混控计算 */ +void Mixer_Compute(int16_t *channels); + +/* 全局页面状态 */ +extern Page_t g_page; + +/* 通道输出值 (混控后) */ +extern int16_t g_channels[CHANNEL_COUNT]; + +#endif /* MENU_H */ diff --git a/Core/Inc/nrf24l01.h b/Core/Inc/nrf24l01.h new file mode 100644 index 0000000..9fb66ba --- /dev/null +++ b/Core/Inc/nrf24l01.h @@ -0,0 +1,114 @@ +/** + * NRF24L01+ 2.4G 无线模块驱动 + * 硬件 SPI1: PB3=SCK, PB4=MISO, PB5=MOSI + * CE=PB7, CSN=PB6, IRQ=PD2 + */ +#ifndef NRF24L01_H +#define NRF24L01_H + +#include "main.h" +#include "spi.h" +#include "config.h" + +/* NRF24L01 寄存器地址 */ +#define NRF_CONFIG 0x00 +#define NRF_EN_AA 0x01 +#define NRF_EN_RXADDR 0x02 +#define NRF_SETUP_AW 0x03 +#define NRF_SETUP_RETR 0x04 +#define NRF_RF_CH 0x05 +#define NRF_RF_SETUP 0x06 +#define NRF_STATUS 0x07 +#define NRF_OBSERVE_TX 0x08 +#define NRF_RPD 0x09 +#define NRF_RX_ADDR_P0 0x0A +#define NRF_RX_ADDR_P1 0x0B +#define NRF_RX_ADDR_P2 0x0C +#define NRF_RX_ADDR_P3 0x0D +#define NRF_RX_ADDR_P4 0x0E +#define NRF_RX_ADDR_P5 0x0F +#define NRF_TX_ADDR 0x10 +#define NRF_RX_PW_P0 0x11 +#define NRF_RX_PW_P1 0x12 +#define NRF_RX_PW_P2 0x13 +#define NRF_RX_PW_P3 0x14 +#define NRF_RX_PW_P4 0x15 +#define NRF_RX_PW_P5 0x16 +#define NRF_FIFO_STATUS 0x17 +#define NRF_DYNPD 0x1C +#define NRF_FEATURE 0x1D + +/* 命令 */ +#define NRF_CMD_R_REGISTER 0x00 +#define NRF_CMD_W_REGISTER 0x20 +#define NRF_CMD_R_RX_PAYLOAD 0x61 +#define NRF_CMD_W_TX_PAYLOAD 0xA0 +#define NRF_CMD_FLUSH_TX 0xE1 +#define NRF_CMD_FLUSH_RX 0xE2 +#define NRF_CMD_REUSE_TX_PL 0xE3 +#define NRF_CMD_NOP 0xFF + +/* 状态标志 */ +#define NRF_STATUS_RX_DR 0x40 +#define NRF_STATUS_TX_DS 0x20 +#define NRF_STATUS_MAX_RT 0x10 + +/* 数据速率 */ +#define NRF_RATE_250K 0x20 +#define NRF_RATE_1M 0x00 +#define NRF_RATE_2M 0x08 + +/* 发射功率 */ +#define NRF_PA_MIN 0x00 +#define NRF_PA_LOW 0x02 +#define NRF_PA_HIGH 0x04 +#define NRF_PA_MAX 0x06 + +/* 地址宽度 */ +#define NRF_ADDR_WIDTH 5 + +/* 最大通道数 */ +#define NRF_MAX_CHANNEL 125 + +/* 宏: 引脚操作 */ +#define NRF_CE_H() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET) +#define NRF_CE_L() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET) +#define NRF_CSN_H() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET) +#define NRF_CSN_L() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET) +#define NRF_IRQ_READ() HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2) + +/* 函数声明 */ +void NRF24L01_Init(void); +uint8_t NRF24L01_Check(void); /* 检测模块是否存在 */ + +/* 基本配置 */ +void NRF24L01_SetChannel(uint8_t ch); +void NRF24L01_SetRate(uint8_t rate); +void NRF24L01_SetPower(uint8_t power); +void NRF24L01_SetTXAddr(const uint8_t *addr); +void NRF24L01_SetRXAddr(uint8_t pipe, const uint8_t *addr); + +/* 发送/接收 */ +void NRF24L01_TXMode(void); +void NRF24L01_RXMode(void); +uint8_t NRF24L01_TxPacket(const uint8_t *data, uint8_t len); +uint8_t NRF24L01_RxPacket(uint8_t *data); +uint8_t NRF24L01_IsDataReady(void); + +/* 对频相关 */ +void NRF24L01_BindMode(void); /* 进入对频模式 */ +uint8_t NRF24L01_BindScan(uint8_t *found_addr); /* 扫描对频设备 */ + +/* 低层 SPI 操作 */ +uint8_t NRF24L01_ReadReg(uint8_t reg); +void NRF24L01_WriteReg(uint8_t reg, uint8_t value); +void NRF24L01_ReadBuf(uint8_t reg, uint8_t *buf, uint8_t len); +void NRF24L01_WriteBuf(uint8_t reg, const uint8_t *buf, uint8_t len); + +/* 全局状态 */ +extern uint8_t nrf_connected; +extern uint8_t nrf_bind_phrase[7]; /* 对频短语, 最多6字符+'\0' */ +extern uint8_t nrf_channel; +extern uint8_t nrf_tx_addr[NRF_ADDR_WIDTH]; + +#endif /* NRF24L01_H */ diff --git a/Core/Inc/oled.h b/Core/Inc/oled.h new file mode 100644 index 0000000..a92660d --- /dev/null +++ b/Core/Inc/oled.h @@ -0,0 +1,65 @@ +/** + * OLED SSD1306 / SSD1315 128x64 I2C 驱动 + * 基于硬件 I2C2 (PB10=SCL, PB11=SDA) + * + * 芯片选择: 修改下方 OLED_CHIP 宏即可切换 + * OLED_CHIP_SSD1306 - 外部电荷泵 (0x8D 0x14) + * OLED_CHIP_SSD1315 - 内置 DC-DC (0xAD 0x8A) + */ +#ifndef OLED_H +#define OLED_H + +#include "main.h" +#include "i2c.h" + +/* ---- 芯片选择 ---- */ +#define OLED_CHIP_SSD1306 0 +#define OLED_CHIP_SSD1315 1 +#define OLED_CHIP OLED_CHIP_SSD1315 /* 根据实际模块修改 */ + +#define OLED_ADDR 0x78 /* SSD1306 I2C 地址 (SA0=0) */ +#define OLED_WIDTH 128 +#define OLED_HEIGHT 64 +#define OLED_PAGES 8 /* 64/8 = 8 pages */ + +/* OLED 初始化 */ +void OLED_Init(void); + +/* 基础操作 */ +void OLED_Clear(void); +void OLED_Display(void); /* 刷新显存到屏幕 */ +void OLED_SetCursor(uint8_t x, uint8_t y); /* x:0-127, y:0-7(page) */ + +/* 绘制函数 */ +void OLED_DrawPixel(uint8_t x, uint8_t y, uint8_t color); /* y:0-63 */ +void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2); +void OLED_DrawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h); +void OLED_FillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color); +void OLED_DrawCircle(uint8_t cx, uint8_t cy, uint8_t r); + +/* 文字绘制 */ +void OLED_ShowChar(uint8_t x, uint8_t y, char ch, uint8_t size); /* size:6或16 */ +void OLED_ShowString(uint8_t x, uint8_t y, const char *str, uint8_t size); +void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size); + +/* 汉字绘制 (使用 ui/words.h 中的字库) */ +void OLED_ShowCN(uint8_t x, uint8_t y, uint8_t index); + +/* 图片绘制 */ +void OLED_DrawBitmap(uint8_t x, uint8_t y, const uint8_t *bmp, uint8_t w, uint8_t h); + +/* 反色/滚动 */ +void OLED_InvertDisplay(uint8_t invert); +void OLED_StartScrollRight(uint8_t start_page, uint8_t end_page); +void OLED_StopScroll(void); + +/* 进度条 */ +void OLED_DrawProgressBar(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t percent); + +/* 外部显存缓冲区 (128*64/8 = 1024 bytes) */ +extern uint8_t OLED_Buffer[OLED_WIDTH * OLED_HEIGHT / 8]; + +/* 开机图片 (来自 ui/image.h) */ +extern const unsigned char bitmap_bytes[]; + +#endif /* OLED_H */ diff --git a/Core/Inc/protocol.h b/Core/Inc/protocol.h new file mode 100644 index 0000000..d2a02a9 --- /dev/null +++ b/Core/Inc/protocol.h @@ -0,0 +1,52 @@ +/** + * 协议层: 遥控信号打包/解包、SBUS 解析、USB HID Joystick + * 统一管理 NRF24/CRFS/SBUS/USB 四种协议的数据流 + */ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include "main.h" +#include "nrf24l01.h" +#include "storage.h" +#include "menu.h" + +/* 数据包结构 (NRF24 协议) */ +#define RF_PACKET_SIZE 32 +#define RF_HEADER_SIZE 6 + +/* 数据包头 */ +#define RF_SYNC_BYTE0 0xAA +#define RF_SYNC_BYTE1 0x55 + +/* SBUS 帧结构 */ +#define SBUS_FRAME_SIZE 25 +#define SBUS_BAUDRATE 100000 + +/* USB HID 报告大小 */ +#define HID_REPORT_SIZE 16 + +/* 函数声明 */ +void Protocol_Init(void); + +/* RF 协议 */ +void Protocol_SendRFPacket(void); /* 发送 NRF24 数据包 */ +void Protocol_ProcessRF(void); /* 处理 RF 收发 */ + +/* SBUS 输入 */ +void Protocol_SBUS_Init(void); +uint8_t Protocol_SBUS_Parse(const uint8_t *frame, int16_t *channels); + +/* USB HID Joystick */ +void Protocol_HID_Init(void); +void Protocol_HID_Send(void); /* 发送 HID 报告 */ + +/* 主循环调用 */ +void Protocol_Run(void); + +/* 回传数据 */ +extern uint16_t telem_voltage; /* 电压 (mV) */ +extern uint8_t telem_rssi; /* RSSI */ +extern uint8_t telem_packet_loss; /* 丢包率 */ +extern uint16_t telem_temp; /* 温度 */ + +#endif /* PROTOCOL_H */ diff --git a/Core/Inc/pwm_out.h b/Core/Inc/pwm_out.h new file mode 100644 index 0000000..c26b94a --- /dev/null +++ b/Core/Inc/pwm_out.h @@ -0,0 +1,58 @@ +/** + * PWM 输出与 LED 控制模块 + * TIM3 CH1/CH2/CH3 -> PC6/PC7/PC8 (LED 指示灯) + * TIM4 CH3/CH4 -> PB8/PB9 (PWM_OUT1/2, 可配置 WS2812/LED/振动) + */ +#ifndef PWM_H +#define PWM_H + +#include "main.h" +#include "tim.h" +#include "config.h" + +/* PWM 输出模式 */ +#define PWM_MODE_DISABLED 0 +#define PWM_MODE_WS2812 1 +#define PWM_MODE_LED 2 +#define PWM_MODE_VIBRATE 3 + +/* WS2812 模式 */ +#define WS2812_MODE_RAINBOW_BREATH 0 +#define WS2812_MODE_COLOR_FLOW 1 +#define WS2812_MODE_SINGLE_FLOW 2 +#define WS2812_MODE_SINGLE_BREATH 3 +#define WS2812_MODE_GRADIENT 4 +#define WS2812_MODE_STROBE 5 +#define WS2812_MODE_COUNT 6 + +/* LED 模式 */ +#define LED_MODE_BREATH 0 +#define LED_MODE_CONSTANT 1 + +/* 振动档位 */ +#define VIBRATE_LEVEL_MIN 1 +#define VIBRATE_LEVEL_MAX 9 + +/* 函数声明 */ +void PWM_Init(void); + +/* LED 指示灯控制 */ +void LED_SetSystem(uint8_t on); /* 系统状态 LED (PC6) */ +void LED_SetNRF(uint8_t mode); /* NRF 状态 LED (PC7): 0=慢闪,1=快闪,2=常亮,3=灭 */ +void LED_SetCRFS(uint8_t mode); /* CRFS 状态 LED (PC8) */ +void LED_Update(void); /* 每 10ms 调用, 更新 LED 闪烁 */ + +/* PWM 输出控制 */ +void PWM_SetMode(uint8_t ch, uint8_t mode); /* ch: 0=PWM_OUT1, 1=PWM_OUT2 */ +void PWM_SetWS2812Mode(uint8_t mode); /* 设置 WS2812 效果模式 */ +void PWM_SetLEDBrightness(uint8_t brightness); /* 0-100 */ +void PWM_SetVibrateLevel(uint8_t level); /* 1-9 */ + +/* 配置存储 */ +extern uint8_t pwm1_mode; +extern uint8_t pwm2_mode; +extern uint8_t ws2812_effect; +extern uint8_t led_brightness; +extern uint8_t vibrate_level; + +#endif /* PWM_H */ diff --git a/Core/Inc/storage.h b/Core/Inc/storage.h new file mode 100644 index 0000000..fb3b780 --- /dev/null +++ b/Core/Inc/storage.h @@ -0,0 +1,111 @@ +/** + * Flash 存储模块 (模拟 EEPROM) + * 使用 STM32F103 内部 Flash 最后一页存储配置 + * Flash: 128KB, 页大小 1KB, 最后一页 0x0801FC00 + */ +#ifndef STORAGE_H +#define STORAGE_H + +#include "main.h" +#include "nrf24l01.h" +#include "pwm_out.h" +#include + +/* Flash 页地址 (最后一页, 不占用程序空间) */ +#define STORAGE_PAGE_SIZE 1024 +#define FLASH_STORAGE_ADDR 0x0801FC00 /* Page 127 (128KB Flash, 最后一页) */ + +/* 模型最大数量 */ +#define MODEL_MAX_COUNT 16 +#define MODEL_NAME_LEN 9 /* 8字符 + '\0' */ + +/* 模型类型 */ +#define MODEL_TYPE_AIRPLANE 0 +#define MODEL_TYPE_CAR 1 +#define MODEL_TYPE_BOAT 2 +#define MODEL_TYPE_MULTIROTOR 3 + +/* 通道数 */ +#define CHANNEL_COUNT 16 + +/* 输入类型 */ +#define INPUT_TYPE_ADC 0 +#define INPUT_TYPE_KEY 1 +#define INPUT_TYPE_NONE 0xFF + +/* 混控类型 */ +#define MIXER_TYPE_NONE 0 +#define MIXER_TYPE_SIMPLE 1 /* 简单比例 */ +#define MIXER_TYPE_DELTA 2 /* 三角翼混控 */ +#define MIXER_TYPE_VTAIL 3 /* V尾混控 */ +#define MIXER_TYPE_ELEVON 4 /* 升降副翼 */ + +/* 回传信息项 */ +#define TELEM_VOLTAGE 0 +#define TELEM_RSSI 1 +#define TELEM_PACKET_LOSS 2 +#define TELEM_TEMP 3 +#define TELEM_COUNT 4 + +/* ---- 模型结构体 ---- */ +typedef struct { + char name[MODEL_NAME_LEN]; /* 模型名称 */ + uint8_t type; /* 模型类型 */ + uint8_t channel_map[CHANNEL_COUNT]; /* 通道映射: CHx -> ADC_INy 或 KEY_INy */ + uint8_t input_type[CHANNEL_COUNT]; /* 输入类型: INPUT_TYPE_ADC/KEY */ + uint8_t mixer_type[CHANNEL_COUNT]; /* 混控类型 */ + int16_t mixer_scale[CHANNEL_COUNT]; /* 混控比例 (x100) */ + int16_t mixer_offset[CHANNEL_COUNT];/* 混控偏移 */ + uint8_t telem_enable[TELEM_COUNT]; /* 回传信息使能 */ +} Model_t; + +/* ---- 全局配置结构体 ---- */ +typedef struct { + uint8_t magic[4]; /* 魔数 "LOLI" */ + uint8_t active_model; /* 当前活动模型索引 */ + Model_t models[MODEL_MAX_COUNT]; /* 模型列表 */ + + /* 高频头配置 */ + uint8_t rf_type; /* 0=NRF24, 1=CRFS */ + uint8_t nrf_channel; /* NRF24 频道 */ + uint8_t nrf_rate; /* 速率 */ + uint8_t nrf_power; /* 功率 */ + uint8_t nrf_addr[5]; /* 地址 */ + char nrf_phrase[7]; /* 对频短语 */ + + /* CRFS 配置 */ + uint16_t crfs_packet_rate; /* 数据包速率 */ + uint8_t crfs_telemetry_ratio; /* 遥测比例 */ + uint8_t crfs_power; /* 功率 */ + + /* PWM 配置 */ + uint8_t pwm1_mode; /* PWM_OUT1 模式 */ + uint8_t pwm2_mode; /* PWM_OUT2 模式 */ + uint8_t ws2812_effect; /* WS2812 效果 */ + uint8_t led_brightness; /* LED 亮度 */ + uint8_t vibrate_level; /* 振动档位 */ + + /* 首页设置 */ + uint8_t home_page; /* 0=回传, 1=INx值 */ + + /* CRC32 校验 */ + uint32_t crc32; +} Config_t; + +/* 函数声明 */ +void Storage_Init(void); +void Storage_Load(void); /* 从 Flash 加载配置 */ +void Storage_Save(void); /* 保存配置到 Flash */ +void Storage_Reset(void); /* 恢复出厂设置 */ + +/* 模型操作 */ +uint8_t Storage_ModelAdd(const char *name, uint8_t type); +void Storage_ModelDelete(uint8_t idx); +void Storage_ModelSelect(uint8_t idx); +Model_t* Storage_GetActiveModel(void); +Model_t* Storage_GetModel(uint8_t idx); + +/* 全局配置访问 */ +extern Config_t g_config; + +#endif /* STORAGE_H */ diff --git a/Core/Src/input.c b/Core/Src/input.c new file mode 100644 index 0000000..7fc338d --- /dev/null +++ b/Core/Src/input.c @@ -0,0 +1,189 @@ +/** + * 按键输入与 ADC 读取模块实现 + */ +#include "input.h" + +/* 全局数据 */ +uint16_t adc_values[ADC_CHANNEL_COUNT]; +uint8_t key_values[4]; + +/* 按键引脚: PB12, PB13, PB14, PB15 */ +static const uint16_t key_pins[4] = {GPIO_PIN_12, GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15}; + +/* 按键去抖状态机 */ +static uint8_t key_debounce[4]; /* 去抖计数器 */ +static uint8_t key_current[4]; /* 当前稳定状态 */ +static uint8_t key_prev[4]; /* 上一帧状态 */ +static uint32_t key_press_time[4]; /* 按下时刻 (ms) */ +static uint8_t key_state[4]; /* 状态: IDLE/PRESS/HOLD/RELEASE */ +static uint32_t sys_tick_ms; /* 系统毫秒计数 */ + +/* ADC 通道映射表 (ADC_INx -> ADC2 channel) */ +static const uint32_t adc_channel_map[ADC_CHANNEL_COUNT] = { + ADC_CHANNEL_10, /* ADC_IN0 = PC0 */ + ADC_CHANNEL_11, /* ADC_IN1 = PC1 */ + ADC_CHANNEL_12, /* ADC_IN2 = PC2 */ + ADC_CHANNEL_13, /* ADC_IN3 = PC3 */ + ADC_CHANNEL_0, /* ADC_IN4 = PA0 */ + ADC_CHANNEL_1, /* ADC_IN5 = PA1 */ + ADC_CHANNEL_2, /* ADC_IN6 = PA2 */ + ADC_CHANNEL_3, /* ADC_IN7 = PA3 */ + ADC_CHANNEL_4, /* ADC_IN8 = PA4 */ + ADC_CHANNEL_5, /* ADC_IN9 = PA5 */ + ADC_CHANNEL_6, /* ADC_IN10 = PA6 */ + ADC_CHANNEL_7, /* ADC_IN11 = PA7 */ + ADC_CHANNEL_14, /* ADC_IN12 = PC4 */ + ADC_CHANNEL_15, /* ADC_IN13 = PC5 */ + ADC_CHANNEL_8, /* ADC_IN14 = PB0 */ + ADC_CHANNEL_9, /* ADC_IN15 = PB1 */ +}; + +void Input_Init(void) { + sys_tick_ms = 0; + for (uint8_t i = 0; i < 4; i++) { + key_debounce[i] = 0; + key_current[i] = 0; + key_prev[i] = 0; + key_press_time[i] = 0; + key_state[i] = KEY_STATE_IDLE; + } + for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) { + adc_values[i] = 0; + } +} + +/* 由 SysTick 中断调用,更新系统时间 */ +void Input_TickInc(void) { + sys_tick_ms++; +} + +void Input_Scan(void) { + /* ---- 按键扫描 ---- */ + for (uint8_t i = 0; i < 4; i++) { + uint8_t raw = (HAL_GPIO_ReadPin(GPIOB, key_pins[i]) == GPIO_PIN_RESET) ? 1 : 0; + + /* 去抖 */ + if (raw == key_current[i]) { + key_debounce[i] = 0; + } else { + key_debounce[i]++; + if (key_debounce[i] >= 3) { /* 30ms 去抖 */ + key_current[i] = raw; + key_debounce[i] = 0; + } + } + + /* 状态机 */ + key_prev[i] = key_current[i]; /* 保存上一帧 (在更新前) */ + + if (key_current[i]) { + /* 按键按下 */ + if (key_state[i] == KEY_STATE_IDLE) { + key_state[i] = KEY_STATE_PRESS; + key_press_time[i] = sys_tick_ms; + } else if (key_state[i] == KEY_STATE_PRESS) { + if (sys_tick_ms - key_press_time[i] >= KEY_LONG_PRESS_MS) { + key_state[i] = KEY_STATE_HOLD; + } + } + } else { + /* 按键释放 */ + if (key_state[i] == KEY_STATE_PRESS || key_state[i] == KEY_STATE_HOLD) { + key_state[i] = KEY_STATE_RELEASE; + } else { + key_state[i] = KEY_STATE_IDLE; + } + } + + key_values[i] = key_current[i]; + } + + /* ---- ADC 读取 (轮询单通道) ---- */ + static uint8_t adc_scan_idx = 0; + /* 配置当前通道并读取 */ + ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.Channel = adc_channel_map[adc_scan_idx]; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; + HAL_ADC_ConfigChannel(&hadc2, &sConfig); + + HAL_ADC_Start(&hadc2); + if (HAL_ADC_PollForConversion(&hadc2, 5) == HAL_OK) { + adc_values[adc_scan_idx] = HAL_ADC_GetValue(&hadc2); + } + HAL_ADC_Stop(&hadc2); + + adc_scan_idx++; + if (adc_scan_idx >= ADC_CHANNEL_COUNT) adc_scan_idx = 0; +} + +/* ---- 按键查询 ---- */ +uint8_t Input_GetKey(void) { + for (uint8_t i = 0; i < 4; i++) { + if (key_state[i] == KEY_STATE_PRESS) { + key_state[i] = KEY_STATE_IDLE; /* 消费事件 */ + return i; + } + } + return KEY_NONE; +} + +uint8_t Input_GetKeyState(uint8_t key) { + if (key > 3) return KEY_STATE_IDLE; + return key_state[key]; +} + +uint8_t Input_IsKeyPressed(uint8_t key) { + if (key > 3) return 0; + if (key_state[key] == KEY_STATE_PRESS) { + key_state[key] = KEY_STATE_IDLE; + return 1; + } + return 0; +} + +uint8_t Input_IsKeyHeld(uint8_t key) { + if (key > 3) return 0; + return (key_state[key] == KEY_STATE_HOLD) ? 1 : 0; +} + +uint8_t Input_IsKeyReleased(uint8_t key) { + if (key > 3) return 0; + if (key_state[key] == KEY_STATE_RELEASE) { + key_state[key] = KEY_STATE_IDLE; + return 1; + } + return 0; +} + +/* ---- ADC 查询 ---- */ +uint16_t Input_GetADC(uint8_t ch) { + if (ch >= ADC_CHANNEL_COUNT) return 0; + return adc_values[ch]; +} + +uint16_t Input_GetADC_Percent(uint8_t ch) { + if (ch >= ADC_CHANNEL_COUNT) return 0; + uint32_t val = adc_values[ch]; + return (uint16_t)(val * 1000 / ADC_RAW_MAX); +} + +void Input_ReadAllADC(void) { + /* 已在 Input_Scan 中轮询完成 */ +} + +/* ---- 引脚编码解码 ---- */ +GPIO_TypeDef* Config_GetPort(uint16_t pin_code) { + uint8_t port = (pin_code >> 8) & 0x0F; + switch (port) { + case 0: return GPIOA; + case 1: return GPIOB; + case 2: return GPIOC; + case 3: return GPIOD; + default: return GPIOA; + } +} + +uint16_t Config_GetPin(uint16_t pin_code) { + return (uint16_t)1 << (pin_code & 0x0F); +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 89e11c9..f39b518 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -2,17 +2,23 @@ /** ****************************************************************************** * @file : main.c - * @brief : Main program body + * @brief : 萝莉3代航模遥控器 - 主程序 + * @author : 小云 (Hermes Agent) + * @date : 2026-06-25 ****************************************************************************** - * @attention - * - * Copyright (c) 2026 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. + * 系统架构: + * - 10ms 定时循环: 按键扫描 + ADC 轮询 + LED 更新 + * - 主循环: 混控计算 + 菜单 UI + 协议收发 + * - 中断: SysTick (时基), EXTI (NRF IRQ), UART (SBUS) * + * 模块依赖: + * oled.h -> OLED SSD1306 128x64 显示 + * input.h -> 按键/ADC 输入采集 + * menu.h -> 菜单系统与 UI 交互 + * storage.h -> Flash 存储 (模型/配置) + * pwm_out.h -> PWM/LED/WS2812 输出 + * nrf24l01.h-> NRF24L01+ 2.4G 无线 + * protocol.h-> 协议层 (RF/SBUS/USB HID) ****************************************************************************** */ /* USER CODE END Header */ @@ -26,6 +32,15 @@ #include "usb.h" #include "gpio.h" +/* 应用层模块 */ +#include "oled.h" +#include "input.h" +#include "menu.h" +#include "storage.h" +#include "pwm_out.h" +#include "nrf24l01.h" +#include "protocol.h" + /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -38,7 +53,7 @@ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ - +#define MAIN_LOOP_PERIOD_MS 10 /* 主循环周期 10ms */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ @@ -49,13 +64,14 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ - +static uint32_t last_loop_tick = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ - +static void System_Init(void); +static void System_Loop10ms(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -69,7 +85,6 @@ void SystemClock_Config(void); */ int main(void) { - /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ @@ -101,8 +116,10 @@ int main(void) MX_USB_PCD_Init(); MX_TIM3_Init(); MX_TIM4_Init(); - /* USER CODE BEGIN 2 */ + /* USER CODE BEGIN 2 */ + /* ---- 应用层初始化 ---- */ + System_Init(); /* USER CODE END 2 */ /* Infinite loop */ @@ -112,6 +129,18 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + uint32_t now = HAL_GetTick(); + + /* 10ms 定时任务 */ + if (now - last_loop_tick >= MAIN_LOOP_PERIOD_MS) { + last_loop_tick = now; + System_Loop10ms(); + } + + /* 实时任务: 混控 + 菜单 + 协议 */ + Mixer_Compute(g_channels); + Menu_Run(); + Protocol_Run(); } /* USER CODE END 3 */ } @@ -165,6 +194,67 @@ void SystemClock_Config(void) /* USER CODE BEGIN 4 */ +/** + * @brief 系统初始化: 加载配置、初始化各模块、显示开机画面 + * @retval None + */ +static void System_Init(void) { + /* 1. 加载存储配置 */ + Storage_Init(); + Storage_Load(); + + /* 2. 初始化 OLED 并显示开机画面 */ + OLED_Init(); + OLED_DrawBitmap(0, 0, bitmap_bytes, 64, 64); /* 开机 Logo */ + OLED_ShowString(70, 20, "Loli3", 16); + OLED_ShowString(70, 40, "RC v3.0", 6); + OLED_Display(); + HAL_Delay(2000); /* 显示 2 秒 */ + + /* 3. 初始化输入模块 */ + Input_Init(); + + /* 4. 初始化 PWM/LED */ + PWM_Init(); + LED_SetSystem(1); /* 系统 LED 常亮 */ + + /* 5. 初始化 NRF24L01 */ + NRF24L01_Init(); + if (NRF24L01_Check()) { + /* NRF24L01 存在 */ + NRF24L01_SetChannel(g_config.nrf_channel); + LED_SetNRF(0); /* 慢闪 = 未连接 */ + } else { + /* NRF24L01 未检测到 */ + LED_SetNRF(3); /* 灭 */ + } + + /* 6. 初始化协议层 */ + Protocol_Init(); + + /* 7. 初始化菜单 */ + Menu_Init(); + + /* 8. 根据配置设置 PWM 模式 */ + PWM_SetMode(0, g_config.pwm1_mode); + PWM_SetMode(1, g_config.pwm2_mode); + PWM_SetWS2812Mode(g_config.ws2812_effect); + PWM_SetLEDBrightness(g_config.led_brightness); + PWM_SetVibrateLevel(g_config.vibrate_level); +} + +/** + * @brief 10ms 定时任务: 按键扫描 + ADC 轮询 + LED 闪烁更新 + * @retval None + */ +static void System_Loop10ms(void) { + /* 按键 + ADC 扫描 */ + Input_Scan(); + + /* LED 闪烁更新 */ + LED_Update(); +} + /* USER CODE END 4 */ /** @@ -174,13 +264,17 @@ void SystemClock_Config(void) void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ + /* 错误时 LED 快闪 */ __disable_irq(); while (1) { + /* 系统 LED 快闪指示错误 */ + HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6); + for (volatile uint32_t i = 0; i < 500000; i++); } /* USER CODE END Error_Handler_Debug */ } + #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number diff --git a/Core/Src/menu.c b/Core/Src/menu.c new file mode 100644 index 0000000..7078e3c --- /dev/null +++ b/Core/Src/menu.c @@ -0,0 +1,738 @@ +/** + * 菜单系统实现 + * 基于 OLED 128x64 的层级菜单 UI + */ +#include "menu.h" +#include +#include + +/* 全局页面状态 */ +Page_t g_page; + +/* 通道输出值 (混控后) */ +int16_t g_channels[CHANNEL_COUNT]; + +/* 模型类型名称 */ +static const char *model_types[] = {"Airplane", "Car", "Boat", "MultiRotor"}; + +/* 输入名称缓存 */ +static char input_name_buf[16]; + +/* 获取输入名称 */ +static const char* GetInputName(uint8_t idx, uint8_t type) { + if (type == INPUT_TYPE_ADC) { + snprintf(input_name_buf, sizeof(input_name_buf), "ADC_IN%d", idx); + } else if (type == INPUT_TYPE_KEY) { + snprintf(input_name_buf, sizeof(input_name_buf), "KEY_IN%d", idx); + } else { + snprintf(input_name_buf, sizeof(input_name_buf), "None"); + } + return input_name_buf; +} + +/* 获取通道值显示 */ +static const char* GetChannelValue(uint8_t ch) { + Model_t *m = Storage_GetActiveModel(); + if (m->input_type[ch] == INPUT_TYPE_ADC) { + snprintf(input_name_buf, sizeof(input_name_buf), "%4d", + adc_values[m->channel_map[ch]]); + } else if (m->input_type[ch] == INPUT_TYPE_KEY) { + snprintf(input_name_buf, sizeof(input_name_buf), "%s", + key_values[m->channel_map[ch]] ? "ON " : "OFF"); + } else { + snprintf(input_name_buf, sizeof(input_name_buf), "----"); + } + return input_name_buf; +} + +void Menu_Init(void) { + memset(&g_page, 0, sizeof(Page_t)); + g_page.page_id = PAGE_HOME; + g_page.cursor = 0; +} + +/* ---- 混控计算 ---- */ +void Mixer_Compute(int16_t *channels) { + Model_t *m = Storage_GetActiveModel(); + + for (uint8_t i = 0; i < CHANNEL_COUNT; i++) { + if (m->input_type[i] == INPUT_TYPE_NONE) { + channels[i] = 0; + continue; + } + + int16_t raw = 0; + if (m->input_type[i] == INPUT_TYPE_ADC) { + /* ADC: 0-4095 -> -1000 ~ +1000 */ + raw = (int16_t)(adc_values[m->channel_map[i]]) - 2048; + raw = raw * 1000 / 2048; + } else { + /* 按键: 0/1 -> -1000/+1000 */ + raw = key_values[m->channel_map[i]] ? 1000 : -1000; + } + + /* 应用混控 */ + switch (m->mixer_type[i]) { + case MIXER_TYPE_SIMPLE: + channels[i] = (raw * m->mixer_scale[i] / 100) + m->mixer_offset[i]; + break; + case MIXER_TYPE_DELTA: + /* 三角翼: CH1=elevon_left, CH2=elevon_right */ + if (i == 0) channels[i] = (raw * m->mixer_scale[i] / 100) + m->mixer_offset[i]; + if (i == 1) channels[i] = (-raw * m->mixer_scale[i] / 100) + m->mixer_offset[i]; + break; + case MIXER_TYPE_VTAIL: + channels[i] = (raw * m->mixer_scale[i] / 100) + m->mixer_offset[i]; + break; + case MIXER_TYPE_ELEVON: + channels[i] = (raw * m->mixer_scale[i] / 100) + m->mixer_offset[i]; + break; + default: + channels[i] = raw; + break; + } + + /* 限幅 */ + if (channels[i] > 1000) channels[i] = 1000; + if (channels[i] < -1000) channels[i] = -1000; + } +} + +/* ---- 通用菜单导航 ---- */ +static void Menu_Navigate(void) { + uint8_t key = Input_GetKey(); + + if (key == KEY_UP) { + if (g_page.cursor > 0) g_page.cursor--; + } else if (key == KEY_DOWN) { + if (g_page.cursor < g_page.item_count - 1) g_page.cursor++; + } else if (key == KEY_OK) { + /* 执行选中项 */ + if (g_page.cursor < g_page.item_count && g_page.items[g_page.cursor].target_page != 0xFF) { + g_page.page_id = g_page.items[g_page.cursor].target_page; + g_page.cursor = 0; + g_page.item_count = 0; + } + if (g_page.cursor < g_page.item_count && g_page.items[g_page.cursor].action) { + g_page.items[g_page.cursor].action(); + } + } else if (key == KEY_BACK) { + /* 返回上一级 */ + if (g_page.page_id == PAGE_HOME) { + /* 首页按返回: 切换值/回传 */ + g_config.home_page = !g_config.home_page; + } else if (g_page.page_id == PAGE_MAIN_MENU) { + g_page.page_id = PAGE_HOME; + } else if (g_page.page_id >= PAGE_MODEL_LIST && g_page.page_id <= PAGE_MIXER_EDIT) { + g_page.page_id = PAGE_MAIN_MENU; + } else { + g_page.page_id = PAGE_MAIN_MENU; + } + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 首页 ---- */ +void Menu_DrawHome(void) { + OLED_Clear(); + + if (g_config.home_page == 0) { + /* 回传信息页 */ + OLED_ShowString(0, 0, "Telemetry", 6); + OLED_DrawLine(0, 9, 127, 9); + + /* 电压 */ + OLED_ShowString(0, 14, "V:", 6); + OLED_ShowNum(18, 14, 0, 4, 6); /* TODO: 实际电压 */ + OLED_ShowString(48, 14, "V", 6); + + /* RSSI */ + OLED_ShowString(0, 24, "RSSI:", 6); + OLED_ShowNum(36, 24, 0, 3, 6); + + /* 丢包率 */ + OLED_ShowString(0, 34, "Lost:", 6); + OLED_ShowNum(36, 34, 0, 3, 6); + OLED_ShowString(60, 34, "%", 6); + + /* 模型名 */ + Model_t *m = Storage_GetActiveModel(); + OLED_ShowString(0, 48, m->name, 6); + + /* 高频头状态 */ + OLED_ShowString(80, 48, g_config.rf_type == 0 ? "NRF" : "CRFS", 6); + OLED_ShowString(80, 56, nrf_connected ? "OK" : "--", 6); + } else { + /* INx 值页 */ + OLED_ShowString(0, 0, "ADC Values", 6); + OLED_DrawLine(0, 9, 127, 9); + + Model_t *m = Storage_GetActiveModel(); + for (uint8_t i = 0; i < 8; i++) { + uint8_t row = i / 2; + uint8_t col = (i % 2) * 64; + OLED_ShowString(col, 12 + row * 12, "IN", 6); + OLED_ShowNum(col + 12, 12 + row * 12, i, 2, 6); + OLED_ShowString(col + 24, 12 + row * 12, ":", 6); + if (m->input_type[i] == INPUT_TYPE_ADC) { + OLED_ShowNum(col + 30, 12 + row * 12, + adc_values[m->channel_map[i]], 4, 6); + } else { + OLED_ShowString(col + 30, 12 + row * 12, + key_values[m->channel_map[i]] ? "ON " : "OFF", 6); + } + } + } + + OLED_Display(); + Menu_Navigate(); + + /* 首页长按确认 -> 高频头快捷页 */ + if (Input_IsKeyHeld(KEY_OK)) { + g_page.page_id = PAGE_RF_QUICK; + g_page.cursor = 0; + g_page.item_count = 0; + } + + /* 长按返回 2s -> 休眠 */ + if (Input_IsKeyHeld(KEY_BACK)) { + /* TODO: 进入休眠模式 */ + } +} + +/* ---- 主菜单 ---- */ +void Menu_DrawMainMenu(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Main Menu", 16); + OLED_DrawLine(0, 17, 127, 17); + + static const char *items[] = { + "Model Select", + "RF Config", + "Channel Map", + "Mixer", + "PWM Driver", + "Home Page" + }; + g_page.item_count = 6; + + for (uint8_t i = 0; i < g_page.item_count; i++) { + uint8_t y = 20 + i * 10; + if (i == g_page.cursor) { + OLED_ShowString(0, y, ">", 6); + } + OLED_ShowString(8, y, items[i], 6); + } + + OLED_Display(); + Menu_Navigate(); + + /* 映射到具体页面 */ + if (Input_IsKeyPressed(KEY_OK)) { + switch (g_page.cursor) { + case 0: g_page.page_id = PAGE_MODEL_LIST; break; + case 1: g_page.page_id = PAGE_RF_CONFIG; break; + case 2: g_page.page_id = PAGE_CHANNEL_MAP; break; + case 3: g_page.page_id = PAGE_MIXER; break; + case 4: g_page.page_id = PAGE_PWM_CONFIG; break; + case 5: g_page.page_id = PAGE_HOME_SET; break; + } + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 模型列表 ---- */ +void Menu_DrawModelList(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Models", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 0; + /* 第一项: 新建 */ + OLED_ShowString(0, 20, g_page.cursor == 0 ? ">[New]" : " [New]", 6); + g_page.item_count++; + + for (uint8_t i = 0; i < MODEL_MAX_COUNT; i++) { + if (g_config.models[i].name[0] != '\0') { + uint8_t y = 20 + g_page.item_count * 10; + if (y > 54) break; /* 超出屏幕 */ + char buf[20]; + snprintf(buf, sizeof(buf), "%s[%c] %s", + g_page.cursor == g_page.item_count ? ">" : " ", + i == g_config.active_model ? '*' : ' ', + g_config.models[i].name); + OLED_ShowString(0, y, buf, 6); + g_page.item_count++; + } + } + + OLED_Display(); + Menu_Navigate(); + + /* 处理选择 */ + if (Input_IsKeyPressed(KEY_OK)) { + if (g_page.cursor == 0) { + /* 新建模型 */ + g_page.page_id = PAGE_MODEL_NEW; + g_page.cursor = 0; + g_page.edit_idx = 0; + g_page.edit_str_len = 0; + memset(g_page.edit_str, 0, sizeof(g_page.edit_str)); + } else { + /* 选择模型 */ + uint8_t model_idx = 0xFF; + uint8_t cnt = 1; + for (uint8_t i = 0; i < MODEL_MAX_COUNT; i++) { + if (g_config.models[i].name[0] != '\0') { + if (cnt == g_page.cursor) { model_idx = i; break; } + cnt++; + } + } + if (model_idx != 0xFF) { + Storage_ModelSelect(model_idx); + g_page.page_id = PAGE_MAIN_MENU; + } + } + g_page.cursor = 0; + g_page.item_count = 0; + } + + /* 长按确认 -> 编辑/删除 */ + if (Input_IsKeyHeld(KEY_OK) && g_page.cursor > 0) { + /* TODO: 弹出编辑/删除选项 */ + } +} + +/* ---- 新建模型 ---- */ +void Menu_DrawModelNew(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "New Model", 16); + OLED_DrawLine(0, 17, 127, 17); + + /* 名称编辑 */ + OLED_ShowString(0, 22, "Name:", 6); + OLED_ShowString(36, 22, g_page.edit_str, 6); + if (g_page.edit_idx == 0) { + /* 闪烁光标 */ + OLED_ShowString(36 + g_page.edit_str_len * 6, 22, "_", 6); + } + + /* 类型选择 */ + OLED_ShowString(0, 34, "Type:", 6); + OLED_ShowString(36, 34, (char*)model_types[g_page.edit_value], 6); + + /* 按钮 */ + OLED_ShowString(20, 50, "[OK]", 6); + OLED_ShowString(80, 50, "[Cancel]", 6); + + OLED_Display(); + + /* 处理输入 */ + uint8_t key = Input_GetKey(); + if (g_page.edit_idx == 0) { + /* 编辑名称 */ + if (key == KEY_UP) { + /* 字符递增 */ + if (g_page.edit_str_len < 8) { + g_page.edit_str[g_page.edit_str_len] = 'A'; + g_page.edit_str_len++; + } + } else if (key == KEY_DOWN) { + if (g_page.edit_str_len > 0) { + g_page.edit_str_len--; + g_page.edit_str[g_page.edit_str_len] = '\0'; + } + } else if (key == KEY_OK) { + g_page.edit_idx = 1; /* 切换到类型选择 */ + } + } else if (g_page.edit_idx == 1) { + if (key == KEY_UP && g_page.edit_value < 3) g_page.edit_value++; + if (key == KEY_DOWN && g_page.edit_value > 0) g_page.edit_value--; + if (key == KEY_OK) g_page.edit_idx = 2; /* 到确认按钮 */ + } else if (g_page.edit_idx == 2) { + /* 确认/取消 */ + if (key == KEY_UP || key == KEY_DOWN) g_page.edit_idx = (g_page.edit_idx == 2) ? 3 : 2; + if (key == KEY_OK) { + if (g_page.edit_idx == 2) { + /* 确认创建 */ + Storage_ModelAdd(g_page.edit_str, g_page.edit_value); + g_page.page_id = PAGE_MODEL_LIST; + } else { + g_page.page_id = PAGE_MODEL_LIST; + } + g_page.cursor = 0; + g_page.item_count = 0; + } + } + + if (key == KEY_BACK) { + g_page.page_id = PAGE_MODEL_LIST; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 通道映射 ---- */ +void Menu_DrawChannelMap(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Channel Map", 16); + OLED_DrawLine(0, 17, 127, 17); + + Model_t *m = Storage_GetActiveModel(); + g_page.item_count = CHANNEL_COUNT + 1; /* +1 for [Next] */ + + uint8_t start = g_page.scroll_offset; + for (uint8_t i = start; i < start + 4 && i < CHANNEL_COUNT; i++) { + uint8_t y = 20 + (i - start) * 10; + char buf[32]; + snprintf(buf, sizeof(buf), "%s[CH%d]->[%s]", + i == g_page.cursor ? ">" : " ", + i + 1, + GetInputName(m->channel_map[i], m->input_type[i])); + OLED_ShowString(0, y, buf, 6); + } + + /* [下一步] 按钮 */ + if (g_page.cursor >= CHANNEL_COUNT - 4) { + OLED_ShowString(40, 56, "[Next]", 6); + } + + OLED_Display(); + Menu_Navigate(); + + /* 编辑通道映射 */ + if (Input_IsKeyPressed(KEY_OK) && g_page.cursor < CHANNEL_COUNT) { + /* 循环切换输入源 */ + m->input_type[g_page.cursor]++; + if (m->input_type[g_page.cursor] > INPUT_TYPE_KEY) + m->input_type[g_page.cursor] = INPUT_TYPE_ADC; + } + + /* 下一步 */ + if (Input_IsKeyPressed(KEY_OK) && g_page.cursor == CHANNEL_COUNT) { + g_page.page_id = PAGE_MIXER; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 混控列表 ---- */ +void Menu_DrawMixer(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Mixer", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = CHANNEL_COUNT + 1; + + uint8_t start = g_page.scroll_offset; + for (uint8_t i = start; i < start + 4 && i < CHANNEL_COUNT; i++) { + uint8_t y = 20 + (i - start) * 10; + char buf[20]; + snprintf(buf, sizeof(buf), "%s[CH%d]: %4d", + i == g_page.cursor ? ">" : " ", + i + 1, g_channels[i]); + OLED_ShowString(0, y, buf, 6); + } + + if (g_page.cursor >= CHANNEL_COUNT - 4) { + OLED_ShowString(40, 56, "[Next]", 6); + } + + OLED_Display(); + Menu_Navigate(); + + if (Input_IsKeyPressed(KEY_OK) && g_page.cursor < CHANNEL_COUNT) { + g_page.page_id = PAGE_MIXER_EDIT; + g_page.edit_idx = g_page.cursor; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 混控编辑 ---- */ +void Menu_DrawMixerEdit(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Mixer Edit", 16); + OLED_DrawLine(0, 17, 127, 17); + + Model_t *m = Storage_GetActiveModel(); + uint8_t ch = g_page.edit_idx; + + char buf[32]; + snprintf(buf, sizeof(buf), "CH%d Mixer", ch + 1); + OLED_ShowString(0, 20, buf, 6); + + /* 混控类型 */ + static const char *mixer_names[] = {"None", "Simple", "Delta", "V-Tail", "Elevon"}; + snprintf(buf, sizeof(buf), "Type: %s", mixer_names[m->mixer_type[ch]]); + OLED_ShowString(0, 30, buf, 6); + + /* 比例 */ + snprintf(buf, sizeof(buf), "Scale: %d%%", m->mixer_scale[ch]); + OLED_ShowString(0, 40, buf, 6); + + /* 偏移 */ + snprintf(buf, sizeof(buf), "Offset: %d", m->mixer_offset[ch]); + OLED_ShowString(0, 50, buf, 6); + + OLED_Display(); + + uint8_t key = Input_GetKey(); + if (key == KEY_UP) { + if (g_page.cursor == 0) { + m->mixer_type[ch]++; + if (m->mixer_type[ch] > MIXER_TYPE_ELEVON) m->mixer_type[ch] = MIXER_TYPE_NONE; + } else if (g_page.cursor == 1) { + m->mixer_scale[ch] += 5; + if (m->mixer_scale[ch] > 200) m->mixer_scale[ch] = 200; + } else if (g_page.cursor == 2) { + m->mixer_offset[ch] += 10; + } + } else if (key == KEY_DOWN) { + if (g_page.cursor == 0) { + if (m->mixer_type[ch] > 0) m->mixer_type[ch]--; + } else if (g_page.cursor == 1) { + m->mixer_scale[ch] -= 5; + if (m->mixer_scale[ch] < 0) m->mixer_scale[ch] = 0; + } else if (g_page.cursor == 2) { + m->mixer_offset[ch] -= 10; + } + } else if (key == KEY_OK) { + g_page.cursor++; + if (g_page.cursor > 2) g_page.cursor = 0; + } else if (key == KEY_BACK) { + g_page.page_id = PAGE_MIXER; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 高频头配置 ---- */ +void Menu_DrawRFConfig(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "RF Config", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 2; + + OLED_ShowString(0, 22, g_page.cursor == 0 ? ">[NRF24]" : " [NRF24]", 6); + OLED_ShowString(0, 34, g_page.cursor == 1 ? ">[CRFS]" : " [CRFS]", 6); + + OLED_Display(); + Menu_Navigate(); + + if (Input_IsKeyPressed(KEY_OK)) { + if (g_page.cursor == 0) { + g_config.rf_type = 0; + g_page.page_id = PAGE_NRF_CONFIG; + } else { + g_config.rf_type = 1; + g_page.page_id = PAGE_CRFS_CONFIG; + } + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- NRF24 配置 ---- */ +void Menu_DrawNRFConfig(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "NRF24 Config", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 5; + + char buf[32]; + snprintf(buf, sizeof(buf), "%sPhrase: %s", + g_page.cursor == 0 ? ">" : " ", g_config.nrf_phrase); + OLED_ShowString(0, 20, buf, 6); + + snprintf(buf, sizeof(buf), "%sChannel: %d", + g_page.cursor == 1 ? ">" : " ", g_config.nrf_channel); + OLED_ShowString(0, 30, buf, 6); + + snprintf(buf, sizeof(buf), "%sAddr: %02X%02X%02X%02X%02X", + g_page.cursor == 2 ? ">" : " ", + g_config.nrf_addr[0], g_config.nrf_addr[1], + g_config.nrf_addr[2], g_config.nrf_addr[3], + g_config.nrf_addr[4]); + OLED_ShowString(0, 40, buf, 6); + + static const char *rates[] = {"250K", "1M", "2M"}; + snprintf(buf, sizeof(buf), "%sRate: %s", + g_page.cursor == 3 ? ">" : " ", rates[g_config.nrf_rate]); + OLED_ShowString(0, 50, buf, 6); + + snprintf(buf, sizeof(buf), "%sPower: %d", + g_page.cursor == 4 ? ">" : " ", g_config.nrf_power); + OLED_ShowString(0, 60, buf, 6); + + OLED_Display(); + Menu_Navigate(); +} + +/* ---- CRFS 配置 ---- */ +void Menu_DrawCRFSConfig(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "CRFS Config", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 3; + + char buf[32]; + snprintf(buf, sizeof(buf), "%sPkt Rate: %dHz", + g_page.cursor == 0 ? ">" : " ", g_config.crfs_packet_rate); + OLED_ShowString(0, 22, buf, 6); + + snprintf(buf, sizeof(buf), "%sTelem: 1:%d", + g_page.cursor == 1 ? ">" : " ", g_config.crfs_telemetry_ratio); + OLED_ShowString(0, 34, buf, 6); + + snprintf(buf, sizeof(buf), "%sPower: %dmW", + g_page.cursor == 2 ? ">" : " ", g_config.crfs_power); + OLED_ShowString(0, 46, buf, 6); + + OLED_Display(); + Menu_Navigate(); +} + +/* ---- PWM 配置 ---- */ +void Menu_DrawPWMConfig(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "PWM Config", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 5; + + static const char *pwm_modes[] = {"Disabled", "WS2812", "LED", "Vibrate"}; + char buf[32]; + + snprintf(buf, sizeof(buf), "%sPWM1: %s", + g_page.cursor == 0 ? ">" : " ", pwm_modes[g_config.pwm1_mode]); + OLED_ShowString(0, 20, buf, 6); + + snprintf(buf, sizeof(buf), "%sPWM2: %s", + g_page.cursor == 1 ? ">" : " ", pwm_modes[g_config.pwm2_mode]); + OLED_ShowString(0, 30, buf, 6); + + snprintf(buf, sizeof(buf), "%sWS2812 Effect: %d", + g_page.cursor == 2 ? ">" : " ", g_config.ws2812_effect); + OLED_ShowString(0, 40, buf, 6); + + snprintf(buf, sizeof(buf), "%sLED Bright: %d%%", + g_page.cursor == 3 ? ">" : " ", g_config.led_brightness); + OLED_ShowString(0, 50, buf, 6); + + snprintf(buf, sizeof(buf), "%sVibrate: Lv%d", + g_page.cursor == 4 ? ">" : " ", g_config.vibrate_level); + OLED_ShowString(0, 60, buf, 6); + + OLED_Display(); + Menu_Navigate(); +} + +/* ---- 首页设置 ---- */ +void Menu_DrawHomeSet(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Home Page", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 2; + + OLED_ShowString(0, 25, g_page.cursor == 0 ? ">Telemetry" : " Telemetry", 6); + OLED_ShowString(0, 37, g_page.cursor == 1 ? ">INx Values" : " INx Values", 6); + + OLED_Display(); + Menu_Navigate(); + + if (Input_IsKeyPressed(KEY_OK)) { + g_config.home_page = g_page.cursor; + g_page.page_id = PAGE_MAIN_MENU; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 对频页 ---- */ +void Menu_DrawBind(void) { + OLED_Clear(); + OLED_ShowString(0, 0, "Binding...", 16); + OLED_DrawLine(0, 17, 127, 17); + + OLED_ShowString(0, 30, "Scanning channels", 6); + OLED_DrawProgressBar(10, 45, 108, 8, 50); /* 示例进度 */ + + OLED_Display(); + Menu_Navigate(); +} + +/* ---- 高频头快捷页 ---- */ +void Menu_DrawRFQuick(void) { + OLED_Clear(); + + if (g_config.rf_type == 0) { + OLED_ShowString(0, 0, "NRF24 Quick", 16); + OLED_DrawLine(0, 17, 127, 17); + + g_page.item_count = 3; + + char buf[32]; + snprintf(buf, sizeof(buf), "%s[Bind]", + g_page.cursor == 0 ? ">" : " "); + OLED_ShowString(0, 22, buf, 6); + + snprintf(buf, sizeof(buf), "%sCh: %d", + g_page.cursor == 1 ? ">" : " ", g_config.nrf_channel); + OLED_ShowString(0, 34, buf, 6); + + snprintf(buf, sizeof(buf), "%sAddr: %02X%02X%02X%02X%02X", + g_page.cursor == 2 ? ">" : " ", + g_config.nrf_addr[0], g_config.nrf_addr[1], + g_config.nrf_addr[2], g_config.nrf_addr[3], + g_config.nrf_addr[4]); + OLED_ShowString(0, 46, buf, 6); + } else { + OLED_ShowString(0, 0, "CRFS Quick", 16); + OLED_DrawLine(0, 17, 127, 17); + OLED_ShowString(0, 30, "CRFS mode active", 6); + } + + OLED_Display(); + Menu_Navigate(); + + if (Input_IsKeyPressed(KEY_OK) && g_page.cursor == 0) { + /* 进入对频模式 */ + g_page.page_id = PAGE_BIND; + g_page.cursor = 0; + g_page.item_count = 0; + } + + if (Input_IsKeyPressed(KEY_BACK)) { + g_page.page_id = PAGE_HOME; + g_page.cursor = 0; + g_page.item_count = 0; + } +} + +/* ---- 主运行循环 ---- */ +void Menu_Run(void) { + switch (g_page.page_id) { + case PAGE_HOME: Menu_DrawHome(); break; + case PAGE_MAIN_MENU: Menu_DrawMainMenu(); break; + case PAGE_MODEL_LIST: Menu_DrawModelList(); break; + case PAGE_MODEL_NEW: Menu_DrawModelNew(); break; + case PAGE_CHANNEL_MAP: Menu_DrawChannelMap(); break; + case PAGE_MIXER: Menu_DrawMixer(); break; + case PAGE_MIXER_EDIT: Menu_DrawMixerEdit(); break; + case PAGE_RF_CONFIG: Menu_DrawRFConfig(); break; + case PAGE_NRF_CONFIG: Menu_DrawNRFConfig(); break; + case PAGE_CRFS_CONFIG: Menu_DrawCRFSConfig(); break; + case PAGE_PWM_CONFIG: Menu_DrawPWMConfig(); break; + case PAGE_HOME_SET: Menu_DrawHomeSet(); break; + case PAGE_BIND: Menu_DrawBind(); break; + case PAGE_RF_QUICK: Menu_DrawRFQuick(); break; + default: g_page.page_id = PAGE_HOME; break; + } +} diff --git a/Core/Src/nrf24l01.c b/Core/Src/nrf24l01.c new file mode 100644 index 0000000..9f526b1 --- /dev/null +++ b/Core/Src/nrf24l01.c @@ -0,0 +1,246 @@ +/** + * NRF24L01+ 驱动实现 + */ +#include "nrf24l01.h" +#include + +/* 全局状态 */ +uint8_t nrf_connected = 0; +uint8_t nrf_bind_phrase[7] = "LOVE"; +uint8_t nrf_channel = 40; +uint8_t nrf_tx_addr[NRF_ADDR_WIDTH] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; + +/* ---- 低层 SPI 操作 ---- */ +static void NRF_SPI_CS(uint8_t level) { + if (level) NRF_CSN_H(); else NRF_CSN_L(); +} + +static uint8_t NRF_SPI_Transfer(uint8_t dat) { + uint8_t rx; + HAL_SPI_TransmitReceive(&hspi1, &dat, &rx, 1, 10); + return rx; +} + +uint8_t NRF24L01_ReadReg(uint8_t reg) { + uint8_t val; + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_R_REGISTER | reg); + val = NRF_SPI_Transfer(0xFF); + NRF_SPI_CS(1); + return val; +} + +void NRF24L01_WriteReg(uint8_t reg, uint8_t value) { + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_W_REGISTER | reg); + NRF_SPI_Transfer(value); + NRF_SPI_CS(1); +} + +void NRF24L01_ReadBuf(uint8_t reg, uint8_t *buf, uint8_t len) { + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_R_REGISTER | reg); + for (uint8_t i = 0; i < len; i++) + buf[i] = NRF_SPI_Transfer(0xFF); + NRF_SPI_CS(1); +} + +void NRF24L01_WriteBuf(uint8_t reg, const uint8_t *buf, uint8_t len) { + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_W_REGISTER | reg); + for (uint8_t i = 0; i < len; i++) + NRF_SPI_Transfer(buf[i]); + NRF_SPI_CS(1); +} + +/* ---- 初始化 ---- */ +void NRF24L01_Init(void) { + NRF_CE_L(); + NRF_CSN_H(); + + /* 上电延时 */ + HAL_Delay(100); + + /* 配置寄存器 */ + NRF24L01_WriteReg(NRF_CONFIG, 0x0E); /* EN_CRC, CRC0, PWR_UP, PTX */ + NRF24L01_WriteReg(NRF_EN_AA, 0x01); /* pipe0 auto ACK */ + NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01); /* pipe0 enable */ + NRF24L01_WriteReg(NRF_SETUP_AW, 0x03); /* 5 bytes address */ + NRF24L01_WriteReg(NRF_SETUP_RETR, 0x1A); /* 500us + 15 retries */ + NRF24L01_WriteReg(NRF_RF_CH, nrf_channel); + NRF24L01_WriteReg(NRF_RF_SETUP, NRF_RATE_1M | NRF_PA_MAX); + NRF24L01_WriteReg(NRF_RX_PW_P0, 32); /* payload = 32 bytes */ + NRF24L01_WriteReg(NRF_FIFO_STATUS, 0x11); /* clear FIFO */ + + /* 设置地址 */ + NRF24L01_SetTXAddr(nrf_tx_addr); + NRF24L01_SetRXAddr(0, nrf_tx_addr); + + /* 清空 FIFO */ + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_FLUSH_TX); + NRF_SPI_CS(1); + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_FLUSH_RX); + NRF_SPI_CS(1); + + /* 清除状态 */ + NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT); + + NRF_CE_L(); +} + +uint8_t NRF24L01_Check(void) { + uint8_t buf[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5}; + uint8_t rx[5]; + NRF24L01_WriteBuf(NRF_TX_ADDR, buf, 5); + NRF24L01_ReadBuf(NRF_TX_ADDR, rx, 5); + for (uint8_t i = 0; i < 5; i++) + if (rx[i] != 0xA5) return 0; + return 1; +} + +/* ---- 配置 ---- */ +void NRF24L01_SetChannel(uint8_t ch) { + if (ch > NRF_MAX_CHANNEL) ch = NRF_MAX_CHANNEL; + nrf_channel = ch; + NRF24L01_WriteReg(NRF_RF_CH, ch); +} + +void NRF24L01_SetRate(uint8_t rate) { + uint8_t rf = NRF24L01_ReadReg(NRF_RF_SETUP); + rf &= ~0x28; + rf |= (rate & 0x28); + NRF24L01_WriteReg(NRF_RF_SETUP, rf); +} + +void NRF24L01_SetPower(uint8_t power) { + uint8_t rf = NRF24L01_ReadReg(NRF_RF_SETUP); + rf &= ~0x06; + rf |= (power & 0x06); + NRF24L01_WriteReg(NRF_RF_SETUP, rf); +} + +void NRF24L01_SetTXAddr(const uint8_t *addr) { + memcpy(nrf_tx_addr, addr, NRF_ADDR_WIDTH); + NRF24L01_WriteBuf(NRF_TX_ADDR, addr, NRF_ADDR_WIDTH); +} + +void NRF24L01_SetRXAddr(uint8_t pipe, const uint8_t *addr) { + if (pipe > 5) return; + if (pipe < 2) { + NRF24L01_WriteBuf(NRF_RX_ADDR_P0 + pipe, addr, NRF_ADDR_WIDTH); + } else { + NRF24L01_WriteReg(NRF_RX_ADDR_P0 + pipe, addr[0]); + } +} + +/* ---- 模式切换 ---- */ +void NRF24L01_TXMode(void) { + NRF_CE_L(); + uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG); + cfg &= ~0x01; /* PRIM_RX = 0 -> TX */ + NRF24L01_WriteReg(NRF_CONFIG, cfg); + NRF_CE_H(); +} + +void NRF24L01_RXMode(void) { + NRF_CE_L(); + uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG); + cfg |= 0x01; /* PRIM_RX = 1 -> RX */ + NRF24L01_WriteReg(NRF_CONFIG, cfg); + NRF_CE_H(); +} + +/* ---- 发送/接收 ---- */ +uint8_t NRF24L01_TxPacket(const uint8_t *data, uint8_t len) { + uint8_t status; + + NRF_CE_L(); + + /* 清 TX FIFO */ + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_FLUSH_TX); + NRF_SPI_CS(1); + + /* 写 payload */ + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_W_TX_PAYLOAD); + for (uint8_t i = 0; i < len && i < 32; i++) + NRF_SPI_Transfer(data[i]); + NRF_SPI_CS(1); + + /* 发射 */ + NRF_CE_H(); + HAL_Delay(1); + NRF_CE_L(); + + /* 等待完成 */ + uint32_t timeout = 10000; + while (timeout--) { + status = NRF24L01_ReadReg(NRF_STATUS); + if (status & (NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT)) break; + } + + /* 清除状态 */ + NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT); + + if (status & NRF_STATUS_TX_DS) { + nrf_connected = 1; + return 1; /* 发送成功 */ + } + nrf_connected = 0; + return 0; /* 发送失败 */ +} + +uint8_t NRF24L01_RxPacket(uint8_t *data) { + uint8_t status = NRF24L01_ReadReg(NRF_STATUS); + if (!(status & NRF_STATUS_RX_DR)) return 0; + + /* 读 payload */ + NRF_SPI_CS(0); + NRF_SPI_Transfer(NRF_CMD_R_RX_PAYLOAD); + for (uint8_t i = 0; i < 32; i++) + data[i] = NRF_SPI_Transfer(0xFF); + NRF_SPI_CS(1); + + /* 清除 RX_DR */ + NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR); + + return 1; +} + +uint8_t NRF24L01_IsDataReady(void) { + uint8_t status = NRF24L01_ReadReg(NRF_STATUS); + return (status & NRF_STATUS_RX_DR) ? 1 : 0; +} + +/* ---- 对频 ---- */ +void NRF24L01_BindMode(void) { + /* 进入接收模式,监听对频请求 */ + NRF_CE_L(); + NRF24L01_WriteReg(NRF_CONFIG, 0x0F); /* PRX, PWR_UP, CRC */ + NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01); + NRF24L01_WriteReg(NRF_RX_PW_P0, 32); + NRF24L01_WriteBuf(NRF_RX_ADDR_P0, nrf_tx_addr, NRF_ADDR_WIDTH); + NRF24L01_WriteReg(NRF_STATUS, 0x70); + NRF_CE_H(); +} + +uint8_t NRF24L01_BindScan(uint8_t *found_addr) { + /* 扫描所有通道寻找对频设备 */ + for (uint8_t ch = 0; ch <= NRF_MAX_CHANNEL; ch++) { + NRF24L01_SetChannel(ch); + HAL_Delay(2); + if (NRF24L01_RxPacket(found_addr)) { + /* 验证对频短语 */ + if (memcmp(found_addr, nrf_bind_phrase, strlen((char*)nrf_bind_phrase)) == 0) { + /* 对频成功,记录地址 */ + memcpy(nrf_tx_addr, found_addr + 6, NRF_ADDR_WIDTH); + nrf_connected = 1; + return 1; + } + } + } + return 0; +} diff --git a/Core/Src/oled.c b/Core/Src/oled.c new file mode 100644 index 0000000..a0261ff --- /dev/null +++ b/Core/Src/oled.c @@ -0,0 +1,257 @@ +/** + * OLED SSD1306 / SSD1315 128x64 I2C 驱动实现 + */ +#include "oled.h" +#include "words.h" +#include "image.h" +#include + +/* 显存缓冲区 */ +uint8_t OLED_Buffer[OLED_WIDTH * OLED_HEIGHT / 8]; + +/* 内部命令发送 */ +static void OLED_WriteCmd(uint8_t cmd) { + uint8_t buf[2] = {0x00, cmd}; /* Co=0, D/C#=0 */ + HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDR << 1, buf, 2, 10); +} + +static void OLED_WriteData(uint8_t dat) { + uint8_t buf[2] = {0x40, dat}; /* Co=0, D/C#=1 */ + HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDR << 1, buf, 2, 10); +} + +void OLED_Init(void) { + /* 通用初始化序列 (SSD1306 & SSD1315 共用) */ + OLED_WriteCmd(0xAE); /* display off */ + + OLED_WriteCmd(0xD5); /* set display clock divide */ + OLED_WriteCmd(0x80); + OLED_WriteCmd(0xA8); /* set multiplex */ + OLED_WriteCmd(0x3F); /* 64 */ + OLED_WriteCmd(0xD3); /* set display offset */ + OLED_WriteCmd(0x00); + OLED_WriteCmd(0x40); /* set start line */ + +#if OLED_CHIP == OLED_CHIP_SSD1306 + /* SSD1306: 外部电荷泵 */ + OLED_WriteCmd(0x8D); /* charge pump setting */ + OLED_WriteCmd(0x14); /* enable charge pump */ +#elif OLED_CHIP == OLED_CHIP_SSD1315 + /* SSD1315: 内置 DC-DC 升压 */ + OLED_WriteCmd(0xAD); /* DC-DC control */ + OLED_WriteCmd(0x8A); /* enable DC-DC (0x8A=on with 7.5V VPP) */ + /* 也可用 0x8B 关闭 DC-DC (外部供电模式) */ +#endif + + OLED_WriteCmd(0x20); /* memory mode */ + OLED_WriteCmd(0x00); /* horizontal */ + OLED_WriteCmd(0xA1); /* segment remap (左右镜像) */ + OLED_WriteCmd(0xC8); /* COM scan direction (上下镜像) */ + + OLED_WriteCmd(0xDA); /* set COM pins */ + OLED_WriteCmd(0x12); + OLED_WriteCmd(0x81); /* set contrast */ + OLED_WriteCmd(0xCF); + OLED_WriteCmd(0xD9); /* set pre-charge */ + OLED_WriteCmd(0xF1); + OLED_WriteCmd(0xDB); /* set VCOMH */ + OLED_WriteCmd(0x40); + + OLED_WriteCmd(0xA4); /* display on resume */ + OLED_WriteCmd(0xA6); /* normal display (not inverted) */ + OLED_WriteCmd(0x2E); /* deactivate scroll */ + + OLED_WriteCmd(0xAF); /* display on */ + OLED_Clear(); + OLED_Display(); +} + +void OLED_Clear(void) { + memset(OLED_Buffer, 0x00, sizeof(OLED_Buffer)); +} + +void OLED_Display(void) { + for (uint8_t page = 0; page < OLED_PAGES; page++) { + OLED_WriteCmd(0xB0 + page); /* set page address */ + OLED_WriteCmd(0x00); /* set lower column */ + OLED_WriteCmd(0x10); /* set higher column */ + for (uint8_t col = 0; col < OLED_WIDTH; col++) { + OLED_WriteData(OLED_Buffer[page * OLED_WIDTH + col]); + } + } +} + +void OLED_SetCursor(uint8_t x, uint8_t y) { + /* 仅用于记录,实际绘制由各函数自行计算位置 */ + (void)x; (void)y; +} + +void OLED_DrawPixel(uint8_t x, uint8_t y, uint8_t color) { + if (x >= OLED_WIDTH || y >= OLED_HEIGHT) return; + uint8_t page = y / 8; + uint8_t bit = y % 8; + if (color) + OLED_Buffer[page * OLED_WIDTH + x] |= (1 << bit); + else + OLED_Buffer[page * OLED_WIDTH + x] &= ~(1 << bit); +} + +void OLED_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { + int16_t dx = (int16_t)x2 - x1; + int16_t dy = (int16_t)y2 - y1; + int16_t sx = dx > 0 ? 1 : -1; + int16_t sy = dy > 0 ? 1 : -1; + dx = dx > 0 ? dx : -dx; + dy = dy > 0 ? dy : -dy; + int16_t err = dx - dy; + + while (1) { + OLED_DrawPixel(x1, y1, 1); + if (x1 == x2 && y1 == y2) break; + int16_t e2 = err * 2; + if (e2 > -dy) { err -= dy; x1 += sx; } + if (e2 < dx) { err += dx; y1 += sy; } + } +} + +void OLED_DrawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h) { + OLED_DrawLine(x, y, x + w - 1, y); + OLED_DrawLine(x, y + h - 1, x + w - 1, y + h - 1); + OLED_DrawLine(x, y, x, y + h - 1); + OLED_DrawLine(x + w - 1, y, x + w - 1, y + h - 1); +} + +void OLED_FillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) { + for (uint8_t i = 0; i < w; i++) + for (uint8_t j = 0; j < h; j++) + OLED_DrawPixel(x + i, y + j, color); +} + +void OLED_DrawCircle(uint8_t cx, uint8_t cy, uint8_t r) { + int16_t x = 0, y = r; + int16_t d = 3 - 2 * r; + while (x <= y) { + OLED_DrawPixel(cx + x, cy + y, 1); + OLED_DrawPixel(cx - x, cy + y, 1); + OLED_DrawPixel(cx + x, cy - y, 1); + OLED_DrawPixel(cx - x, cy - y, 1); + OLED_DrawPixel(cx + y, cy + x, 1); + OLED_DrawPixel(cx - y, cy + x, 1); + OLED_DrawPixel(cx + y, cy - x, 1); + OLED_DrawPixel(cx - y, cy - x, 1); + if (d < 0) d += 4 * x + 6; + else { d += 4 * (x - y) + 10; y--; } + x++; + } +} + +/* ---- 文字绘制 ---- */ + +/* 6x8 ASCII 字体 (来自 words.h 的 font[][6]) */ +void OLED_ShowChar(uint8_t x, uint8_t y, char ch, uint8_t size) { + if (size == 6) { + /* 使用小字体 6x8 */ + uint8_t idx = (uint8_t)ch - 32; + if (idx > 94) return; + for (uint8_t i = 0; i < 6; i++) { + uint8_t line = font[idx][i]; + for (uint8_t j = 0; j < 8; j++) { + if (line & (1 << j)) + OLED_DrawPixel(x + i, y + j, 1); + } + } + } else { + /* 使用大字体 8x16 (font_big) */ + uint8_t idx = (uint8_t)ch - 32; + if (idx > 94) return; + for (uint8_t i = 0; i < 8; i++) { + uint8_t line_l = font_big[idx][i * 2]; + uint8_t line_h = font_big[idx][i * 2 + 1]; + for (uint8_t j = 0; j < 8; j++) { + if (line_l & (1 << j)) + OLED_DrawPixel(x + i, y + j, 1); + if (line_h & (1 << j)) + OLED_DrawPixel(x + i, y + 8 + j, 1); + } + } + } +} + +void OLED_ShowString(uint8_t x, uint8_t y, const char *str, uint8_t size) { + while (*str) { + OLED_ShowChar(x, y, *str, size); + x += size; + if (x + size > OLED_WIDTH) { x = 0; y += (size == 6 ? 1 : 2); } + str++; + } +} + +void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size) { + char buf[12]; + uint8_t i; + for (i = 0; i < len; i++) { + buf[len - 1 - i] = '0' + (num % 10); + num /= 10; + } + buf[len] = '\0'; + OLED_ShowString(x, y, buf, size); +} + +/* ---- 汉字绘制 ---- */ +void OLED_ShowCN(uint8_t x, uint8_t y, uint8_t index) { + /* hzk 数组索引: 0=空, 1=→, 2=空, 3=v, 4=←, 5=→, 6=工... */ + /* 每个汉字 12x12 点阵,占 24 bytes */ + for (uint8_t i = 0; i < 12; i++) { + uint8_t line_l = hzk[index][i * 2]; + uint8_t line_h = hzk[index][i * 2 + 1]; + for (uint8_t j = 0; j < 8; j++) { + if (line_l & (0x80 >> j)) + OLED_DrawPixel(x + i, y + j, 1); + if (line_h & (0x80 >> j)) + OLED_DrawPixel(x + i, y + 8 + j, 1); + } + } +} + +/* ---- 图片绘制 ---- */ +void OLED_DrawBitmap(uint8_t x, uint8_t y, const uint8_t *bmp, uint8_t w, uint8_t h) { + uint8_t bytes_per_col = (h + 7) / 8; + for (uint8_t i = 0; i < w; i++) { + for (uint8_t j = 0; j < h; j++) { + uint8_t byte_idx = i * bytes_per_col + j / 8; + uint8_t bit_idx = j % 8; + if (bmp[byte_idx] & (1 << bit_idx)) + OLED_DrawPixel(x + i, y + j, 1); + } + } +} + +/* ---- 反色/滚动 ---- */ +void OLED_InvertDisplay(uint8_t invert) { + OLED_WriteCmd(invert ? 0xA7 : 0xA6); +} + +void OLED_StartScrollRight(uint8_t start_page, uint8_t end_page) { + OLED_WriteCmd(0x2E); /* stop scroll first */ + OLED_WriteCmd(0x26); /* horizontal scroll right */ + OLED_WriteCmd(0x00); /* dummy */ + OLED_WriteCmd(start_page); + OLED_WriteCmd(0x00); /* speed */ + OLED_WriteCmd(end_page); + OLED_WriteCmd(0x00); /* dummy */ + OLED_WriteCmd(0xFF); /* dummy */ + OLED_WriteCmd(0x2F); /* activate scroll */ +} + +void OLED_StopScroll(void) { + OLED_WriteCmd(0x2E); +} + +/* ---- 进度条 ---- */ +void OLED_DrawProgressBar(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t percent) { + if (percent > 100) percent = 100; + OLED_DrawRect(x, y, w, h); + uint8_t fill_w = (uint16_t)(w - 2) * percent / 100; + if (fill_w > 0) + OLED_FillRect(x + 1, y + 1, fill_w, h - 2, 1); +} diff --git a/Core/Src/protocol.c b/Core/Src/protocol.c new file mode 100644 index 0000000..4cb3947 --- /dev/null +++ b/Core/Src/protocol.c @@ -0,0 +1,178 @@ +/** + * 协议层实现 + * NRF24 发射 / SBUS 接收 / USB HID Joystick + */ +#include "protocol.h" +#include "usart.h" +#include "usb.h" +#include + +/* 回传数据 */ +uint16_t telem_voltage = 0; +uint8_t telem_rssi = 0; +uint8_t telem_packet_loss = 0; +uint16_t telem_temp = 0; + +/* 协议状态 */ +static uint32_t last_rf_send = 0; +static uint32_t rf_interval_ms = 10; /* 默认 100Hz */ + +/* SBUS 接收缓冲 */ +static uint8_t sbus_buf[SBUS_FRAME_SIZE]; +static uint8_t sbus_idx = 0; +static uint8_t sbus_got_frame = 0; + +/* USB HID 报告缓冲 */ +static uint8_t hid_report[HID_REPORT_SIZE]; + +void Protocol_Init(void) { + last_rf_send = 0; + sbus_idx = 0; + sbus_got_frame = 0; + memset(hid_report, 0, sizeof(hid_report)); +} + +/* ---- NRF24 协议 ---- */ +void Protocol_SendRFPacket(void) { + uint8_t packet[RF_PACKET_SIZE]; + memset(packet, 0, RF_PACKET_SIZE); + + /* 包头 */ + packet[0] = RF_SYNC_BYTE0; + packet[1] = RF_SYNC_BYTE1; + + /* 对频短语 (6字节) */ + memcpy(&packet[2], g_config.nrf_phrase, 6); + + /* 通道数据 (16通道 * 2字节 = 32字节, 但只取前16字节核心通道) */ + /* 每个通道用 int16_t, 压缩为 2 bytes */ + for (uint8_t i = 0; i < 8; i++) { + int16_t val = g_channels[i]; + /* 范围 -1000 ~ +1000, 映射到 0~2000 */ + uint16_t mapped = (uint16_t)(val + 1000); + packet[8 + i * 2] = (mapped >> 8) & 0xFF; + packet[8 + i * 2 + 1] = mapped & 0xFF; + } + + /* 校验和 (简单 XOR) */ + uint8_t checksum = 0; + for (uint8_t i = 0; i < RF_PACKET_SIZE - 1; i++) + checksum ^= packet[i]; + packet[RF_PACKET_SIZE - 1] = checksum; + + /* 发送 */ + NRF24L01_TxPacket(packet, RF_PACKET_SIZE); +} + +void Protocol_ProcessRF(void) { + /* 接收回传数据 */ + uint8_t rx_buf[32]; + if (NRF24L01_RxPacket(rx_buf)) { + /* 解析回传包 */ + if (rx_buf[0] == 0xBB && rx_buf[1] == 0x44) { + telem_voltage = (rx_buf[2] << 8) | rx_buf[3]; + telem_rssi = rx_buf[4]; + telem_packet_loss = rx_buf[5]; + telem_temp = (rx_buf[6] << 8) | rx_buf[7]; + } + } +} + +/* ---- SBUS 协议 ---- */ +void Protocol_SBUS_Init(void) { + /* USART1 配置为 SBUS 模式 (100000 baud, 8E2) */ + huart1.Init.BaudRate = SBUS_BAUDRATE; + huart1.Init.WordLength = UART_WORDLENGTH_9B; + huart1.Init.Parity = UART_PARITY_EVEN; + huart1.Init.StopBits = UART_STOPBITS_2; + if (HAL_UART_Init(&huart1) != HAL_OK) { + Error_Handler(); + } + /* 启动接收中断 */ + HAL_UART_Receive_IT(&huart1, sbus_buf, SBUS_FRAME_SIZE); +} + +uint8_t Protocol_SBUS_Parse(const uint8_t *frame, int16_t *channels) { + /* SBUS 帧: 0x0F 起始, 0x00 结束 */ + if (frame[0] != 0x0F || frame[24] != 0x00) return 0; + + /* 解析 16 通道 (11-bit each) */ + channels[0] = ((frame[1] | frame[2]<<8) & 0x07FF); + channels[1] = ((frame[2]>>3 | frame[3]<<5) & 0x07FF); + channels[2] = ((frame[3]>>6 | frame[4]<<2 | frame[5]<<10) & 0x07FF); + channels[3] = ((frame[5]>>1 | frame[6]<<7) & 0x07FF); + channels[4] = ((frame[6]>>4 | frame[7]<<4) & 0x07FF); + channels[5] = ((frame[7]>>7 | frame[8]<<1 | frame[9]<<9) & 0x07FF); + channels[6] = ((frame[9]>>2 | frame[10]<<6) & 0x07FF); + channels[7] = ((frame[10]>>5 | frame[11]<<3) & 0x07FF); + channels[8] = ((frame[12] | frame[13]<<8) & 0x07FF); + channels[9] = ((frame[13]>>3 | frame[14]<<5) & 0x07FF); + channels[10] = ((frame[14]>>6 | frame[15]<<2 | frame[16]<<10) & 0x07FF); + channels[11] = ((frame[16]>>1 | frame[17]<<7) & 0x07FF); + channels[12] = ((frame[17]>>4 | frame[18]<<4) & 0x07FF); + channels[13] = ((frame[18]>>7 | frame[19]<<1 | frame[20]<<9) & 0x07FF); + channels[14] = ((frame[20]>>2 | frame[21]<<6) & 0x07FF); + channels[15] = ((frame[21]>>5 | frame[22]<<3) & 0x07FF); + + /* SBUS 范围: 172~1811, 映射到 -1000~+1000 */ + for (uint8_t i = 0; i < 16; i++) { + channels[i] = (int16_t)((int32_t)(channels[i] - 992) * 1000 / 819); + if (channels[i] > 1000) channels[i] = 1000; + if (channels[i] < -1000) channels[i] = -1000; + } + + return 1; +} + +/* ---- USB HID Joystick ---- */ +void Protocol_HID_Init(void) { + /* USB 已在 MX_USB_PCD_Init 中初始化 */ + /* HID 描述符需在 usbd_hid.c 中配置 (通常由 CubeMX 生成) */ +} + +void Protocol_HID_Send(void) { + /* 构造 HID Joystick 报告 */ + /* 标准 Joystick 报告: 8 axis (16-bit) + buttons */ + memset(hid_report, 0, HID_REPORT_SIZE); + + /* X, Y, Z, Rx, Ry, Rz, Slider, Dial */ + for (uint8_t i = 0; i < 8 && i < CHANNEL_COUNT; i++) { + /* 映射 -1000~+1000 到 16-bit */ + int16_t val = g_channels[i]; + hid_report[i * 2] = val & 0xFF; + hid_report[i * 2 + 1] = (val >> 8) & 0xFF; + } + + /* 发送 HID 报告 (需要 USB HID 库支持) */ + /* USBD_HID_SendReport(&hUsbDeviceFS, hid_report, HID_REPORT_SIZE); */ +} + +/* ---- 主循环 ---- */ +void Protocol_Run(void) { + uint32_t now = HAL_GetTick(); + + /* 根据刷新率发送 RF 数据 */ + if (now - last_rf_send >= rf_interval_ms) { + last_rf_send = now; + + if (g_config.rf_type == 0) { + /* NRF24 模式 */ + Protocol_SendRFPacket(); + /* 短暂切换到接收模式收遥测 */ + NRF24L01_RXMode(); + HAL_Delay(1); + Protocol_ProcessRF(); + NRF24L01_TXMode(); + } else { + /* CRFS 模式 (通过 USART3 发送) */ + /* TODO: CRFS 协议实现 */ + } + } + + /* USB HID 发送 (每 10ms) */ + static uint32_t last_hid = 0; + if (now - last_hid >= 10) { + last_hid = now; + Protocol_HID_Send(); + } +} diff --git a/Core/Src/pwm_out.c b/Core/Src/pwm_out.c new file mode 100644 index 0000000..ebb9e4f --- /dev/null +++ b/Core/Src/pwm_out.c @@ -0,0 +1,132 @@ +/** + * PWM 输出与 LED 控制模块实现 + */ +#include "pwm_out.h" + +/* 全局配置 */ +uint8_t pwm1_mode = PWM_MODE_DISABLED; +uint8_t pwm2_mode = PWM_MODE_DISABLED; +uint8_t ws2812_effect = WS2812_MODE_RAINBOW_BREATH; +uint8_t led_brightness = 50; +uint8_t vibrate_level = 5; + +/* LED 闪烁状态 */ +static uint8_t led_nrf_mode = 3; /* 0=慢闪, 1=快闪, 2=常亮, 3=灭 */ +static uint8_t led_crfs_mode = 3; +static uint16_t led_tick = 0; +static uint8_t led_blink_state = 0; + +/* WS2812 动画状态 */ +static uint8_t ws2812_tick = 0; +static uint8_t ws2812_hue = 0; + +void PWM_Init(void) { + /* 启动 TIM3 PWM (LED 指示灯) */ + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /* PC6 - 系统状态 */ + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* PC7 - NRF 状态 */ + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); /* PC8 - CRFS 状态 */ + + /* 初始全灭 */ + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); + + /* TIM4 初始关闭 */ + HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3); + HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4); +} + +/* ---- LED 指示灯 ---- */ +void LED_SetSystem(uint8_t on) { + /* PC6: 系统状态 - 开机常亮 */ + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, on ? 65535 : 0); +} + +void LED_SetNRF(uint8_t mode) { + led_nrf_mode = mode; +} + +void LED_SetCRFS(uint8_t mode) { + led_crfs_mode = mode; +} + +void LED_Update(void) { + led_tick++; + + /* NRF LED (PC7) */ + uint16_t nrf_val = 0; + switch (led_nrf_mode) { + case 0: /* 慢闪: 500ms on / 500ms off */ + nrf_val = ((led_tick % 100) < 50) ? 65535 : 0; + break; + case 1: /* 快闪: 100ms on / 100ms off */ + nrf_val = ((led_tick % 20) < 10) ? 65535 : 0; + break; + case 2: /* 常亮 */ + nrf_val = 65535; + break; + case 3: /* 灭 */ + default: + nrf_val = 0; + break; + } + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, nrf_val); + + /* CRFS LED (PC8) */ + uint16_t crfs_val = 0; + switch (led_crfs_mode) { + case 0: crfs_val = ((led_tick % 100) < 50) ? 65535 : 0; break; + case 1: crfs_val = ((led_tick % 20) < 10) ? 65535 : 0; break; + case 2: crfs_val = 65535; break; + default: crfs_val = 0; break; + } + __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, crfs_val); +} + +/* ---- PWM 输出控制 ---- */ +void PWM_SetMode(uint8_t ch, uint8_t mode) { + if (ch == 0) { + pwm1_mode = mode; + if (mode == PWM_MODE_DISABLED) { + HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3); + } else { + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); + } + } else { + pwm2_mode = mode; + if (mode == PWM_MODE_DISABLED) { + HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4); + } else { + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); + } + } +} + +void PWM_SetWS2812Mode(uint8_t mode) { + if (mode >= WS2812_MODE_COUNT) return; + ws2812_effect = mode; + ws2812_tick = 0; + ws2812_hue = 0; +} + +void PWM_SetLEDBrightness(uint8_t brightness) { + if (brightness > 100) brightness = 100; + led_brightness = brightness; + uint16_t pwm_val = (uint32_t)65535 * brightness / 100; + /* 应用到已启用的 LED 模式通道 */ + if (pwm1_mode == PWM_MODE_LED) + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pwm_val); + if (pwm2_mode == PWM_MODE_LED) + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, pwm_val); +} + +void PWM_SetVibrateLevel(uint8_t level) { + if (level < VIBRATE_LEVEL_MIN) level = VIBRATE_LEVEL_MIN; + if (level > VIBRATE_LEVEL_MAX) level = VIBRATE_LEVEL_MAX; + vibrate_level = level; + uint16_t pwm_val = (uint32_t)65535 * level / VIBRATE_LEVEL_MAX; + if (pwm1_mode == PWM_MODE_VIBRATE) + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pwm_val); + if (pwm2_mode == PWM_MODE_VIBRATE) + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, pwm_val); +} diff --git a/Core/Src/storage.c b/Core/Src/storage.c new file mode 100644 index 0000000..104fd63 --- /dev/null +++ b/Core/Src/storage.c @@ -0,0 +1,182 @@ +/** + * Flash 存储模块实现 + * 使用 STM32F1 HAL Flash 驱动 + */ +#include "storage.h" + +/* 全局配置 */ +Config_t g_config; + +/* CRC32 计算 */ +static uint32_t Storage_CRC32(const uint8_t *data, uint32_t len) { + uint32_t crc = 0xFFFFFFFF; + for (uint32_t i = 0; i < len; i++) { + crc ^= data[i]; + for (uint8_t j = 0; j < 8; j++) { + if (crc & 1) + crc = (crc >> 1) ^ 0xEDB88320; + else + crc >>= 1; + } + } + return ~crc; +} + +void Storage_Init(void) { + /* 解锁 Flash */ + HAL_FLASH_Unlock(); +} + +void Storage_Load(void) { + Config_t *flash_cfg = (Config_t *)FLASH_STORAGE_ADDR; + + /* 检查魔数 */ + if (flash_cfg->magic[0] == 'L' && flash_cfg->magic[1] == 'O' && + flash_cfg->magic[2] == 'L' && flash_cfg->magic[3] == 'I') { + + /* 校验 CRC */ + uint32_t calc_crc = Storage_CRC32((uint8_t*)flash_cfg, + sizeof(Config_t) - sizeof(uint32_t)); + if (calc_crc == flash_cfg->crc32) { + /* 有效配置, 加载 */ + memcpy(&g_config, flash_cfg, sizeof(Config_t)); + return; + } + } + + /* 无效或无配置, 恢复出厂 */ + Storage_Reset(); +} + +void Storage_Save(void) { + /* 计算 CRC */ + g_config.crc32 = Storage_CRC32((uint8_t*)&g_config, + sizeof(Config_t) - sizeof(uint32_t)); + + /* 擦除页 */ + FLASH_EraseInitTypeDef erase = {0}; + uint32_t page_error; + erase.TypeErase = FLASH_TYPEERASE_PAGES; + erase.PageAddress = FLASH_STORAGE_ADDR; + erase.NbPages = 1; + + HAL_FLASH_Unlock(); + HAL_FLASHEx_Erase(&erase, &page_error); + + /* 写入 (按 32-bit 写入) */ + uint32_t *src = (uint32_t*)&g_config; + uint32_t *dst = (uint32_t*)FLASH_STORAGE_ADDR; + uint32_t count = (sizeof(Config_t) + 3) / 4; + + for (uint32_t i = 0; i < count; i++) { + HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, + (uint32_t)(dst + i), src[i]); + } + + HAL_FLASH_Lock(); +} + +void Storage_Reset(void) { + memset(&g_config, 0, sizeof(Config_t)); + + /* 魔数 */ + g_config.magic[0] = 'L'; + g_config.magic[1] = 'O'; + g_config.magic[2] = 'L'; + g_config.magic[3] = 'I'; + + /* 默认模型 */ + g_config.active_model = 0; + strcpy(g_config.models[0].name, "Model1"); + g_config.models[0].type = MODEL_TYPE_AIRPLANE; + + /* 默认通道映射: CH1->ADC_IN0, CH2->ADC_IN1, CH3->ADC_IN2, CH4->ADC_IN3 */ + for (uint8_t i = 0; i < 4; i++) { + g_config.models[0].channel_map[i] = i; + g_config.models[0].input_type[i] = INPUT_TYPE_ADC; + g_config.models[0].mixer_type[i] = MIXER_TYPE_SIMPLE; + g_config.models[0].mixer_scale[i] = 100; /* 1:1 */ + g_config.models[0].mixer_offset[i] = 0; + } + for (uint8_t i = 4; i < CHANNEL_COUNT; i++) { + g_config.models[0].channel_map[i] = i; + g_config.models[0].input_type[i] = INPUT_TYPE_NONE; + g_config.models[0].mixer_type[i] = MIXER_TYPE_NONE; + } + + /* 默认高频头: NRF24 */ + g_config.rf_type = 0; + g_config.nrf_channel = 40; + g_config.nrf_rate = NRF_RATE_1M; + g_config.nrf_power = NRF_PA_MAX; + memcpy(g_config.nrf_addr, "\xE7\xE7\xE7\xE7\xE7", 5); + strcpy(g_config.nrf_phrase, "LOVE"); + + /* CRFS 默认 */ + g_config.crfs_packet_rate = 500; + g_config.crfs_telemetry_ratio = 4; + g_config.crfs_power = 100; + + /* PWM 默认 */ + g_config.pwm1_mode = PWM_MODE_DISABLED; + g_config.pwm2_mode = PWM_MODE_DISABLED; + g_config.ws2812_effect = WS2812_MODE_RAINBOW_BREATH; + g_config.led_brightness = 50; + g_config.vibrate_level = 5; + + /* 首页默认: 回传 */ + g_config.home_page = 0; + + /* 保存 */ + Storage_Save(); +} + +/* ---- 模型操作 ---- */ +uint8_t Storage_ModelAdd(const char *name, uint8_t type) { + for (uint8_t i = 0; i < MODEL_MAX_COUNT; i++) { + if (g_config.models[i].name[0] == '\0') { + strncpy(g_config.models[i].name, name, MODEL_NAME_LEN - 1); + g_config.models[i].name[MODEL_NAME_LEN - 1] = '\0'; + g_config.models[i].type = type; + + /* 默认通道映射 */ + for (uint8_t j = 0; j < 4; j++) { + g_config.models[i].channel_map[j] = j; + g_config.models[i].input_type[j] = INPUT_TYPE_ADC; + g_config.models[i].mixer_type[j] = MIXER_TYPE_SIMPLE; + g_config.models[i].mixer_scale[j] = 100; + g_config.models[i].mixer_offset[j] = 0; + } + for (uint8_t j = 4; j < CHANNEL_COUNT; j++) { + g_config.models[i].channel_map[j] = j; + g_config.models[i].input_type[j] = INPUT_TYPE_NONE; + g_config.models[i].mixer_type[j] = MIXER_TYPE_NONE; + } + return i; + } + } + return 0xFF; /* 已满 */ +} + +void Storage_ModelDelete(uint8_t idx) { + if (idx >= MODEL_MAX_COUNT) return; + memset(&g_config.models[idx], 0, sizeof(Model_t)); + if (g_config.active_model == idx) { + g_config.active_model = 0; + } +} + +void Storage_ModelSelect(uint8_t idx) { + if (idx >= MODEL_MAX_COUNT) return; + if (g_config.models[idx].name[0] == '\0') return; /* 空模型 */ + g_config.active_model = idx; +} + +Model_t* Storage_GetActiveModel(void) { + return &g_config.models[g_config.active_model]; +} + +Model_t* Storage_GetModel(uint8_t idx) { + if (idx >= MODEL_MAX_COUNT) return NULL; + return &g_config.models[idx]; +} diff --git a/Makefile b/Makefile index cdba08a..8433edf 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,13 @@ Core/Src/usart.c \ Core/Src/usb.c \ Core/Src/stm32f1xx_it.c \ Core/Src/stm32f1xx_hal_msp.c \ +Core/Src/oled.c \ +Core/Src/input.c \ +Core/Src/menu.c \ +Core/Src/storage.c \ +Core/Src/pwm_out.c \ +Core/Src/nrf24l01.c \ +Core/Src/protocol.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c \ @@ -131,6 +138,7 @@ AS_INCLUDES = # C includes C_INCLUDES = \ -ICore/Inc \ +-Iui \ -IDrivers/STM32F1xx_HAL_Driver/Inc \ -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ -IDrivers/CMSIS/Device/ST/STM32F1xx/Include \ diff --git a/README.md b/README.md index 5a9b959..8201cbd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,41 @@ -# ZhaTianRC +# Loli3 -炸天控 \ No newline at end of file +#### 介绍 +这个是萝莉3航模遥控器的开源项目,包含硬件电路及固件源码,原创作者“我爱萝丽爱萝丽”,原发于“模型中国”论坛,后来“模型中国”论坛消亡,作者遂转战于“模友之吧”,虽然萝莉4代从提出到现在已经有1年半了(2017年12月31日提出萝莉4代至今),但由于4代正式版一直难产当中,到目前为止最新版仍然是3代,由于群(1群:272416403;2群:556473744)里文件比较混乱,特将相关内容放于git上,奢望能统一管理源码。开源许可协议由于原作者没说,所以我随便选了个MIT吧。 +托管于几个git仓库: +https://gitee.com/wooddoor/Loli3 【这个是主仓库,其它的为备份,有事没事都不会在那几个仓库出现,所以有问题请在这个主仓库提交】 +https://github.com/wooddoor/Loli3 +https://code.aliyun.com/wooddoor/Loli3.git + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 码云特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 +5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..d3e93d2 --- /dev/null +++ b/ui/README.md @@ -0,0 +1,52 @@ +# UI界面介绍 +值: 显示当前ADC_IN0~14的数值,ADC显示为数字值,按钮显示开/关 +回传:显示电压、rssi等参数,显示哪些内容可在菜单设置里配置 + +# 点击“确认”进入菜单 +包括以下项:模型选择、高频头配置、通道映射、混控、PWM驱动、首页[ ] + +## 模型 +通过切换模型选择不同的通道映射和混控设置,以便适应多种不同种类的模型。 +具体操作说明:进入“模型选择”页面,页面第一个永远固定为“新建”选项。没一项开头为“[ ]”,选中(正在使用)的显示为“[*]”。单击 + +### 新建页 +选择新建后进入新建页面:第一行为"命名:_______",支持最多输入8个英文字母;第二行选择模型类型“类型:[选项]”,可选“airplane、car、Boat、Multirotor”;下方横向排列两个按钮“[确认] [取消]”。 +点进确认后进入通道映射页面,每一行结构样式为“[CH1] -> [ADC_INx]或[Key_INx]”,将16个输入作为选项选择,每个都可以设置为ADC或GPIO输入。最后一项下方居中排列一个选项按钮“[下一步]”。 +进入混控设置,每一行结构显示为“[CHx]: ”,共16个。点击确认进入,里面包含名称、通道等,按下返回按钮即保存并确认。最后一项下方居中排列一个选项按钮“[下一步]”。 +下一步为回传信息设置,可以选择显示哪些回传信息到首页的回传信息屏,如电压、RSSI、丢包率等 + +### 编辑 +通过长按某个模型弹出选项:选择、编辑、删除,点击选择即选中此模型,点击编辑即依次走一遍上述新建页的流程,点击删除弹出确认删除确认对话框 + +## 高频头配置项 +进入后第一项选择使用哪一种高频头,默认[NRF24],可选[CRFS],选择不同高频头下方选项同步发生改变。 + +### [NRF24] +第一项为对频短语,可输入最多6个英文大小写+数字字符,默认“LOVE”。第二项为频道选择,可选NRF24L01支持的128个通道。第三项为地址设置,设置发射模块的地址。第四个可选刷新率,在“50Hz、100Hz、250Hz”中选择。第五项可选空中速率,可选NRF24L01支持的“2Mbps、1Mbps和250Kbps” + +### [CRFS] +参照elrs推荐的设置项显示。 + +## 通道映射 +同步使用“模型 -> 编辑”中通道映射页的内容 + +## 混控 +同步使用“模型 -> 编辑”中混控页的内容 + +## PWM驱动 +两个PWM可设置为WS2812、LED、振动,默认为Disabled,具体的硬件连接由用户决定 +ws2812实现彩虹呼吸灯、彩色流水灯、单色流水灯、单色呼吸灯、彩色渐变、彩色爆闪等模式 +LED为呼吸灯、常亮(亮度调节) +振动为1-9挡强弱 + +## 首页[] +选择开机默认进入哪一页,可选“回传”、“INx值” + +# 在首页,长按确认进入“高频头配置页” +根据高频头配置项中选择的不同选项呈现不同内容 +1、若选择[NRF24],则显示“通道、地址、对频短语”编辑选项,ui按钮:第一项[Bind]:点击进入对频模式,此模式自动扫描所有通道发现周围正处于对频模式的NRF24L01接收机,扫描到之后自动记录对频成功的接收机。下方显示记录的接收机的地址,也可以手动修改。 +2、若选择[CRFS],则按照elrs高频头的功能特点进行设计。 + +# 开/关机 +长按返回键2s进入休眠模式,并关闭全部外设,保存一遍所有数据到eeprom。 +长按返回2s开机,上电默认进入休眠模式,成功开机显示2s开机图片 diff --git a/ui/image.h b/ui/image.h new file mode 100644 index 0000000..3bee40d --- /dev/null +++ b/ui/image.h @@ -0,0 +1,67 @@ +// 启动image +const unsigned char bitmap_bytes[] = { + 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, 0xfe, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xf0, 0x04, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x27, 0x02, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x00, 0x0e, 0x04, 0x40, 0x38, 0x80, 0x00, + 0x00, 0x00, 0x1c, 0x08, 0x40, 0x18, 0x40, 0x00, + 0x00, 0x00, 0x19, 0x00, 0x80, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x31, 0x00, 0x40, 0x2e, 0x80, 0x00, + 0x00, 0x00, 0x28, 0x10, 0x40, 0x36, 0xf0, 0x00, + 0x00, 0x00, 0x60, 0x02, 0x02, 0x17, 0xf0, 0x00, + 0x00, 0x00, 0x52, 0x00, 0x02, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x50, 0x24, 0x22, 0x03, 0x40, 0x00, + 0x00, 0x00, 0x52, 0x28, 0x03, 0x0b, 0xc0, 0x00, + 0x00, 0x00, 0x10, 0x28, 0x02, 0x0b, 0x80, 0x00, + 0x00, 0x00, 0x14, 0x30, 0x22, 0x2a, 0xc0, 0x00, + 0x00, 0x00, 0x14, 0x37, 0x82, 0xc8, 0x40, 0x00, + 0x00, 0x04, 0x5c, 0x3f, 0xd2, 0x4c, 0x20, 0x00, + 0x00, 0x04, 0x5c, 0x3b, 0x82, 0x1c, 0x00, 0x00, + 0x00, 0x05, 0x4c, 0x28, 0x88, 0x7c, 0x10, 0x00, + 0x00, 0x05, 0x7c, 0x00, 0x81, 0xf8, 0x00, 0x00, + 0x00, 0x05, 0x64, 0x04, 0x04, 0x58, 0x08, 0x00, + 0x00, 0x04, 0x40, 0x00, 0x01, 0x58, 0x0c, 0x00, + 0x00, 0x04, 0x40, 0x00, 0x01, 0x58, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x58, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x40, 0x00, 0x18, 0x03, 0x00, + 0x00, 0x00, 0x80, 0x40, 0x00, 0x0c, 0x03, 0x00, + 0x00, 0x00, 0x90, 0x40, 0x06, 0x0c, 0x03, 0x80, + 0x00, 0x00, 0x8c, 0x40, 0x00, 0x0c, 0x03, 0xc0, + 0x00, 0x04, 0x9c, 0x40, 0x00, 0x10, 0xef, 0xc0, + 0x00, 0x00, 0x9e, 0x40, 0x00, 0x10, 0x7f, 0xc0, + 0x00, 0x01, 0x9e, 0x60, 0x00, 0x38, 0x3f, 0xc0, + 0x00, 0x09, 0x9e, 0x60, 0x00, 0x78, 0x1f, 0x80, + 0x00, 0x09, 0xce, 0x20, 0x00, 0xe0, 0x0f, 0x00, + 0x00, 0x09, 0xce, 0x20, 0x01, 0xa0, 0x00, 0x00, + 0x00, 0x13, 0xce, 0x00, 0x7f, 0x68, 0x00, 0x00, + 0x00, 0x13, 0xef, 0x00, 0x1f, 0xec, 0x00, 0x00, + 0x00, 0x13, 0xe7, 0x00, 0x08, 0xec, 0x00, 0x00, + 0x00, 0x03, 0xe7, 0x00, 0x08, 0x0c, 0x00, 0x00, + 0x00, 0x27, 0xf7, 0x20, 0x3c, 0x06, 0x00, 0x00, + 0x00, 0x24, 0x16, 0x30, 0x02, 0x53, 0x00, 0x00, + 0x00, 0x10, 0x1a, 0x20, 0x8c, 0x50, 0xc0, 0x00, + 0x00, 0x07, 0x1a, 0x00, 0x80, 0x40, 0x7e, 0x00, + 0x00, 0x3f, 0x9c, 0x00, 0x48, 0x40, 0x3c, 0x00, + 0x00, 0x3f, 0xcd, 0x00, 0x30, 0x50, 0x3c, 0x00, + 0x00, 0x78, 0x66, 0x10, 0x10, 0x54, 0x68, 0x00, + 0x00, 0xe0, 0x36, 0xc0, 0x10, 0x0c, 0x48, 0x00, + 0x00, 0xc0, 0x1a, 0x10, 0x00, 0x04, 0x40, 0x00, + 0x01, 0xf8, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xfa, 0x0f, 0x48, 0x00, 0x20, 0x80, 0x00, + 0x03, 0xc0, 0x0f, 0x68, 0x00, 0x1e, 0x00, 0x00, + 0x07, 0xc2, 0x07, 0x28, 0x00, 0x1f, 0x00, 0x03, + 0x07, 0x80, 0x27, 0x2c, 0x04, 0x09, 0x60, 0x1f, + 0x07, 0x80, 0x03, 0x5c, 0x00, 0x09, 0x60, 0x0b, + 0x07, 0x88, 0x07, 0x5c, 0x00, 0x09, 0xe0, 0x0b, + 0x0b, 0x08, 0x07, 0x5c, 0x01, 0x85, 0xe0, 0x0b, + 0x0b, 0x08, 0x01, 0xf6, 0x01, 0xc5, 0xc0, 0x09, + 0x0b, 0x00, 0x02, 0xf4, 0x01, 0xc5, 0xc0, 0x09, + 0x0b, 0x00, 0x05, 0xf0, 0x03, 0xe5, 0x80, 0x11, + 0x0a, 0x00, 0x01, 0xd1, 0x03, 0xe5, 0xb0, 0x00, + 0x02, 0x00, 0x01, 0xd5, 0x01, 0xe1, 0xb0, 0x00 +}; \ No newline at end of file diff --git a/ui/words.h b/ui/words.h new file mode 100644 index 0000000..73d6fc5 --- /dev/null +++ b/ui/words.h @@ -0,0 +1,811 @@ +//取码规则: 低位在前, 列行扫描, 阴码(1-亮, 0-灭) +//查表方法: 要显示的ASCII码-32就可以得到字库码的指针 +const unsigned char font[][6] = { +{0x00,0x00,0x00,0x00,0x00,0x00},// (0) +{0x00,0x00,0x00,0x4F,0x00,0x00},//!(1) +{0x00,0x00,0x07,0x00,0x07,0x00},//"(2) +{0x00,0x14,0x7F,0x14,0x7F,0x14},//#(3) +{0x00,0x24,0x2A,0x7F,0x2A,0x12},//$(4) +{0x00,0x23,0x13,0x08,0x64,0x62},//%(5) +{0x00,0x36,0x49,0x55,0x22,0x50},//&(6) +{0x00,0x00,0x05,0x03,0x00,0x00},//'(7) +{0x00,0x00,0x1C,0x22,0x41,0x00},//((8) +{0x00,0x00,0x41,0x22,0x1C,0x00},//)(9) +{0x00,0x14,0x08,0x3E,0x08,0x14},//*(10) +{0x00,0x08,0x08,0x3E,0x08,0x08},//+(11) +{0x00,0x00,0x50,0x30,0x00,0x00},//,(12) +{0x00,0x08,0x08,0x08,0x08,0x08},//-(13) +{0x00,0x00,0x60,0x60,0x00,0x00},//.(14) +{0x00,0x20,0x10,0x08,0x04,0x02},///(15) +{0x00,0x3E,0x51,0x49,0x45,0x3E},//0(16) +{0x00,0x00,0x42,0x7F,0x40,0x00},//1(17) +{0x00,0x42,0x61,0x51,0x49,0x46},//2(18) +{0x00,0x21,0x41,0x45,0x4B,0x31},//3(19) +{0x00,0x18,0x14,0x12,0x7F,0x10},//4(20) +{0x00,0x27,0x45,0x45,0x45,0x39},//5(21) +{0x00,0x3C,0x4A,0x49,0x49,0x30},//6(22) +{0x00,0x01,0x71,0x09,0x05,0x03},//7(23) +{0x00,0x36,0x49,0x49,0x49,0x36},//8(24) +{0x00,0x06,0x49,0x49,0x29,0x1E},//9(25) +{0x00,0x00,0x36,0x36,0x00,0x00},//:(26) +{0x00,0x00,0x56,0x36,0x00,0x00},//;(27) +{0x00,0x08,0x14,0x22,0x41,0x00},//<(28) +{0x00,0x14,0x14,0x14,0x14,0x14},//=(29) +{0x00,0x00,0x41,0x22,0x14,0x08},//>(30) +{0x00,0x02,0x01,0x51,0x09,0x06},//?(31) +{0x00,0x32,0x49,0x79,0x41,0x3E},//@(32) +{0x00,0x7E,0x11,0x11,0x11,0x7E},//A(33) +{0x00,0x7F,0x49,0x49,0x49,0x3E},//B(34) +{0x00,0x3E,0x41,0x41,0x41,0x22},//C(35) +{0x00,0x7F,0x41,0x41,0x22,0x1C},//D(36) +{0x00,0x7F,0x49,0x49,0x49,0x41},//E(37) +{0x00,0x7F,0x09,0x09,0x09,0x01},//F(38) +{0x00,0x3E,0x41,0x49,0x49,0x7A},//G(39) +{0x00,0x7F,0x08,0x08,0x08,0x7F},//H(40) +{0x00,0x00,0x41,0x7F,0x41,0x00},//I(41) +{0x00,0x20,0x40,0x41,0x3F,0x01},//J(42) +{0x00,0x7F,0x08,0x14,0x22,0x41},//K(43) +{0x00,0x7F,0x40,0x40,0x40,0x40},//L(44) +{0x00,0x7F,0x02,0x04,0x02,0x7F},//M(45) +{0x00,0x7F,0x04,0x08,0x10,0x7F},//N(46) +{0x00,0x3E,0x41,0x41,0x41,0x3E},//O(47) +{0x00,0x7F,0x09,0x09,0x09,0x06},//P(48) +{0x00,0x3E,0x41,0x51,0x21,0x5E},//Q(49) +{0x00,0x7F,0x09,0x19,0x29,0x46},//R(50) +{0x00,0x46,0x49,0x49,0x49,0x31},//S(51) +{0x00,0x01,0x01,0x7F,0x01,0x01},//T(52) +{0x00,0x3F,0x40,0x40,0x40,0x3F},//U(53) +{0x00,0x1F,0x20,0x40,0x20,0x1F},//V(54) +{0x00,0x3F,0x40,0x38,0x40,0x3F},//W(55) +{0x00,0x63,0x14,0x08,0x14,0x63},//X(56) +{0x00,0x03,0x04,0x78,0x04,0x03},//Y(57) +{0x00,0x61,0x51,0x49,0x45,0x43},//Z(58) +{0x00,0x00,0x7F,0x41,0x41,0x00},//[(59) +{0x00,0x15,0x16,0x7C,0x16,0x15},//\(60) +{0x00,0x00,0x41,0x41,0x7F,0x00},//](61) +{0x00,0x04,0x02,0x01,0x02,0x04},//^(62) +{0x00,0x40,0x40,0x40,0x40,0x40},//_(63) +{0x00,0x00,0x01,0x02,0x04,0x00},//`(64) +{0x00,0x20,0x54,0x54,0x54,0x78},//a(65) +{0x00,0x7F,0x48,0x44,0x44,0x38},//b(66) +{0x00,0x38,0x44,0x44,0x44,0x20},//c(67) +{0x00,0x38,0x44,0x44,0x48,0x7F},//d(68) +{0x00,0x38,0x54,0x54,0x54,0x18},//e(69) +{0x00,0x08,0x7E,0x09,0x01,0x02},//f(70) +{0x00,0x0C,0x52,0x52,0x52,0x3E},//g(71) +{0x00,0x7F,0x08,0x04,0x04,0x78},//h(72) +{0x00,0x00,0x44,0x7D,0x40,0x00},//i(73) +{0x00,0x20,0x40,0x44,0x3D,0x00},//j(74) +{0x00,0x7F,0x10,0x28,0x44,0x00},//k(75) +{0x00,0x00,0x41,0x7F,0x40,0x00},//l(76) +{0x00,0x7E,0x02,0x0C,0x02,0x7C},//m(77) +{0x00,0x7E,0x04,0x02,0x02,0x7C},//n(78) +{0x00,0x38,0x44,0x44,0x44,0x38},//o(79) +{0x00,0x7C,0x14,0x14,0x14,0x08},//p(80) +{0x00,0x08,0x14,0x14,0x18,0x7C},//q(81) +{0x00,0x7C,0x08,0x04,0x04,0x08},//r(82) +{0x00,0x48,0x54,0x54,0x54,0x20},//s(83) +{0x00,0x04,0x3F,0x44,0x40,0x20},//t(84) +{0x00,0x3C,0x40,0x40,0x20,0x7C},//u(85) +{0x00,0x1C,0x20,0x40,0x20,0x1C},//v(86) +{0x00,0x3C,0x40,0x30,0x40,0x3C},//w(87) +{0x00,0x44,0x28,0x10,0x28,0x44},//x(88) +{0x00,0x0C,0x50,0x50,0x50,0x3C},//y(89) +{0x00,0x44,0x64,0x54,0x4C,0x44},//z(90) +{0x00,0x00,0x08,0x36,0x41,0x00},//{(91) +{0x00,0x00,0x00,0x7F,0x00,0x00},//|(92) +{0x00,0x00,0x41,0x36,0x08,0x00},//}(93) +{0x00,0x08,0x04,0x08,0x10,0x08},//~(94) +{0x00,0x08,0x08,0x2A,0x1C,0x08},//→(127) +{0x00,0x08,0x1C,0x2A,0x08,0x08},//←(128) +{0x00,0x04,0x02,0x7F,0x02,0x04},//↑(129) +{0x00,0x10,0x20,0x7F,0x20,0x10},//↓(130) +{0x00,0x1C,0x2A,0x32,0x2A,0x1C},//笑面(131) +{0x00,0x1C,0x22,0x44,0x22,0x1C},//爱心(132) +{0x00,0x11,0x0a,0x04,0x0a,0x11},//><(133) +{0x00,0x07,0x05,0x07,0x00,0x00},//度(134) +}; +//大写字母表 +const unsigned char font_big[][16] = { +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// (0) +{0x00,0x00,0x38,0xFC,0xFC,0x38,0x00,0x00,0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00},//!(1) +{0x00,0x0E,0x1E,0x00,0x00,0x1E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//"(2) +{0x20,0xF8,0xF8,0x20,0xF8,0xF8,0x20,0x00,0x02,0x0F,0x0F,0x02,0x0F,0x0F,0x02,0x00},//#(3) +{0x38,0x7C,0x44,0x47,0x47,0xCC,0x98,0x00,0x03,0x06,0x04,0x1C,0x1C,0x07,0x03,0x00},//$(4) +{0x30,0x30,0x00,0x80,0xC0,0x60,0x30,0x00,0x0C,0x06,0x03,0x01,0x00,0x0C,0x0C,0x00},//%(5) +{0x80,0xD8,0x7C,0xE4,0xBC,0xD8,0x40,0x00,0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00},//&(6) +{0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//'(7) +{0x00,0x00,0xF0,0xF8,0x0C,0x04,0x00,0x00,0x00,0x00,0x03,0x07,0x0C,0x08,0x00,0x00},//((8) +{0x00,0x00,0x04,0x0C,0xF8,0xF0,0x00,0x00,0x00,0x00,0x08,0x0C,0x07,0x03,0x00,0x00},//)(9) +{0x80,0xA0,0xE0,0xC0,0xC0,0xE0,0xA0,0x80,0x00,0x02,0x03,0x01,0x01,0x03,0x02,0x00},//*(10) +{0x00,0x80,0x80,0xE0,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00},//+(11) +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x1E,0x0E,0x00,0x00,0x00},//,(12) +{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//-(13) +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00},//.(14) +{0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x00,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00},///(15) +{0xF8,0xFC,0x04,0xC4,0x24,0xFC,0xF8,0x00,0x07,0x0F,0x09,0x08,0x08,0x0F,0x07,0x00},//0(16) +{0x00,0x10,0x18,0xFC,0xFC,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x0F,0x08,0x08,0x00},//1(17) +{0x08,0x0C,0x84,0xC4,0x64,0x3C,0x18,0x00,0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0C,0x00},//2(18) +{0x08,0x0C,0x44,0x44,0x44,0xFC,0xB8,0x00,0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00},//3(19) +{0xC0,0xE0,0xB0,0x98,0xFC,0xFC,0x80,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00},//4(20) +{0x7C,0x7C,0x44,0x44,0xC4,0xC4,0x84,0x00,0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00},//5(21) +{0xF0,0xF8,0x4C,0x44,0x44,0xC4,0x80,0x00,0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00},//6(22) +{0x0C,0x0C,0x04,0x84,0xC4,0x7C,0x3C,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00},//7(23) +{0xB8,0xFC,0x44,0x44,0x44,0xFC,0xB8,0x00,0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00},//8(24) +{0x38,0x7C,0x44,0x44,0x44,0xFC,0xF8,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00},//9(25) +{0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00},//:(26) +{0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x08,0x0E,0x06,0x00,0x00,0x00},//;(27) +{0x00,0x80,0xC0,0x60,0x30,0x18,0x08,0x00,0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x00},//<(28) +{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00},//=(29) +{0x00,0x08,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x08,0x0C,0x06,0x03,0x01,0x00,0x00},//>(30) +{0x18,0x1C,0x04,0xC4,0xE4,0x3C,0x18,0x00,0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00},//?(31) +{0xF0,0xF8,0x08,0xC8,0x48,0xF8,0xF0,0x00,0x07,0x0F,0x08,0x0B,0x0B,0x0B,0x01,0x00},//@(32) +{0xE0,0xF0,0x98,0x8C,0x98,0xF0,0xE0,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00},//A(33) +{0x04,0xFC,0xFC,0x44,0x44,0xFC,0xB8,0x00,0x08,0x0F,0x0F,0x08,0x08,0x0F,0x07,0x00},//B(34) +{0xF0,0xF8,0x0C,0x04,0x04,0x0C,0x18,0x00,0x03,0x07,0x0C,0x08,0x08,0x0C,0x06,0x00},//C(35) +{0x04,0xFC,0xFC,0x04,0x0C,0xF8,0xF0,0x00,0x08,0x0F,0x0F,0x08,0x0C,0x07,0x03,0x00},//D(36) +{0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00,0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00},//E(37) +{0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00},//F(38) +{0xF0,0xF8,0x0C,0x84,0x84,0x8C,0x98,0x00,0x03,0x07,0x0C,0x08,0x08,0x07,0x0F,0x00},//G(39) +{0xFC,0xFC,0x40,0x40,0x40,0xFC,0xFC,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00},//H(40) +{0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00},//I(41) +{0x00,0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00,0x00},//J(42) +{0x04,0xFC,0xFC,0xC0,0xF0,0x3C,0x0C,0x00,0x08,0x0F,0x0F,0x00,0x01,0x0F,0x0E,0x00},//K(43) +{0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00},//L(44) +{0xFC,0xFC,0x38,0x70,0x38,0xFC,0xFC,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00},//M(45) +{0xFC,0xFC,0x38,0x70,0xE0,0xFC,0xFC,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00},//N(46) +{0xF0,0xF8,0x0C,0x04,0x0C,0xF8,0xF0,0x00,0x03,0x07,0x0C,0x08,0x0C,0x07,0x03,0x00},//O(47) +{0x04,0xFC,0xFC,0x44,0x44,0x7C,0x38,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00},//P(48) +{0xF8,0xFC,0x04,0x04,0x04,0xFC,0xF8,0x00,0x07,0x0F,0x08,0x0E,0x3C,0x3F,0x27,0x00},//Q(49) +{0x04,0xFC,0xFC,0x44,0xC4,0xFC,0x38,0x00,0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00},//R(50) +{0x18,0x3C,0x64,0x44,0xC4,0x9C,0x18,0x00,0x06,0x0E,0x08,0x08,0x08,0x0F,0x07,0x00},//S(51) +{0x00,0x1C,0x0C,0xFC,0xFC,0x0C,0x1C,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00},//T(52) +{0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00,0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00},//U(53) +{0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00,0x01,0x03,0x06,0x0C,0x06,0x03,0x01,0x00},//V(54) +{0xFC,0xFC,0x00,0x80,0x00,0xFC,0xFC,0x00,0x03,0x0F,0x0E,0x03,0x0E,0x0F,0x03,0x00},//W(55) +{0x0C,0x3C,0xF0,0xC0,0xF0,0x3C,0x0C,0x00,0x0C,0x0F,0x03,0x00,0x03,0x0F,0x0C,0x00},//X(56) +{0x00,0x3C,0x7C,0xC0,0xC0,0x7C,0x3C,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00},//Y(57) +{0x1C,0x0C,0x84,0xC4,0x64,0x3C,0x1C,0x00,0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0E,0x00},//Z(58) +{0x00,0x00,0xFC,0xFC,0x04,0x04,0x00,0x00,0x00,0x00,0x0F,0x0F,0x08,0x08,0x00,0x00},//[(59) +{0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x00},//\(60) +{0x00,0x00,0x04,0x04,0xFC,0xFC,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x0F,0x00,0x00},//](61) +{0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//^(62) +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},//_(63) +{0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//'(64) +{0x00,0xA0,0xA0,0xA0,0xE0,0xC0,0x00,0x00,0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00},//a(65) +{0x04,0xFC,0xFC,0x20,0x60,0xC0,0x80,0x00,0x08,0x0F,0x07,0x08,0x08,0x0F,0x07,0x00},//b(66) +{0xC0,0xE0,0x20,0x20,0x20,0x60,0x40,0x00,0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00},//c(67) +{0x80,0xC0,0x60,0x24,0xFC,0xFC,0x00,0x00,0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00},//d(68) +{0xC0,0xE0,0xA0,0xA0,0xA0,0xE0,0xC0,0x00,0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00},//e(69) +{0x40,0xF8,0xFC,0x44,0x0C,0x18,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00},//f(70) +{0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00,0x27,0x6F,0x48,0x48,0x7F,0x3F,0x00,0x00},//g(71) +{0x04,0xFC,0xFC,0x40,0x20,0xE0,0xC0,0x00,0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00},//h(72) +{0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00},//i(73) +{0x00,0x00,0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x30,0x70,0x40,0x40,0x7F,0x3F,0x00},//j(74) +{0x04,0xFC,0xFC,0x80,0xC0,0x60,0x20,0x00,0x08,0x0F,0x0F,0x01,0x03,0x0E,0x0C,0x00},//k(75) +{0x00,0x00,0x04,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00},//l(76) +{0xE0,0xE0,0x60,0xC0,0x60,0xE0,0xC0,0x00,0x0F,0x0F,0x00,0x0F,0x00,0x0F,0x0F,0x00},//m(77) +{0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00,0x00,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00},//n(78) +{0xC0,0xE0,0x20,0x20,0x20,0xE0,0xC0,0x00,0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00},//o(79) +{0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00,0x40,0x7F,0x7F,0x48,0x08,0x0F,0x07,0x00},//p(80) +{0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00,0x07,0x0F,0x08,0x48,0x7F,0x7F,0x40,0x00},//q(81) +{0x20,0xE0,0xC0,0x60,0x20,0x60,0xC0,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00},//r(82) +{0x40,0xE0,0xA0,0x20,0x20,0x60,0x40,0x00,0x04,0x0C,0x09,0x09,0x0B,0x0E,0x04,0x00},//s(83) +{0x20,0x20,0xF8,0xFC,0x20,0x20,0x00,0x00,0x00,0x00,0x07,0x0F,0x08,0x0C,0x04,0x00},//t(84) +{0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00},//u(85) +{0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x03,0x07,0x0C,0x0C,0x07,0x03,0x00},//v(86) +{0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x07,0x0F,0x0C,0x07,0x0C,0x0F,0x07,0x00},//w(87) +{0x20,0x60,0xC0,0x80,0xC0,0x60,0x20,0x00,0x08,0x0C,0x07,0x03,0x07,0x0C,0x08,0x00},//x(88) +{0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x47,0x4F,0x48,0x48,0x68,0x3F,0x1F,0x00},//y(89) +{0x60,0x60,0x20,0xA0,0xE0,0x60,0x20,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x0C,0x0C,0x00},//z(90) + +{0xFF,0xBD,0xFF,0xFF,0xBD,0xFF,0x00,0x00,0x7F,0x40,0x40,0x40,0x40,0x7F,0x00,0x00},//SA1(123) +{0xFF,0x81,0x81,0x81,0x81,0xFF,0x00,0x00,0x7F,0x5E,0x7F,0x7F,0x5E,0x7F,0x00,0x00},//SA3(124) +{0xFF,0x2D,0x3F,0x3F,0x2D,0xFF,0x00,0x00,0x7F,0x42,0x42,0x42,0x42,0x7F,0x00,0x00},//SB1(125) +{0xFF,0xA1,0xE1,0xE1,0xA1,0xFF,0x00,0x00,0x7F,0x42,0x43,0x43,0x42,0x7F,0x00,0x00},//SB2(126) +{0xFF,0x21,0x21,0x21,0x21,0xFF,0x00,0x00,0x7F,0x5A,0x7E,0x7E,0x5A,0x7F,0x00,0x00},//SB3(127) + + +/*{0xC0,0xC0,0xC8,0xD8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x00},//→(91) +{0xC0,0xE0,0xF0,0xD8,0xC8,0xC0,0xC0,0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00,0x00},//←(92) +{0x60,0x30,0x18,0xFC,0xFC,0x18,0x30,0x60,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00},//↑(93) +{0x80,0x00,0x00,0xF0,0xF0,0x00,0x00,0x80,0x01,0x03,0x06,0x0F,0x0F,0x06,0x03,0x01},//↓(94)*/ + + +}; + + +const unsigned char hzk[][24]={//汉字库 +// 0 + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, +//->1 + {0xF8,0x88,0x88,0x88,0x88,0x8F,0x02,0x04,0x88,0x50,0x20,0x00,0x00,0x00,0x00,0x00, +0x00,0x07,0x02,0x01,0x00,0x00,0x00,0x00,}, +// 2 + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, +//v3 + {0x80,0x80,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x18,0x00,0x00,0x01,0x03,0x06, +0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,}, +//<-4 + {0x40,0xA0,0x10,0x08,0x04,0x1E,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x01,0x02, +0x04,0x0F,0x01,0x01,0x01,0x01,0x01,0x00,}, +//->5 + {0xF8,0x88,0x88,0x88,0x88,0x8F,0x02,0x04,0x88,0x50,0x20,0x00,0x00,0x00,0x00,0x00, +0x00,0x07,0x02,0x01,0x00,0x00,0x00,0x00,}, + +//工6 + {0x00,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x08,0x00}, +//作7 + {0x20,0x10,0xFC,0x03,0x08,0x07,0xFC,0x24,0x24,0x24,0x04,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x01,0x01,0x01,0x01,0x00}, +//模8 + {0x88,0x68,0xFF,0x48,0x02,0xFA,0xAF,0xAA,0xAF,0xFA,0x02,0x00,0x00,0x00,0x0F,0x00,0x0A,0x0A,0x06,0x03,0x06,0x0A,0x0A,0x00}, +//式9 + {0x08,0x48,0x48,0xC8,0x48,0x48,0x08,0xFF,0x08,0x09,0x0A,0x00,0x08,0x08,0x08,0x07,0x04,0x04,0x04,0x00,0x03,0x04,0x0E,0x00}, +//无10 + {0x20,0x22,0x22,0x22,0xE2,0x3E,0xE2,0x22,0x22,0x22,0x20,0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x07,0x08,0x08,0x08,0x0E,0x00}, +//线11 + {0x98,0xD4,0xB3,0x88,0x00,0x48,0x48,0xFF,0x24,0xA5,0x26,0x00,0x04,0x04,0x02,0x02,0x08,0x08,0x04,0x03,0x05,0x08,0x0E,0x00}, +//配12 + {0xFA,0x4A,0x3E,0x0A,0x3E,0x4A,0xFA,0x00,0xE2,0x22,0x3E,0x00,0x0F,0x05,0x05,0x05,0x05,0x05,0x0F,0x00,0x07,0x08,0x0E,0x00}, +//置13 + {0x10,0x17,0xD5,0x55,0x57,0x7D,0x57,0x55,0xD5,0x17,0x10,0x00,0x08,0x08,0x0F,0x08,0x08,0x0E,0x08,0x08,0x0F,0x08,0x08,0x00}, +//管14 + {0x1C,0x0B,0xEA,0xAE,0xAA,0xAC,0xAB,0xAA,0xEE,0x0A,0x1A,0x00,0x00,0x00,0x0F,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0E,0x00,0x00}, +//理15 + {0x22,0xFE,0x22,0x00,0x7F,0x49,0x49,0xFF,0x49,0x49,0x7F,0x00,0x04,0x07,0x02,0x08,0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x00}, +//通16 + {0x11,0xF2,0x00,0xF9,0xA9,0xAB,0xFD,0xAD,0xAB,0xF8,0x00,0x00,0x08,0x07,0x08,0x0B,0x08,0x08,0x0B,0x08,0x0A,0x0B,0x08,0x00}, +//道17 + {0x10,0x11,0xF2,0x00,0xFA,0xAB,0xAE,0xAA,0xAA,0xAB,0xFA,0x00,0x08,0x04,0x03,0x04,0x0B,0x0A,0x0A,0x0A,0x0A,0x0A,0x0B,0x00}, +//设18 + {0x10,0x11,0xF2,0x00,0x50,0xCF,0x41,0x41,0x4F,0xD0,0x10,0x00,0x00,0x00,0x07,0x02,0x08,0x08,0x05,0x02,0x05,0x08,0x08,0x00}, +//高19 + {0x82,0x82,0xBA,0xAA,0xAA,0xAB,0xAA,0xAA,0xBA,0x82,0x82,0x00,0x0F,0x00,0x00,0x0E,0x0A,0x0A,0x0A,0x0E,0x00,0x08,0x0F,0x00}, +//级20 + {0x98,0xD4,0xB3,0x88,0x02,0xFE,0x82,0x02,0x32,0x2E,0xE0,0x00,0x04,0x04,0x02,0x0A,0x06,0x01,0x08,0x05,0x02,0x05,0x08,0x00}, +//混21 + {0x10,0x21,0x02,0x00,0xDF,0x15,0x15,0x15,0xD5,0x1F,0x80,0x00,0x04,0x02,0x01,0x00,0x0F,0x09,0x05,0x00,0x07,0x09,0x0C,0x00}, +//控22 + {0x88,0xFF,0x48,0x00,0x4C,0xA4,0x95,0x86,0x94,0xA4,0x4C,0x00,0x08,0x0F,0x00,0x00,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x00}, +//系23 + {0x00,0x82,0x92,0xDA,0xD6,0xB2,0xB1,0x91,0x89,0xC1,0x80,0x00,0x08,0x04,0x02,0x00,0x08,0x0F,0x00,0x00,0x02,0x04,0x09,0x00}, +//统24 + {0x98,0xD4,0xB3,0x88,0x00,0x64,0xD4,0x4D,0xC6,0x54,0xE4,0x00,0x04,0x04,0x02,0x02,0x08,0x04,0x03,0x00,0x07,0x08,0x0C,0x00}, +//快25 + {0x78,0x00,0xFF,0x48,0x44,0x44,0xFF,0x44,0x44,0x7C,0x40,0x00,0x00,0x00,0x0F,0x08,0x04,0x03,0x00,0x03,0x04,0x08,0x08,0x00}, +//捷26 + {0x88,0x88,0xFF,0x48,0x00,0xAA,0xAA,0xFF,0xAA,0xFA,0x22,0x00,0x00,0x08,0x0F,0x00,0x08,0x06,0x08,0x0F,0x0A,0x0A,0x0A,0x00}, +//功27 + {0x04,0x04,0xFC,0x04,0x04,0x08,0xFF,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x01,0x09,0x05,0x03,0x00,0x00,0x08,0x08,0x07,0x00}, +//能28 + {0x04,0xF6,0x55,0x54,0xF6,0x00,0xCF,0x14,0x12,0x91,0x18,0x00,0x00,0x0F,0x01,0x09,0x0F,0x00,0x07,0x0A,0x09,0x08,0x0E,0x00}, +//发29 + {0x0E,0x08,0x88,0x78,0xCF,0x48,0x48,0x49,0xCA,0x08,0x08,0x00,0x04,0x02,0x09,0x08,0x04,0x05,0x02,0x05,0x04,0x08,0x08,0x00}, +//射30 + {0x80,0xFE,0xAB,0xAA,0xFE,0x00,0x48,0x88,0x08,0xFF,0x08,0x00,0x04,0x02,0x01,0x08,0x0F,0x00,0x00,0x09,0x08,0x0F,0x00,0x00}, +//输31 + {0x34,0x2C,0xF7,0xA4,0xE8,0xA4,0xEA,0x09,0xCA,0x04,0xE8,0x00,0x01,0x01,0x0F,0x00,0x0F,0x02,0x0F,0x00,0x03,0x08,0x0F,0x00}, +//出32 + {0x80,0x1E,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x1E,0x80,0x00,0x07,0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0x0F,0x00}, +//入33 + {0x00,0x00,0x01,0x81,0x72,0x0C,0x70,0x80,0x00,0x00,0x00,0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x00}, +//正34 + {0x00,0x02,0xE2,0x02,0x02,0xFE,0x42,0x42,0x42,0x42,0x00,0x00,0x08,0x08,0x0F,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x08,0x00}, +//反35 + {0x00,0xFE,0x12,0x72,0x92,0x12,0x11,0x11,0x91,0x71,0x00,0x00,0x08,0x07,0x08,0x08,0x04,0x05,0x02,0x05,0x04,0x08,0x08,0x00}, +//舵36 + {0x20,0xFE,0xAB,0xFE,0x00,0x0C,0xE4,0x05,0x86,0x44,0x2C,0x00,0x08,0x07,0x08,0x0F,0x00,0x00,0x07,0x09,0x08,0x08,0x0E,0x00}, +//量37 + {0x08,0xFF,0xA9,0xA9,0xA9,0xFB,0xAD,0xA9,0xA9,0xFF,0x08,0x00,0x08,0x0A,0x0A,0x0A,0x0A,0x0F,0x0A,0x0A,0x0A,0x0A,0x08,0x00}, +//映38 + {0xFE,0x22,0x22,0xFE,0x80,0xFC,0x84,0xFF,0x84,0xFC,0x80,0x00,0x07,0x02,0x02,0x07,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00}, +//微39 + {0x24,0xF2,0x09,0x0E,0xA8,0xAF,0xA8,0x1E,0xE8,0x07,0xFC,0x00,0x00,0x0F,0x00,0x08,0x07,0x00,0x07,0x0A,0x04,0x03,0x0C,0x00}, +//调40 + {0x11,0xF2,0x00,0x00,0xFF,0x21,0xA9,0xBD,0xA9,0x21,0xFF,0x00,0x00,0x07,0x02,0x08,0x07,0x00,0x03,0x02,0x0B,0x08,0x0F,0x00}, +//新41 + {0x20,0xAA,0xB2,0xE3,0xB2,0xAA,0x00,0xFE,0x12,0xF2,0x11,0x00,0x04,0x02,0x08,0x0F,0x00,0x0A,0x04,0x03,0x00,0x0F,0x00,0x00}, +//建42 + {0x32,0x2A,0xE6,0x08,0xAA,0xAA,0xFF,0xAA,0xAA,0xBE,0x08,0x00,0x09,0x06,0x05,0x0A,0x0A,0x0A,0x0F,0x0A,0x0A,0x0A,0x0A,0x00}, +//接43 + {0x88,0x88,0xFF,0x48,0xA4,0xAC,0xB5,0xE6,0xB4,0xAC,0xA4,0x00,0x00,0x08,0x0F,0x00,0x08,0x0A,0x0B,0x04,0x04,0x0B,0x08,0x00}, +//收44 + {0xFE,0x00,0x80,0xFF,0x20,0x10,0xEF,0x08,0x88,0x78,0x08,0x00,0x03,0x01,0x00,0x0F,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00}, +//率45 + {0x02,0x8A,0x52,0x9A,0xD6,0xB3,0xD2,0x8A,0x52,0x8A,0x02,0x00,0x02,0x02,0x02,0x02,0x02,0x0F,0x02,0x02,0x02,0x02,0x02,0x00}, +//失46 + {0xA0,0x90,0x8E,0x88,0x88,0xFF,0x88,0x88,0x88,0x80,0x80,0x00,0x08,0x08,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x08,0x08,0x00}, +//信47 + {0x10,0xFC,0x03,0x04,0x54,0x54,0x55,0x56,0x54,0x54,0x04,0x00,0x00,0x0F,0x00,0x00,0x0F,0x05,0x05,0x05,0x05,0x0F,0x00,0x00}, +//密48 + {0x46,0x32,0x82,0xB2,0x46,0x6B,0x52,0x4A,0x62,0x12,0x66,0x00,0x00,0x0E,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x0E,0x00,0x00}, +//码49 + {0x42,0xF2,0x2E,0xE2,0x01,0x3D,0x21,0x21,0x21,0x3F,0xE0,0x00,0x00,0x07,0x02,0x07,0x01,0x01,0x01,0x01,0x09,0x08,0x07,0x00}, +//多50 + {0x90,0x90,0x48,0x54,0x23,0x92,0x4A,0x66,0x52,0xC0,0x40,0x00,0x08,0x08,0x08,0x09,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x00}, +//点51 + {0x00,0xF0,0x10,0x10,0x10,0x1F,0x12,0x12,0x12,0xF2,0x02,0x00,0x08,0x05,0x01,0x05,0x09,0x01,0x05,0x09,0x01,0x05,0x08,0x00}, +//跳52 + {0xCF,0x09,0xF9,0x4F,0x84,0x48,0xFF,0x00,0xFF,0x48,0x84,0x00,0x07,0x04,0x03,0x02,0x08,0x04,0x03,0x00,0x07,0x08,0x0E,0x00}, +//频53 + {0x10,0xDE,0x10,0xFF,0x12,0x92,0xF9,0x0D,0xEB,0x09,0xF9,0x00,0x09,0x08,0x04,0x02,0x01,0x00,0x09,0x04,0x03,0x04,0x09,0x00}, +//教54 + {0xA8,0x6A,0x3F,0xAA,0x6C,0x0A,0x10,0xEF,0x08,0xF8,0x08,0x00,0x02,0x02,0x0A,0x0F,0x01,0x01,0x08,0x05,0x02,0x05,0x08,0x00}, +//练55 + {0x98,0xD4,0xB3,0x88,0x14,0x74,0x5C,0xF7,0x44,0x44,0x44,0x00,0x04,0x04,0x02,0x02,0x04,0x03,0x08,0x0F,0x00,0x01,0x06,0x00}, +//音56 + {0x10,0xD2,0x56,0x5A,0x52,0x53,0x52,0x5A,0x56,0xD2,0x10,0x00,0x00,0x0F,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0F,0x00,0x00}, +//效57 + {0x44,0x34,0x85,0x06,0x94,0x24,0x10,0xEF,0x08,0xF8,0x08,0x00,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x04,0x03,0x04,0x08,0x00}, +//开58 + {0x40,0x42,0x42,0xFE,0x42,0x42,0x42,0xFE,0x42,0x42,0x40,0x00,0x00,0x08,0x06,0x01,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00}, +//关59 + {0x40,0x48,0x49,0x4A,0x48,0xF8,0x48,0x4A,0x49,0x48,0x40,0x00,0x08,0x08,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x08,0x08,0x00}, +//背60 + {0x12,0x12,0xEA,0xBF,0xA0,0xA0,0xA7,0xAA,0xEA,0x09,0x0C,0x00,0x00,0x00,0x0F,0x02,0x02,0x02,0x02,0x0A,0x0F,0x00,0x00,0x00}, +//光61 + {0x20,0x22,0x24,0xE8,0x20,0x3F,0x20,0xE8,0x24,0x22,0x20,0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x07,0x08,0x08,0x0E,0x00}, +//液62 + {0x22,0x44,0x80,0xE4,0x1C,0xC5,0x3E,0x54,0x94,0x74,0x04,0x00,0x04,0x02,0x00,0x0F,0x01,0x08,0x05,0x02,0x05,0x08,0x08,0x00}, +//晶63 + {0xC0,0x40,0x5F,0x55,0xD5,0x15,0xD5,0x55,0x5F,0x40,0xC0,0x00,0x0F,0x05,0x05,0x05,0x0F,0x00,0x0F,0x05,0x05,0x05,0x0F,0x00}, +//屏64 + {0x00,0xFF,0x05,0x25,0x2D,0xF5,0x25,0x25,0xF5,0x2D,0x27,0x00,0x08,0x07,0x01,0x09,0x05,0x03,0x01,0x01,0x0F,0x01,0x01,0x00}, +//单65 + {0x00,0x7C,0x55,0x56,0x54,0xFC,0x54,0x56,0x55,0x7C,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,0x01,0x01,0x00}, +//回66 + {0x00,0xFE,0x02,0x02,0xF2,0x92,0x92,0xF2,0x02,0x02,0xFE,0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//传67 + {0x20,0x10,0xFC,0x23,0x24,0xE4,0xBC,0xA7,0xA4,0xA4,0x20,0x00,0x00,0x00,0x0F,0x00,0x00,0x02,0x02,0x04,0x06,0x09,0x00,0x00}, +//号68 + {0x20,0x20,0xAF,0x69,0x29,0x29,0x29,0x29,0x2F,0x20,0x20,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x09,0x09,0x07,0x00,0x00}, +//低69 + {0x20,0x10,0xFC,0x03,0xFE,0x22,0x22,0xFE,0x21,0x21,0x20,0x00,0x00,0x00,0x0F,0x00,0x07,0x02,0x05,0x08,0x03,0x04,0x0F,0x00}, +//压70 + {0x00,0xFE,0x02,0x42,0x42,0x42,0xFA,0x42,0x42,0x42,0x02,0x00,0x08,0x07,0x08,0x08,0x08,0x08,0x0F,0x08,0x09,0x0A,0x08,0x00}, +//报71 + {0x88,0x88,0xFF,0x48,0x00,0xFE,0x42,0xC2,0x52,0x52,0xCE,0x00,0x00,0x08,0x0F,0x00,0x00,0x0F,0x08,0x05,0x02,0x05,0x08,0x00}, +//警72 + {0x92,0xBF,0xAA,0xBA,0xCF,0xBA,0xC4,0xAB,0x92,0xAE,0xC2,0x00,0x00,0x02,0x0E,0x0A,0x0A,0x0A,0x0A,0x0A,0x0E,0x02,0x00,0x00}, +//版73 + {0x00,0xFE,0x90,0x9F,0x10,0xFE,0x12,0xF2,0x12,0x91,0x71,0x00,0x08,0x07,0x00,0x0F,0x04,0x03,0x08,0x05,0x02,0x05,0x08,0x00}, +//本74 + {0x04,0x04,0x84,0x64,0x14,0xFF,0x14,0x64,0x84,0x04,0x04,0x00,0x02,0x01,0x02,0x02,0x02,0x0F,0x02,0x02,0x02,0x01,0x02,0x00}, +//息75 + {0x00,0xFE,0xAA,0xAA,0xAB,0xAA,0xAA,0xAA,0xAA,0xFE,0x00,0x00,0x08,0x06,0x00,0x06,0x08,0x09,0x0A,0x08,0x0C,0x02,0x0C,0x00}, +//全76 + {0x10,0x10,0x28,0x24,0x22,0xE1,0x22,0x24,0x28,0x10,0x10,0x00,0x08,0x09,0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x09,0x08,0x00}, +//扫77 + {0x88,0x88,0xFF,0x48,0x48,0x02,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,0x08,0x0F,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//描78 + {0x88,0x88,0xFF,0x48,0xF2,0x97,0x92,0xF2,0x92,0x97,0xF2,0x00,0x00,0x08,0x0F,0x00,0x0F,0x04,0x04,0x07,0x04,0x04,0x0F,0x00}, +//向79 + {0xFC,0x04,0x04,0xE6,0x25,0x24,0x24,0xE4,0x04,0x04,0xFC,0x00,0x0F,0x00,0x00,0x03,0x02,0x02,0x02,0x03,0x08,0x08,0x0F,0x00}, +//器80 + {0x20,0x27,0xA5,0xA5,0x67,0x38,0x67,0xA5,0xAD,0x37,0x20,0x00,0x01,0x0F,0x0A,0x0A,0x0E,0x00,0x0E,0x0A,0x0A,0x0F,0x01,0x00}, +//一81 + {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +//二82 + {0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00}, +//三83 + {0x00,0x02,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x02,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00}, +//四84 + {0x00,0xFE,0x02,0x82,0x7E,0x02,0x02,0x7E,0x82,0x82,0xFE,0x00,0x00,0x0F,0x05,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//五85 + {0x02,0x22,0x22,0xE2,0x3E,0x22,0x22,0x22,0xE2,0x02,0x00,0x00,0x08,0x08,0x0E,0x09,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x00}, +//六86 + {0x10,0x10,0x10,0xD0,0x11,0x16,0x10,0x50,0x90,0x10,0x10,0x00,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x00}, +//七87 + {0x20,0x20,0x20,0x20,0xFF,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x08,0x08,0x08,0x08,0x0E,0x00}, +//八88 + {0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x00,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x08,0x00}, +//九89 + {0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x07,0x08,0x08,0x0E,0x00}, +//十90 + {0x20,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, +//同91 + {0x00,0xFE,0x02,0xEA,0x2A,0x2A,0x2A,0x2A,0xEA,0x02,0xFE,0x00,0x00,0x0F,0x00,0x01,0x01,0x01,0x01,0x01,0x09,0x08,0x0F,0x00}, +//端92 + {0xE9,0x0A,0xE8,0x00,0xAE,0xA8,0xA8,0xEF,0xA8,0xA8,0xAE,0x00,0x04,0x05,0x02,0x00,0x0F,0x00,0x07,0x00,0x07,0x08,0x0F,0x00}, +//差93 + {0x44,0x54,0x55,0xD6,0x74,0x5C,0x54,0x56,0x55,0x54,0x44,0x00,0x04,0x02,0x09,0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x08,0x00}, +//运94 + {0x10,0x11,0xF2,0x00,0x10,0x92,0x52,0x32,0x12,0x92,0x10,0x00,0x08,0x04,0x03,0x04,0x09,0x09,0x09,0x09,0x09,0x09,0x0B,0x00}, +//算95 + {0x04,0x03,0xFA,0xAE,0xAA,0xA8,0xAC,0xAB,0xFA,0x06,0x02,0x00,0x02,0x02,0x0B,0x06,0x02,0x02,0x02,0x0E,0x03,0x02,0x02,0x00}, +//摇96 + {0x88,0x88,0xFF,0x48,0x4A,0x32,0x26,0xEA,0x21,0x29,0x05,0x00,0x00,0x08,0x0F,0x00,0x0D,0x09,0x09,0x0F,0x09,0x09,0x0D,0x00}, +//杆97 + {0x88,0x68,0xFF,0x28,0x40,0x42,0x42,0xFE,0x42,0x42,0x40,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00}, +//校98 + {0x88,0x68,0xFF,0x28,0x44,0x24,0xD5,0x06,0xD4,0x24,0x44,0x00,0x00,0x00,0x0F,0x00,0x08,0x08,0x05,0x02,0x05,0x08,0x08,0x00}, +//准99 + {0x04,0x08,0x20,0x10,0xFC,0x27,0x24,0xFD,0x26,0x24,0x04,0x00,0x04,0x02,0x01,0x00,0x0F,0x09,0x09,0x0F,0x09,0x09,0x08,0x00}, +//旋100 + {0x08,0xF8,0x49,0x4A,0xD0,0x08,0xD7,0x14,0xF4,0x14,0x34,0x00,0x08,0x07,0x08,0x08,0x07,0x08,0x07,0x08,0x0F,0x09,0x09,0x00}, +//钮101 + {0x98,0xF7,0x94,0x94,0x42,0xC2,0x7E,0x42,0x42,0xFE,0x00,0x00,0x00,0x0F,0x04,0x08,0x08,0x0F,0x08,0x08,0x08,0x0F,0x08,0x00}, +//角102 + {0x08,0xF4,0x53,0x52,0x52,0xF2,0x5A,0x56,0x50,0xF0,0x00,0x00,0x08,0x07,0x01,0x01,0x01,0x07,0x01,0x01,0x09,0x0F,0x00,0x00}, +//度103 + {0x00,0xFE,0x0A,0x8A,0xBE,0xAA,0xAB,0xAA,0xBE,0x8A,0x0A,0x00,0x08,0x07,0x00,0x08,0x09,0x0A,0x04,0x04,0x0A,0x09,0x08,0x00}, +//自104 + {0x00,0xFC,0x24,0x24,0x26,0x25,0x24,0x24,0x24,0xFC,0x00,0x00,0x00,0x0F,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0F,0x00,0x00}, +//动105 + {0x10,0xD2,0x32,0x92,0x10,0x00,0x08,0xFF,0x08,0x08,0xF8,0x00,0x03,0x02,0x02,0x02,0x03,0x08,0x06,0x01,0x08,0x08,0x07,0x00}, +//恢106 + {0x78,0x00,0xFF,0x08,0xC4,0x3F,0xC4,0x04,0xF4,0x44,0x24,0x00,0x00,0x00,0x0F,0x04,0x03,0x08,0x04,0x02,0x01,0x06,0x08,0x00}, +//复107 + {0x04,0x02,0x7D,0xD5,0x55,0x55,0x55,0x55,0x55,0x7D,0x01,0x00,0x00,0x0A,0x09,0x0B,0x05,0x05,0x05,0x05,0x0B,0x09,0x08,0x00}, +//默108 + {0x5F,0x55,0x51,0xFF,0x55,0x5F,0x00,0x10,0xFF,0x12,0x14,0x00,0x0A,0x06,0x0A,0x05,0x09,0x05,0x08,0x07,0x00,0x07,0x08,0x00}, +//认109 + {0x10,0x11,0xF2,0x00,0x00,0x00,0xC0,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x07,0x02,0x09,0x06,0x01,0x00,0x01,0x06,0x08,0x00}, +//三110 + {0x00,0x02,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x02,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00}, +//角111 + {0x08,0xF4,0x53,0x52,0x52,0xF2,0x5A,0x56,0x50,0xF0,0x00,0x00,0x08,0x07,0x01,0x01,0x01,0x07,0x01,0x01,0x09,0x0F,0x00,0x00}, +//翼112 + {0x01,0x8B,0xFD,0xA9,0xAF,0xF8,0xA9,0xAB,0xFD,0x81,0x0F,0x00,0x02,0x0A,0x06,0x03,0x02,0x02,0x02,0x03,0x06,0x0A,0x02,0x00}, +//差113 + {0x44,0x54,0x55,0xD6,0x74,0x5C,0x54,0x56,0x55,0x54,0x44,0x00,0x04,0x02,0x09,0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x08,0x00}, +//速114 + {0x11,0xF2,0x00,0x7A,0x4A,0xCA,0xFF,0xCA,0x4A,0x7A,0x02,0x00,0x08,0x07,0x08,0x0A,0x09,0x08,0x0F,0x08,0x09,0x0A,0x08,0x00}, +//尾115 + {0x00,0xFF,0x05,0xA5,0xA5,0xA5,0xE5,0x55,0x55,0x15,0x07,0x00,0x08,0x07,0x02,0x02,0x02,0x02,0x07,0x09,0x09,0x09,0x0C,0x00}, +//襟116 + {0x84,0x45,0xF6,0xAC,0x0A,0x5F,0x52,0x4A,0x5F,0x4A,0x12,0x00,0x00,0x00,0x0F,0x00,0x05,0x03,0x09,0x0F,0x01,0x03,0x05,0x00}, +//副117 + {0xC1,0x5D,0x55,0xD5,0x55,0x5D,0xC1,0x00,0xFC,0x00,0xFF,0x00,0x0F,0x05,0x05,0x07,0x05,0x05,0x0F,0x00,0x01,0x08,0x0F,0x00}, +//曲118 + {0x00,0xFC,0x44,0x44,0xFF,0x44,0x44,0xFF,0x44,0x44,0xFC,0x00,0x00,0x0F,0x04,0x04,0x07,0x04,0x04,0x07,0x04,0x04,0x0F,0x00}, +//协119 + {0x10,0xFF,0x10,0x88,0x48,0xFF,0x08,0x08,0xF8,0x40,0x80,0x00,0x00,0x0F,0x00,0x08,0x06,0x01,0x08,0x08,0x07,0x00,0x01,0x00}, +//议120 + {0x10,0x11,0xF2,0x00,0x18,0x60,0x81,0x06,0x80,0x60,0x1C,0x00,0x00,0x00,0x07,0x02,0x09,0x04,0x02,0x01,0x02,0x04,0x08,0x00}, +//搜121 + {0x88,0x88,0xFF,0x48,0xBC,0xAA,0xA0,0xFF,0xA0,0xAA,0xBE,0x00,0x00,0x08,0x0F,0x00,0x08,0x09,0x0A,0x04,0x04,0x0A,0x09,0x00}, +//索122 + {0x18,0x0A,0x4A,0x6A,0xDA,0x4F,0x4A,0x2A,0x8A,0x0A,0x18,0x00,0x00,0x09,0x05,0x01,0x09,0x0F,0x01,0x01,0x05,0x09,0x00,0x00}, +//机123 + {0x88,0x68,0xFF,0x28,0x40,0xFE,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,0x0F,0x08,0x04,0x03,0x00,0x00,0x07,0x08,0x0E,0x00}, +//成124 + {0x00,0xFC,0x24,0x24,0xE4,0x04,0xFF,0x04,0x85,0x66,0x04,0x00,0x08,0x07,0x00,0x02,0x0B,0x04,0x02,0x01,0x02,0x04,0x0F,0x00}, +//功125 + {0x04,0x04,0xFC,0x04,0x04,0x08,0xFF,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x01,0x09,0x05,0x03,0x00,0x00,0x08,0x08,0x07,0x00}, +//取126 + {0x02,0xFE,0x52,0x52,0xFE,0x02,0x04,0xFC,0x04,0xFC,0x00,0x00,0x02,0x03,0x02,0x02,0x0F,0x01,0x08,0x04,0x03,0x04,0x08,0x00}, +//消127 + {0x10,0x22,0x04,0x00,0xF2,0x54,0x50,0x5F,0x50,0x54,0xF2,0x00,0x04,0x02,0x01,0x00,0x0F,0x01,0x01,0x01,0x01,0x09,0x0F,0x00}, +//操128 + {0x88,0x88,0xFF,0x48,0x70,0x57,0x75,0x85,0x75,0x57,0x70,0x00,0x00,0x08,0x0F,0x00,0x09,0x05,0x03,0x0F,0x03,0x05,0x09,0x00}, +//作129 + {0x20,0x10,0xFC,0x03,0x08,0x07,0xFC,0x24,0x24,0x24,0x04,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x01,0x01,0x01,0x01,0x00}, +//第130 + {0x04,0xD3,0x52,0x56,0x52,0xF4,0x53,0x52,0x56,0x72,0x02,0x00,0x08,0x09,0x05,0x03,0x01,0x0F,0x01,0x01,0x09,0x09,0x07,0x00}, +//次131 + {0x02,0x04,0x80,0x20,0x18,0x87,0x74,0x84,0x04,0x14,0x0C,0x00,0x02,0x01,0x08,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x08,0x00}, +//机132 + {0x88,0x68,0xFF,0x28,0x40,0xFE,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,0x0F,0x08,0x04,0x03,0x00,0x00,0x07,0x08,0x0E,0x00}, +//偏133 + {0x10,0xFC,0x03,0x80,0xFE,0x2A,0xEA,0x2B,0xEA,0x2A,0xEE,0x00,0x00,0x0F,0x01,0x00,0x0F,0x01,0x07,0x01,0x07,0x09,0x0F,0x00}, +//负134 + {0x08,0xF4,0x13,0x12,0x12,0xD2,0x1A,0x16,0x10,0xF0,0x00,0x00,0x08,0x09,0x04,0x04,0x02,0x01,0x02,0x02,0x04,0x05,0x08,0x00}, +//钟135 + {0x88,0x97,0xF4,0x94,0x94,0x00,0xF8,0x88,0xFF,0x88,0xF8,0x00,0x00,0x00,0x0F,0x04,0x02,0x00,0x01,0x00,0x0F,0x00,0x01,0x00}, +//厂136 + {0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, +//确137 + {0x42,0xF2,0x2E,0xE2,0x00,0xF4,0x53,0xF2,0x5A,0x56,0xF0,0x00,0x00,0x07,0x02,0x07,0x08,0x07,0x01,0x07,0x01,0x09,0x0F,0x00}, +//重138 + {0x08,0xFA,0xAA,0xAA,0xAA,0xFE,0xA9,0xA9,0xA9,0xF9,0x08,0x00,0x08,0x0A,0x0A,0x0A,0x0A,0x0F,0x0A,0x0A,0x0A,0x0A,0x08,0x00}, +//启139 + {0x00,0x00,0xFC,0xA4,0xA4,0xA5,0xA6,0xA4,0xA4,0xA4,0xBC,0x00,0x08,0x06,0x01,0x0F,0x04,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//生140 + {0x20,0x10,0x8E,0x88,0x88,0xFF,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x08,0x00}, +//油141 + {0x10,0x22,0x04,0x00,0xFC,0x44,0x44,0xFF,0x44,0x44,0xFC,0x00,0x04,0x02,0x01,0x00,0x0F,0x04,0x04,0x07,0x04,0x04,0x0F,0x00}, +//门142 + {0x00,0xF9,0x02,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x00}, +//指143 + {0x88,0x88,0xFF,0x48,0x00,0xCF,0x54,0x54,0x52,0x52,0xD9,0x00,0x00,0x08,0x0F,0x00,0x00,0x0F,0x05,0x05,0x05,0x05,0x0F,0x00}, +//数144 + {0x48,0x2A,0x98,0x7F,0x28,0x4A,0x10,0xEF,0x08,0xF8,0x08,0x00,0x09,0x0B,0x05,0x05,0x0B,0x00,0x08,0x05,0x02,0x05,0x08,0x00}, +//画145 + {0xFD,0x01,0xFD,0x25,0x25,0xFD,0x25,0x25,0xFD,0x01,0xFD,0x00,0x07,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x04,0x0F,0x00}, +//面146 + {0x02,0xF2,0x12,0x12,0xFA,0x56,0x52,0xF2,0x12,0x12,0xF2,0x00,0x00,0x0F,0x04,0x04,0x07,0x05,0x05,0x07,0x04,0x04,0x0F,0x00}, +//或147 + {0x04,0xF4,0x94,0x94,0xF4,0x04,0xFF,0x04,0xC5,0x36,0x04,0x00,0x04,0x04,0x04,0x02,0x0A,0x04,0x02,0x01,0x02,0x04,0x0F,0x00}, +//按148 + {0x88,0x88,0xFF,0x48,0x00,0x4C,0xC4,0x75,0x46,0xC4,0x4C,0x00,0x00,0x08,0x0F,0x00,0x08,0x08,0x05,0x02,0x02,0x05,0x08,0x00}, +//菜149 + {0x12,0x32,0x52,0x17,0x32,0xD2,0x12,0x4F,0x2A,0x0A,0x02,0x00,0x09,0x09,0x05,0x03,0x01,0x0F,0x01,0x03,0x05,0x09,0x09,0x00}, +//单150 + {0x00,0x7C,0x55,0x56,0x54,0xFC,0x54,0x56,0x55,0x7C,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,0x01,0x01,0x00}, +//键151 + {0x94,0xF3,0x92,0x64,0xDC,0x88,0xAA,0xFF,0xAA,0xBE,0x08,0x00,0x00,0x0F,0x04,0x0A,0x07,0x0A,0x0A,0x0F,0x0A,0x0A,0x0A,0x00}, +//好152 + {0x88,0x78,0x0F,0x88,0x78,0x42,0x42,0xF2,0x4A,0x46,0x40,0x00,0x08,0x05,0x02,0x05,0x08,0x00,0x08,0x0F,0x00,0x00,0x00,0x00}, +//过153 + {0x10,0x11,0xF2,0x00,0x08,0x28,0xC8,0x08,0x08,0xFF,0x08,0x00,0x08,0x04,0x03,0x04,0x08,0x08,0x08,0x0A,0x0A,0x0B,0x08,0x00}, +//原154 + {0x00,0xFE,0x02,0xFA,0xAA,0xAE,0xAA,0xAA,0xAA,0xFA,0x02,0x00,0x08,0x07,0x08,0x04,0x02,0x08,0x0F,0x00,0x02,0x04,0x08,0x00}, +//始155 + {0x88,0x78,0x0F,0xF8,0x00,0xD8,0x54,0x53,0x50,0xD8,0x30,0x00,0x08,0x05,0x02,0x0D,0x00,0x0F,0x04,0x04,0x04,0x0F,0x00,0x00}, +//据156 + {0x88,0x88,0xFF,0x48,0x00,0xFE,0xAA,0xAA,0xFA,0xAA,0xAE,0x00,0x00,0x08,0x0F,0x08,0x06,0x01,0x0F,0x04,0x04,0x04,0x0F,0x00}, +//随157 + {0xFF,0x31,0xCF,0x48,0xD2,0x0A,0xFE,0xAB,0xAA,0xFA,0x02,0x00,0x0F,0x02,0x01,0x08,0x07,0x08,0x0B,0x08,0x0A,0x0B,0x08,0x00}, +//感158 + {0x00,0xFE,0x02,0xEA,0xAA,0xEA,0x02,0x9F,0x62,0x9B,0xC2,0x00,0x09,0x06,0x00,0x06,0x08,0x0A,0x0D,0x08,0x0C,0x02,0x0D,0x00}, +//型159 + {0x90,0x52,0x3E,0x12,0x12,0x7E,0x12,0x00,0x3E,0x80,0xFF,0x00,0x08,0x0A,0x0A,0x0A,0x0A,0x0F,0x0A,0x0A,0x0A,0x0A,0x08,0x00}, +//状160 + {0x04,0x88,0xFF,0x00,0x10,0x10,0xD0,0x3F,0xD0,0x12,0x14,0x00,0x01,0x00,0x0F,0x00,0x08,0x06,0x01,0x00,0x01,0x06,0x08,0x00}, +//态161 + {0x44,0x44,0x24,0x14,0x0C,0xA7,0x4C,0x14,0x24,0x44,0x44,0x00,0x04,0x03,0x00,0x07,0x08,0x08,0x0B,0x08,0x0C,0x01,0x06,0x00}, +//选162 + {0x10,0x11,0xF2,0x00,0x28,0x26,0xE4,0x3F,0xE4,0x24,0x20,0x00,0x08,0x04,0x03,0x04,0x0A,0x09,0x08,0x08,0x09,0x0A,0x0B,0x00}, +//择163 + {0x88,0x88,0xFF,0x48,0x21,0xA3,0x95,0xE9,0x95,0xA3,0x20,0x00,0x00,0x08,0x0F,0x00,0x02,0x02,0x02,0x0F,0x02,0x02,0x02,0x00}, +//命164 + {0x10,0xD0,0x48,0x54,0xD2,0x11,0xD2,0x54,0x48,0xD0,0x10,0x00,0x00,0x07,0x02,0x02,0x07,0x00,0x0F,0x00,0x04,0x07,0x00,0x00}, +//名165 + {0x00,0x10,0x88,0x94,0xE7,0xC4,0xA4,0xA4,0x94,0x8C,0x80,0x00,0x01,0x01,0x00,0x0F,0x04,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//复166 + {0x04,0x02,0x7D,0xD5,0x55,0x55,0x55,0x55,0x55,0x7D,0x01,0x00,0x00,0x0A,0x09,0x0B,0x05,0x05,0x05,0x05,0x0B,0x09,0x08,0x00}, +//监167 + {0x00,0x9E,0x80,0x80,0xBF,0x90,0x88,0x87,0x94,0xA4,0x04,0x00,0x08,0x0F,0x08,0x08,0x0F,0x08,0x0F,0x08,0x08,0x0F,0x08,0x00}, +//视168 + {0x84,0x45,0xF6,0x2C,0x40,0xFE,0x02,0xFA,0x02,0xFE,0x00,0x00,0x00,0x00,0x0F,0x00,0x08,0x04,0x03,0x00,0x07,0x08,0x0C,0x00}, +//制169 + {0x18,0xD6,0x54,0xFF,0x54,0xD4,0x10,0xFC,0x00,0x00,0xFF,0x00,0x00,0x07,0x00,0x0F,0x04,0x07,0x00,0x01,0x08,0x08,0x0F,0x00}, +//归170 + {0xFC,0x00,0x00,0xFF,0x00,0x02,0x22,0x22,0x22,0x22,0xFE,0x00,0x01,0x08,0x06,0x01,0x00,0x04,0x04,0x04,0x04,0x04,0x0F,0x00}, +//位171 + {0x10,0xFC,0x03,0x08,0x68,0x88,0x09,0x0A,0x08,0xE8,0x08,0x00,0x00,0x0F,0x00,0x08,0x08,0x0B,0x08,0x0C,0x0B,0x08,0x08,0x00}, +//起172 + {0x20,0xA4,0x24,0xFF,0x24,0x00,0xF2,0x12,0x12,0x1E,0x80,0x00,0x08,0x07,0x04,0x0F,0x09,0x08,0x09,0x0A,0x0A,0x0A,0x0B,0x00}, +//终173 + {0x98,0xD4,0xB3,0x08,0x48,0x44,0xAB,0x92,0x2A,0x46,0x40,0x00,0x04,0x04,0x02,0x02,0x00,0x02,0x02,0x04,0x05,0x08,0x00,0x00}, +//分174 + {0x20,0x10,0x2C,0x23,0xE0,0x20,0x20,0x23,0xEC,0x10,0x20,0x00,0x00,0x08,0x04,0x03,0x00,0x08,0x08,0x08,0x07,0x00,0x00,0x00}, +//电175 + {0xFC,0x24,0x24,0x24,0xFF,0x24,0x24,0x24,0xFC,0x00,0x00,0x00,0x03,0x01,0x01,0x01,0x07,0x09,0x09,0x09,0x09,0x08,0x0E,0x00}, +//到176 + {0x92,0x9A,0x96,0xF2,0x92,0x9A,0xB2,0x00,0xFC,0x00,0xFF,0x00,0x08,0x08,0x08,0x07,0x04,0x04,0x04,0x00,0x01,0x08,0x0F,0x00}, +//贴177 + {0xFE,0x02,0xFA,0x02,0xFE,0x00,0xC0,0x40,0x7F,0x48,0xC8,0x00,0x09,0x04,0x03,0x04,0x09,0x00,0x0F,0x04,0x04,0x04,0x0F,0x00}, +//大178 + {0x10,0x10,0x10,0x10,0xD0,0x3F,0xD0,0x10,0x10,0x10,0x10,0x00,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x00}, +//小179 + {0x00,0xC0,0x30,0x00,0x00,0xFF,0x00,0x00,0x10,0x60,0x80,0x00,0x01,0x00,0x00,0x08,0x08,0x0F,0x00,0x00,0x00,0x00,0x01,0x00}, +//平180 + {0x80,0x8A,0xB2,0x82,0x82,0xFE,0x82,0x82,0xA2,0x9A,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, +//定181 + {0x2C,0x24,0xA4,0x24,0x25,0xE6,0x24,0x24,0x24,0x24,0x2C,0x00,0x08,0x04,0x03,0x04,0x08,0x0F,0x09,0x09,0x09,0x09,0x08,0x00}, +//时182 + {0xFE,0x22,0x22,0xFE,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x00,0x07,0x02,0x02,0x07,0x00,0x00,0x00,0x09,0x08,0x0F,0x00,0x00}, +//大183 + {0x10,0x10,0x10,0x10,0xD0,0x3F,0xD0,0x10,0x10,0x10,0x10,0x00,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x00}, +//小184 + {0x00,0xC0,0x30,0x00,0x00,0xFF,0x00,0x00,0x10,0x60,0x80,0x00,0x01,0x00,0x00,0x08,0x08,0x0F,0x00,0x00,0x00,0x00,0x01,0x00}, +//危185 + {0x10,0x08,0xFC,0x0B,0xEA,0x2A,0x2A,0x2A,0x2E,0xE8,0x08,0x00,0x08,0x06,0x01,0x00,0x07,0x08,0x08,0x09,0x09,0x08,0x0E,0x00}, +//险186 + {0xFE,0x02,0x32,0xCE,0x10,0x28,0xA4,0x23,0x24,0xA8,0x10,0x00,0x0F,0x02,0x02,0x01,0x09,0x0E,0x08,0x0B,0x0C,0x0B,0x08,0x00}, +//对187 + {0x24,0xC4,0x04,0xC4,0x3C,0x00,0x48,0x88,0x08,0xFF,0x08,0x00,0x08,0x06,0x01,0x02,0x0C,0x00,0x00,0x09,0x08,0x0F,0x00,0x00}, +//比188 + {0x00,0xFF,0x10,0x10,0x10,0x00,0xFF,0x20,0x10,0x08,0x04,0x00,0x00,0x0F,0x04,0x02,0x01,0x00,0x07,0x08,0x08,0x08,0x0E,0x00}, +//左189 + {0x04,0x04,0x84,0x74,0x4F,0x44,0xC4,0x44,0x44,0x44,0x04,0x00,0x04,0x02,0x09,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x00}, +//右190 + {0x04,0x04,0x84,0xE4,0x5C,0x47,0x44,0x44,0x44,0xC4,0x04,0x00,0x02,0x01,0x00,0x0F,0x04,0x04,0x04,0x04,0x04,0x0F,0x00,0x00}, +//手191 + {0x80,0x92,0x92,0x92,0x92,0xFE,0x91,0x91,0x91,0x91,0x80,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, +//PPM 192 + {0x04,0xFC,0xFC,0x44,0x44,0x7C,0x38,0x00,0x04,0xFC,0xFC,0x44,0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x08}, +//PPM 193 + {0x44,0x7C,0x38,0x00,0xFC,0xFC,0x38,0x70,0x38,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00}, +//检194 + {0x88,0x68,0xFF,0x48,0x10,0x28,0xA4,0x23,0x24,0xA8,0x10,0x00,0x00,0x00,0x0F,0x00,0x09,0x0E,0x08,0x0B,0x0C,0x0B,0x08,0x00}, +//锁195 + {0x94,0xF3,0x92,0x00,0xF2,0x14,0x10,0xDF,0x10,0x14,0xF2,0x00,0x00,0x0F,0x04,0x08,0x09,0x04,0x02,0x01,0x02,0x04,0x09,0x00}, +//计196 + {0x10,0x11,0xF2,0x00,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x00,0x00,0x00,0x07,0x02,0x01,0x00,0x00,0x0F,0x00,0x00,0x00,0x00}, +//步197 + {0x20,0x20,0x3E,0xA0,0x20,0xBF,0x24,0x24,0x24,0xA4,0x20,0x00,0x00,0x0A,0x09,0x08,0x04,0x07,0x02,0x02,0x01,0x00,0x00,0x00}, +//进198 + {0x10,0x11,0xF2,0x40,0x44,0xFF,0x44,0x44,0xFF,0x44,0x40,0x00,0x08,0x04,0x03,0x04,0x0A,0x09,0x08,0x08,0x0B,0x08,0x08,0x00}, +//停199 + {0x20,0x10,0xFC,0x03,0x82,0xBA,0xAA,0xAB,0xAA,0xBA,0x82,0x00,0x00,0x00,0x0F,0x00,0x01,0x02,0x0A,0x0E,0x02,0x02,0x01,0x00}, +//止200 + {0x00,0x00,0xF8,0x00,0x00,0x00,0xFF,0x10,0x10,0x10,0x00,0x00,0x08,0x08,0x0F,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x00}, +//原201 + {0x00,0xFE,0x02,0xFA,0xAA,0xAE,0xAA,0xAA,0xAA,0xFA,0x02,0x00,0x08,0x07,0x08,0x04,0x02,0x08,0x0F,0x00,0x02,0x04,0x08,0x00}, +//新202 + {0x20,0xAA,0xB2,0xE3,0xB2,0xAA,0x00,0xFE,0x12,0xF2,0x11,0x00,0x04,0x02,0x08,0x0F,0x00,0x0A,0x04,0x03,0x00,0x0F,0x00,0x00}, +//组203 + {0x98,0xD4,0xB3,0x88,0x00,0xFE,0x92,0x92,0x92,0xFE,0x00,0x00,0x04,0x04,0x02,0x02,0x08,0x0F,0x08,0x08,0x08,0x0F,0x08,0x00}, +//合204 + {0x10,0x90,0xA8,0xA4,0xA2,0xA1,0xA2,0xA4,0xA8,0x90,0x10,0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0F,0x00,0x00}, +//段205 + {0x00,0xFE,0x2A,0xA9,0x00,0x28,0xE7,0x21,0x21,0xEF,0x08,0x00,0x02,0x0F,0x01,0x00,0x08,0x08,0x05,0x02,0x05,0x08,0x08,0x00}, +//力206 + {0x08,0x08,0x08,0x88,0x7F,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x08,0x08,0x08,0x07,0x00,0x00}, +//芯207 + {0x04,0x84,0x04,0xCF,0x04,0x24,0xC4,0x0F,0x04,0x84,0x04,0x00,0x04,0x03,0x00,0x07,0x08,0x08,0x08,0x08,0x0E,0x00,0x07,0x00}, +//片208 + {0x00,0x00,0xFE,0x90,0x90,0x90,0x90,0x9F,0x90,0x10,0x10,0x00,0x08,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00}, +//保209 + {0x20,0x10,0xFC,0x03,0x40,0x5E,0x52,0xF2,0x52,0x5E,0x40,0x00,0x00,0x00,0x0F,0x00,0x04,0x02,0x01,0x0F,0x01,0x02,0x04,0x00}, +//存210 + {0x84,0x44,0xF4,0x0C,0x87,0x94,0x94,0xD4,0xB4,0x94,0x84,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08,0x0F,0x00,0x00,0x00,0x00}, +//清211 + {0x22,0x44,0x22,0xEA,0xAA,0xAA,0xBF,0xAA,0xAA,0xEA,0x22,0x00,0x04,0x02,0x00,0x0F,0x02,0x02,0x02,0x02,0x0A,0x0F,0x00,0x00}, +//零212 + {0x0C,0x25,0xAD,0xAD,0x45,0xBF,0x45,0xAD,0xAD,0x25,0x0C,0x00,0x01,0x01,0x00,0x05,0x05,0x05,0x0B,0x09,0x00,0x01,0x01,0x00}, +//方213 + {0x04,0x04,0x04,0xFC,0x25,0x26,0x24,0x24,0x24,0xE4,0x04,0x00,0x08,0x04,0x03,0x00,0x00,0x00,0x08,0x08,0x08,0x07,0x00,0x00}, + + + + + + + + + + + +}; + +const unsigned char screen1[]= //遥控界面 +{ +0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0xFF,0xFF,0x7F,0x07,0x03, +0x03,0x00,0x00,0x00,0x00,0xE0,0xF8,0xFC,0x1E,0x06,0x03,0x03,0x03,0x03,0x07,0xFE, +0xFC,0xF8,0x00,0x00,0xC3,0xFF,0xFF,0x7F,0x07,0x03,0x03,0x00,0x00,0x00,0x00,0x00, +0xC3,0xFF,0xFF,0x7F,0x07,0x03,0x03,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,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00, +0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x58,0x58,0x5C,0x5F,0x5F,0x5F,0x58,0x58,0x58, +0x5C,0x5E,0x47,0x41,0x40,0x43,0x47,0x4F,0x5C,0x58,0x58,0x58,0x58,0x4C,0x4F,0x47, +0x43,0x58,0x58,0x5C,0x5F,0x5F,0x5F,0x58,0x58,0x58,0x5C,0x5E,0x47,0x59,0x58,0x5C, +0x5F,0x5F,0x5F,0x58,0x00,0x42,0x7E,0x42,0x7E,0x42,0x7E,0x42,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, +0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x78,0x4E,0x49,0x59,0x59,0x49,0x4E,0x78, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x3E, +0x51,0x49,0x45,0x3E,0x00,0x24,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x3E,0x51,0x49, +0x45,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x3E, +0x51,0x49,0x45,0x3E,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x40,0x00,0x3E,0x51,0x49, +0x45,0x3E,0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00,0x3E,0x22,0x7F,0x41,0x5D,0x5D, +0x5D,0x5D,0x5D,0x5D,0x5D,0x5D,0x5D,0x5D,0x41,0x7F,0x00,0x00,0x00,0xFF,0x00,0x00, +0xF0,0x48,0xFF,0x48,0xF0,0x00,0x00,0xFE,0x01,0x01,0x01,0x01,0xFE,0x00,0x18,0x0E, +0x19,0x01,0x7D,0x46,0x44,0x7C,0x00,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x40,0x00, +0x3E,0x51,0x49,0x45,0x3E,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x1F,0x20,0x40,0x20, +0x1F,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0xFF,0x48,0xF0, +0x01,0x02,0xFF,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x18,0x24, +0x44,0x4E,0x0A,0x0A,0x0A,0x0E,0x00,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x40,0x00, +0x3E,0x51,0x49,0x45,0x3E,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x1F,0x20,0x40,0x20, +0x1F,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0xFF,0x02,0x01, +0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x1F, +0x01,0x20,0x30,0x38,0x3C,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x46,0x26,0x10,0x08,0x64,0x62, +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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, +0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00,0x80,0xFF,0x00,0x0F,0x05, +0x07,0x48,0x60,0x70,0x78,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x46,0x26,0x10,0x08,0x64,0x62, +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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, +0x00,0x00,0x03,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x54,0x54, +0x7C,0x54,0x54,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x54,0x54,0x7C, +0x54,0x54,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x03,0x00,0x00, +}; + +const unsigned char screen2[]= //NRF TEST +{ +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,0xFF, +0x01,0x01,0x01,0xF9,0x09,0x09,0x79,0x41,0x41,0x79,0x09,0x09,0x79,0x41,0x41,0x79, +0x09,0x09,0x09,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xFE,0x02,0x02,0xFE,0x00,0x00,0x08,0xC8,0xFF,0x48,0x80,0xF4,0x5F, +0x54,0x54,0x54,0x5F,0xF4,0x04,0x00,0x10,0x10,0xFF,0x10,0x90,0x84,0x84,0xFF,0x84, +0x84,0x84,0xFC,0x80,0x00,0x10,0x28,0xE7,0x24,0x24,0x00,0xA4,0xBF,0xA4,0xA4,0xBF, +0xA4,0x20,0x00,0x20,0x21,0xE6,0x00,0x00,0x4F,0x49,0x49,0xC9,0x49,0x49,0x4F,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,0xFF, +0x00,0x00,0x80,0x9B,0x00,0x00,0x18,0x80,0x98,0x80,0x98,0x00,0x18,0xC0,0x20,0x20, +0xC0,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3B,0x2A,0x2A,0x3B,0x00,0x00,0x01,0x00,0x3F,0x00,0x24,0x25,0x15, +0x0D,0x07,0x0D,0x15,0x25,0x24,0x00,0x04,0x04,0x07,0x02,0x22,0x10,0x0C,0x03,0x00, +0x03,0x0C,0x10,0x20,0x00,0x01,0x01,0x3F,0x11,0x09,0x00,0x3F,0x24,0x24,0x24,0x24, +0x3F,0x00,0x00,0x00,0x00,0x1F,0x08,0x22,0x12,0x0A,0x06,0x03,0x06,0x0A,0x12,0x22, +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,0xFF, +0x00,0x00,0xE5,0xA5,0xA0,0xA0,0xE0,0xA7,0xA7,0xA7,0xE7,0xA0,0xA0,0xA7,0xE8,0xA8, +0xA7,0xA0,0xE0,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xC0,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,0x0F, +0xF8,0x08,0x0B,0x0A,0x0A,0x0A,0x0B,0x0A,0x0A,0x0A,0xFB,0x0A,0x0A,0x0A,0x0B,0x0A, +0x0A,0x0A,0x0B,0x08,0xF8,0x0F,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, +0x05,0x05,0x05,0xFD,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,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, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,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, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,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, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,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,0xF8,0x88,0x88,0x00,0xF8,0xA8,0xA8, +0x00,0x00,0x00,0x00,0xF8,0x88,0x88,0x00,0xF8,0x80,0x80,0x00,0xF8,0x20,0x50,0x00, +0x00,0x00,0x00,0xF8,0x10,0xF8,0x00,0x88,0xF8,0x88,0x00,0xB8,0xA8,0xE8,0x00,0x70, +0x88,0x70,0x00,0x00,0x00,0x88,0xF8,0x88,0x00,0xF8,0x28,0x78,0x80,0x00,0x38,0x28, +0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0xF8,0x00,0x70,0x88,0x70,0x00,0xB8,0xA8, +0xE8,0x00,0x88,0xF8,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x88,0x88,0x00, +0xB8,0xA8,0xE8,0x00,0xF8,0x10,0x20,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + + +const unsigned char name6[72]= //SU27 +{ +0x18,0x3C,0x64,0x44,0xC4,0x9C,0x18,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC, +0x00,0x00,0x08,0x0C,0x84,0xC4,0x64,0x3C,0x18,0x00,0x00,0x0C,0x0C,0x04,0x84,0xC4, +0x7C,0x3C,0x00,0x00,0x06,0x0E,0x08,0x08,0x08,0x0F,0x07,0x00,0x00,0x07,0x0F,0x08, +0x08,0x08,0x0F,0x07,0x00,0x00,0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0C,0x00,0x00,0x00, +0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00 +}; \ No newline at end of file