<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> STM32 >> 瀏覽文章

        RTC:能夠自動進行網絡對時的電子時鐘

        作者:佚名   來源:互聯網   點擊數:  更新時間:2014年05月16日   【字體:

          STM32片內包含一個32位的RTC定時器,可以通過外部時鐘提供32.768kHz計數時鐘,實現按秒的精確計數,并且這個定時器在MCU復位或者斷電的時候,只要VBAT管腳能夠提供3V的供電,計數器將會繼續計數。

         
            網上有很多人埋怨說STM32的RTC時鐘不準,說實話這完全是冤枉ST,RTC僅僅是個計數器,計數肯定是準確的,如果說時鐘不準,基本上是由于用了劣質的晶振導致的。下圖這是Rainbow用到的RTC晶振:
            考慮到很多鐵殼RTC晶振會出現不能起振、時鐘不準確,我們特意選用了這種高精度的晶振,因此網上提到的時鐘不準的問題是可以避免的。
         
            還有一些網友提到說STM32的RTC耗電量很大,一顆紐扣電池只能維持6個月左右。我個人認為能夠在斷電的情況下維持這么久已經足夠了,試想想,如果一個設備半年都不用了,再次啟用的時候需要換個紐扣電池也是可以接受的,如果設備正常使用,是不會消耗紐扣電池的電量的。
         
            由于Rainbow具有網絡接入能力,因此我們在對RTC類庫做封裝的時候特地增加了從NTP服務器讀取網絡時間的功能。通過類庫可以讀取網絡上標準32位的unix格式的時間戳,將這個時間戳寫入到STM32的RTC計數器中,就可以實現Rainbow和網絡時間同步,之后Rainbow的RTC將按秒進行計數,可以繼續維持這個時鐘。
         
            由于我們的計數值采用的是符合unix標準的時間戳,所以我們可以輕松通過這個時間戳計算出當前的日期、時間、星期幾等,誰叫STM32運算能力有這么強呢?NTP的時間戳是從1900-01-01 00:00:00開始到現在按照秒計數的,而unix的時鐘又是從1970年開始的,所以我們將從NTP服務器獲取的時間戳減去從1900到1970的秒數,寫入到Rainbow的RTC計數器即可。
         
           在軟件包的“Projects\RTC”文件夾包含了本文的完整工程,可以直接編譯、燒寫和調試。程序代碼如下:
        #include "WProgram.h"
        #include "Ethernet.h"
        #include "HardwareRTC.h"
        #include "LiquidCrystal.h"
         
        byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
        //發送NTP請求的本地端口
        uint16_t localPort = 8888;
        EthernetUDP Udp;
         
        //NTP服務器地址
        IPAddress timeServer(132, 163, 4, 101);
         
        //定義LCD對象,使用d4-d7四條數據線進行驅動,將rw接地
        //我們共用到了6個IO:RS、E、D4-D7,RW接低電平
        //本程序接法:
        //  RS => PC0
        // E => PC2
        // D4-D7 => PA0、PA2、PA4、PA6
        LiquidCrystal lcd(PC0, PC2, PA0, PA2, PA4, PA6);
         
        //RTC對象
        HardwareRTC rtc;
         
        void setup()
        {
          //兩行顯示,每行16個字符
          lcd.begin(16, 2);
          lcd.print("Waiting...");
         
          uint8_t ethFlag = Ethernet.begin(mac);
          //啟用RTC
          rtc.begin();
         
          //將RTC與網絡時間進行同步
          if(ethFlag)
          {
            Udp.begin(localPort);
            rtc._udp = &Udp;
            rtc._timeServer = &timeServer;
            rtc.syncNetworkTime();
          }
          //重新初始化,兩行顯示,每行16個字符
          lcd.begin(16, 2);
        }
         
        void loop()
        {
          while(1)
          {
            lcd.setCursor(0, 0);
            tm t = rtc.getTime();
            lcd.print(t.tm_year);
            lcd.print('-');
            if(t.tm_mon < 9) lcd.print('0');
            lcd.print(t.tm_mon + 1);
            lcd.print('-');
            if(t.tm_mday < 10) lcd.print('0');
            lcd.print(t.tm_mday);
            lcd.setCursor(0, 1);
            if(t.tm_hour < 10) lcd.print('0');
            lcd.print(t.tm_hour);
            lcd.print(':');
            if(t.tm_min < 10) lcd.print('0');
            lcd.print(t.tm_min);
            lcd.print(':');
            if(t.tm_sec < 10) lcd.print('0');
            lcd.print(t.tm_sec);
            //每隔1秒刷新
            delay(1000);
          }
        }
         
         
        int main(void)
        {
          //初始化開發板
          boardInit();
          setup();
          while(1) loop();
        }
         
            這個程序使用了1602的LCD作為時鐘顯示,程序首先通過DHCP獲取到網絡參數,如果獲取成功,則調用HardwareRTC類的syncNetworkTime()方法,從NTP服務器同步時間戳到Rainbow,在之后的程序運行中,每隔1秒對LCD上的時間進行一次更新。下圖是程序運行的效果:
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