点击上方“小麦大叔”,选择“置顶/星标公众号”

福利干货,第一时间送达

大家好,我是小麦,以前用单片机做用户交互的菜单的时候,都比较痛苦,如何写一个复用性高,方便维护,可扩展性高的GUI框架呢?当然可以自己动手写一个,这个过程充满了艰辛和挑战,现在我推荐一个很棒的框架,直接拿来用就行,也可以借鉴和学习其中的思路,一定会收获颇丰。

知道有多少人折腾过液晶显示的菜单,我觉得很多人都应该搞过,我还记得以前大学参加电子设计竞赛获奖的作品,我就用到了一个12864,里面有菜单功能。

以前可能觉得菜单高大上,其实并不是想象中的复杂,本文为大家分享一个用单色屏做的菜单框架。

代码托管在github:

https://github.com/wujique/stm32f407/tree/sw_arch

公众号回复"菜单"也可获得源码.

1、概述

本处所说的菜单是用在128*64这种小屏幕的菜单,例如下面这种,不是彩屏上的GUI。

2、菜单框架设计

作为一个底层驱动工程师,驱动写完了,是要写硬件测试程序的。这个测试程序,一般给测试部/硬件工程师用来测试硬件, 也会给工厂产线测试准成品。

开始的人偷懒,不想一秒就直接上,所有菜单都这样做,一层套一层

1void test_main(void)2{3    while(1)4    {5        get_key(&key);6        switch(key)7        {8            case 1:9                test_key();
10                break;
11            case 2:
12                test_lcd();
13                break;
14            ....
15        }
16    }
17}

当菜单越来越多,就开始纠结了,这样写维护不便,看起来也不美,还浪费程序空间。

作为一个天天看《编程之美》的码农,决定改变现状。

搜索引擎找了很久,找到了两个参考:

  • 基于二叉树的多层的液晶菜单界面设计

  • 基于节点编号的通用树状菜单设计方法与实现.pdf

按照他们的设计方法,鼓捣了一个版本,能用,挺好,但是也纠结。因为他们用了树这种数据结构。对于程序运行来说,非常好,效率高。但是对于我来说,菜单代码是一次性的,但是菜单内容,却是会经常改的。让我用人脑去维护一个包含几十个上百个菜单的树,不容易。

想来想去,这些菜单到底有什么不好?对于我来说,为什么不好用?得出下面结论:

  1. 管得太宽 菜单,你就管菜单切换就行了,到了最低一层,也就是实际的测试功能,就不要管了。菜单切换是类似的,实际测试都是不同的。比如在菜单中,按键1,是进入第一个菜单。但是在测试中,按键1,功能都不一样。如果菜单连这个也要管,相同动作功能太多,无法进行统一抽象,就很难模块化。

  2. 出发点不一样 上面说到的菜单,出发点都是如何设计一个好的菜单数据结构,让程序快速,高效运行。我想要的却是一个容易维护的菜单结构,至于菜单的代码有多乱多纠结,没关系, 而且,几百上千个菜单,就算用轮询的方法,也不过几百us吧,没关系。

3、改进菜单

根据需求,我重新设计了一个菜单结构体

1/**2 * @brief  菜单对象3*/4typedef struct _strMenu5{6    MenuLel l;     ///<菜单等级7    char cha[MENU_LANG_BUF_SIZE];   ///中文8    char eng[MENU_LANG_BUF_SIZE];   ///英文9    MenuType type;  ///菜单类型
10    s32 (*fun)(void);  ///测试函数
11
12} MENU;

是的,就这么简单,每一个菜单都是这个结构体 用这个结构体填充一个列表,就是我们的菜单了、

