美文网首页
基于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