新增PageVersion分支并提交对应代码

This commit is contained in:
Silent Sheep 2024-02-19 11:50:46 +08:00
parent 1d7d10dfb2
commit 2482979960
35 changed files with 4151 additions and 0 deletions

View File

@ -0,0 +1,11 @@
# 本文件夹的一些小说明
## 文件目录
```c
|---example(使用接口函数构建的例子需要使用接口函数构建的可以参考这个文件夹下的例子共有2个)
|---LittleClock(一个用air001的小时钟)
|---UITest(页面展示的例子,基本上所有页面类型都有用到)
|---src(主要的源代码文件7个文件不包含oled_port.c)
```

View File

@ -0,0 +1,338 @@
#include "LittleClockUI.h"
#include "string.h"
#include "System.h"
#include "BATADC.h"
//定义的跨文件的全局变量
uint16_t fps = 0; //帧率
uint8_t update_flag = 0;
//-------枚举id唯一标识一个页面防止有两个页面使用同一id
enum
{
main_page_id = 0x00,
calendar_page_id,
clock_page_id,
alarm_list_page_id,
alarm1_page_id,
alarm2_page_id,
about_page_id,
ring_page_id, //这个页面是单独游离的,只有闹钟时才会调出来
};
//--------定义页面对象
TitlePage main_page;
DigitalPage calendar_page;
DigitalPage clock_page;
ListPage alarm_list_page;
DigitalPage alarm1_page;
DigitalPage alarm2_page;
RaderPicPage about_page;
RaderPicPage ring_page; //闹钟响起时的界面(空的RaderPicPage页面用于自己绘制)
//--------定义每个页面需要的一些参数
//部分页面内选项个数
#define MAIN_PAGE_NUM 5
#define CALENDAR_LABEL_NUM 7
#define ALARM_LIST_PAGE_NUM 3
#define ALARM12_LABEL_NUM 3
#define ABOUT_PAGE_NUM 1
//定义部分页面选项
//********main页面的选项
Option mian_option_array[MAIN_PAGE_NUM] =
{///{ order,max,min,step,int_val,text,} //option的成员顺序但对单纯title的页面来说只有text需要赋值
{.text = "- Calendar"}, //前两个字符是前缀,不显示,用于标识一般选项(-),二值选项(+),数值弹窗(~),确认弹窗($)
{.text = "- Clock"},
{.text = "- Alarm"},
{.text = "~ BATLevel", .item_max = 100, .item_min = 0, .step = 0,.val = 50,},
//数值弹窗电压显示(step = 0则为只读无法使用按键编辑(其实就是使操作+-0无效))
{.text = "- Aoubt"},
};
//main页面的图标
Icon main_icon_array[MAIN_PAGE_NUM] =
{
[0] = {0xF0,0xF8,0x38,0x38,0x38,0x38,0x7F,0xFF,0x7F,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
0x38,0x38,0x38,0x38,0x38,0x7F,0xFF,0xFF,0x38,0x38,0x38,0x38,0xF8,0xF0,0xFF,0xFF,
0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x8E,0x8E,0xCE,0xCE,0x0E,0x0E,
0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFF,0xFF,0xFF,0xFF,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x1F,0x3F,0x38,0x38,0x38,0x38,
0x38,0x38,0x38,0x38,0x38,0x39,0x3B,0x3B,0x39,0x39,0x3B,0x3B,0x39,0x38,0x38,0x38,
0x38,0x38,0x38,0x38,0x38,0x38,0x3F,0x1F}, //Canlendar
[1] = {0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x1C,0x0E,0x06,0x07,0x07,0x07,0x03,0xE3,0xE3,
0x03,0x07,0x07,0x07,0x06,0x0E,0x1C,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0xFC,0xFF,
0x1F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x1F,0xFF,0xFC,0x0F,0x3F,0xFE,0xE0,
0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x07,
0x07,0x07,0x07,0x06,0x0E,0xCE,0xE2,0xFE,0x3F,0x0F,0x00,0x00,0x00,0x01,0x03,0x07,
0x0E,0x0E,0x1C,0x18,0x38,0x38,0x38,0x30,0x30,0x30,0x30,0x38,0x38,0x38,0x18,0x1C,
0x0E,0x0E,0x07,0x03,0x01,0x00,0x00,0x00}, //clock
[2] = {0xF0,0xF8,0x9C,0xCE,0xEE,0x76,0xBE,0xDC,0xEC,0x60,0x70,0x30,0x38,0x38,0xF8,0xF8,
0x38,0x38,0x30,0x30,0x70,0xEC,0xDC,0xFE,0xF6,0xEE,0xCE,0x9C,0xFC,0xF0,0x01,0x03,
0xE7,0xFB,0xFF,0x0F,0x03,0x01,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0xFE,0xFD,0xE7,0x03,0x01,0x00,0x00,0x01,0x1F,
0x7F,0xF8,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xC0,0xF0,0x7F,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x0C,0x1E,0x0F,
0x07,0x03,0x07,0x07,0x0E,0x0E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x0E,0x07,0x07,
0x03,0x03,0x07,0x0E,0x1C,0x08,0x00,0x00}, //alarm
[3] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,
0x30,0x18,0x18,0x10,0x30,0x70,0xD8,0x98,0x18,0x30,0xE0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xC0,0xE0,0x30,0x18,0x4C,0x26,0x13,0x03,0x01,0x00,0x00,0x00,0x00,
0x0A,0x04,0x0A,0x00,0x00,0x81,0xC2,0x6F,0x39,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,
0x41,0x81,0x00,0x10,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x18,
0x0C,0x06,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x02,0x06,0x0C,0x08,0x08,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //Bat level
[4] = {0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x1C,0x0E,0x06,0x07,0x07,0x07,0x03,0x03,0x03,
0x03,0x03,0x07,0x07,0x06,0x0E,0x1C,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0xFC,0xFF,
0x1F,0x01,0x00,0xC0,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xE0,0xE0,0xC0,0x00,
0x00,0x00,0x00,0xC0,0xE0,0xE0,0xC0,0x00,0x01,0x1F,0xFF,0xF8,0x0F,0x3F,0xFE,0xE0,
0xC0,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x01,0x00,0xC0,0xF0,0xFE,0x3F,0x0F,0x00,0x00,0x00,0x01,0x03,0x07,
0x0E,0x0E,0x1C,0x18,0x38,0x38,0x38,0x30,0x30,0x30,0x30,0x38,0x38,0x38,0x18,0x1C,
0x0E,0x0E,0x07,0x03,0x01,0x00,0x00,0x00}, //more
};
//Calendar 页面的选项
Option calendar_option_array[3] =
{///{ order,max,min,step,int_val,text,}
[Digital_Pos_IndexLeft] = { .item_max = 99, .item_min = 0, .step = 1, .text = "Year"},
[Digital_Pos_IndexMid] = { .item_max = 12, .item_min = 1, .step = 1, .text = "Month"},
[Digital_Pos_IndexRight] = { .item_max = 31, .item_min = 1, .step = 1, .text = "day"},
};
//标签数组
String week_str[CALENDAR_LABEL_NUM] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
//Clock页面选项
Option clock_option_array[3]=
{
[Digital_Pos_IndexLeft] = { .item_max = 23, .item_min = 0, .step = 1, .text = "Hour"},
[Digital_Pos_IndexMid] = { .item_max = 59, .item_min = 0, .step = 1, .text = "Minute"},
[Digital_Pos_IndexRight] = { .item_max = 59, .item_min = 0, .step = 1, .text = "Second"},
};
//alarm页面选项
Option alarm_list_option_array[3]=
{
{.text = " alarm list"},
{.text = "+ Alarm1", .val = 0,}, //为二值选项单选项值由Alarm12页面控制(读全局update_flag中enable_msk位可以设置)
{.text = "+ Alarm2", .val = 0,}, //默认值为0close
};
//alarm1页面选项
Option alarm1_option_array[3]=
{
[Digital_Pos_IndexLeft] = { .item_max = 23, .item_min = 0, .step = 1, .text = "Hour"},
[Digital_Pos_IndexMid] = { .item_max = 59, .item_min = 0, .step = 1, .text = "Minute"},
[Digital_Pos_IndexRight] = { .item_max = 59, .item_min = 0, .step = 1, .text = "Second"},
};
Option alarm2_option_array[3]=
{
[Digital_Pos_IndexLeft] = { .item_max = 23, .item_min = 0, .step = 1, .text = "Hour"},
[Digital_Pos_IndexMid] = { .item_max = 59, .item_min = 0, .step = 1, .text = "Minute"},
[Digital_Pos_IndexRight] = { .item_max = 59, .item_min = 0, .step = 0, .text = "Second"},
//DS3231只有两个闹钟且闹钟2的秒无效所以alarm2的step为0,为不可编辑模式
//(因为air001的内存不够也不想做软件闹钟了)
};
String alarm12_label_array[3] = { "Close", "Open", "Delete"};
//About页面
const uint8_t QRCode[] = {
0xFF,0xFF,0xFF,0x07,0x07,0xE7,0x27,0x27,0x27,0x27,0x27,0x27,0xE7,0x07,0x07,0xFF,
0xFF,0xDF,0x1F,0x1F,0x27,0x27,0x27,0x27,0xFF,0xC7,0xC7,0x27,0x27,0x1F,0x1F,0xFF,
0xFF,0xFF,0x07,0x07,0xE7,0x27,0x27,0x27,0x27,0x27,0x27,0xE7,0x07,0x07,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x80,0x9F,0x90,0x90,0x90,0x90,0x90,0x90,0x9F,0x80,
0x80,0xFF,0xFF,0x93,0xF0,0xF0,0x90,0x90,0xF3,0xF3,0x90,0x6F,0x6F,0x9F,0x9F,0xEC,
0xEC,0x0F,0xFF,0xFF,0x80,0x80,0x9F,0x90,0x90,0x90,0x90,0x90,0x90,0x9F,0x80,0x80,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x01,0x3F,0x31,0x31,0x3F,0x3F,0xF1,0xF1,
0x3F,0xCD,0xCD,0xC3,0xC3,0xCF,0x0F,0x0F,0xFF,0xFF,0x03,0x03,0x3F,0x00,0x00,0xCF,
0xCF,0xFD,0xFD,0x0C,0x3F,0x3F,0x03,0x03,0x0F,0xCD,0xCD,0xFF,0xFF,0xCF,0xCF,0x0D,
0xC3,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x66,0x66,0x9E,0x86,0x86,0x9F,0x9F,
0x07,0x07,0x80,0x66,0x66,0x66,0x66,0xFE,0x86,0x86,0xE0,0xE0,0x98,0x98,0x7F,0x87,
0x87,0xE7,0xE7,0xFE,0xFE,0x78,0x1F,0x1F,0x60,0x60,0x66,0x1F,0x1F,0x78,0x78,0xE7,
0xE7,0x86,0xE0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x03,0xF3,0x13,0x13,
0x13,0x13,0x13,0x13,0xF3,0x03,0x03,0xFF,0xFF,0x9C,0x00,0x00,0x73,0x73,0x10,0x10,
0xE0,0xEF,0xEF,0x80,0x80,0x70,0x70,0x00,0x1F,0x1F,0x93,0x93,0x1F,0x00,0x00,0x00,
0x00,0x7F,0x7F,0x80,0x80,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0xC0,0xCF,
0xC8,0xC8,0xC8,0xC8,0xC8,0xC8,0xCF,0xC0,0xC0,0xFF,0xFF,0xC9,0xC0,0xC0,0xFE,0xFE,
0xF6,0xF6,0xCF,0xF9,0xF9,0xFF,0xFF,0xF0,0xF0,0xC6,0xC8,0xC8,0xFF,0xFF,0xCE,0xF0,
0xF0,0xF6,0xF6,0xFE,0xFE,0xC7,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
}; //Qrcode
RaderPic qrcode_raderpic[ABOUT_PAGE_NUM] =
{
{.pic = QRCode, .start_x = 7, .start_y = 7, .w = 50, .h = 50, .rd = RD_RIGHT_DOWN},
};
//--------定义每个页面的回调函数
void MainPage_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order)
{
case 0: OLED_UIJumpToPage(self_page_id,&calendar_page); break;
case 1: OLED_UIJumpToPage(self_page_id,&clock_page); break;
case 2: OLED_UIJumpToPage(self_page_id,&alarm_list_page); break;
case 3: //更新电量
select_item->val = BATADC_Read();
break;
case 4: OLED_UIJumpToPage(self_page_id,&about_page); break;
default: break;
}
}
void CalendarPage_CallBack(uint8_t self_page_id,Option* select_item)
{
uint8_t month_days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
switch (select_item->order)
{
case Digital_Pos_Complete : //全部数据设置完成后,也会检测一次数据
SET_FLAG(update_flag,DATE_UPDATE_MSK); //同时会通知main函数设置rtc芯片
case Digital_Pos_IndexRight: //更正日期数据
if( calendar_page.option_array[Digital_Pos_IndexRight].val > //大于每个月的最大月数,更正日期
month_days[calendar_page.option_array[Digital_Pos_IndexMid].val -1])
OLED_DigitalPage_UpdateDigitalNumAnimation(&calendar_page,
calendar_page.option_array[Digital_Pos_IndexLeft].val,
calendar_page.option_array[Digital_Pos_IndexMid].val,
month_days[calendar_page.option_array[Digital_Pos_IndexMid].val -1], Digital_Direct_Decrease);
break;
default:break;
}
}
void ClockPage_CallBack(uint8_t self_page_id,Option* select_item)
{
if(select_item->order == Digital_Pos_Complete) //时间设置完成
SET_FLAG(update_flag,TIME_UPDATE_MSK); //通知主函数更新时间
}
void AlarmList_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order)
{
// case 0:
// OLED_UIJumpToPage(self_page_id, &ring_page); //只是作为绘制页面的跳转测试
// break;
case 1:
OLED_UIJumpToPage(self_page_id, &alarm1_page);
//设置其标签
alarm1_page.select_label_index = (!!FLAG_IS_SET(update_flag, ALARM1_ENABLE_MSK)); //将数值变量转为逻辑
break;
case 2:
OLED_UIJumpToPage(self_page_id, &alarm2_page);
alarm2_page.select_label_index = (!!FLAG_IS_SET(update_flag, ALARM2_ENABLE_MSK)); //将数值变量转为逻辑
break;
default :break;
}
}
void Alarm12_CallBack(uint8_t self_page_id,Option* select_item)
{
uint8_t update_msk = 0;
uint8_t enable_msk = 0;
if(self_page_id == alarm1_page_id){update_msk = ALARM1_UPDATE_MSK;enable_msk = ALARM1_ENABLE_MSK;}
else if(self_page_id == alarm2_page_id){update_msk = ALARM2_UPDATE_MSK;enable_msk = ALARM2_ENABLE_MSK;}
switch (select_item->order)
{
case Digital_Pos_Complete: //编辑完成
SET_FLAG(update_flag, update_msk);
break;
case Digital_Pos_IndexLabel: //click标签时
if(strcmp(select_item->text, alarm12_label_array[0]) == 0) //close
CLEAR_FLAG(update_flag,enable_msk);
else if(strcmp(select_item->text, alarm12_label_array[1]) == 0) //open
SET_FLAG(update_flag,enable_msk);
else if(strcmp(select_item->text, alarm12_label_array[2]) == 0) //Delete
{
CLEAR_FLAG(update_flag,enable_msk); //闹钟标志位关闭
if(self_page_id == alarm1_page_id)
OLED_DigitalPage_UpdateDigitalNumAnimation(&alarm1_page, 0,0,0,Digital_Direct_Decrease);
else if(self_page_id == alarm2_page_id)
OLED_DigitalPage_UpdateDigitalNumAnimation(&alarm2_page, 0,0,0,Digital_Direct_Decrease);
}
default:
break;
}
}
void About_CallBack(uint8_t self_page_id,Option* select_item)
{
uint8_t buff[10] = {0};
sprintf((char*)buff, "fps:%d",fps);
if(select_item->order == ABOUT_PAGE_NUM) //图像绘制完成后
{
OLED_WinDrawStr(&w_all, 64, 7, 16, buff);
OLED_WinDrawStr(&w_all, 64, 24, 16, "Scan");
OLED_WinDrawStr(&w_all, 64, 40, 16, "QrCode");
}
}
void Ring_CallBack(uint8_t self_page_id,Option* select_item)
{
static float x = 2;
static float x_trg = 12;
static uint8_t color = 1;
OLED_Animation(&x, &x_trg, 200);
OLED_WinDrawBMP(&w_all, 15, 15 , 30, 30 , main_icon_array[2], color); // 实色绘制闹钟图标
OLED_SetPointColor(2); //反色绘制
int16_t len = 62-2*x;
OLED_WinDrawRBox(&w_all, x, x, len, len,2);
OLED_SetPointColor(1); //恢复正常颜色
if(x == x_trg)
{
if(x_trg == 12){x_trg = 2;color =! color;}
else if(x_trg == 2){x_trg = 12;color =! color;}
}
if(FLAG_IS_SET(update_flag, ALARM1_RING_MSK))
OLED_WinDrawStr(&w_all, 60, 8, 16, "Alarm1");
else if((FLAG_IS_SET(update_flag, ALARM2_RING_MSK)))
OLED_WinDrawStr(&w_all, 60, 8, 16, "Alarm2");
OLED_WinDrawStr(&w_all, 60, 34, 8, "Press Any");
OLED_WinDrawStr(&w_all, 60, 44, 8, "Key to exit!");
}
//-------------一些需要用的内部函数
//--------------给主函数调用的接口函数
void LittleClockUI_Init(void)
{
OLED_Init(); //硬件的初始化
LL_mDelay(100);
OLED_ClearBuff(); //清空缓存
OLED_RefreshBuff(); //刷新屏幕(清空屏幕)
OLED_SetPointColor(1); //设置绘制颜色
OLED_UiInit(); //必要的ui参数初始化
OLED_TitlePageInit(&main_page, main_page_id, MAIN_PAGE_NUM, mian_option_array, main_icon_array, MainPage_CallBack);
OLED_DigitalPageInit(&calendar_page, calendar_page_id, calendar_option_array, CALENDAR_LABEL_NUM, week_str, '-', 0, 100, CalendarPage_CallBack);
OLED_DigitalPageInit(&clock_page, clock_page_id, clock_option_array, CALENDAR_LABEL_NUM, week_str, ':', 50, 100, ClockPage_CallBack); //时钟页面的标签也显示周
OLED_ListPageInit(&alarm_list_page, alarm_list_page_id, ALARM_LIST_PAGE_NUM, alarm_list_option_array, AlarmList_CallBack);
OLED_DigitalPageInit(&alarm1_page, alarm1_page_id, alarm1_option_array, ALARM12_LABEL_NUM, alarm12_label_array, ':', 50, 100, Alarm12_CallBack);
OLED_DigitalPageInit(&alarm2_page, alarm2_page_id, alarm2_option_array, ALARM12_LABEL_NUM, alarm12_label_array, ':', 50, 100, Alarm12_CallBack);
OLED_RaderPicPageInit(&about_page, about_page_id, ABOUT_PAGE_NUM, qrcode_raderpic, Rader_Pic_Mode_Hold, About_CallBack);
OLED_RaderPicPageInit(&ring_page, ring_page_id, 0, NULL, Rader_Pic_Mode_Hold, Ring_CallBack); //相当于一个空的页面可以自由绘制
}
void LittleClockUI_Proc(void)
{
OLED_UIProc();
//由updataflag接管 alarmlist中两个选框的选中与否
if(FLAG_IS_SET(update_flag,ALARM1_ENABLE_MSK))alarm_list_option_array[1].val = 1;
else alarm_list_option_array[1].val = 0;
if(FLAG_IS_SET(update_flag,ALARM2_ENABLE_MSK))alarm_list_option_array[2].val = 1;
else alarm_list_option_array[2].val = 0;
}