1const MENU EMenuListTest[]=2{3        MENU_L_0,//菜单等级4        "测试程序",//中文5        "test",        //英文6        MENU_TYPE_LIST,//菜单类型7        NULL,//菜单函数,功能菜单才会执行,有子菜单的不会执行89                MENU_L_1,//菜单等级
10                "LCD",//中文
11                "LCD",        //英文
12                MENU_TYPE_LIST,//菜单类型
13                NULL,//菜单函数,功能菜单才会执行,有子菜单的不会执行
14                        MENU_L_2,//菜单等级
15                        "VSPI OLED",//中文
16                        "VSPI OLED",        //英文
17                        MENU_TYPE_FUN,//菜单类型
18                        test_oled,//菜单函数,功能菜单才会执行,有子菜单的不会执行
19
20                        MENU_L_2,//菜单等级
21                        "I2C OLED",//中文
22                        "I2C OLED",        //英文
23                        MENU_TYPE_FUN,//菜单类型
24                        test_i2coled,//菜单函数,功能菜单才会执行,有子菜单的不会执行
25
26
27                MENU_L_1,//菜单等级
28                "声音",//中文
29                "sound",        //英文
30                MENU_TYPE_LIST,//菜单类型
31                NULL,//菜单函数,功能菜单才会执行,有子菜单的不会执行
32                        MENU_L_2,//菜单等级
33                        "蜂鸣器",//中文
34                        "buzzer",        //英文
35                        MENU_TYPE_FUN,//菜单类型
36                        test_test,//菜单函数,功能菜单才会执行,有子菜单的不会执行
37
38                        MENU_L_2,//菜单等级
39                        "DAC音乐",//中文
40                        "DAC music",        //英文
41                        MENU_TYPE_FUN,//菜单类型
42                        test_test,//菜单函数,功能菜单才会执行,有子菜单的不会执行
43
44                        MENU_L_2,//菜单等级
45                        "收音",//中文
46                        "FM",        //英文
47                        MENU_TYPE_FUN,//菜单类型
48                        test_test,//菜单函数,功能菜单才会执行,有子菜单的不会执行
49
50
51                MENU_L_1,//菜单等级
52                "触摸屏",//中文
53                "tp",        //英文
54                MENU_TYPE_LIST,//菜单类型
55                NULL,//菜单函数,功能菜单才会执行,有子菜单的不会执行
56
57                        MENU_L_2,//菜单等级
58                        "校准",//中文
59                        "calibrate",        //英文
60                        MENU_TYPE_FUN,//菜单类型
61                        test_cal,//菜单函数,功能菜单才会执行,有子菜单的不会执行
62
63                        MENU_L_2,//菜单等级
64                        "测试",//中文
65                        "test",        //英文
66                        MENU_TYPE_FUN,//菜单类型
67                        test_tp,//菜单函数,功能菜单才会执行,有子菜单的不会执行
68
69                MENU_L_1,//菜单等级
70                "按键",//中文
71                "KEY",        //英文
72                MENU_TYPE_FUN,//菜单类型
73                test_key,//菜单函数,功能菜单才会执行,有子菜单的不会执行
74
75        /*最后的菜单是结束菜单,无意义*/
76        MENU_L_0,//菜单等级
77        "END",//中文
78        "END",        //英文
79        MENU_TYPE_NULL,//菜单类型
80        NULL,//菜单函数,功能菜单才会执行,有子菜单的不会执行
81};

这个菜单列表有什么特点和要求呢?1 需要一个根节点和结束节点 2 子节点必须跟父节点,类似下面结构

1-----------------------------------------------2根节点3        第1个1级菜单4                       第1个子菜单5                       第2个子菜单6                       第3个子菜单7        第2个1级菜单8                       第1个子菜单9                                     第1个孙菜单
10                                     第2个孙菜单
11                       第2个子菜单
12                       第3个子菜单
13        第3个1级菜单
14        第4个1级菜单
15        第5个1级菜单
16结束节点
17------------------------------------------------

第2个1级菜单有3个子菜单,子菜单是2级菜单,其中第1个子菜单下面又有2个孙菜单(3级菜单)。

维护菜单,就是维护这个列表,添加删除修改,非常容易。那菜单程序怎么样呢?管他呢。定义好菜单后,通过下面函数运行菜单,

1 emenu_run(WJQTestLcd, (MENU *)&WJQTestList[0], sizeof(WJQTestList)/sizeof(MENU), FONT_SONGTI_1616, 2);

-第1个参数是在哪个LCD上显示菜单, -第2个是菜单列表, -第3个是菜单长度, -第4个四字体, -第5则是行间距

注意:运行这个菜单需要有rtos,因为菜单代码是while(1)的,陷进去就不出来了。需要有其他线程(TASK)维护系统,例如按键扫描。

4、菜单实现效果

相关文件:emenu.c、emenu.h、emenu_test.c

当前代码:

1实现了双列菜单,用数字键选择进入下一层。每页最多显示8个菜单(4*4键盘用1-8键)

2 实现了单列菜单,通过上下翻查看菜单,确认键进入菜单。3 天顶菜单未实现,谁有兴趣可以加上。

3 基于LCD驱动架构,这个简易菜单自适应于多种LCD。

效果如下,有需要的尽管拿去,不用谢。

显示效果

128*64 OLED

128*128 tft lcd

320*240 tft lcd

5、最后说明

以上菜单框架来源屋脊雀工作室,适合初学者练习。我看下这个菜单框架,其实还有很多改进地方。

我当初大学电子设计竞赛用到类似结构体方式,但我那菜单框架用到了二级指针,可以做到无限极扩展,而且可以指向(跳转)任意菜单,方便按键进入、返回等操作。

本文就分享到这里,感兴趣的读者可以自己写一个菜单框架。

素材源于:网络,作者:屋脊雀工作室

版权归原作者所有。仅供技术的传播和学习讨论,如涉及作品版权问题,请联系我进行删除。

