嵌入式菜单需求

相信大家做嵌入式的东西的时候,会有许多的参数需要显示到显示屏幕上,那么这些参数肯定不是拿来看看这么简单,最好还可以用按键来调节大小参数。

任务要求

根据前面大家的需求,我们简单想想我们这个菜单需要做到什么程度,有了目标才可以更好的实现对吧。
基础要求
1.至少参数需要可以显示到显示屏幕上
2.需要一个箭头“—>”来显示当前的指示行
3.在当前指示行中的参数可以改变大小

升级要求
1.可以翻页,让显示屏不再拘于屏幕大小的限制
2.可以拓展参数的数量
3.只用四个按键解决,上下左右

特殊要求:简单的编程实现

实现方法

1.为了满足上述的要求,我将用switch case语句来向大家实现最简单的菜单,方便大家移植。
2.这次实验代码用正点原子的战舰f103板子,配用4.3寸的LCD屏幕,如果你的硬件和我的一样,那么可以直接用。
3.这次代码需要用到的c语言知识,需要掌握switch case语句,全局变量和局部变量的使用,指针的基本使用,指针地址的偏移。
4.需要你对于状态的变化有一个非常的清晰的逻辑变化,方便排除bug

首先创建一个menu.c的文件和一个menu.h的头文件

在.c中定义全局变量,这些变量是用来测试的,这都是可以自己改的。
首先我们来看看下面的指针变量,这个相当于一个容器,最主要的是掌握里面的是理解地址,然后就是普通的全局变量,这些变量就是你需要的参数了,不一定要在这里定义,你也可以在其他的.c文件中定义一个全局变量,然后再对应的.h文件中用extern来外部申明,就可以在menu.c中调用,用&变量来赋给指针。
同时大家也可以看到菜单的那些变量参数,也是后面大家拓展时用到的数据,比如你一页要六七个参数,改对应的hang_max,如果你要拓展页数的,,那么改掉page_max就可以了。这里的程序我们时一页展示四个参数,一共两页,可以来回切换

//*************全局变量****************//
uint8_t *text_1;  //菜单要显示的参数名字
uint8_t *text_2;
uint8_t *text_3;
uint8_t *text_4;
uint8_t *text_5;
uint8_t *text_6;uint8_t a=1;    //菜单要现实的值,需要传递的值或是需要改变的值
uint8_t b=2;
uint8_t c=3;
uint8_t led_once=4;
uint8_t sec_1=5;
uint8_t sec_2=6;
//*********************************////*********菜单参数**********//u8 hang=1;        //如果需要改变页数或者行数,从这段中直接修改值即可u8 hang_max=4;u8 hang_min=1;u8 page=1;       u8 page_min=1;u8 page_max=2;u8 page_statu=1;  //页数的状态切换//****************************//在这里插入代码片

定义完了,我们就需要给指针地址中的内容赋值初始化了。
这里我们用一个函数来封装,这个函数直接扔进主函数中初始化部分

void MENU_Init(void)
{text_1=&a;   //取要改变的值,进行指针的值的初始化text_2=&b;text_3=&c;text_4=&led_once;text_5=&sec_1;text_6=&sec_2;
}   在这里插入代码片

然后就是重头戏了,下面就是如何具体实现了
完整版先看一下,后面有分段的程序思路讲解