View File

@ -0,0 +1,33 @@
#ifndef __LITTLECLOCKUI_H__
#define __LITTLECLOCKUI_H__
#include "oled_ui.h"
#include "oled_g.h"
#include "oled_port.h"
void LittleClockUI_Init(void);
void LittleClockUI_Proc(void);
#define DATE_UPDATE_MSK 0x01
#define TIME_UPDATE_MSK 0x02
#define ALARM1_UPDATE_MSK 0x04
#define ALARM2_UPDATE_MSK 0x08 //用于检测update flag的置位
#define ALARM1_ENABLE_MSK 0x10
#define ALARM2_ENABLE_MSK 0x20 //用于检测update flag的置位
#define ALARM1_RING_MSK 0x40
#define ALARM2_RING_MSK 0x80 //主函数中置位,在响铃页面检测
#define SET_FLAG(flag, msk) (flag|=msk)
#define FLAG_IS_SET(flag, msk) (flag&msk)
#define CLEAR_FLAG(flag, msk) (flag&= (~msk))
extern uint16_t fps; // 外界需要提供一个变量统计一秒内UIproc能刷新几次粗略估计帧率'
extern uint8_t update_flag; //用于主函数中判断是否需要更新rtc芯片的数据
extern DigitalPage calendar_page;
extern DigitalPage clock_page; //用于主函数中1秒更新一次时间
extern DigitalPage alarm1_page;
extern DigitalPage alarm2_page;
extern RaderPicPage ring_page;
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

View File

