OLED显示中文和图像,状态机实现多级菜单系统

发布时间:2026/7/14 19:13:55
OLED显示中文和图像,状态机实现多级菜单系统 移植OLED模块并配置复制文件到HareWare目录下在Keil5中导入这些文件并配置头文件路径更改OLED的引脚配置OLED库的使用常规以128*64像素的OLED显示屏为例8X16表示字符宽8个像素高16个像素6X8表示字符宽6个像素高8个像素。测试程序如下/* //8X16 OLED_ShowChar(0,0,1,OLED_8X16); //前两个参数表示相对于坐标0点的偏移 ----x v y OLED_ShowString(0,16,1234567890123456,OLED_8X16);//横16个字符就铺满了 OLED_ShowString(0,32,89012,OLED_8X16);// OLED_ShowString(0,48,111,OLED_8X16); */ //6X8 高最多8行 宽21个字符 OLED_ShowChar(0,0,a,OLED_6X8); OLED_ShowString(0,8,1234567890123456789012,OLED_6X8);//21个字符 OLED_ShowString(0,16,129012,OLED_6X8); OLED_ShowString(0,24,129012,OLED_6X8); OLED_ShowString(0,32,129012,OLED_6X8); OLED_ShowString(0,40,129012,OLED_6X8); OLED_ShowString(0,48,129012,OLED_6X8); OLED_ShowString(0,56,129012,OLED_6X8); OLED_Update();图形绘制函数//绘制函数 OLED_DrawPoint(1,1); if(OLED_GetPoint(1,1)) OLED_ShowNum(0,40,1,1,OLED_8X16); else OLED_ShowNum(0,40,0,1,OLED_8X16); //画线画矩形 //OLED_DrawLine(0,0,127,63); //OLED_DrawRectangle(10,10,100,50,OLED_FILLED);//填充或者不填充。 //三角形 //OLED_DrawTriangle(0,0,40,10,40,60,OLED_FILLED); //圆 //OLED_DrawCircle(20,20,10,OLED_FILLED); //椭圆 OLED_DrawEllipse(50,30,40,20,OLED_FILLED);显示中文char str[20] 花开富贵; /* OLED_Printf(0,0,OLED_8X16,test:%5d,180);//格式化输出 OLED_Printf(0,20,OLED_8X16,test2:%0.5f,1.2645456); */ //中文要进行取模 OLED_ShowString(0,0,花开花落,OLED_8X16); OLED_Printf(0,20,OLED_8X16,test:%s,str); OLED_Update();取模流程使用PCtoLCD参数设置如图生成字模后按照格式要求复制到函数中显示图像修改模式为图形模式然后设置像素大小绘制图形后生成字模新增一个数组存储。/*********************图像数据*/ const uint8_t Flower[]{ 0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0xB0,0x10,0x10,0x10,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x36, 0x14,0x1C,0x0C,0x0F,0xFF,0xDF,0xB3,0x23,0x47,0x45,0x4C,0x58,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0F,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x08, };然后就可以打印输出了。PCtoLCD导入BMP位图PS处理图片查找边缘后并调整阈值调整图片大小导出BMP位图导入到PCtoLCD中生成字模。有限状态机包含三个元素状态State、事件Event、动作Handler。同一时间只有一种状态执行该状态对应的动作同时轮询判断状态事件状态转移函数是否发生了。实现流程1.分析需求画状态图找出有多少状态和事件封装为枚举类型重要2.分析状态需要保存哪些变量。比如当前处在哪个菜单需要变量State哪一行被选中了需要变量flag3.编写驱动层将硬件转换为事件比如串口收到了信息为一个事件按键按下为一个事件只负责产出事件不操心状态机。Key_Init()等初始化函数4.定义系统的初始化状态5.写状态转移函数Transition()根据事件进行不同状态的转移形参为事件返回值为状态根据当前状态当前事件决定下一状态6.写状态处理函数Handler()当前状态应该做什么执行什么动作7.主循环。最后switch的流程获取事件状态转移Transition状态处理Handler)。switch(state1) //状态机实现操作以及轮询判断触发转换(key) { case menu_main://主菜单 { //获取事件 Event_key event GetEvent(); //状态转移 state1 Menu_Main_Transition(event); //状态处理函数 OLED_Clear(); Menu_Main_Handler(); break; }状态和事件可以封装成一个枚举类型以附带的多级菜单项目说明有限状态机的代码实现。多级菜单实现(有限状态机简要说明系统设置了4个按键向上、向下、进入、返回来切换菜单和高亮显示共有三级菜单。//4个按键 4个事件一个空事件! //B11向上 B1向下 A6确认 A4后退 #define KEY_UP GPIO_Pin_11 #define KEY_DOWN GPIO_Pin_1 #define KEY_ENTER GPIO_Pin_6 #define KEY_BACK GPIO_Pin_4状态和事件封装5个状态分别为主菜单、二级菜单两个、三级菜单两个。//事件 4个事件一个空事件 typedef enum { EVENT_NONE, //无事件 EVENT_KEY_UP, //上键 EVENT_KEY_DOWN, //下键 EVENT_ENTER, //确认 EVENT_BACK //返回 }Event_key; //5个状态 typedef enum{ //5种状态 menu_main, menu_2_1, menu_2_2, menu_3_1, menu_3_2 }State;状态转移函数与状态处理函数状态转移函数根据事件的不同进行状态的切换传入值为一个事件最后会返回一个要切换的状态。状态处理函数各级菜单的显示高光显示都在这个函数。/*状态转换函数*/ State Menu_Main_Transition(Event_key event); //根据事件的不同切换状态 State Menu_2_1_Transition(Event_key event); State Menu_2_2_Transition(Event_key event); State Menu_3_1_Transition(Event_key event); State Menu_3_2_Transition(Event_key event); /*状态处理函数动作)*/ void Menu_Main_Handler(void); void Menu_2_1_Handler(void); void Menu_2_2_Handler(void); void Menu_3_1_Handler(void); void Menu_3_2_Handler(void);主循环while(1) { switch(state1) //状态机实现操作以及轮询判断触发转换(key) { case menu_main://主菜单 { //获取事件 Event_key event GetEvent(); //状态切换 state1 Menu_Main_Transition(event); //状态处理函数 OLED_Clear(); Menu_Main_Handler(); break; } case menu_2_1://二级菜单 { Event_key event GetEvent(); state1 Menu_2_1_Transition(event); OLED_Clear(); Menu_2_1_Handler(); break; } case menu_2_2://二级菜单 { Event_key event GetEvent(); state1 Menu_2_2_Transition(event); OLED_Clear(); Menu_2_2_Handler(); break; } case menu_3_1://三级菜单 { Event_key event GetEvent(); state1 Menu_3_1_Transition(event); OLED_Clear(); Menu_3_1_Handler(); break; } case menu_3_2://三级菜单 { Event_key event GetEvent(); state1 Menu_3_2_Transition(event); OLED_Clear(); Menu_3_2_Handler(); break; } } }接线图只需要一个4引脚OLED模块和4个按钮。绑定的资源为项目接线后可以执行更改如有不同见解可以讨论