查看: 1001|回复: 0

基于GD32F190的电子钟

[复制链接]
  • TA的每日心情
    奋斗
    2023-5-10 20:09
  • 签到天数: 1742 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2016-6-1 13:37:22 | 显示全部楼层 |阅读模式
    分享到:
    在GD32F190提供的资料中,有许多极具应用价值的例程,善加利用就可设计出有用的作品,如关于RTC的例程就是一例。
    首先该例程提供了RTC的基本用法,并可借助串口通讯对RTC进行设置和观察。当然要想使之成为一件作品,还是要有一些工作要做的,主要涉及以下问题:
    1)借助串口通讯先让RTC走起来
    2)通过显示器件来显示运行效果
    3)使用按键来设置修改参数
    4)添加相关器件拓展应用功能
    1.让RTC走起来
    RTC例程的基本功能是通过串口显示提示信息,然后接收相应的参数并出给程序使用,涉及的参数有RTC的起始时间值和闹钟提示时间值。用户具体怎样用就将代码自行添加到while (1) { }循环吧。
    经程序分析可以分析,使用RTC_ShowTime( )函数就能完成这个任务。但运行程序时你就会发现,时钟的时间是在一刻不停地在发送,其中大部分的时间值是相同的,除了说明时钟在走外,有用的数据并不多。为此要添加一个排重处理,方法是只显示不同的时间值。具体的语句如下:
    RTC_GetTimeDate(&RTC_InitStructure, RTC_STORE_NORMAL);
    tt=RTC_InitStructure.RTC_Second;
    if(tt != tp)
    {
             tp=tt;
             RTC_ShowTime();
    }
    显示正常后,又如何来实现闹钟提示呢?
    方法是每当秒数出现变化时就用当前时钟值与闹钟设置值进行一次判别,如两者相等,就给出一次提示,语句如下:
               if((RTC_InitStructure.RTC_Hour==RTC_AlarmInitStructure.RTC_Hour)&&(RTC_InitStructure.RTC_Minute==RTC_AlarmInitStructure.RTC_Minute)&&(RTC_InitStructure.RTC_Second==RTC_AlarmInitStructure.RTC_Second))
    {
             GD_EVAL_LEDOff(LED2); //   用于控制或提示
          printf(" Alarm ***\n\r");
    }   
    有了这些,RTC就算走起来,其执行效果如图所示。


                                                       基于虚拟串口的RTC测试
    2.增添液晶显示器功能
    一个只能依赖串口来工作的电子钟是不具生命力的,必须为它添加一个显示器件来输出时间值和闹钟设置值。在显示器件的选择上,用LCD5110是一个不错的选择。因为它工作电压低,只需3.3V。此外,价格相对便宜,且显示字符数也较多。使用时,需在主程序的文件头添加#include "LCD5110.h",并在GD32F1x0_Peripherals目录下添加lcd5110.c文件。
    应注意的是,文件lcd5110.c和LCD5110.h应分别复制到Peripherals目录下的src和inc文件夹下。
    为了显示汉字显示,可使用软件LCD3310.exe来构建专用的小字库。
    以“定时控制计时器”为例,其字模如下:
    const char china_char[][24]={
    //定
    {0x2C,0x24,0xA4,0x24,0x25,0xE6,0x24,0x24,0x24,0x24,0x2C,0x00,0x08,0x04,0x03,0x04,0x08,0x0F,0x09,0x09,0x09,0x09,0x08,0x00},
    //时
    {0xFE,0x22,0x22,0xFE,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x00,0x07,0x02,0x02,0x07,0x00,0x00,0x00,0x09,0x08,0x0F,0x00,0x00},
    //控
    {0x88,0xFF,0x48,0x00,0x4C,0xA4,0x95,0x86,0x94,0xA4,0x4C,0x00,0x08,0x0F,0x00,0x00,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x00},
    //制
    {0x18,0xD6,0x54,0xFF,0x54,0xD4,0x10,0xFC,0x00,0x00,0xFF,0x00,0x00,0x07,0x00,0x0F,0x04,0x07,0x00,0x01,0x08,0x08,0x0F,0x00},
    //计
    {0x10,0x11,0xF2,0x00,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x00,0x00,0x00,0x07,0x02,0x01,0x00,0x00,0x0F,0x00,0x00,0x00,0x00},
    //时
    {0xFE,0x22,0x22,0xFE,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x00,0x07,0x02,0x02,0x07,0x00,0x00,0x00,0x09,0x08,0x0F,0x00,0x00},
    //器
    {0x20,0x27,0xA5,0xA5,0x67,0x38,0x67,0xA5,0xAD,0x37,0x20,0x00,0x01,0x0F,0x0A,0x0A,0x0E,0x00,0x0E,0x0A,0x0A,0x0F,0x01,0x00},
          };
    为显示字库的字模,其显示函数如下:
    /*-----------------------------------------------------------------------
    LCD_write_chi: 在LCD上显示汉字
    输入参数:X、Y    :显示汉字的起始X、Y坐标;
              ch_with :汉字点阵的宽度
              num     :显示汉字的个数;  
              line    :汉字点阵数组中的起始行数
              row     :汉字显示的行间距
    -----------------------------------------------------------------------*/
    void LCD_write_chi(unsigned char X, unsigned char Y,
                       unsigned char ch_with,unsigned char num,
                       unsigned char line,unsigned char row)
    {   unsigned char i,n;
        LCD_set_XY(X,Y);                         // 设置初始位置
          for (i=0;i<num;)
          {   for (n=0; n<ch_with*2; n++)              // 写一个汉字
                    {   if (n==ch_with)                     // 写汉字的下半部分
                        { if (i==0) LCD_set_XY(X,Y+1);
                          else
                          LCD_set_XY((X+(ch_with+row)*i),Y+1);
                  }
                      LCD_write_byte(china_char[line+i][n],1);
                    }
                  i++;
                  LCD_set_XY((X+(ch_with+row)*i),Y);
          }
    }

                                                 基于LCD5110显示屏的电子时钟
    3.实现参数设置
    由于先前是采用串口来传送相关参数,在去掉串口通讯后,参数的设置就只能通过按键操作了。
    在添加按键函数后,是使用3个板上的按键来进行设置处理,3个键的功能是B2用于参数位置的选择,B3键用于增大数值,B4用于减小增加数值。伴随参数位置的不同,数值的上限也会随着进行调整,从而保证设置值在合理的区间。
    以时钟起始值设置为例,其程序代码如下:
    while(1)
         {  key_scan();
                if(KEY_VAL != 0)
                     {         switch(KEY_VAL)
                             {         case 3 :
                                     Set_W++;
                                     break;
                                     case 2 :
                                     if(Set_W == 1)
                                     {         Set[0]++;
                                             if(Set [0] > 24)         Set [0]=24;
                                     }
                                     if(Set_W == 2)
                                     {         Set [1]++;
                                             if(Set [1] > 60)    Set [1]=0;
                                     }
                                     if(Set_W == 3)
                                     {
                                             Set [2]++;
                                             if(Set [2] > 60)   Set [2]=0;
                                             }
                                     break;
                                     case 1 :
                                     if(Set_W == 1)
                                     {
    if(Set [0] > 0)  Set [0]--;
                                     }
                                     if(Set_W == 2)
                                     {
                                             if(Set [1] > 0)  Set [1]--;
                                     }
                                     if(Set_W == 3)
                                     {
                                             if(Set [2] > 0)  Set [2]--;
                                     }
                                     break;
                              }        
                              switch(Set_W)
                             {         case 0 :
                                     LCD_set_XY(36,1);
                                     LCD_write_char(Set [0]/10+'0',0);
                                     LCD_set_XY(42,1);
                                     LCD_write_char(Set [0]+'0',0);
                                     LCD_set_XY(54,1);
                                     LCD_write_char(Set [1]/10+'0',0);
                                     LCD_set_XY(60,1);
                                     LCD_write_char(Set [1]+'0',0);
                                     LCD_set_XY(72,1);
                                     LCD_write_char(Set [2]/10+'0',0);
                                     LCD_set_XY(78,1);
                                     LCD_write_char(Set [2]+'0',0);
                                     break;
                                     case 1 :
                                     LCD_set_XY(36,1);
                                     LCD_write_char(Set [0]/10+'0',1);
                                     LCD_set_XY(42,1);
                                     LCD_write_char(Set [0]+'0',1);
                                     LCD_set_XY(54,1);
                                     LCD_write_char(Set [1]/10+'0',0);
                                     LCD_set_XY(60,1);
                                     LCD_write_char(Set [1]+'0',0);
                                     LCD_set_XY(72,1);
                                     LCD_write_char(Set [2]/10+'0',0);
                                     LCD_set_XY(78,1);
                                     LCD_write_char(Set [2]+'0',0);
                                     break;
                                     case 2 :
                                     LCD_set_XY(36,1);
                                     LCD_write_char(Set [0]/10+'0',0);
                                     LCD_set_XY(42,1);
                                     LCD_write_char(Set [0]+'0',0);
                                     LCD_set_XY(54,1);
                                     LCD_write_char(Set [1]/10+'0',1);
                                     LCD_set_XY(60,1);
                                     LCD_write_char(Set [1]+'0',1);
                                     LCD_set_XY(72,1);
                                     LCD_write_char(Set [2]/10+'0',0);
                                     LCD_set_XY(78,1);
                                     LCD_write_char(Set [2]+'0',0);
                                     break;
                                     case 3 :
                                     LCD_set_XY(36,1);
                                     LCD_write_char(Set[0]/10+'0',0);
                                     LCD_set_XY(42,1);
                                     LCD_write_char(Set[0]+'0',0);
                                     LCD_set_XY(54,1);
                                     LCD_write_char(Set[1]/10+'0',0);
                                     LCD_set_XY(60,1);
                                     LCD_write_char(Set[1]+'0',0);
                                     LCD_set_XY(72,1);
                                     LCD_write_char(Set[2]/10+'0',1);
                                     LCD_set_XY(78,1);
                                     LCD_write_char(Set[2]+'0',1);
                                     break;
                             }
                 KEY_VAL=0;
                            }
                    }
    至于闹钟设置值得处理,与时钟起始值设置相仿,只是显示位置不同,所存放的目的地不同罢了。
    有了相对完整的人机交互能力,整体设计才算相对完成。
    4.功能拓展
    具备了相应功能的设计并不是设计的结束,还需将其功能最大化,这样才能提升设计的效率。针对已实现的功能,又能做哪些拓展呢?
    首先,可从器件方面加以改变。例如在到达设置闹钟时间时,是通过LED的点亮来起提示作用的。此时不妨把LED改为蜂鸣器、振子、继电器等。别小看这样的小小改变,作用是不小的。作为LED指示,它是被动的,你不去观察它,它就等于不起作用。而改作蜂鸣器,它的提示作用却是主动的,到时准会吵到你。当然,也会有例外的情况存在,如耳背。此时换上振子,总会振到你了吧。若换上继电器,你就可以定时控制电路了。
       其次,是将单时间限制提升为多时间段限值,在这方面课间打铃控制器便是比较典型的例子,另外一些管道清洗控制器也是基于多个时段进行控制的。
    因此不要小看一个基本性的设计,只要你用心它会为你带来想不到的创造力。
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 08:36 , Processed in 0.114469 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.