@ -0,0 +1,332 @@
#include "TestUI.h"
#include "string.h"
#include "math.h"
#include "System.h"
//-------枚举id唯一标识一个页面防止有两个页面使用同一id
enum
{
main_page_id = 0x00,
logo_page_id,
setting_page_id,
curve_page_id,
lock_page_id,
about_page_id,
about_wououi_page_id,
about_page_version_id,
};
//--------定义页面对象
TitlePage main_page;
RaderPicPage logo_page;
ListPage setting_page;
WavePage curve_page;
DigitalPage lock_page;
ListPage about_page;
RadioPage about_wououi_page; //这两个相关页使用单选项RadioPage类型只是为了展示单选项页面而已
RadioPage about_page_version_page;
//--------定义每个页面需要的一些参数
//部分页面内选项个数
#define MAIN_PAGE_NUM 5
#define LOGO_PAGE_NUM 4
#define SETTING_PAGE_NUM 13
#define CURVE_PAGE_NUM 2
#define LOCK_PAGE_LABEL_NUM 2
#define ABOUT_PAGE_NUM 3
#define ABOUT_WOUOUI_PAGE_NUM 9
#define ABOUT_PAGEVERSION_NUM 8
//定义部分页面选项
//********main页面的选项
Option mian_option_array[MAIN_PAGE_NUM] =
{///{ order,max,min,step,int_val,text,} //option的成员顺序但对单纯title的页面来说只有text需要赋值
{.text = "- Logo"}, //前两个字符是前缀,不显示,用于标识一般选项(-),二值选项(+),数值弹窗(~),确认弹窗($)
{.text = "- Setting"},
{.text = "- Curve"},
{.text = "- DigLock"},
{.text = "- Aoubt"},
};
//main页面的图标
Icon main_icon_array[MAIN_PAGE_NUM] =
{
[0] = {0xFC,0xFE,0xFF,0x3F,0x1F,0x0F,0x07,0x03,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x03,0x07,0x07,0x0F,0x1F,0x3F,0xFF,0xFE,0xFC,0xFF,0x01,
0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,
0x00,0x00,0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xF0,0xC0,0x00,
0x00,0x00,0x03,0x07,0x0F,0x1F,0x3E,0x3C,0x3C,0x3C,0x1E,0x1F,0x0F,0x03,0x00,0x00,
0x1F,0x3F,0x3F,0x1F,0x00,0x00,0x00,0xC0,0xF0,0xFF,0xCF,0xDF,0xFF,0xFF,0xFE,0xFC,
0xF8,0xF8,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,
0xF8,0xF8,0xFC,0xFE,0xFF,0xFF,0xDF,0xCF}, //logo
[1] = {0xFC,0xFE,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x83,0x81,0x01,0x01,0x81,0xE1,0xE1,0xE1,
0xE1,0x81,0x01,0x81,0x81,0x83,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFE,0xFC,0xFF,0x01,
0x00,0x00,0x00,0xE0,0xE0,0xF3,0xFF,0xFF,0x3F,0x0F,0x07,0x07,0x03,0x03,0x07,0x07,
0x0F,0x3F,0xFF,0xFF,0xF7,0xE0,0xE0,0x00,0x00,0x00,0x01,0xFF,0xFF,0xE0,0x80,0x00,
0x00,0x01,0x01,0x3B,0x7F,0x7F,0x7F,0x3C,0x78,0xF8,0xF0,0xF0,0xF8,0x78,0x3C,0x3F,
0x7F,0x7F,0x33,0x01,0x01,0x00,0x00,0x80,0xE0,0xFF,0xCF,0xDF,0xFF,0xFF,0xFE,0xFC,
0xF8,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0,0xE1,0xE1,0xE1,0xE1,0xE0,0xE0,0xE0,0xE0,0xF0,
0xF0,0xF8,0xFC,0xFC,0xFF,0xFF,0xDF,0xCF}, // Setting
[2] = {0xFC,0xFE,0x07,0xF3,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0x03,0x03,
0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xFB,0xF3,0x07,0xFE,0xFC,0xFF,0xFF,
0x00,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0xBF,0x3F,0x7F,0x20,0x08,0x8F,0x07,
0x61,0x30,0x36,0x38,0x39,0x39,0x39,0x39,0x39,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0xE7,
0xE7,0xE7,0xE7,0xE7,0xC7,0xDB,0xC3,0xE1,0xF8,0xFC,0x04,0x01,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xCF,0xDF,0xF8,0xF3,0xF7,0xF7,
0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF0,0xF0,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,
0xF7,0xF7,0xF7,0xF7,0xF3,0xF8,0xDF,0xCF}, //Curve
[3] = {0xFC,0xFE,0x1F,0x07,0x07,0xC3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0x63,0x63,0x63,
0x63,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xE3,0xC3,0x07,0x07,0x1F,0xFE,0xFC,0xFF,0xFF,
0x00,0x00,0x00,0xFF,0xFF,0xFF,0x3F,0x3F,0x3F,0x01,0x00,0x00,0x3C,0x3C,0x00,0x00,
0x01,0x3F,0x3F,0x3F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,
0x00,0xFF,0xFF,0xFF,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xCF,0xDF,0xFE,0xF8,0xF8,0xF0,
0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,
0xF1,0xF1,0xF0,0xF8,0xF8,0xFE,0xDF,0xCF}, //DigitalLock
[4] = {0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x3F,0x1F,0x0F,0x0F,0x0F,0x07,0x07,0x07,
0x07,0x0F,0x0F,0x0F,0x1F,0x3F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xFF,0xFF,
0xFF,0x3F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xEE,0xE6,0x66,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1F,0x1F,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x60,0xF0,0xFF,0xFF,0xFF,0xFF,0xCF,0xDF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,
0xF8,0xF8,0xF8,0xF8,0xFF,0xFF,0xDF,0xCF} //about
};
//LOGO页面的参数
const uint8_t logo_wouo_pic[] = {0x00,0x00,0xF8,0xF0,0x80,0x00,0x00,0x00,0xE0,0xFC,0xE0,0x00,0x00,0x00,0x00,0xF0,
0xFC,0x04,0x18,0x30,0x70,0xE0,0xC0,0xE0,0xF0,0xF8,0x38,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x70,0x70,0xE0,0xC0,0xE0,0xF0,0x78,0x18,0x00,
0x00,0x00,0x00,0x00,0x1F,0xFF,0xF0,0xF8,0x3F,0x03,0x01,0x1F,0x7E,0xF0,0xE0,0xFE,
0x7F,0x01,0x00,0x00,0xF8,0x8E,0x83,0x81,0xC1,0x41,0x71,0x3F,0x00,0x00,0x7F,0xC0,
0xC0,0xC0,0x60,0x30,0x7E,0xFF,0x00,0x00,0xFC,0x8E,0x83,0x81,0xC1,0x61,0x3B,0x1F,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
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,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00}; //49*20
const uint8_t logo_ui_pic[] = {0x00,0x00,0x00,0xF0,0xFC,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFE,
0xFC,0x00,0x00,0x0C,0x0C,0xFC,0xFC,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7F,
0xC0,0x80,0x80,0x80,0xC0,0xE0,0x70,0x38,0x1C,0xFF,0xFF,0xF8,0x00,0x00,0x80,0xC0,
0xFF,0x9F,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00,
0x00}; // 27*20
const uint8_t logo_page_pic[] = {0x00,0x00,0x00,0xF0,0xFC,0x0C,0x0C,0x0C,0x98,0xF0,0x00,0x00,0x00,0x00,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x80,0x80,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xCF,0x0C,0x0E,0x06,0x03,0x03,0x00,0x18,
0x2E,0x21,0x21,0x31,0x1E,0x3C,0x20,0x0C,0x1F,0x11,0x10,0x90,0xFF,0x00,0x1C,0x3E,
0x65,0x65,0x62,0x21,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x03,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //36*20
const uint8_t logo_version_pic[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0xE0,0xDC,0x9C,
0xD8,0xC0,0xC0,0xE8,0xFC,0xDC,0x8C,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,
0x01,0x01,0x00,0x0F,0x1F,0x1F,0x0F,0x0F,0x0F,0x07,0x83,0x80,0x80,0x00,0xC0,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,
0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x83,0x83,
0xBB,0xBC,0xFC,0xFC,0xFC,0xB8,0x83,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x00,0x00,0xFE,0xFF,0xC3,0xC1,
0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,
0xFF,0xFF,0x0F,0x1C,0x38,0x70,0xE0,0x80,0x00,0x00,0x80,0xE0,0x7C,0x1F,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,
0xFF,0xFF,0x00,0xE0,0xFF,0x07,0x00,0x00,0x80,0xC0,0xE1,0x73,0x3F,0x1E,0x3F,0x71,
0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x00,0x00,
0x00,0x00,0x00,0x07,0x07,0x03,0x00,0x07,0x07,0x00,0x00,0x07,0x33,0x79,0x78,0x78,
0x30,0x80,0xC0,0xE0,0xC0,0x03,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x02,0x03,0x03,0x03,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //36*60 版
//镭射图片对象
RaderPic logo_rpp_array[LOGO_PAGE_NUM] =
{//{pic,x,y,w,h,rd} //镭射图片的成员参数
{logo_wouo_pic, 4, 8, 49, 20, RD_RIGHT_DOWN},
{logo_ui_pic, 53, 8, 27, 20, RD_RIGHT_DOWN},
{logo_page_pic, 20, 36, 36, 20, RD_RIGHT_DOWN},
{logo_version_pic, 84, 2, 36, 60, RD_RIGHT_DOWN}
};
//设置的列表选项数组
Option setting_option_array[SETTING_PAGE_NUM] =
{///{ order,max,min,step,int_val,text,} //option的成员顺序
{.text = "- Setting"}, //第一个做说明标签,没有功能
{0, 255, 0, 1, 0, "~ Tile Ani"},
{0, 255, 0, 1, 0, "~ List Ani"}, //对于数值弹窗,需要给定最大最小值和步长
{.text = "+ T Ufd Fm Scr", .step = 1,},
{.text = "+ L Ufd Fm Scr", .step = 1,},
{.text = "+ T Loop Mode", .step = 1,},
{.text = "+ L Loop Mode", .step = 1,},
{.text = "+ ValWin Bok", .step = 1,},
{.text = "+ ConWin Bok", .step = 1,},
{.text = "$ Dig Ripple", .step = 1,},
{.text = "+ RaderPicMode", .step = 1,}, //step为1,能够使用clcik控制取反为0则失能取反(通常用于需要外部接管这个变量的情况)
{0, 10, 1, 1, 0, "~ RP_S_Rate"},
{0, 100, 0, 1, 0, "~ RP_M_Rate"}, //因为没有办法给初始化的全局变量使用变量值进行初始化所以int_val暂时先设为0
};
//curve页面的选项数组
Option curve_option_array[CURVE_PAGE_NUM] =
{//{ order,max,min,step,int_val,text,} //option的成员顺序
{.item_max = 50, .item_min = -50, .step = 0, .val = 0, .text = "sin" },
{.item_max = 50, .item_min = -50, .step = 0, .val = 0, .text = "tri" }, //wave页面的option中text不需要前缀
};
int16_t n = 0; //曲线横坐标自增变量
//Lock页面参数
Option lock_option_array[3] = //由于Digital页面有三个数字选项所以digital页面选项数组大小必须为3
{//{ order,max,min,step,int_val,text,} //option的成员顺序
{.item_max = 99 , .item_min = 0, .step = 1, .val = 0, .text = NULL},
{.item_max = 99 , .item_min = 0, .step = 1, .val = 0, .text = NULL},
{.item_max = 99 , .item_min = 0, .step = 1, .val = 0, .text = NULL}, //设置每一个数字的上限值和步长
} ;
String lock_label_array[LOCK_PAGE_LABEL_NUM] = {"Confirm", "Clear All"};
// uint8_t lock_password[3] = {56,34, 12}; //3个两位数字组成的密码(注意三个数字从0-2是从右到左)(两种形式的初始化均可)
uint8_t lock_password[3] = {[Digital_Pos_IndexLeft] = 12, [Digital_Pos_IndexMid] = 34, [Digital_Pos_IndexRight] = 56}; //3个两位数字组成的密码(注意三个数字从0-2是从右到左)
uint8_t lcok_page_state = 0; //0表示正常情况1表示密码正确(Confirm后密码正确)2表示清除所有位(ClearALL)
//about页面的选项数组
Option about_option_array[ABOUT_PAGE_NUM] =
{
{.text = "- About wouo"}, //第一项只是说明
{.text = "- WouoUI origin"}, //原wououi的说明
{.text = "- Page version"}, //Page version的说明
};
//about wououi页面的数组
Option about_wououi_option_array[ABOUT_WOUOUI_PAGE_NUM] =
{ //单选项需要以“=”开头
{.text = "- From WouoUI1.2"},
{.text = "- Thanks for the "},
{.text = " original author"},
{.text = "- Bilibili UID:"},
{.text = "= 9182439"},
{.text = "- Github URL: "},
{.text = "= https://"},
{.text = " github.com/"},
{.text = " RQNG/WouoUI"}
};
Option about_pageversion_array[ABOUT_PAGEVERSION_NUM] =
{
{.text = "- Page Version"},
{.text = "- MyBilili UID:"},
{.text = "= 679703519"},
{.text = "- Github URL:"},
{.text = "= https://"},
{.text = " github.com/"},
{.text = " Sheep118/WouoUI"},
{.text = " -PageVersion"},
};
//--------定义每个页面的回调函数
void MainPage_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order)
{
case 0: OLED_UIJumpToPage(self_page_id,&logo_page); break;
case 1: OLED_UIJumpToPage(self_page_id,&setting_page); break;
case 2: OLED_UIJumpToPage(self_page_id,&curve_page); break;
case 3: OLED_UIJumpToPage(self_page_id,&lock_page); break;
case 4: OLED_UIJumpToPage(self_page_id,&about_page); break;
default: break;
}
}
void SettingPage_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order) //对选中项的真实参数值赋值
{ //由于第0项是说明文字“Setting”
case 1: ui_para.ani_param[TILE_ANI] = select_item->val;break;//ani_tile
case 2: ui_para.ani_param[LIST_ANI] = select_item->val;break;//ani_list
case 3: ui_para.ufd_param[TILE_UFD] = select_item->val;break;//ani_tile
case 4: ui_para.ufd_param[LIST_UFD] = select_item->val;break;//ani_list
case 5: ui_para.loop_param[TILE_UFD] = select_item->val;break;//loop_tile
case 6: ui_para.loop_param[LIST_UFD] = select_item->val;break;//loop_list
case 7: ui_para.valwin_broken = select_item->val;break;//ValWin Broken
case 8: ui_para.conwin_broken = select_item->val;break;//ConWin Broken
case 9: ui_para.digital_ripple = select_item->val;break;//Digital Ripple Enable/not
case 10: ui_para.raderpic_scan_mode = select_item->val;break;//RaderPic scan mode
case 11: ui_para.raderpic_scan_rate = select_item->val;break;//RaderPic scan rate
case 12: ui_para.raderpic_move_rate = select_item->val;break;//RaderPic move rate
default:
break;
}
}
void LockPage_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order)
{
case Digital_Pos_IndexLabel: //选中label项并单击click的话
if(strcmp(select_item->text, lock_label_array[0]) == 0) //“confirm”
{
if(lock_option_array[0].val == lock_password[0] && lock_option_array[1].val == lock_password[1] && lock_option_array[2].val == lock_password[2])
//密码正确的话转到logopage
OLED_UIChangeCurrentPage(&logo_page);
}
else if(strcmp(select_item->text, lock_label_array[1]) == 0) //“Clear All”
OLED_DigitalPage_UpdateDigitalNumAnimation(&lock_page, 0, 0, 0, Digital_Direct_Increase);
break;
default:
break;
}
}
void About_CallBack(uint8_t self_page_id,Option* select_item)
{
switch (select_item->order)
{//第0项是说明文字
case 1: OLED_UIJumpToPage(self_page_id,&about_wououi_page); break;
case 2: OLED_UIJumpToPage(self_page_id,&about_page_version_page); break;
default: break;
}
}
//-------------一些需要用的内部函数
//生成三角波的函数
int16_t Triangle_Func(int16_t x)
{
static int16_t ret = 0;
if(x%20 != 0) ret+= (curve_option_array[1].item_max - curve_option_array[1].item_min)/2/19;
else ret = curve_option_array[1].item_min/2 ;
return ret;
}
//--------------给主函数调用的接口函数
void TestUI_Init(void)
{
OLED_Init(); //硬件的初始化
LL_mDelay(100);
OLED_ClearBuff(); //清空缓存
OLED_RefreshBuff(); //刷新屏幕(清空屏幕)
OLED_SetPointColor(1); //设置绘制颜色
OLED_UiInit(); //必要的ui参数初始化
//补充列表页面的初值
setting_option_array[1].val = ui_para.ani_param[TILE_ANI];
setting_option_array[2].val = ui_para.ani_param[LIST_ANI];
setting_option_array[3].val = ui_para.ani_param[TILE_UFD];
setting_option_array[4].val = ui_para.ani_param[LIST_UFD];
setting_option_array[5].val = ui_para.ani_param[TILE_LOOP];
setting_option_array[6].val = ui_para.ani_param[LIST_LOOP];
setting_option_array[7].val = ui_para.valwin_broken;
setting_option_array[8].val = ui_para.conwin_broken;
setting_option_array[9].val = ui_para.digital_ripple;
setting_option_array[10].val = ui_para.raderpic_scan_mode;
setting_option_array[11].val = ui_para.raderpic_scan_rate;
setting_option_array[12].val = ui_para.raderpic_move_rate;
//设置界面选项
OLED_TitlePageInit(&main_page, main_page_id, MAIN_PAGE_NUM, mian_option_array, main_icon_array, MainPage_CallBack);
OLED_RaderPicPageInit(&logo_page, logo_page_id, LOGO_PAGE_NUM, logo_rpp_array,Rader_Pic_Mode_Loop, NULL);
OLED_ListPageInit(&setting_page, setting_page_id, SETTING_PAGE_NUM, setting_option_array, SettingPage_CallBack);
OLED_WavePageInit(&curve_page, curve_page_id, CURVE_PAGE_NUM, curve_option_array, NULL);
OLED_DigitalPageInit(&lock_page, lock_page_id, lock_option_array, LOCK_PAGE_LABEL_NUM, lock_label_array, '-', 0, 50, LockPage_CallBack);
OLED_ListPageInit(&about_page, about_page_id, ABOUT_PAGE_NUM, about_option_array, About_CallBack);
OLED_RadioPageInit(&about_wououi_page, about_wououi_page_id, ABOUT_WOUOUI_PAGE_NUM, about_wououi_option_array, NULL);
OLED_RadioPageInit(&about_page_version_page,about_page_version_id, ABOUT_PAGEVERSION_NUM, about_pageversion_array, NULL);
}
void TestUI_Proc(void)
{
OLED_UIProc();
OLED_UIWaveUpdateVal(&(curve_option_array[0]), sin(0.1*n)*(curve_option_array[0].item_max)*0.75);
OLED_UIWaveUpdateVal(&(curve_option_array[1]), Triangle_Func(n));
n++;
}

View File

@ -0,0 +1,12 @@
#ifndef __TEST_UI_H__
#define __TEST_UI_H__
#include "oled_port.h"
#include "oled_g.h"
#include "oled_ui.h"
void TestUI_Init(void);
void TestUI_Proc(void);
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

View File

@ -0,0 +1,14 @@
#ifndef __OLED_CONF_H__
#define __OLED_CONF_H__
#define UI_CONWIN_ENABLE 1 //是否使能 以"$ " 为开头的选项使用确认弹窗
#define UI_MAX_PAGE_NUM 32 //页面的最大数量这个数字需要大于所有页面的page_id
#define UI_INPUT_MSG_QUNEE_SIZE 4 //ui内部消息对列的大小(至少需要是2)
//页面类型使能宏使用对应的页面类型则需要开启该宏将宏置为1默认都开启
#define PAGE_WAVE_ENABLE 1
#define PAGE_RADIO_ENABLE 1
#define PAGE_RADERPIC_ENABLE 1
#define PAGE_DIGITAL_ENABLE 1
#endif

View File