—— The End ——

推荐好文  点击蓝色字体即可跳转

☞ 状态机的三种骚操作,值得你了解

☞ 推荐一个直接用于项目开发的PID库!很好用,很稳定

☞ 这14种嵌入式实时系统,你用过哪些?

☞ 推荐一款我私藏已久的串口示波神器

欢迎转发、留言、点赞、分享给你的朋友,感谢您的支持!

点击上方名片关注公众号

分享 

值得学习的单片机菜单框架(附源码)相关推荐

  1. 精选9个值得学习的 HTML5 效果【附源码】

    这里精选了一组很酷的 HTML5 效果.HTML5 是现 Web 开发领域的热点, 拥有很多让人期待已久的新特性,特别是在移动端,Web 开发人员可以借助 HTML5 强大功能轻松制作各种交互性强.效 ...

  2. 【博主推荐】html后台管理系统框架(附源码)

    html后台管理系统框架(附源码) 提示:内含有九套系统框架静态源码,包括列表,表单,曲线图,地图,报表,统计,弹框,加载等所有日常应用:不同的风格,炫酷的界面,可以直接嵌入自己的项目,并使用. 框架 ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(2)-easyui构建前端页面框架[附源码]

    系列目录 前言 为了符合后面更新后的重构系统,本文于2016-10-31日修正一些截图,文字 我们有了一系列的解决方案,我们将动手搭建新系统吧. 后台系统没有多大的UI视觉,这次我们采用的是标准的左右 ...

  4. Silverlight4中右键菜单实现-附源码下载

    在发布Silverlight4 Beta版本和RC时 增加不少新的特性和控件. 类似在WinForm实现右键菜单ContentMenu功能. 在Silverlight 4中也有所体现. 当初在Silv ...

  5. 基于设计模式的学习之旅-----访问者模式(附源码)

    基于设计模式的学习之旅-----访问者模式 1.初始访问者模式 2.什么是访问者模式 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 3.模 ...

  6. Winforn中实现ZedGraph自定义添加右键菜单项(附源码下载)

    场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...

  7. 【C#+SQL Server+打印组件】实现电商快递单打印系统 三:主窗体中的快捷菜单(附源码和资源)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.快捷单设置的快捷菜单 打开主窗体AppForm的设计界面,双击主窗体的标题栏,切换到主窗体的代码页,在代码页的公共变量或方法的编写区,创建CommCl ...

  8. 2023新版图文详解SpringBoot整合SSM框架(附源码)

    版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 教程概述 本教程以图文形式详细讲解SpringBoot整合SSM框架的流程以及具体步骤及其注意 ...

  9. APP+spring boot基于Android智能手机的微课程学习系统设计与实现 毕业设计-附源码100909

    摘  要 随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多学校的眼球之中,他们利用网络来做这个微课程学习系统的网站,随之就产生了"智能手机的微课程学习系统 ",这 ...

最新文章

  1. jquery 二级导航
  2. matlab bs2rv.m,Matlab智能算法之遗传算法(一)
  3. 剑指 offer set 19 翻转单词顺序 字符串左旋
  4. 升级php7_Drupal 8.8.0 正式发布,升级须知
  5. Android系统(45)--Monkey 测试相关知识
  6. 用户可以使用三种方式使用计算机,计算机操作系统期末复习笔记
  7. C语言头文件#includestdlib.h的作用
  8. The Wave kernel Signature: A Quantum Mechanical Approach to shape Analysis
  9. 供SAPI中TTS功能用使的Win10语言包安装
  10. android preference-headers 属性,Android开发之PreferenceActivity的使用
  11. java开源项目-SpringBoot在线教育平台
  12. gre红宝书词汇量是多少?考试够用吗?
  13. excel制作复合饼状图_如何在Excel中制作饼图
  14. Python非线性拟合自定义函数参数(对标MATLAB-nlinfit函数)
  15. 如何优雅的将Mybatis日志中的Preparing与Parameters转换为可执行SQL
  16. FineReport填报--批量删除
  17. Thinkphp5+JWT开发 api接口
  18. Linux 内核likely与unlikey
  19. 1.Cocos跑酷游戏——List工具篇
  20. 外网映射工具(操作很简单)

热门文章

  1. DNS解析常见问题:如何添加AAAA记录?
  2. 理想汽车×OceanBase:当造车新势力遇上数据库新势力
  3. win11音频无声音排查解决方案
  4. 【STM32F429的DSP教程】第21章 DSP矩阵运算-加法,减法和逆矩阵
  5. 大规模MIMO技术概述
  6. 聊聊前端工程化的实践与未来
  7. 超强:Unix道德经(英文版) 1
  8. USACO 2020你知道你的ABC吗
  9. Android Error之动画递归
  10. UI自动化测试经验之谈(一)