大家好,亲爱的读者们~
在上一章中,我主要讲述了LCD12864库函数的建立,在这一章节中,我将结合所建立的库函数,完成多功能时钟UI界面的设计。原谅小编不是美术专业的,而且在审美方面天赋不足,如果您认为我设计的界面不好看的话,你可以自己设计一下,多多包涵~
注:UI显示界面是后期拍摄的,可能与程序有些差异,这里就不改正了。
1.设计思路
1.开机画面:乐创DIYlogo显示2秒,个人签名显示2秒
2.显示页面:显示时间,温湿度和空气质量
3.设置页面:1)设置时间 2)设置温湿度阈值 3)设置空气质量上限值
4)测距 5)取消报警
4.监视界面:监视是否异常、是否报警、是否取消报警等
5.时间界面:设置时位、分位和秒位
6.温湿度界面:设置温湿度上下限
7.空气质量界面:设置空气质量上限值
8.测距界面:显示距离值,设置安全距离
9.取消报警界面:用于取消报警
10.电机运行界面:用于监视电机状态,并且可以强制启停电机
2.人机界面
(1)开机画面
这里需要对显示的图片进行数据取模,调用显示图片函数,并延时即可。
void display_start(void)
{
lcd_clearscreen();
lcd_display_picture(0);
delay_ms(2000);
lcd_display_picture(1);
delay_ms(2000);
lcd_clearscreen();
}
(2)显示界面
显示界面需要显示时间、温度、湿度和空气质量等,再显示对应的单位即可。
void display_show(void)
{
lcd_display_string(0,32,"显示界面");
lcd_display_num_m(2, 16, hour/10);
lcd_display_num_m(2, 24, hour%10);
lcd_display_string(2,32,"时");
lcd_display_num_m(2, 48, min/10);
lcd_display_num_m(2, 56, min%10);
lcd_display_string(2,64,"分");
lcd_display_num_m(2, 80, sec/10);
lcd_display_num_m(2, 88, sec%10);
lcd_display_string(2,96,"秒");
lcd_display_string(4,0,"温度");
lcd_display_num_m(4,32,temperature/10);
lcd_display_num_m(4,40,temperature%10);
lcd_display_special_str(4,48,1);
lcd_display_string(4,64,"空气质量");
lcd_display_string(6,0,"湿度");
lcd_display_num_m(6,32,humidity/10);
lcd_display_num_m(6,40,humidity%10);
lcd_display_special_str(6,48,0);
lcd_display_letter_m(6,56,'R');
lcd_display_letter_m(6,64,'H');
lcd_display_num_m(6,72,value/1000);
lcd_display_num_m(6,80,(value%1000)/100);
lcd_display_num_m(6,88,(value%100)/10);
lcd_display_num_m(6,96,value%10);
lcd_display_letter_m(6,104,'P');
lcd_display_letter_m(6,112,'P');
lcd_display_letter_m(6,120,'M');
}
显示界面(3)设置界面
/*设置界面1函数*/
void display_set1(void)
{
lcd_display_string(0,32,"设置界面");
lcd_display_num_m(2,16,1);//1
lcd_display_special_str(2,24,7);//.
lcd_display_string(2,32,"时间");
lcd_display_num_m(4,16,2);//2
lcd_display_special_str(4,24,7);//.
lcd_display_string(4,32,"温湿度");
lcd_display_num_m(6,16,3);//3
lcd_display_special_str(6,24,7);//.
lcd_display_string(6,32,"空气质量");
lcd_display_string(line,96,"箭");
}
设置界面1/*设置界面2函数*/
void display_set2(void)
{
lcd_display_string(0,32,"设置界面");
lcd_display_num_m(2,16,4);//4
lcd_display_special_str(2,24,7);//.
lcd_display_string(2,32,"测距");
lcd_display_num_m(4,16,5);//5
lcd_display_special_str(4,24,7);//.
lcd_display_string(4,32,"取消报警");
lcd_display_string(line-6,96,"箭");
}
设置界面2设置界面主要显示设置选项,由于选项较多,暂时分居两页,并且为了选择时的人性化,设置了选择箭头,这样,达到更好的人机交互效果。具体如何选择设置项,我会在下面的按键扫描里讲解。
(4)监视界面
/*监视界面函数*/
void display_monitor(void)
{
lcd_display_string(0,32,"监视界面");
if(temper_sign==0&&humid_sign==0&&air_sign==0&&length_sign==0)
{
lcd_display_string(3,32,"一切正常");
lcd_display_special_str(3,96,8);//,
lcd_display_string(3,104,"笑");
lcd_display_string(5,24,"请放心使用");
lcd_display_special_str(5,104,7);//.
}
else
{
if(temper_sign==1&&humid_sign==0&&air_sign==0&&length_sign==0)
{
lcd_display_string(3,32,"温度异常");
}
else if(temper_sign==0&&humid_sign==1&&air_sign==0&&length_sign==0)
{
lcd_display_string(3,32,"湿度异常");
}
else if(temper_sign==0&&humid_sign==0&&air_sign==1&&length_sign==0)
{
lcd_display_string(3,32,"空气异常");
}
else if(temper_sign==0&&humid_sign==0&&air_sign==0&&length_sign==1)
{
lcd_display_string(3,32,"距离异常");
}
else
{
lcd_display_string(3,32,"多处异常");
}
lcd_display_special_str(3,96,8);//,
lcd_display_string(3,104,"哭");
if(cancel)
{
lcd_display_string(5,24,"已关闭报警");
}
else
{
lcd_display_string(5,24,"已开启报警");
}
lcd_display_special_str(5,104,6);//!
}
}
监视界面(情况正常)这里,异常情况的界面处理将在下一章节展示,因为下一章节针对的就是异常情况的处理。
监视界面用于监视异常情况,以防止报警灯和蜂鸣器同时坏掉的情况,当然,但愿没有这么糟糕的事情~如果检测都正常,则显示一切正常,如果某处异常,可以显示出是某处,并且显示已开启报警,如果此时人员知晓,取消了警报,则监视界面显示已取消报警。
(5)时间设置、温湿度设置、空气质量设置、测距等界面
由于受到代码篇幅的影响,所以这里就以温湿度阈值设置界面为例,进行讲解。其实,这些UI设计的代码,就是合理布局一下界面,没有什么实质性的东西。
/*设置温湿度阈值界面*/
void display_setTemperAndHumid(void)
{
lcd_display_string(0,24,"温湿度界面");
lcd_display_string(2,0,"温度");
lcd_display_special_str(2,32,4);//(
lcd_display_special_str(2,40,1);//du
lcd_display_special_str(2,48,5);//)
lcd_display_string(2,56,"湿度");
lcd_display_special_str(2,88,4);//(
lcd_display_special_str(2,96,0);//%
lcd_display_letter_m(2,104,'R');
lcd_display_letter_m(2,112,'H');
lcd_display_special_str(2,120,5);//)
lcd_display_string(4,8,"上限");
lcd_display_special_str(4,40,2);//:
lcd_display_num_m(4,48,temper_H/10);
lcd_display_num_m(4,56,temper_H%10);
lcd_display_string(4,72,"上限");
lcd_display_special_str(4,104,2);//:
lcd_display_num_m(4,112,humid_H/10);
lcd_display_num_m(4,120,humid_H%10);
lcd_display_string(6,8,"下限");
lcd_display_special_str(6,40,2);//:
lcd_display_num_m(6,48,temper_L/10);
lcd_display_num_m(6,56,temper_L%10);
lcd_display_string(6,72,"下限");
lcd_display_special_str(6,104,2);//:
lcd_display_num_m(6,112,humid_L/10);
lcd_display_num_m(6,120,humid_L%10);
lcd_display_special_str(cur.x,cur.y,3);//*
}
这里,分别显示温度上限、温度下限、湿度上限和湿度下限。同时,在当前选中的设置选项前,标注了一个标记,也比较人性化。
时间设置界面 温湿度阈值界面 空气质量界面 测距界面 报警界面(情况正常) 电机界面(情况正常)(6)取消报警界面
/*取消报警界面*/
void display_cancelAlarm(void)
{
lcd_display_string(0,16,"取消报警界面");
lcd_display_string(3,16,"是否取消报警");
lcd_display_string(6,32,"是");
lcd_display_string(6,80,"否");
if(cancel)
{
lcd_display_special_str(6,24,3);//*
lcd_clearstr(6,64);
}
else
{
lcd_display_special_str(6,72,3);//*
lcd_clearstr(6,16);
}
}
取消报警界面是调试的时候临时加上的,由于调试时,有些参数设置不对,导致在持续报警,为关闭报警,增加了这一功能,当然,现在保留了下来,个人觉得还是有点用的。
3.按键控制
敲黑板,重点来了!界面设计完成后,需要按键进行控制。所谓"人机交互",就是人与机器之间的交流互动。但显示模块里就只有4个独立按键,而要控制的功能又比较多,所以如何合理规划按键的功能显得尤为重要,同时还要保证按键之间不能相互冲突。
经过前期的设计,结合调试时的经验,按键功能定义如下:
K1:界面切换/数值加 K2:位选择 K3:数值减 K4:确定/返回
为实现按键多功能,需要定义一些标志位,如下:
u8 page;//设置界面标志位,page=0:显示界面,page=1:设置界面,
//page=2:监视界面,page=3:设置时间界面,page=4:设置温湿度
//阈值界面,page=5:设置空气指数阈值界面
u8 cancel;//定义取消报警标志位
u8 line;//定义设置选项(设置页面中)
u8 row;//定义时间位选择
POSITION cur;//定义温湿度上下限选择标志位
u8 check;//定义确认/返回切换标志位
u8 flag;//定义电机启/停标志位
u8 mark;//定义时间位选择标志位,mark=0:未选中,mark=1:时位,mark=2:分位,mark=3:秒位
u8 sign;//定义温湿度阈值设置选择位,
//sign=0:温度上限,sign=1:温度下限,sign=2:湿度上限,sign=3:湿度下限
/*按键扫描函数*/
void keyscan(void)
{
//界面切换&&数值加
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET)
{
//界面切换
if(page==0||page==1||page==2)
{
lcd_clearscreen();
page = page>=2?0:page+1;
}
//时间设置
else if(page==3)
{
switch(mark)
{
case 0:hour = hour<23?hour+1:0;break;
case 1:min = min<59?min+1:0;break;
case 2:sec = sec<59?sec+1:0;break;
default:break;
}
}
//温湿度阈值设置
else if(page==4)
{
switch(sign)
{
case 0:temper_H = temper_H>=99?99:temper_H+1;break;
case 1:temper_L = temper_L>=99?99:temper_L+1;break;
case 2:humid_H = humid_H>=99?99:humid_H+1;break;
case 3:humid_L = humid_L>=99?99:humid_L+1;break;
default:break;
}
}
//空气指标阈值设置
else if(page==5)
{
air_upperlimit = air_upperlimit>=1000?1000:air_upperlimit+10;
}
//安全距离设置
else if(page==6)
{
length = length>=450?450:length+10;
}
}while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET);
}
//设置选择:设置位选择
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET)
{
//设置界面:选择时间、选择温湿度、选择空气质量、测距、取消报警
if(page==1||page==7)
{
if(line<=6)
{
lcd_clearstr(line,96);
}
else
{
lcd_clearstr(line-6,96);
}
line = line>=10?2:line+2;
if(line<=6)
{
page = 1;
lcd_clearscreen();
}
else
{
page = 7;
lcd_clearscreen();
}
}
//设置时间界面
else if(page==3)
{
lcd_clearstr(row,16);
row = row>=6?2:row+2;
mark = mark>=2?0:mark+1;
}
//设置温湿度阈值界面
else if(page==4)
{
lcd_clearstr(cur.x,cur.y);
sign = sign>=3?0:sign+1;
switch(sign)
{
case 0:cur.x = 4;cur.y = 0;break;
case 1:cur.x = 6;cur.y = 0;break;
case 2:cur.x = 4;cur.y = 64;break;
case 3:cur.x = 6;cur.y = 64;break;
default:break;
}
}
else if(page==8)
{
cancel = ~ cancel;
}
}while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)==RESET);
}
//数值减
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET)
{
//时间设置
if(page==3)
{
switch(mark)
{
case 0:hour = hour>0?hour-1:23;break;
case 1:min = min>0?min-1:59;break;
case 2:sec = sec>0?sec-1:59;break;
default:break;
}
}
//温湿度阈值设置
else if(page==4)
{
switch(sign)
{
case 0:temper_H = temper_H>0?temper_H-1:0;break;
case 1:temper_L = temper_L>0?temper_L-1:0;break;
case 2:humid_H = humid_H>0?humid_H-1:0;break;
case 3:humid_L = humid_L>0?humid_L-1:0;break;
default:break;
}
}
//空气指标阈值设置
else if(page==5)
{
air_upperlimit = air_upperlimit>0?air_upperlimit-10:0;
}
//安全距离设置
else if(page==6)
{
length = length>0?length-10:0;
}
}while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET);
}
//确认/返回
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)
{
lcd_clearscreen();
check = ~check;
if(check)
{
//设置时间
if(line==2)
{
page = 3;
TIM_Cmd(TIM2, DISABLE);
}
//设置温湿度
else if(line==4)
{
page = 4;
}
//设置空气质量
else if(line==6)
{
page = 5;
}
//测量距离
else if(line==8)
{
page = 6;
}
//取消报警
else
{
page = 8;
}
}
else
{
//设置界面
if(line<=6)
{
page = 1;
}
else
{
page = 7;
}
TIM_Cmd(TIM2, ENABLE);
}
}while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET);
}
}
这里,通过page来区分按键控制功能,通过其他一些标志位来控制调整的对象或者显示位置。这里,大家可以仔细研究研究,其实不难。主程序调用显示函数即可。
UI界面设计部分,花了不少的篇幅,在下一章中,小编将介绍报警模块的设计。
网友评论