@ -0,0 +1,471 @@
#include "oled_g.h"
#include "string.h"
#include "oledfont.h"
#include "math.h"
#define OLED_BUFF_SIZE (OLED_HEIGHT/8*OLED_WIDTH)
uint8_t oled_buff[OLED_HEIGHT/8][OLED_WIDTH] = {0}; //全局buff对应oled中的GRAM
uint8_t oled_color = '|'; //默认| 表示白色,'&'表示黑色
/**
* @brief : void OLED_ClearBuff(void)
* @param : Nonw
* @attention : buff
* @author : Sheep
* @date : 23/10/04
*/
void OLED_ClearBuff(void)
{
memset(oled_buff,0,1024);
}
/**
* @brief : void OLED_SetPointColor(uint8_t color)
* @param : color1=0=,2=
* @attention : None
* @author : Sheep
* @date : 23/10/04
*/
void OLED_SetPointColor(uint8_t color)
{
switch (color)
{
case 0: oled_color = '&';break;
case 1: oled_color = '|';break;
case 2: oled_color = '^';break;
default:break;
}
// oled_color = (color != 0 )?'|':'&';
}
/**
* @brief : void OLED_RefreshBUff(void)
* @param : buff到oledGRAM
* @attention : oled_ok表示成功
* @author : Sheep
* @date : 23/10/04
*/
void OLED_RefreshBuff(void)
{
OLED_SendBuff(oled_buff);
}
/*
void OLED_BuffWriteByte(uint8_t x, uint8_t y , uint8_t val)
x y buff的位置 coverORadd \
'='buff'|'1buff中置1()'&'val中为1的位在buff中置0
:Sheep
23/09/27
*/
static void OLED_BuffWriteByte(int16_t x, int16_t y ,uint8_t coverORaddORclear, uint8_t val)
{
if( x > (OLED_WIDTH-1) || y>(OLED_HEIGHT/8-1) || x<0 || y<0) return;
switch (coverORaddORclear)
{
case '|':oled_buff[y][x] |= val;break;
case '&':oled_buff[y][x] &= (~val);break;
case '^':oled_buff[y][x] ^= val;break;
default:
break;
}
}
/**
* @brief : static void OLED_WinWriteByte(window * win ,int16_t x, int16_t y, uint8_t val)
* @param : win x相对于画图原点的横坐标y相对于画图原点的纵坐标
* @attention : OLED_OK/OUT/ERR
* @author : Sheep
* @date : 23/10/03
*/
static void OLED_WinWriteByte(window * win ,int16_t x, int16_t y, uint8_t val)
{
uint8_t n = 0,m = 0,temp1 = 0,temp2 = 0;
if(x > win->w || y > win->h || x < 0 || y <= -7) return ; //超出窗口大小
if(y+7 > (win->h -1) ) val &= (~(0xFF<<(win->h - y))); //超过窗口的部分不显示
if(y > -7 && y < 0)
{
val >>=(-1*y);
n = win->start_y/8;
m = win->start_y%8;
}
else
{
n = (win->start_y + y)/8; m = (win->start_y + y)%8;
}
temp1 = val<<m; temp2 = (val>>(8-m));
//在全局buff中第几个字节的第几位 ,取出低字节的位,取出高字节的位
if(m==0) OLED_BuffWriteByte(win->start_x+x,n,oled_color,val); //恰好是整字节
else if(m != 0)
{
OLED_BuffWriteByte(win->start_x+x,n,oled_color,temp1);
OLED_BuffWriteByte(win->start_x+x,n+1,oled_color,temp2);
}
}
/*
void OLED_WinDrawASCII(window *win,int16_t x, int16_t y ,uint8_t size, char c)
[in] win xy ,size(12,16,24) c
x的位置
:Sheep
24/01/30
*/
int16_t OLED_WinDrawASCII(window *win,int16_t x, int16_t y ,uint8_t size, char c)
{
c = c - ' '; //得到偏移值
switch (size)
{
case 16://16号字8x16
for(uint8_t i=0;i<8;i++)
{
OLED_WinWriteByte(win,x,y,F8X16[c*2][i]);
OLED_WinWriteByte(win,x,y+8,F8X16[c*2+1][i]);
x++;if(x > win->w)break; //已经超出边框没必要再写了
}
break;
case 24://24号字12*24
for(uint8_t i=0;i<12;i++)
{
OLED_WinWriteByte(win,x,y,F12X24[c*3][i]);
OLED_WinWriteByte(win,x,y+8,F12X24[c*3+1][i]);
OLED_WinWriteByte(win,x,y+16,F12X24[c*3+2][i]);
x++;if(x > win->w)break; //已经超出边框没必要再写了
}
break;
case 8://12号字6*8
for(uint8_t i=0;i<6;i++)
{
OLED_WinWriteByte(win,x,y,F6x8[c][i]);
x++;if(x > win->w)break; //已经超出边框没必要再写了
}
break;
default:
break;
}
return x;
}
/**
* @brief : void OLED_WinDrawStr(window *win,int16_t x, int16_t y ,uint8_t size, uint8_t* str)
* @param : win指定窗口xy相对于窗口的恒重坐标str
* @attention : None
* @author : Sheep
* @date : 23/10/03
*/
void OLED_WinDrawStr(window *win,int16_t x, int16_t y ,uint8_t size, uint8_t* str)
{
int16_t cur_x = x; //由于绘制时x的递增在drawAscii中完成所以利用返回值将X位置返回出来下次传入
while(*str != '\0')
{
cur_x = OLED_WinDrawASCII(win, cur_x, y, size, *str);
str++;
if(x > win->w) break; //已经到边了没必要再写了
}
}
/**
* @brief : void OLED_WinDrawVLine(window *win,int16_t x, int16_t y_start, int16_t y_end)
* @param : 线y_end y_start
* @attention : None
* @author : Sheep
* @date : 23/10/03
*/
void OLED_WinDrawVLine(window *win,int16_t x, int16_t y_start, int16_t y_end)
{
uint8_t n = 0, m = 0;
if(y_start < 0 && y_end < 0)return;
if(y_start < 0) y_start = 0;
if(y_end > win->h )y_end = win->h;
if(x > win->w || x < 0)return ;
if((y_end - y_start) < 7) OLED_WinWriteByte(win,x,y_start, ~(0xFF<<(y_end - y_start)));
else
{
uint8_t i = 0;
n = (y_end - y_start)/8;
m = (y_end - y_start)%8;
for(i = 0; i < n; i++)OLED_WinWriteByte(win,x,y_start+i*8,0xFF);
OLED_WinWriteByte(win,x,y_start+i*8,~(0xFF<<m));
}
}
/**
* @brief : void OLED_WinDrawHLine(window * win, int16_t x_start, int16_t x_end, int16_t y)
* @param : x_end > x_start
* @attention :
* @author : Sheep
* @date : 23/10/04
*/
void OLED_WinDrawHLine(window * win, int16_t x_start, int16_t x_end, int16_t y)
{
if(x_start < 0) x_start = 0;
if(x_end > win->w ) x_start = win->w;
if(y > win->h || y < 0)return ;
for(uint8_t i = 0; i < (x_end - x_start); i++)
OLED_WinWriteByte(win,x_start+i,y,0x01);
}
/**
* @brief : void OLED_WinDrawRBox(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r)
* @param : r
* @attention : ,1/2
* @author : Sheep
* @date : 23/10/04
*/
void OLED_WinDrawRBox(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r)
{
uint8_t cir_r = r; //
if((2*r > width) || (2*r > height))return;
for(uint8_t i = 0; i < width; i++)
{
OLED_WinDrawVLine(win,x_start+i,y_start+r,y_start+height-r);
if(i < cir_r)r--;
if(i >= (width - cir_r-1))r++;
}
}
/**
* @brief : void OLED_WinDrawRBoxEmpty(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r)
* @param : ,r
* @attention : ,1/2
* @author : Sheep
* @date : 23/10/04
*/
void OLED_WinDrawRBoxEmpty(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r)
{
uint8_t cir_r = r; //默认倒角为2
if((2*r > width) || (2*r > height))return;
for(uint8_t i = 0; i < height ; i++)
{
if(i == 0 || i == (height-1))OLED_WinDrawHLine(win,x_start+r,x_start+width-r+1,y_start+i);
else
{
OLED_WinWriteByte(win,x_start+r,y_start+i,0x01);
OLED_WinWriteByte(win,x_start+width-r,y_start+i,0x01);
}
if(i < cir_r)r--;
if(i>= (height -cir_r -1) )r++;
}
}
/**
* @brief : void OLED_WinDrawBMP(window * win, int16_t x, int16_t y, int16_t width, int16_t height,const uint8_t * BMP, uint8_t color)
* @param : heigh must be a total times of 8, the color is convenient for draw inverse-color BMP
* @attention : None
* @author : Sheep
* @date : 23/10/06
*/
void OLED_WinDrawBMP(window * win, int16_t x, int16_t y, int16_t width, int16_t height,const uint8_t * BMP, uint8_t color)
{
if(BMP == NULL) return; //如果是NULL直接返回
uint8_t n = height/8, m = height%8;
for(uint8_t i = 0; i < n; i++)
{
for(uint8_t j = 0; j < width; j++)
{
if(x+j > win->w)break;
if(y+i*8 > win->h)return;
if(color == 1) OLED_WinWriteByte(win,x+j,y+i*8,(BMP[i*width+j]));
else OLED_WinWriteByte(win,x+j,y+i*8,~(BMP[i*width+j]));
}
}
if(m!=0)
{
for(uint8_t j = 0; j < width; j++)
{
if(x+j > win->w)return;
if(color == 1) OLED_WinWriteByte(win,x+j,y+n*8,(BMP[n*width+j] & (~(0xFF<<m))));
else OLED_WinWriteByte(win,x+j,y+n*8,~(BMP[n*width+j] & (~(0xFF<<m))) );
}
}
}
/**
* @brief : void OLED_WinDrawPoint(window * win, int16_t x, int16_t y)
* @param : //画点函数尚未测试
* @attention : None
* @author : Sheep
* @date : 23/10/15
*/
void OLED_WinDrawPoint(window * win, int16_t x, int16_t y)
{
OLED_WinWriteByte(win,x,y,0x01);
}
/**
* @brief : uint8_t OLED_GetStrWidth(const char * str, uint8_t size)
* @param : size字号只有81624
* @attention : len
* @author : Sheep
* @date : 23/10/08
*/
uint8_t OLED_GetStrWidth(const char * str, uint8_t size)
{
uint8_t len = 0;
if(size == 8) len = strlen(str)*6; //由于8号字体是8*6的
else len = strlen(str)*size/2; //16-16x824-24x12.
return len;
}
/**
* @brief : void OLED_Animation(float *a, float *a_trg, float n)
* @param : 线n为运动步长(10)
* @attention : None
* @author : Sheep
* @date : 23/10/04
*/
void OLED_Animation(float *a, float *a_trg, float n)
{
if (*a != *a_trg)
{
if (fabs(*a - *a_trg) < 0.15) *a = *a_trg;
else *a += (*a_trg - *a) / (n / 10.0); //慢慢接近,
}
}
/**
* @brief : void OLED_AllSrcFade(uint8_t Odd0OrEven1,uint8_t byte)
* @param : OddorEven 10
byte为填充的内容(0xAA,0x55,0xFF)
* @attention : 01OLED_SetPointColor设置的颜色决定
* @author : Sheep
* @date : 23/10/10
*/
void OLED_AllSrcFade(uint8_t Odd0OrEven1,uint8_t byte)
{
for (uint8_t i = 0; i < OLED_HEIGHT/8; i++)
for (uint8_t j = 0; j < OLED_WIDTH; j++)
if(j%2 == Odd0OrEven1) OLED_BuffWriteByte(j,i,oled_color,byte);
}
/**
* @brief : void OLED_WinDrawLine(window* win,int16_t x1, int16_t y1, int16_t x2, int16_t y2)
* @param : (x1,y1)(x2,y2)
* @attention : 使Bresenham算法进行画直线,x1 != x2
* @author : Sheep
* @date : 23/10/31
*/
void OLED_WinDrawLine(window* win,int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
int16_t x_small = 0, x_big = 0, temp = 0, y_small = 0, y_big = 0;
int32_t dx = 0, dy = 0, p = 0; // deltax 和deltay
if(x2 == x1)return;
else p = (y2-y1)/(x2-x1);
p = (p>0)?p:(-p); //求斜率的绝对值,后面作误差变量使用
if(p < 1) //p>0 && p<1
{
if(x2 > x1){x_small = x1; x_big = x2; }
else{x_small = x2; x_big = x1; temp = y1; y1 = y2; y2 = temp;} //默认与 xsmall对应的y是y1
dx = x_big - x_small;
dy = ((y1 - y2)>0)?(y1-y2):(y2-y1);
p = (dy<<1) - dx;
while (x_small <= x_big)
{
OLED_WinWriteByte(win, x_small, y1, 0x01);
if(p > 0)
{
if(y1 < y2)y1++;
else y1--;
p = p+(dy<<1)-(dx<<1);
}
else {p = p+(dy<<1);}
x_small++;
}
}
else //p>=1
{
if(y2 > y1){y_small = y1; y_big = y2;}
else {y_small = y2; y_big = y1; temp = x1; x1 = x2; x2 = temp;} //默认与y_small对应的是x1;
dx = (x1>x2)?(x1-x2):(x2-x1);
dy = y_big - y_small;
p = (dx<<1) - dy;
while (y_small <= y_big)
{
OLED_WinWriteByte(win, x1, y_small, 0x01);
if(p > 0)
{
if(x1 < x2)x1++;
else x1--;
p = p+(dx<<1)-(dy<<1);
}
else {p = p+(dx<<1);}
y_small++;
}
}
}
/**
* @brief : uint8_t OLED_WinDrawRaderPic(window * win,const uint8_t* pic,int16_t start_x, uint16_t start_y, uint8_t width, uint8_t height, RaderDirection direct, uint8_t enable_all_point_scan)
* @param : [in] win
* @param : [in] pic
* @param : [in] start_xstart_y,width,height,(x,y)
* @param : [in] direct 线RaderDirection
* @param : [in] enable_all_point_scan true/FasleFasle的话线
* @param : [in] scan_rate
* @return : 10
* @attention : None
* @author : Sheep
* @date : 23/11/15
*/
uint8_t OLED_WinDrawRaderPic(window * win,const uint8_t* pic,int16_t start_x, uint16_t start_y, uint8_t width, uint8_t height, RaderDirection direct, uint8_t enable_all_point_scan, uint8_t scan_rate)
{
static uint16_t now_end_point = 1; //静态计数变量(允许在描文字的过程中被打断)
uint8_t mask = 1, horizon_line_flag = 0, ret = 0;
int16_t x = 0, y = 0;
uint16_t i = 0,array_index = 0;
if(pic == NULL) return 0; //如果图像为null直接返回0表示未完成
//绘制前面绘制好的图形
for(i = 0; i < now_end_point; i++)
{
if((i % width == 0) && (i!=0))
if(mask == 0x80){mask = 1;}
else {mask <<= 1;array_index-=width;}
if(pic[array_index]&mask)
OLED_WinDrawPoint(win,start_x + i%width, start_y + i/width);
array_index++;
}
//绘制镭射那根线
if((pic[array_index]&mask) || enable_all_point_scan)
{
switch (direct) //确定端点
{
case RD_LEFT_UP: x = win->start_x; y = win->start_y; break;
case RD_LEFT_DOWN: x = win->start_x; y = win->start_y+win->h-1; break;
case RD_RIGHT_UP: x = win->start_x + win->w-1; y = win->start_y; break;
case RD_RIGHT_DOWN: x = win->start_x+win->w-1; y = win->start_y+win->h-1; break;
case RD_LEFT: horizon_line_flag = 1;x = win->start_x;break;
case RD_RIGHT: horizon_line_flag = 1;x = win->start_x+win->w;break;
default:
break;
}
if(horizon_line_flag)
if(start_x + i%width < x)OLED_WinDrawHLine(win,start_x + i%width,x,start_y + i/width);
else OLED_WinDrawHLine(win,x , start_x + i%width,start_y + i/width);
else
if(i%width != x){OLED_WinDrawLine(win,start_x + i%width,start_y + i/width,x,y);}
else
if(start_y + i/width < y )OLED_WinDrawVLine(win,x,start_y + i/width,y);
else OLED_WinDrawVLine(win,x,y,start_y+i/width);
}
//终点自增
if(now_end_point < (width*height-1)){now_end_point+=scan_rate;ret = 0;}
else {now_end_point = 1;ret= 1;} //图像绘制结束
return ret;
}