void MENU_processing(void)
{   if(page==1)
{page_statu=page;switch(key_text){case WKUP_PRES:   hang--;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;case KEY1_PRES:      hang++;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;case KEY0_PRES:      *(text_1+hang-1)=*(text_1+hang-1)+1; LCD_Clear(WHITE);break;case KEY2_PRES:     *(text_1+hang-1)=*(text_1+hang-1)-1;  LCD_Clear(WHITE);break;}LCD_ShowString(30,1*25,200,200,16,"text_1:");  //如果移植,需要自己改变坐标LCD_ShowString(30,2*25,200,200,16,"text_2:");LCD_ShowString(30,3*25,200,200,16,"text_3:");LCD_ShowString(30,4*25,200,200,16,"text_4:");LCD_ShowxNum(80,1*25,*text_1,5,16,1);LCD_ShowxNum(80,2*25,*text_2,5,16,1);LCD_ShowxNum(80,3*25,*text_3,5,16,1);LCD_ShowxNum(80,4*25,*text_4,5,16,1);LCD_ShowString(1,hang*25,200,200,16,"--->");if(page_statu!=page){LCD_Clear(WHITE);}
}
else if(page==2)
{page_statu=page;switch(key_text){case WKUP_PRES:   hang--;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;case KEY1_PRES:      hang++;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;case KEY0_PRES:      *(text_5+hang-1)=*(text_5+hang-1)+1; LCD_Clear(WHITE);break;case KEY2_PRES:     *(text_5+hang-1)=*(text_5+hang-1)-1;  LCD_Clear(WHITE);break;}LCD_ShowString(30,1*25,200,200,16,"text_5:");LCD_ShowString(30,2*25,200,200,16,"text_6:");LCD_ShowxNum(80,1*25,*text_5,5,16,1);LCD_ShowxNum(80,2*25,*text_6,5,16,1);LCD_ShowString(1,hang*25,200,200,16,"--->");if(page_statu!=page){LCD_Clear(WHITE);}
}
} 在这里插入代码片

大家先看一眼,用switch case是不是很方便,这个语句主要是解决按键的问题。我们利用hang的大小来表示当前指示行的改变,上下键可以改变这个箭头的位置,这里一定要注意限幅,因为按的时候我们一定是会多按或者是少按的,会产生误操作

         case WKUP_PRES:      hang--;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;case KEY1_PRES:      hang++;if(hang>hang_max) {hang=hang_min;page=page+1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}if(hang<hang_min) {hang=hang_max;page=page-1;if(page>page_max)page=page_max;if(page<page_min)page=page_min;}LCD_Clear(WHITE);break;在这里插入代码片

再用这句代码实现LCD_ShowString(1,hang*25,200,200,16,"—>");

那么下一个问题是如何改变当前指示行的参数的值,这里就要利用指针地址的偏移来解决了,这是第一页的改变

         case KEY0_PRES:    *(text_1+hang-1)=*(text_1+hang-1)+1; LCD_Clear(WHITE);break;case KEY2_PRES:     *(text_1+hang-1)=*(text_1+hang-1)-1;  LCD_Clear(WHITE);break;在这里插入代码片

这是第二页的,大家发现了,这两页的开始的指针不一样,每一页的第一行的参数为起始地址,然后偏移,所以这里的移植拓展就会有点麻烦,如果你要五六页的参数,拓展需要写五六个if,然后需要算一下每一页的起始指针是哪个,这里大家需要注意一下

         case KEY0_PRES:    *(text_5+hang-1)=*(text_5+hang-1)+1; LCD_Clear(WHITE);break;case KEY2_PRES:     *(text_5+hang-1)=*(text_5+hang-1)-1;  LCD_Clear(WHITE);break;在这里插入代码片

