美文网首页
基于stm32的多功能时钟6——UI界面设计

基于stm32的多功能时钟6——UI界面设计

作者: 世缘 | 来源:发表于2020-02-06 16:51 被阅读0次

大家好,亲爱的读者们~

        在上一章中,我主要讲述了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界面设计部分,花了不少的篇幅,在下一章中,小编将介绍报警模块的设计

相关文章

网友评论

      本文标题:基于stm32的多功能时钟6——UI界面设计

      本文链接:https://www.haomeiwen.com/subject/fmymthtx.html