View File

@ -0,0 +1,48 @@
#ifndef __OLED_G_H__
#define __OLED_G_H__
#include "oled_port.h"
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
typedef struct
{
int16_t start_x;
int16_t start_y;
int16_t w;
int16_t h;
} window;
typedef enum
{
RD_LEFT_UP = 0x00, //射线从左上角出发
RD_LEFT_DOWN, //射线从左下角出发
RD_RIGHT_UP, //射线从右上角出发
RD_RIGHT_DOWN, //射线从右下角出发
RD_RIGHT, //射线从水平向右
RD_LEFT, //射线从水平向左
} RaderDirection;
void OLED_ClearBuff(void);
void OLED_SetPointColor(uint8_t color);
void OLED_RefreshBuff(void);
int16_t OLED_WinDrawASCII(window *win,int16_t x, int16_t y ,uint8_t size, char c);
void OLED_WinDrawStr(window *win,int16_t x, int16_t y ,uint8_t size, uint8_t* str);
void OLED_WinDrawVLine(window *win,int16_t x, int16_t y_start, int16_t y_end);
void OLED_WinDrawHLine(window * win, int16_t x_start, int16_t x_end, int16_t y);
void OLED_WinDrawRBox(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r);
void OLED_WinDrawRBoxEmpty(window *win, int16_t x_start, int16_t y_start, int16_t width, int16_t height, uint8_t r);
void OLED_WinDrawBMP(window * win, int16_t x, int16_t y, int16_t width, int16_t height,const uint8_t * BMP, uint8_t color);
void OLED_WinDrawPoint(window * win, int16_t x, int16_t y);
void OLED_WinDrawLine(window* win,int16_t x1, int16_t y1, int16_t x2, int16_t y2);
uint8_t OLED_GetStrWidth(const char * str, uint8_t size);
void OLED_Animation(float *a, float *a_trg, float n);
void OLED_AllSrcFade(uint8_t Odd0OrEven1,uint8_t byte);
uint8_t OLED_WinDrawRaderPic(window * win,const uint8_t* pic,int16_t start_x, uint16_t start_y, uint8_t width, uint8_t height, RaderDirection direct, uint8_t enable_all_point_scan, uint8_t scan_rate);
#endif

View File

@ -0,0 +1,14 @@
#ifndef __OLED_PORT_H__
#define __OLED_PORT_H__
#include "stdio.h"
#include "stdint.h"
#define OLED_LOG (void)
//对应要实现的接口函数
void OLED_Init(void); //初始化驱动
void OLED_SendBuff(uint8_t buff[8][128]); //将8*128字节的buff一次性全部发送的函数
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,376 @@
#ifndef __OLED_UI_H__
#define __OLED_UI_H__
#include "oled_g.h"
#include "oled_conf.h"
/*============================================常量定义=========================================*/
#define True 1
#define False 0
// 输入消息缓冲队列的大小(至少为2)
#define INPUT_MSG_QUNEE_SIZE UI_INPUT_MSG_QUNEE_SIZE
//磁贴默认参数
//所有磁贴页面都使用同一套参数
#define TILE_B_TITLE_H 24 //磁贴大标题字体高度
#define TILE_ICON_H 30 //磁贴图标高度
#define TILE_ICON_W 30 //磁贴图标宽度
#define TILE_ICON_S 36 //磁贴图标间距
#define TILE_INDI_H 27 //磁贴大标题指示器高度
#define TILE_INDI_W 8 //磁贴大标题指示器宽度
#define TILE_INDI_S 36 //磁贴大标题指示器上边距
#define ICON_BUFFSIZE (TILE_ICON_W*(TILE_ICON_H/8+1))
// 列表默认参数
//所有列表使用同一套参数
#define LIST_TEXT_H 8 // 列表每行文字字体的高度
#define LIST_LINE_H 16 // 列表单行高度
#define LIST_TEXT_S 4 // 列表每行文字的上边距,左边距和右边距,下边距由它和字体高度和行高度决定
#define LIST_BAR_W 5 // 列表进度条宽度需要是奇数因为正中间有1像素宽度的线
#define LIST_BOX_R 2 // 列表选择框倒角
// 列表行尾选择选项参数
#define CHECK_BOX_L_S 95 // 选择框在每行的左边距
#define CHECK_BOX_U_S 2 // 选择框在每行的上边距
#define CHECK_BOX_F_W 12 // 选择框外框宽度
#define CHECK_BOX_F_H 12 // 选择框外框高度
#define CHECK_BOX_D_S 2 // 选择框里面的点距离外框的边距
// 弹窗参数
#define WIN_FNOT_H 16 // 弹窗字体高度
#define WIN_H 32 // 弹窗高度
#define WIN_W 102 // 弹窗宽度
#define WIN_BAR_W 92 // 弹窗进度条宽度
#define WIN_BAR_H 7 // 弹窗进度条高度
#define WIN_Y (-WIN_H - 2) // 弹窗竖直方向出场起始位置
#define WIN_Y_TRG (-WIN_H - 2) // 弹窗竖直方向退场终止位置
// 确认弹窗变量
#define CON_WIN_FONT_H 16 // 弹窗字体高度
#define CON_WIN_H 38 // 弹窗高度
#define CON_WIN_W 102 // 弹窗宽度
#define CON_WIN_BTN_H 20
#define CON_WIN_R 3
#define CON_WIN_Y (-CON_WIN_H - 2) // 弹窗竖直方向出场起始位置
#define CON_WIN_Y_TRG (-CON_WIN_H - 2) // 弹窗竖直方向退场终止位置
//曲线相关参数
#define WAVE_SAMPLE 1 //采集倍数
#define WAVE_W 94 //波形宽度
#define WAVE_L 24 //波形左边距
#define WAVE_U 0 //波形上边距
#define WAVE_MAX 27 //最大值
#define WAVE_MIN 4 //最小值
#define WAVE_BOX_H 32 //波形边框高度
#define WAVE_BOX_W 94 //波形边框宽度
#define WAVE_BOX_L_S 24 //波形边框左边距
//列表和文字背景框相关参数
#define WAVE_FONT_H 24 //电压数字字体
#define WAVE_TEXT_BG_L_S 24 //文字背景框左边距
#define WAVE_TEXT_BG_W 94 //文字背景框宽度
#define WAVE_TEXT_BG_H 29
//数字控件页面相关参数
#define DIGITAL_RECT_X 8 //外框的横坐标
#define DIGITAL_RECT_Y 4 //外框的纵坐标
#define DIGITAL_RECT_H 40 //外框的高度
#define DIGITAL_RECT_W 112 //外框的宽度
#define DIGITAL_RECT_R 3 //外框的倒角
#define DIGITAL_NUM_T_S 8 //数字到外框的边距
#define DIGITAL_NUM_SIZE 24 //数字的尺寸
#define DIGITAL_Label_SIZE 16 //数字的尺寸
#define DIGITAL_NUM_INDEX_MAX 6 //digital页面共有6个数字
/*============================================类型声明=========================================*/
//--------页面类型枚举
typedef enum
{
//选择框类页面
type_title = 0x00, //磁贴类
type_list, //列表类
//终端类页面
type_radio, //单选框类
type_digital, //数字控件类
type_wave, //波形显示类
type_rader_pic, //镭射图片类
} PageType; //页面类型用于标志传入的每个页面类型方便调用对应的proc函数
//-------页面成员类型
typedef char* String; // 定义字符串类型
typedef struct
{
uint8_t order; //该选项在列表/磁贴中的排序(0-255)
int16_t item_max; //列表项对应变量可取的最大值(若是单选/多选框该值无意义可为0)
int16_t item_min; //列表项对应变量可取的最小值(若是单选/多选框该值无意义可为0)
int16_t step;//列表项对应变量的步长变化,只对数值弹窗有效(若是单选/多选框该值无意义可为0)
int16_t val; //这个列表项关联的显示的值(可以用于设置初值)
String text;
//这个列表项显示的字符串
//(通过选项的第一个字符判断为数值弹窗(~)/确认弹窗($)/其他项(-)/二值选项框(+))
//其中二值选项框由于二值项只能在列表中展示,因此只在列表选择页面中有效,在磁帖页面中如果出现+开头的字串默认为其他项
//其实单选列表项,需使用其他项在应用层关联跳转单选终端页面实现(单选列表项必须使用=做字符串开头)。
} Option; //通用选项类,其中item_max,item_min,entity与列表选项(单选/多选/弹窗项)相关,磁贴选项可不管
//选择类界面的回调函数类型定义,参数为确认选中项的指针。
typedef void (*CallBackFunc)(uint8_t self_page_id,Option* select_item);
typedef const uint8_t Icon[ICON_BUFFSIZE]; //定义图标类型
//页面地址类型,用于声明全局页面数组存放页面使用
#define PageAddr void*
//每个页面都有的三种方法
typedef void (*PageAniInit)(PageAddr); //页面的动画初始化函数
typedef void (*PageShow)(PageAddr); //页面的展示函数
typedef void (*PageReact)(PageAddr); //页面的响应函数
typedef struct
{
PageType page_type; //页面类型,以便在处理时调用不同函数绘制
uint8_t page_id; //页面的序号,每个页面唯一一个,用于指示在数组中的位置,方便跳转
uint8_t last_page_id; //上一个页面的id用于返回时使用
CallBackFunc cb; //页面的回调函数
PageAniInit ani_init;
PageShow show;
PageReact react;
} Page; //最基本的页面类型(所有页面类型的基类和结构体的**第一个成员**)
//----------5种页面类
typedef struct
{
Page page; //基础页面信息
uint8_t item_num ; //页面选项个数option_array和icon_array个数需与此一致
Option *option_array; //选项类型的数组(由于数组大小不确定,使用指针代替)
Icon *icon_array ; //图标数组(由于数组大小不确定,使用指针代替)
uint8_t select_item; //选中选项
float icon_x; //图标的x坐标距选中目标的间距的变量
float icon_x_trg;//图标的x坐标距选中目标的间距的变量目标
float icon_y;//图标的y坐标
float icon_y_trg;//图标的y坐标目标
float indi_x; //指示器的x坐标
float indi_x_trg;//指示器的x坐标目标值
float title_y;//标题的y坐标
float title_y_trg;//标题的y坐标目标值
} TitlePage; //磁帖页面类型(所有类型页面,类型成员为第一个,方便查看)
typedef struct
{
Page page; //基础页面信息
uint8_t item_num ; //页面选项个数title和icon个数需与此一致
uint8_t select_item; //选中选项
Option *option_array; //选项类型的数组(由于数组大小不确定,使用指针代替)
uint8_t slip_flag; //切换动画是否完成的标志位
uint8_t line_n; // = DISP_H / LIST_LINE_H; 屏幕内有多少行选项
float y; //列表中每个选项的间隔值
float y_trg; //列表中每个选项间隔的目标值
float box_x; //选中框x
float box_x_trg; //选中框x的目标值
float box_y; //选中框y
float box_y_trg; //选中框y的目标值
float bar_y; //进度条的y值
float bar_y_trg; //进度条的y目标值
} ListPage; //列表页面类型(所有类型页面,类型成员为第一个,方便查看)
#if PAGE_WAVE_ENABLE
typedef ListPage WavePage; //定义波形页面类型
#endif
#if PAGE_RADIO_ENABLE
typedef ListPage RadioPage; //定义单选项页面类型
#endif
#if PAGE_RADERPIC_ENABLE
typedef struct
{
const uint8_t * pic; //图片指针
int16_t start_x; //起始x
int16_t start_y; //起始y
uint8_t w; //width of pic
uint8_t h; //height of pic
RaderDirection rd; //射线方向选择,枚举类型
} RaderPic; //镭射图片对象
typedef struct
{
Page page; //基类
//镭射界面回调函数传入已经绘制完成的pic序号
//为了方便在镭射图片界面,绘制自己想要的其他元素(如文字提示在模式为Rader_Pic_Mode_Hold是会不断绘制已完成的图片并不断调用回调函数)
uint8_t pic_num ; //页面pic个数pic_array数组大小需与此一致
uint8_t rader_pic_mode:2; //结束之后的操作
RaderPic* pic_array; //镭射图片数组
uint8_t cur_pic_index; //当前正在绘制完成的pic序号(0~pic_num-1)
float move_x;
float move_y;
} RaderPicPage; //镭射图片页面对象
typedef enum
{
// Rader_Pic_Mode_Clear = 0x00, //显示完所有图片后不操作,直接清空(这个模式暂时没有使用到)
Rader_Pic_Mode_Loop = 0x01, //显示完所有图片后不操作,再从第一张开始显示
Rader_Pic_Mode_Hold = 0x02, //显示完所有图片后不操作,保持原图
Rader_Pic_Mode_Num,
} RaderPicMode;
#endif
#if PAGE_DIGITAL_ENABLE
typedef enum
{
Digital_Direct_None = 0x00,
Digital_Direct_Increase = 0x01,
Digital_Direct_Decrease = 0x02,
} DigitalDirect; //用于Digital Show和React函数间传递信号
typedef enum
{
Digital_Mode_Observe = 0x00, //观察模式没有光标
Digital_Mode_Edit = 0x01, //对编辑位置的编辑
Digital_Mode_Singlebit = 0x02, //对单位数字的编辑
} DigitalMode; //digital页面的模式
typedef enum //Digital页面从右往左
{
Digital_Pos_IndexRight = 0x00, //用于指示当前光标或者编辑的位置
Digital_Pos_IndexMid,
Digital_Pos_IndexLeft,
Digital_Pos_IndexLabel, //在标签处
Digital_Pos_Complete, //编辑完成
}DigitalPosIndex; //用于在回调函数中检验选中项的op->order值,表示选中哪个数字位还是标签
typedef struct
{
Page page; //页面的基本信息
char gap_char; //3个digital数字间的间隔字符
uint8_t gap_shine_time; //间隔字符闪烁的时间参数
uint8_t uline_shine_time; //下划线闪烁的时间参数
Option * option_array; //选项数组数组大小必须为3 ,用于显示三个数字
uint8_t label_array_num; // 标签数组的大小
String * label_array; //标签数组,方便标签滚动
DigitalPosIndex select_index:4; //选中项的index
uint8_t digital_num_pos; //0表示没有选中位置1-7bit每一位置1表示该位被选中
uint8_t temp_ripple_index; //用于在ripple时记录选中位置(选中最低位位置开始,慢慢往上增)
DigitalDirect dir:2; //用于Digital Show和React函数间传递信号
DigitalMode mod:2; //digital页面的模式
uint8_t select_label_index; //在标签数组中选中的标签的index
window w_digtal[2]; //用限制数字时钟的窗口(1个数字窗口+1个label窗口) 2个窗口
float rect_y; //移动外框的顶点坐标
float rect_y_trg; //移动外框的顶点坐标目标
float label_y; //移动外框的顶点坐标
float label_y_trg; //移动外框的顶点坐标目标
float num_y; //移动数字的顶点坐标
float num_y_trg; //移动数字的顶点坐标目标
} DigitalPage; //时间页面
#endif
//---------输入消息枚举类型
typedef enum
{
msg_none = 0x00, //none表示没有操作
msg_up, //上或者last消息表上一个
msg_down, //下或者next消息表下一个
msg_return, //返回消息,表示返回,从一个页面退出
msg_click, //点击消息,表确认,确认某一选项,回调用一次回调
msg_home, //home消息表回主界面(尚未设计目前还没有设计对应的功能默认以page_id为0的页面为主页面)
} InputMsg; //输入消息类型UI设计只供输入5种消息
//------类别下标声明。用于UI参数数组中做索引
enum _ani_kind //动画速度类别(数组中的下标)
{
TILE_ANI = 0x00, //磁贴动画速度
LIST_ANI, //列表动画速度
WIN_ANI, //弹窗动画速度
// SPOT_ANI, //聚光动画速度
// FADE_ANI, //消失动画速度
TAG_ANI, //标签动画速度
DIGI_ANI, //数字动画滚动速度
AIN_ALL_NUM, //动画速度参数的数目,用于数组初始化
};
enum _ufd_kind //展开方式类别(数组中的下标)
{
TILE_UFD = 0x00, //磁贴图标从头展开开关
LIST_UFD, //菜单列表从头展开开关
UFD_ALL_NUM, //展开方式类别数目
} ;
enum _loop_kind //循环模式类别(数组中的下标)
{
TILE_LOOP = 0x00, //磁贴图标循环模式开关
LIST_LOOP, //菜单列表循环模式开关
LOOP_ALL_NUM, //循环模式类别数目
};
typedef enum
{
ui_layer_in = 0x00, //ui层级深入时
ui_page_proc , //ui页面处理时
} UIState; //UI状态机
//============================================全局变量的外界声明================================
typedef struct
{
uint8_t valwin_broken:1; //数值弹窗背景虚化开关
uint8_t conwin_broken:1; //数值弹窗背景虚化开关
uint8_t digital_ripple:1; //digital页面多位数值递增时是否使用ripple模式还是同时运动递增
uint8_t raderpic_scan_mode:1; //raderpic扫描方式的开关
uint8_t raderpic_scan_rate; //raderpic扫描的速度
uint8_t raderpic_move_rate; //raderpic过度动画的移动速度
uint8_t ani_param[AIN_ALL_NUM]; //动画参数数组
uint8_t ufd_param[UFD_ALL_NUM]; //展开参数数组
uint8_t loop_param[LOOP_ALL_NUM]; //循环参数数组
} UiPara; //UI参数集合类型
extern UiPara ui_para; //共外部使用的全局UI参数变量
extern window w_all; //这个窗口是ui绘制时的全局窗口可供外界自由绘制
/*============================================接口函数=========================================*/
void OLED_TitlePageInit(TitlePage * title_page, uint8_t page_id,uint8_t item_num,Option* option_array,Icon *icon_array,CallBackFunc call_back);
void OLED_ListPageInit(ListPage * lp,uint8_t page_id,uint8_t item_num,Option *option_array,CallBackFunc call_back);
//用于向UI传递一个消息Msg(msg_click/msg_up/msg_down/msg_return)
void OLED_MsgQueSend(InputMsg msg);
//UI必要的一些参数和变量的初始化
void OLED_UiInit(void);
//UI运行任务需要放在主循环中循环调用而且尽量不要阻塞
void OLED_UIProc(void);
/*
* (terminate_page页面收到return消息时self_page_id所代表的页面)
@param self_page_id id
@param terminate_page ()
*/
void OLED_UIJumpToPage(uint8_t self_page_id,PageAddr terminate_page);
/*
* Jump函数不同的时terminate_page return ()
@param terminate_page ()
*/
void OLED_UIChangeCurrentPage(PageAddr terminate_page);
/*获取当前页面的id*/
uint8_t OLED_UIGetCurrentPageID(void);
#if PAGE_WAVE_ENABLE
void OLED_WavePageInit(WavePage * wp, uint8_t page_id, uint8_t item_num, Option *option_array, CallBackFunc call_back);
void OLED_UIWaveUpdateVal(Option * op, int16_t val);
#endif
#if PAGE_RADIO_ENABLE
void OLED_RadioPageInit(RadioPage * rp, uint8_t page_id, uint8_t item_num,Option *option_array,CallBackFunc call_back);
#endif
#if PAGE_RADERPIC_ENABLE
void OLED_RaderPicPageInit(RaderPicPage* rpp,uint8_t page_id,uint8_t pic_num,RaderPic * pic_array,RaderPicMode mode,CallBackFunc cb) ;
#endif
#if PAGE_DIGITAL_ENABLE
void OLED_DigitalPageInit(DigitalPage* dp, uint8_t page_id, Option * option_array, uint8_t label_array_num, String * label_array, char gap_char, uint8_t gap_shine_time, uint8_t uline_shine_time,CallBackFunc cb);
void OLED_DigitalPage_UpdateDigitalNumAnimation(DigitalPage * dp, uint8_t leftval, uint8_t midval, uint8_t rightval, DigitalDirect dir);
void OLED_DigitalPage_UpdateLabelAnimation(DigitalPage * dp, uint8_t label_index, DigitalDirect dir);
#endif
#endif

