嵌入式菜单LCD简单版
嵌入式菜单需求
相信大家做嵌入式的东西的时候,会有许多的参数需要显示到显示屏幕上,那么这些参数肯定不是拿来看看这么简单,最好还可以用按键来调节大小参数。
任务要求
根据前面大家的需求,我们简单想想我们这个菜单需要做到什么程度,有了目标才可以更好的实现对吧。
基础要求:
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简单版相关推荐
- Flutter之仿美团菜单列表简单版
一.背景 公司要制作一个仿美团菜单列表的功能,我们先看下美团的菜单功能. 截图如下: 美团菜单列表视频链接 我们看下做完demo的截图 demo的视频链接: 视频 二.实现的需求点 1.关于绘制列表啥 ...
- 小说下载阅读器_初始简单版
小说下载阅读器_初始简单版 相信园子里面的很多人和我一样喜欢阅读小说,下面是这几年用的比较多一点的阅读器,功能相对完整. Windows本地程序/手机 1.http://www.mybook66.co ...
- 51单片机 时间控制的不同时段交通灯控制设计(简单版)
这个交通灯的设计时简单版,只有一个路口(不是十字路口)的那种(想要实现十字路口可以对代码稍加修改) 使用的开发软件:Keil uVision5 单片机类型为:C51 语言类型:C语言 在这里说一下实现 ...
- SpringBoot 整合Spring Security(简单版)
1 写在前面 关于spring security的介绍,网上一大堆,这里就不介绍了,这里直接使用springboot开始整合 2 整个流程 spring security授权和认证的流程大致和shir ...
- 用JAVA写一个简单版的记事本
下面的代码是一个简单版的记事本.如果需要更多的功能,可以自己去摸索一下更多的功能. import java.awt.FlowLayout; import java.awt.event.ActionEv ...
- LeetCode 11. Container With Most Water--Java 解法--困雨水简单版
LeetCode 11. Container With Most Water–Java 解法 此文首发于我的个人博客:LeetCode 11. Container With Most Water–Ja ...
- luogu P3808 【模板】AC自动机(简单版)
二次联通门 : luogu P3808 [模板]AC自动机(简单版) /*luogu P3808 [模板]AC自动机(简单版)手速越来越快了10分钟一个AC自动机一遍过编译 + 一边AC感觉不错我也就 ...
- 008 数据结构逆向—数组(简单版)
文章目录 前言 逆向背包数组 一维背包数组 二维背包数组 数组结构分析 总结 前言 对于游戏逆向来说,核心需求其实就只有两个 追踪游戏数据 定位游戏功能call 对于追踪游戏数据来说,单纯从一个寄存器 ...
- 【模板】AC自动机(简单版)
题目背景 通过套取数据而直接"打表"过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据 ...
最新文章
- 信息系统项目管理师为什么不建议自学
- Linux shell的标准输入、输出和错误
- LetCode-MSSQL销售分析-I
- python获取手机通知栏消息_Python编写简单的通知栏脚本启动工具
- discard python_Netty入门教程(一) 实现DISCARD服务
- wireshark display reference: https://www.wireshark.org/docs/dfref/
- 【时间同步】IEEE-1588总结
- 【备忘】最新区块链开发入门到精通视频教程下载
- SVG 绘制可交互的中国地图
- Linux 【进程】
- elasticsearch报错:failed send ping to zen unicast
- ANDROID 背光调节
- 计算机网络中帧和字节的关系,关于“帧frame”、“比特bite”、“字节byte”
- 使用Testin云测试进行兼容测试
- (7)-HALCON图像采集助手:界面介绍
- 为什么会有剩男剩女?
- Python之format格式化函数以及数字格式化输出规范
- EasyExcel使用: RGB字体,RGB背景颜色,fillForegroundColor颜色对照表
- 【强化学习知识】强化学习简介
- 整理代码,将一些曾经用过的功能整合进一个spring-boot