好了,下面便是升级了
增加页数起始很简单,用if语句解决就好,但是刷屏会存在一定的问题,所以我提出以下的解决方法,这个框架可以让先检查一下页的状态的然后进行状态改变。

  if(page==1)
{page_statu=page;........
此处省却代码if(page_statu!=page){LCD_Clear(WHITE);}在这里插入代码片

利用上述的方法,就可以写一个简单的菜单程序了
给大家看一下效果,第一页

第二页

因为我的屏幕是4.3寸的,所以肯定显示的范围很大我也用不完,主要是测试翻页的效果,我后面想移植到1.14寸的LCD屏上,毕竟是嵌入式嘛,追求体积的小巧

如果有疑问,欢迎大家在下方留言,有更好更简单的方法也希望大家可以分享,我也想学习一下

嵌入式菜单LCD简单版相关推荐

  1. Flutter之仿美团菜单列表简单版

    一.背景 公司要制作一个仿美团菜单列表的功能,我们先看下美团的菜单功能. 截图如下: 美团菜单列表视频链接 我们看下做完demo的截图 demo的视频链接: 视频 二.实现的需求点 1.关于绘制列表啥 ...

  2. 小说下载阅读器_初始简单版

    小说下载阅读器_初始简单版 相信园子里面的很多人和我一样喜欢阅读小说,下面是这几年用的比较多一点的阅读器,功能相对完整. Windows本地程序/手机 1.http://www.mybook66.co ...

  3. 51单片机 时间控制的不同时段交通灯控制设计(简单版)

    这个交通灯的设计时简单版,只有一个路口(不是十字路口)的那种(想要实现十字路口可以对代码稍加修改) 使用的开发软件:Keil uVision5 单片机类型为:C51 语言类型:C语言 在这里说一下实现 ...

  4. SpringBoot 整合Spring Security(简单版)

    1 写在前面 关于spring security的介绍,网上一大堆,这里就不介绍了,这里直接使用springboot开始整合 2 整个流程 spring security授权和认证的流程大致和shir ...

  5. 用JAVA写一个简单版的记事本

    下面的代码是一个简单版的记事本.如果需要更多的功能,可以自己去摸索一下更多的功能. import java.awt.FlowLayout; import java.awt.event.ActionEv ...

  6. LeetCode 11. Container With Most Water--Java 解法--困雨水简单版

    LeetCode 11. Container With Most Water–Java 解法 此文首发于我的个人博客:LeetCode 11. Container With Most Water–Ja ...

  7. luogu P3808 【模板】AC自动机(简单版)

    二次联通门 : luogu P3808 [模板]AC自动机(简单版) /*luogu P3808 [模板]AC自动机(简单版)手速越来越快了10分钟一个AC自动机一遍过编译 + 一边AC感觉不错我也就 ...

  8. 008 数据结构逆向—数组(简单版)

    文章目录 前言 逆向背包数组 一维背包数组 二维背包数组 数组结构分析 总结 前言 对于游戏逆向来说,核心需求其实就只有两个 追踪游戏数据 定位游戏功能call 对于追踪游戏数据来说,单纯从一个寄存器 ...

  9. 【模板】AC自动机(简单版)

    题目背景 通过套取数据而直接"打表"过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据 ...

最新文章

  1. 信息系统项目管理师为什么不建议自学
  2. Linux shell的标准输入、输出和错误
  3. LetCode-MSSQL销售分析-I
  4. python获取手机通知栏消息_Python编写简单的通知栏脚本启动工具
  5. discard python_Netty入门教程(一) 实现DISCARD服务
  6. wireshark display reference: https://www.wireshark.org/docs/dfref/
  7. 【时间同步】IEEE-1588总结
  8. 【备忘】最新区块链开发入门到精通视频教程下载
  9. SVG 绘制可交互的中国地图
  10. Linux 【进程】
  11. elasticsearch报错:failed send ping to zen unicast
  12. ANDROID 背光调节
  13. 计算机网络中帧和字节的关系,关于“帧frame”、“比特bite”、“字节byte”
  14. 使用Testin云测试进行兼容测试
  15. (7)-HALCON图像采集助手:界面介绍
  16. 为什么会有剩男剩女?
  17. Python之format格式化函数以及数字格式化输出规范
  18. EasyExcel使用: RGB字体,RGB背景颜色,fillForegroundColor颜色对照表
  19. 【强化学习知识】强化学习简介
  20. 整理代码,将一些曾经用过的功能整合进一个spring-boot

热门文章

  1. Mathorcup数学建模竞赛第六届-【妈妈杯】B题:车位分布的优化设计与评价(附一等奖获奖论文和matlab代码)
  2. 用Javascript实现关闭广告案例
  3. Oracle -PL/SQL Developer错误解决方案(ORA-02291)
  4. c语言实现10个数由小到大排序(插入排序法)
  5. python10086查询系统_Python数字移动设备取证
  6. 安装爬虫框架Scrapy,安装后运行不了~
  7. 【JavaScript学习】JavaScript 常用工具类封装
  8. 1024程序员节!Hello world
  9. 网络篇 物理拓扑与逻辑拓扑-19
  10. ReactNative解决方案研究