View File

@ -0,0 +1,595 @@
#ifndef __OLEDFONT_H
#define __OLEDFONT_H
//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
const unsigned char F6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x00, 0x00, 0x00, 0x7E, 0x80, 0x00,/*"{",0*/
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, /*"|",1*/
0x00, 0x80, 0x7E, 0x00, 0x00, 0x00, /*"}",2*/
0x00, 0x08, 0x08, 0x10, 0x10, 0x00, /*"~",0*/
};
/****************************************8*16的点阵************************************/
const unsigned char F8X16[][8] =
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",32*/
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00},/*"!",33*/
{0x00,0x10,0x0C,0x02,0x10,0x0C,0x02,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",34*/
{0x00,0x40,0xC0,0x78,0x40,0xC0,0x78,0x00},
{0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x00},/*"#",35*/
{0x00,0x70,0x88,0x88,0xFC,0x08,0x30,0x00},
{0x00,0x18,0x20,0x20,0xFF,0x21,0x1E,0x00},/*"$",36*/
{0xF0,0x08,0xF0,0x80,0x60,0x18,0x00,0x00},
{0x00,0x31,0x0C,0x03,0x1E,0x21,0x1E,0x00},/*"%",37*/
{0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00},
{0x1E,0x21,0x23,0x2C,0x19,0x27,0x21,0x10},/*"&",38*/
{0x00,0x12,0x0E,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",39*/
{0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00},
{0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00},/*"(",40*/
{0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00},
{0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00},/*")",41*/
{0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00},
{0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00},/*"*",42*/
{0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00},
{0x00,0x01,0x01,0x01,0x0F,0x01,0x01,0x01},/*"+",43*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x90,0x70,0x00,0x00,0x00,0x00,0x00},/*",",44*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00},/*"-",45*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},/*".",46*/
{0x00,0x00,0x00,0x00,0xC0,0x38,0x04,0x00},
{0x00,0x60,0x18,0x07,0x00,0x00,0x00,0x00},/*"/",47*/
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00},
{0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",48*/
{0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00},
{0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00},/*"1",49*/
{0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00},
{0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",50*/
{0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00},
{0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00},/*"3",51*/
{0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00},
{0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24},/*"4",52*/
{0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00},
{0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00},/*"5",53*/
{0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00},
{0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00},/*"6",54*/
{0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00},
{0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00},/*"7",55*/
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00},
{0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",56*/
{0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00},
{0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00},/*"9",57*/
{0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00},
{0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},/*":",58*/
{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00},/*";",59*/
{0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00},
{0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},/*"<",60*/
{0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00},
{0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x00},/*"=",61*/
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00},
{0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00},/*">",62*/
{0x00,0x70,0x48,0x08,0x08,0x88,0x70,0x00},
{0x00,0x00,0x00,0x30,0x37,0x00,0x00,0x00},/*"?",63*/
{0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00},
{0x07,0x18,0x27,0x28,0x2F,0x28,0x17,0x00},/*"@",64*/
{0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00},
{0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20},/*"A",65*/
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00},
{0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},/*"B",66*/
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00},
{0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},/*"C",67*/
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00},
{0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},/*"D",68*/
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00},
{0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},/*"E",69*/
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00},
{0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},/*"F",70*/
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00},
{0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},/*"G",71*/
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08},
{0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},/*"H",72*/
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00},
{0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"I",73*/
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00},
{0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},/*"J",74*/
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00},
{0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},/*"K",75*/
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00},
{0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},/*"L",76*/
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00},
{0x20,0x3F,0x01,0x3E,0x01,0x3F,0x20,0x00},/*"M",77*/
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08},
{0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},/*"N",78*/
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00},
{0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},/*"O",79*/
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00},
{0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},/*"P",80*/
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00},
{0x0F,0x10,0x28,0x28,0x30,0x50,0x4F,0x00},/*"Q",81*/
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00},
{0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},/*"R",82*/
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00},
{0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},/*"S",83*/
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00},
{0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"T",84*/
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08},
{0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},/*"U",85*/
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08},
{0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},/*"V",86*/
{0x08,0xF8,0x00,0xF8,0x00,0xF8,0x08,0x00},
{0x00,0x03,0x3E,0x01,0x3E,0x03,0x00,0x00},/*"W",87*/
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08},
{0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},/*"X",88*/
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00},
{0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"Y",89*/
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00},
{0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},/*"Z",90*/
{0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00},
{0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00},/*"[",91*/
{0x00,0x04,0x38,0xC0,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00},/*"\",92*/
{0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00},
{0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00},/*"]",93*/
{0x00,0x00,0x04,0x02,0x02,0x04,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",94*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},/*"_",95*/
{0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",96*/
{0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00},
{0x00,0x19,0x24,0x24,0x12,0x3F,0x20,0x00},/*"a",97*/
{0x10,0xF0,0x00,0x80,0x80,0x00,0x00,0x00},
{0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},/*"b",98*/
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00},
{0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},/*"c",99*/
{0x00,0x00,0x80,0x80,0x80,0x90,0xF0,0x00},
{0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},/*"d",100*/
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00},/*"e",101*/
{0x00,0x80,0x80,0xE0,0x90,0x90,0x20,0x00},
{0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"f",102*/
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00},
{0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},/*"g",103*/
{0x10,0xF0,0x00,0x80,0x80,0x80,0x00,0x00},
{0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},/*"h",104*/
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00},
{0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"i",105*/
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00},
{0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},/*"j",106*/
{0x10,0xF0,0x00,0x00,0x80,0x80,0x80,0x00},
{0x20,0x3F,0x24,0x06,0x29,0x30,0x20,0x00},/*"k",107*/
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00},
{0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"l",108*/
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00},
{0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},/*"m",109*/
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00},
{0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},/*"n",110*/
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},/*"o",111*/
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00},
{0x80,0xFF,0x91,0x20,0x20,0x11,0x0E,0x00},/*"p",112*/
{0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00},
{0x00,0x0E,0x11,0x20,0x20,0x91,0xFF,0x80},/*"q",113*/
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00},
{0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},/*"r",114*/
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00},
{0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},/*"s",115*/
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00},
{0x00,0x00,0x00,0x1F,0x20,0x20,0x10,0x00},/*"t",116*/
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00},
{0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},/*"u",117*/
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00},
{0x00,0x03,0x0C,0x30,0x0C,0x03,0x00,0x00},/*"v",118*/
{0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80},
{0x01,0x0E,0x30,0x0C,0x07,0x38,0x06,0x01},/*"w",119*/
{0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x00},
{0x00,0x20,0x31,0x0E,0x2E,0x31,0x20,0x00},/*"x",120*/
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80},
{0x00,0x81,0x86,0x78,0x18,0x06,0x01,0x00},/*"y",121*/
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00},
{0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},/*"z",122*/
{0x00,0x00,0x00,0x00,0x00,0xFC,0x02,0x02},
{0x00,0x00,0x00,0x00,0x01,0x3E,0x40,0x40},/*"{",123*/
{0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},/*"|",124*/
{0x02,0x02,0xFC,0x00,0x00,0x00,0x00,0x00},
{0x40,0x40,0x3E,0x01,0x00,0x00,0x00,0x00},/*"}",125*/
{0x00,0x02,0x01,0x02,0x02,0x04,0x02,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",126*/
};
const unsigned char F12X24 [][12]=
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",32*/
{0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00},/*"!",33*/
{0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00},
{0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",34*/
{0x00,0x00,0x00,0x80,0xF0,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00},
{0xC6,0xC6,0xC6,0xFF,0xC7,0xC6,0xC6,0xF6,0xFF,0xC6,0xC6,0x00},
{0x00,0x00,0x1F,0x07,0x00,0x00,0x10,0x1F,0x00,0x00,0x00,0x00},/*"#",35*/
{0x00,0x00,0xC0,0xE0,0x30,0xF8,0x30,0x70,0xE0,0xC0,0x00,0x00},
{0x00,0x80,0x87,0x0F,0x0C,0xFF,0x38,0x70,0xE1,0xC1,0x00,0x00},
{0x00,0x03,0x0F,0x0E,0x18,0x7F,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"$",36*/
{0x00,0xE0,0x30,0x30,0xE0,0x00,0x00,0x00,0xE0,0x10,0x00,0x00},
{0x00,0x0F,0x18,0x18,0xCF,0x30,0x0C,0xE3,0x30,0x30,0xE0,0x00},
{0x00,0x00,0x18,0x06,0x01,0x00,0x01,0x0F,0x18,0x18,0x0F,0x00},/*"%",37*/
{0x00,0x00,0xC0,0xE0,0x30,0x30,0x30,0xE0,0x80,0x00,0x00,0x00},
{0x00,0xE0,0xF3,0x3F,0x3C,0xFC,0xC6,0x83,0x00,0xE0,0x60,0x00},
{0x00,0x07,0x0F,0x0C,0x18,0x18,0x19,0x0F,0x07,0x0F,0x0C,0x00},/*"&",38*/
{0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",39*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x30,0x18,0x08,0x00},
{0x00,0x00,0x00,0x00,0x00,0x38,0xFF,0x01,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0E,0x18,0x30,0x20,0x00},/*"(",40*/
{0x00,0x0C,0x18,0x70,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x60,0x30,0x1C,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*")",41*/
{0x00,0xC0,0x80,0x00,0x00,0xF0,0xF0,0x00,0x00,0x80,0xC0,0x00},
{0x00,0x31,0x19,0x1B,0x0F,0xFF,0xFF,0x0F,0x1B,0x19,0x31,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"*",42*/
{0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00},
{0x10,0x10,0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x10,0x10,0x00},
{0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00},/*"+",43*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x5C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",44*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",45*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",46*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x00},
{0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x07,0x01,0x00,0x00,0x00},
{0x00,0x18,0x0E,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"/",47*/
{0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFE,0x00},
{0x00,0x01,0x07,0x0E,0x0C,0x18,0x18,0x0C,0x0F,0x07,0x00,0x00},/*"0",48*/
{0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x03,0x01,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00},/*"1",49*/
{0x00,0x80,0xE0,0x60,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00},
{0x00,0x01,0x01,0x00,0x80,0xC0,0xE0,0x38,0x1F,0x07,0x00,0x00},
{0x00,0x08,0x0E,0x0F,0x0B,0x09,0x08,0x08,0x08,0x08,0x08,0x00},/*"2",50*/
{0x00,0x80,0xC0,0x60,0x30,0x30,0x30,0x30,0xE0,0xC0,0x00,0x00},
{0x00,0x01,0x01,0x00,0x00,0x18,0x18,0x38,0x7F,0xE7,0x80,0x00},
{0x00,0x03,0x07,0x0C,0x18,0x18,0x18,0x0C,0x0E,0x07,0x01,0x00},/*"3",51*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0x00,0x00,0x00},
{0x80,0xC0,0xF0,0xB8,0x8E,0x87,0x81,0xFF,0xFF,0x80,0x80,0x80},
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01},/*"4",52*/
{0x00,0x00,0xE0,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00},
{0x00,0x1C,0x1F,0x0D,0x04,0x04,0x0C,0x0C,0x3C,0xF8,0xC0,0x00},
{0x01,0x07,0x0E,0x08,0x18,0x18,0x18,0x0C,0x0F,0x07,0x00,0x00},/*"5",53*/
{0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x10,0x00,0x00,0x00},
{0x00,0xE0,0xF8,0x1E,0x0F,0x0D,0x0C,0x0C,0x18,0xF8,0xF0,0x00},
{0x00,0x03,0x07,0x0C,0x18,0x18,0x18,0x18,0x0C,0x0F,0x03,0x00},/*"6",54*/
{0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0xE0,0x60,0x00},
{0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0x1E,0x07,0x01,0x00,0x00},
{0x00,0x00,0x00,0x08,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",55*/
{0x00,0x80,0xE0,0x60,0x30,0x30,0x30,0x20,0xE0,0xC0,0x00,0x00},
{0x00,0xE3,0xFF,0x3C,0x18,0x18,0x18,0x3C,0x3F,0xE7,0xC0,0x00},
{0x00,0x07,0x0F,0x0C,0x18,0x18,0x18,0x18,0x0C,0x07,0x03,0x00},/*"8",56*/
{0x00,0xC0,0xE0,0x60,0x30,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x02,0x1F,0x3D,0x30,0x60,0x60,0xE0,0xF0,0x7F,0x1F,0x03,0x00},
{0x00,0x00,0x00,0x10,0x1C,0x0F,0x03,0x01,0x00,0x00,0x00,0x00},/*"9",57*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00},/*":",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x7C,0x1C,0x00,0x00,0x00,0x00,0x00},/*";",59*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x20,0x10,0x00},
{0x00,0x10,0x38,0x6C,0xC6,0x83,0x01,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x10,0x00},/*"<",60*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",61*/
{0x00,0x30,0x20,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x01,0x83,0xC6,0x6C,0x38,0x10,0x00},
{0x00,0x18,0x08,0x04,0x02,0x03,0x01,0x00,0x00,0x00,0x00,0x00},/*">",62*/
{0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0x01,0x01,0x00,0x00,0xE0,0x78,0x1C,0x0F,0x07,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00},/*"?",63*/
{0x00,0x00,0xC0,0x20,0x20,0x10,0x10,0x10,0x20,0x40,0x80,0x00},
{0x78,0x87,0x00,0xFC,0x0E,0x01,0xC1,0xFF,0x07,0x80,0x7F,0x00},
{0x00,0x03,0x04,0x09,0x11,0x11,0x10,0x11,0x09,0x01,0x00,0x00},/*"@",64*/
{0x00,0x00,0x00,0x00,0xC0,0xF0,0xF0,0x80,0x00,0x00,0x00,0x00},
{0x00,0x00,0xE0,0xFE,0xDF,0xC1,0xC3,0xFF,0xFC,0xC0,0x00,0x00},
{0x10,0x1F,0x1F,0x01,0x00,0x00,0x00,0x00,0x03,0x1F,0x1E,0x10},/*"A",65*/
{0x00,0xF0,0xF0,0x30,0x30,0x30,0x20,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x3F,0xE7,0xC3,0x00},
{0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x0C,0x0E,0x0F,0x03,0x00},/*"B",66*/
{0x00,0x00,0xC0,0xE0,0x60,0x30,0x30,0x30,0x60,0xC0,0x80,0x00},
{0x00,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0x00},
{0x00,0x01,0x07,0x0F,0x0C,0x18,0x18,0x18,0x0E,0x07,0x03,0x00},/*"C",67*/
{0x00,0xF0,0xF0,0x30,0x20,0x20,0x60,0xE0,0xC0,0x80,0x00,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x83,0xFF,0xFE,0x00},
{0x00,0x1F,0x1F,0x18,0x18,0x08,0x0C,0x0E,0x07,0x03,0x00,0x00},/*"D",68*/
{0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00},
{0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00},
{0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00},/*"E",69*/
{0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00},
{0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"F",70*/
{0x00,0x00,0xC0,0xE0,0x60,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0xFF,0xFF,0x01,0x00,0x00,0x30,0x30,0x31,0xF3,0xF3,0x00},
{0x00,0x01,0x07,0x0F,0x0C,0x18,0x18,0x08,0x0E,0x1F,0x1F,0x00},/*"G",71*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00},
{0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0xFF,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00},/*"H",72*/
{0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"I",73*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0x00},
{0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7F,0x00},
{0x00,0x03,0x07,0x0E,0x1C,0x18,0x18,0x0C,0x0F,0x07,0x00,0x00},/*"J",74*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0x30,0x10,0x00},
{0x00,0xFF,0xFF,0x38,0x1C,0x3F,0xF3,0xE1,0x80,0x00,0x00,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x03,0x0F,0x1E,0x18,0x00},/*"K",75*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00},/*"L",76*/
{0x00,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x80,0xF0,0xF0,0xF0,0x00},
{0x00,0xFF,0xFF,0x0F,0xFF,0xE0,0xE0,0xFF,0x07,0xFF,0xFF,0x00},
{0x00,0x1F,0x1F,0x00,0x01,0x1F,0x1F,0x00,0x00,0x1F,0x1F,0x00},/*"M",77*/
{0x00,0xF0,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00},
{0x00,0xFF,0xFF,0x03,0x0F,0x3C,0xF0,0xC0,0x00,0xFF,0xFF,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x07,0x1F,0x1F,0x1F,0x00},/*"N",78*/
{0x00,0x80,0xC0,0xE0,0x70,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0x00},
{0x00,0x03,0x07,0x0E,0x1C,0x18,0x18,0x0C,0x0F,0x07,0x01,0x00},/*"O",79*/
{0x00,0xF0,0xF0,0x30,0x30,0x30,0x20,0x60,0x60,0xC0,0x80,0x00},
{0x00,0xFF,0xFF,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",80*/
{0x00,0x80,0xC0,0xE0,0x70,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x80,0x80,0x01,0xFF,0xFF,0x00},
{0x00,0x03,0x07,0x0E,0x1C,0x18,0x19,0x0F,0x1F,0x1F,0x01,0x00},/*"Q",81*/
{0x00,0xF0,0xF0,0x30,0x30,0x30,0x20,0x60,0xE0,0xC0,0x80,0x00},
{0x00,0xFF,0xFF,0x30,0x30,0x30,0x70,0xF8,0x9C,0x0F,0x07,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x01,0x0F,0x1E,0x18,0x00},/*"R",82*/
{0x00,0x80,0xC0,0xE0,0x30,0x30,0x30,0x60,0xE0,0xC0,0x00,0x00},
{0x00,0x83,0x87,0x0E,0x1C,0x18,0x38,0x30,0x71,0xE1,0xC0,0x00},
{0x00,0x07,0x0F,0x0C,0x18,0x18,0x18,0x18,0x0E,0x07,0x03,0x00},/*"S",83*/
{0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"T",84*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00},
{0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00},
{0x00,0x03,0x0F,0x0C,0x18,0x18,0x18,0x1C,0x0E,0x0F,0x03,0x00},/*"U",85*/
{0x30,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x80,0xF0,0xF0,0x00},
{0x00,0x01,0x1F,0xFF,0xF0,0x00,0x80,0xF8,0x7F,0x07,0x00,0x00},
{0x00,0x00,0x00,0x00,0x07,0x1F,0x1F,0x03,0x00,0x00,0x00,0x00},/*"V",86*/
{0xF0,0xF0,0x00,0x00,0x80,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x10},
{0x00,0xFF,0xFF,0xC0,0xFF,0x03,0x1F,0xFE,0xC0,0xFF,0x1F,0x00},
{0x00,0x00,0x1F,0x1F,0x01,0x00,0x00,0x0F,0x1F,0x0F,0x00,0x00},/*"W",87*/
{0x00,0x30,0xF0,0xE0,0x00,0x00,0x00,0x80,0xE0,0x70,0x10,0x00},
{0x00,0x00,0x00,0x83,0xEF,0x7C,0x7E,0xE7,0x81,0x00,0x00,0x00},
{0x10,0x1C,0x1F,0x07,0x01,0x00,0x00,0x01,0x0F,0x1E,0x18,0x00},/*"X",88*/
{0x10,0x70,0xF0,0x80,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00},
{0x00,0x00,0x01,0x07,0x1E,0xF8,0xFC,0x0F,0x03,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"Y",89*/
{0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x00},
{0x00,0x00,0x00,0xC0,0xE0,0x78,0x1E,0x07,0x03,0x00,0x00,0x00},
{0x00,0x1C,0x1F,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00},/*"Z",90*/
{0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x60,0x60,0x60,0x60,0x00},/*"[",91*/
{0x00,0x10,0x70,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x03,0x0F,0x78,0xE0,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x3C,0x60,0x00,0x00},/*"\",92*/
{0x00,0x0C,0x0C,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x60,0x60,0x60,0x60,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00},/*"]",93*/
{0x00,0x20,0x30,0x18,0x0C,0x04,0x0C,0x1C,0x18,0x20,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",94*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},/*"_",95*/
{0x00,0x00,0x00,0x00,0x04,0x0C,0x38,0x30,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",96*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x98,0x9C,0xCC,0xCC,0xCC,0x4C,0xFC,0xF8,0x00,0x00},
{0x00,0x07,0x0F,0x19,0x18,0x18,0x08,0x0C,0x0F,0x1F,0x10,0x00},/*"a",97*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFF,0xFF,0x18,0x0C,0x04,0x0C,0x0C,0x7C,0xF8,0xC0,0x00},
{0x00,0x1F,0x1F,0x0C,0x08,0x18,0x18,0x1C,0x0F,0x07,0x01,0x00},/*"b",98*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xF0,0xF8,0x1C,0x0C,0x0C,0x0C,0x0C,0x3C,0x38,0x00,0x00},
{0x00,0x03,0x07,0x0C,0x18,0x18,0x18,0x18,0x0E,0x07,0x03,0x00},/*"c",99*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00},
{0x00,0xF0,0xF8,0x1C,0x0C,0x04,0x0C,0x0C,0xFF,0xFF,0x00,0x00},
{0x00,0x03,0x0F,0x0C,0x18,0x18,0x18,0x0C,0x1F,0x1F,0x00,0x00},/*"d",100*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xE0,0xF8,0x5C,0x4C,0x44,0x44,0x4C,0x7C,0x78,0x40,0x00},
{0x00,0x03,0x07,0x0C,0x18,0x18,0x18,0x18,0x0E,0x06,0x02,0x00},/*"e",101*/
{0x00,0x00,0x00,0x00,0xC0,0xE0,0x20,0x30,0x30,0x30,0x60,0x00},
{0x00,0x0C,0x0C,0x0C,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x00,0x00},
{0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00},/*"f",102*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0xF8,0xFC,0x8C,0x04,0x8C,0xFC,0xFC,0x04,0x04,0x00},
{0x00,0x72,0xF7,0xCD,0x8D,0x8D,0x8D,0x89,0xC8,0x78,0x30,0x00},/*"g",103*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFF,0xFF,0x30,0x08,0x0C,0x04,0x0C,0x1C,0xF8,0xE0,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00},/*"h",104*/
{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"i",105*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00},
{0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x7F,0x3F,0x00,0x00,0x00},/*"j",106*/
{0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFF,0xFF,0xC0,0xE0,0x70,0xF8,0x9C,0x0C,0x04,0x00,0x00},
{0x00,0x1F,0x1F,0x01,0x00,0x00,0x01,0x03,0x0E,0x1C,0x10,0x00},/*"k",107*/
{0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00},/*"l",108*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0xFC,0xFC,0x18,0x0C,0x0C,0xFC,0xF8,0x08,0x0C,0x0C,0xFC,0x00},
{0x1F,0x1F,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x1F,0x00},/*"m",109*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFC,0xFC,0x30,0x08,0x0C,0x04,0x0C,0x1C,0xF8,0xE0,0x00},
{0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00},/*"n",110*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xF0,0xF8,0x1C,0x0C,0x0C,0x0C,0x0C,0x18,0xF8,0xE0,0x00},
{0x00,0x03,0x07,0x0C,0x18,0x18,0x18,0x0C,0x0E,0x07,0x03,0x00},/*"o",111*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFC,0xFC,0x18,0x0C,0x0C,0x0C,0x0C,0x78,0xF8,0xC0,0x00},
{0x00,0xFF,0xFF,0x0C,0x08,0x18,0x18,0x1C,0x0F,0x07,0x01,0x00},/*"p",112*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xF0,0xF8,0x1C,0x0C,0x0C,0x0C,0x0C,0xFC,0xFC,0x00,0x00},
{0x00,0x03,0x0F,0x0C,0x18,0x18,0x18,0x0C,0xFF,0xFF,0x00,0x00},/*"q",113*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0xFC,0xFC,0x70,0x18,0x08,0x0C,0x0C,0x00,0x00,0x00},
{0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"r",114*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x78,0x7C,0xCC,0xC4,0xC4,0x8C,0x9C,0x18,0x00,0x00},
{0x00,0x00,0x0E,0x0C,0x18,0x18,0x18,0x18,0x0F,0x0F,0x00,0x00},/*"s",115*/
{0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x0C,0x0C,0x0C,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x00,0x00},
{0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x18,0x18,0x18,0x00,0x00},/*"t",116*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00},
{0x00,0x07,0x0F,0x1C,0x18,0x18,0x08,0x0C,0x07,0x1F,0x1F,0x00},/*"u",117*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x0C,0x7C,0xF0,0x80,0x00,0x00,0xC0,0xF8,0x3C,0x04,0x00},
{0x00,0x00,0x00,0x01,0x0F,0x1C,0x1E,0x07,0x00,0x00,0x00,0x00},/*"v",118*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x0C,0xFC,0xE0,0x00,0xF0,0x3C,0xFC,0xC0,0x00,0xFC,0x7C,0x00},
{0x00,0x00,0x1F,0x1E,0x07,0x00,0x00,0x1F,0x1F,0x07,0x00,0x00},/*"w",119*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x04,0x0C,0x1C,0xF0,0xE0,0xE0,0x38,0x1C,0x04,0x00,0x00},
{0x00,0x10,0x1C,0x0E,0x03,0x01,0x03,0x07,0x0E,0x18,0x10,0x00},/*"x",120*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x0C,0x7C,0xF0,0x80,0x00,0x00,0xC0,0xF8,0x3C,0x04,0x00},
{0x00,0x00,0xC0,0xC1,0xCF,0x7E,0x3E,0x07,0x00,0x00,0x00,0x00},/*"y",121*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x0C,0x0C,0x8C,0xCC,0xEC,0x3C,0x1C,0x0C,0x00,0x00},
{0x00,0x18,0x1C,0x1F,0x1B,0x19,0x18,0x18,0x18,0x18,0x00,0x00},/*"z",122*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0x04,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x10,0x38,0xFF,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x40,0x00,0x00},/*"{",123*/
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},/*"|",124*/
{0x00,0x04,0x04,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0xCF,0xFF,0x30,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x40,0x40,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",125*/
{0x00,0x08,0x0C,0x06,0x06,0x06,0x0C,0x18,0x18,0x0C,0x06,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",126*/
};
#endif

View File

@ -0,0 +1,142 @@
#include "oled_port.h"
#include "string.h"
#include "air001xx.h"
#include "air001xx_ll_spi.h"
#include "air001xx_ll_bus.h"
#include "air001xx_ll_gpio.h"
#include "air001xx_ll_utils.h"
#define OLED_CMD 0
#define OLED_DATA 1
#define RES_PORT GPIOA
#define RES_PIN LL_GPIO_PIN_4
#define DC_PORT GPIOA
#define DC_PIN LL_GPIO_PIN_6
#define SCK_PORT GPIOA
#define SCK_PIN LL_GPIO_PIN_5
#define SDI_PORT GPIOA
#define SDI_PIN LL_GPIO_PIN_7
__STATIC_INLINE void OLED_RES_Set(void)
{
WRITE_REG(RES_PORT->BSRR, READ_REG(RES_PORT->BSRR) | RES_PIN);
}
__STATIC_INLINE void OLED_DC_Set(void)
{
WRITE_REG(DC_PORT->BSRR, READ_REG(DC_PORT->BSRR) | DC_PIN);
}
__STATIC_INLINE void OLED_RES_Clr(void)
{
WRITE_REG(RES_PORT->BRR, READ_REG(RES_PORT->BRR) | RES_PIN);
}
__STATIC_INLINE void OLED_DC_Clr(void)
{
WRITE_REG(DC_PORT->BRR, READ_REG(DC_PORT->BRR) | DC_PIN);
}
static void OLED_SPIRstDCPinInit(void)
{
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIOA的时钟
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = RES_PIN|DC_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
// GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //输出推挽就可以
LL_GPIO_Init(RES_PORT,&GPIO_InitStruct);
GPIO_InitStruct.Pin = SCK_PIN|SDI_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //默认初始化为0就是NO
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
LL_GPIO_Init(SCK_PORT,&GPIO_InitStruct);
}
static void OLED_WriteByte(uint8_t dat, uint8_t cORd)
{
if(cORd) OLED_DC_Set();
else OLED_DC_Clr();
LL_SPI_TransmitData8(SPI1,dat);
while(!LL_SPI_IsActiveFlag_TXE(SPI1))OLED_LOG("hw spi send fail!");
OLED_DC_Set();
}
static void OLED_WriteByteArrayData(uint8_t * data_array,uint16_t len)
{
OLED_DC_Set();
for(uint8_t i = 0; i < len; i++)
{
LL_SPI_TransmitData8(SPI1,data_array[i]);
while(!LL_SPI_IsActiveFlag_TXE(SPI1))OLED_LOG("HW SPI SEND FAIL");
}
}
void OLED_Init(void)
{
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SPI1);
LL_SPI_InitTypeDef SPI_InitStruct = {0};
// LL_SPI_StructInit(&SPI_InitStruct); //默认初始化
// //全双工、从机、8bit、时钟极性低、第一个时钟边沿采数据、硬件NSS、波特率2分频、MSB、normal speed
// SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; //全双工
// SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; //8bit
// SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; //MSB //这三个参数在初始化是就是0设置也是0因此不需要重复设置
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; //主机
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH; //极性高
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE; //第2个时钟延采样
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; //软件NSS
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; //4分频
LL_SPI_Init(SPI1,&SPI_InitStruct);
LL_SPI_Enable(SPI1);
OLED_SPIRstDCPinInit();
LL_mDelay(300);
OLED_RES_Clr();
LL_mDelay(300);
OLED_RES_Set();
OLED_WriteByte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WriteByte(0x00,OLED_CMD);//---set low column address
OLED_WriteByte(0x10,OLED_CMD);//---set high column address
OLED_WriteByte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WriteByte(0x81,OLED_CMD);//--set contrast control register
OLED_WriteByte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
OLED_WriteByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WriteByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WriteByte(0xA6,OLED_CMD);//--set normal display
OLED_WriteByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WriteByte(0x3f,OLED_CMD);//--1/64 duty
OLED_WriteByte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WriteByte(0x00,OLED_CMD);//-not offset
OLED_WriteByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WriteByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WriteByte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WriteByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WriteByte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WriteByte(0x12,OLED_CMD);
OLED_WriteByte(0xDB,OLED_CMD);//--set vcomh
OLED_WriteByte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WriteByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WriteByte(0x02,OLED_CMD);//
OLED_WriteByte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WriteByte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WriteByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WriteByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
//OLED_SPIFill(0x00);
OLED_WriteByte(0xAF,OLED_CMD);
}
void OLED_SendBuff(uint8_t buff[8][128])
{
for(uint8_t i=0;i<8;i++)
{
OLED_WriteByte (0xb0+i,OLED_CMD); //设置页地址0~7(b0-b7)
OLED_WriteByte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WriteByte (0x10,OLED_CMD); //设置显示位置—列高地址
OLED_WriteByteArrayData(buff[i],128); //写一页128个字符
} //更新显示
}

View File

@ -0,0 +1,13 @@
# 本文件夹的一些小说明
## 文件目录
```c
|---Air001(使用air001作为主控SSD1306为OLED驱动器的 WouoUIPage版工程)
|---Port_C_SPI(SPI驱动的底层代码文件`oled_port.c`)
|---Air001_Demo.zip(完整工程文件的压缩包包含TestUI和LittleClok两个例子)
|---Stm32(使用Stm32作为主控SSD1306为OLED驱动器的 WouoUIPage版工程)
|---STM32_HWSPI_TestUI.zip(完整工程文件的压缩包,固件库,TestUI例子使用硬件SPI)
|---Port_C_SPI_STD(Stm32标准固件库硬件spi的底层驱动文件`oled_port.c`)
```

View File

@ -0,0 +1,150 @@
#include "oled_port.h"
#include "string.h"
#include "stm32f10x.h"
#include "main.h"
#define SCL_PORT GPIOA
#define SCL_PIN GPIO_Pin_5
#define SDA_PORT GPIOA
#define SDA_PIN GPIO_Pin_7
#define RES_PORT GPIOB
#define RES_PIN GPIO_Pin_0
#define DC_PORT GPIOB
#define DC_PIN GPIO_Pin_1
#define OLED_CMD 0
#define OLED_DATA 1
void delay(uint8_t i)
{
i = i*5;
while(i--){}
}
static void OLED_RES_Set(void)
{
GPIO_WriteBit(RES_PORT, RES_PIN, Bit_SET);
}
static void OLED_DC_Set(void)
{
GPIO_WriteBit(DC_PORT , DC_PIN, Bit_SET);
}
static void OLED_RES_Clr(void)
{
GPIO_WriteBit(RES_PORT, RES_PIN, Bit_RESET);
}
static void OLED_DC_Clr(void)
{
GPIO_WriteBit(DC_PORT, DC_PIN, Bit_RESET);
}
static void OLED_SPIRstDCPinInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin= DC_PIN|RES_PIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(DC_PORT, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOA
GPIO_InitStructure.GPIO_Pin = SCL_PIN | SDA_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SCL_PORT, &GPIO_InitStructure);
}
static void OLED_WriteByte(uint8_t dat, uint8_t cORd)
{
if(cORd) OLED_DC_Set();
else OLED_DC_Clr();
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, dat);
delay(5);
OLED_DC_Set();
}
static void OLED_WriteByteArrayData(uint8_t * data_array,uint16_t len)
{
OLED_DC_Set();
for(uint8_t i = 0; i < len; i++)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, data_array[i]);
delay(5);
}
}
void OLED_Init(void)
{
OLED_SPIRstDCPinInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE);
SPI_InitTypeDef SPI_InitStructure;
SPI_SSOutputCmd(SPI1, ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
delay_ms(300);
OLED_RES_Clr();
delay_ms(300);
OLED_RES_Set();
OLED_WriteByte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WriteByte(0x00,OLED_CMD);//---set low column address
OLED_WriteByte(0x10,OLED_CMD);//---set high column address
OLED_WriteByte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WriteByte(0x81,OLED_CMD);//--set contrast control register
OLED_WriteByte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
OLED_WriteByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WriteByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WriteByte(0xA6,OLED_CMD);//--set normal display
OLED_WriteByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WriteByte(0x3f,OLED_CMD);//--1/64 duty
OLED_WriteByte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WriteByte(0x00,OLED_CMD);//-not offset
OLED_WriteByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WriteByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WriteByte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WriteByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WriteByte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WriteByte(0x12,OLED_CMD);
OLED_WriteByte(0xDB,OLED_CMD);//--set vcomh
OLED_WriteByte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WriteByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WriteByte(0x02,OLED_CMD);//
OLED_WriteByte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WriteByte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WriteByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WriteByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
//OLED_SPIFill(0x00);
OLED_WriteByte(0xAF,OLED_CMD);
}
void OLED_SendBuff(uint8_t buff[8][128])
{
for(uint8_t i=0;i<8;i++)
{
OLED_WriteByte (0xb0+i,OLED_CMD); //设置页地址0~7(b0-b7)
OLED_WriteByte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WriteByte (0x10,OLED_CMD); //设置显示位置—列高地址
OLED_WriteByteArrayData(buff[i],128); //写一页128个字符
} //更新显示
}

View File

@ -0,0 +1,24 @@
# WouoUI Page 版
## 作者
Sheep118
## 说明
这是一个改动自WouoUI的纯C语言无依赖库只适用于128*64OLED的代码框架将WouoUI抽象出一部分统一的接口以方便快速构建一个具有类似WouoUI风格的OLEDUI。只需要使用简单的初始化函数便可以创建一个具有WouoUI风格的丝滑OLED动画的UI。
具体的接口函数说明请参考下面仓库里的README文件
[https://github.com/Sheep118/WouoUI-PageVersion](https://github.com/Sheep118/WouoUI-PageVersion)
## 本文件夹结构
```c
|---Csource
|---src (这个文件夹是WouoUIPage最主要的源代码文件移植时主要用这里面的几个文件)
|---example (这个是使用WouoUIPage所提供的接口构建的一些应用的例子,只有对应.c.h文件)
|---ProjectExamples (这个文件夹内放着使用WouoUIPage的工程的参考按主控的类型划分为移植时提供一些参考所有工程文件均以zip压缩包上传到对应文件夹中)
|---Air001(Air001的工程压缩包和底层的接口文件示例)
|---Stm32(Stm32的工程压缩包和底层的接口文件示例)
```