找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 25169|回復(fù): 6
收起左側(cè)

[零基礎(chǔ)學(xué)習(xí)STM32]第十講:RTC實(shí)時(shí)時(shí)鐘實(shí)驗(yàn)—顯示日期和時(shí)間

  [復(fù)制鏈接]
ID:278743 發(fā)表于 2018-3-22 11:32 | 顯示全部樓層 |閱讀模式
一、概述
1、實(shí)時(shí)時(shí)鐘定
      實(shí)時(shí)時(shí)鐘(RTC)是一個(gè)獨(dú)立的BCD定時(shí)器/計(jì)數(shù)器。RTC提供一個(gè)日歷時(shí)鐘和兩個(gè)可編程鬧鐘中斷,以及一個(gè)具有中斷功能的周期性可編程喚醒標(biāo)志。RTC還包含用于管理低功耗模式的自動(dòng)喚醒單元。
      兩個(gè)32位寄存器包含二進(jìn)碼十進(jìn)位格式(BCD)的秒、分鐘、小時(shí)(12或24小時(shí)制)、星期幾、日期、月份和年份。此外,還可以提供二進(jìn)制格式的亞秒值。
     系統(tǒng)可以自動(dòng)將月份的天數(shù)補(bǔ)償位28、29(閏年),30和31天。并且還可以進(jìn)行夏令時(shí)的補(bǔ)償。
     其他32位寄存器還包括可編程的鬧鐘亞秒、秒、分鐘、小時(shí)、星期幾和日期。此外,還可以使用數(shù)字校準(zhǔn)功能對(duì)晶振精度的偏差進(jìn)行補(bǔ)償。
     上電復(fù)位后,所有RTC寄存器都會(huì)受到保護(hù),以防止可能的非正常寫訪問。
     無論器件狀態(tài)如何(運(yùn)行模式、低功耗模式或處于復(fù)位狀態(tài)),只要電源電壓保持在工作范圍內(nèi),RTC使不會(huì)停止工作。
2、實(shí)時(shí)時(shí)鐘主要特性
      RTC的主要特性如下:
  • 包含亞秒、秒、分鐘、小時(shí)(12/24小時(shí)制)、星期幾、日期、月份和年份的日期。
  • 軟件可編程的夏令時(shí)補(bǔ)償。
  • 兩個(gè)具有中斷功能的可編程鬧鐘?赏ㄟ^任意日歷字段的組合驅(qū)動(dòng)鬧鐘。
  • 自動(dòng)喚醒單元,可周期性地生成標(biāo)志以觸發(fā)自動(dòng)喚醒中斷。
  • 參考時(shí)鐘檢測(cè):可使用更加精確的第二時(shí)鐘源(50Hz或60Hz)來提高日歷的精確度。
  • 利用亞秒級(jí)移位特性與外部時(shí)鐘實(shí)現(xiàn)精確同步。
  • 可屏蔽中斷/事件:
         —  鬧鐘A
         —  鬧鐘B
         —  喚醒中斷
         —  時(shí)間戳
         —  入侵檢測(cè)
  • 數(shù)字校準(zhǔn)電路(周期性計(jì)數(shù)器調(diào)整)。
        —  精度為5ppm。
        —  精度為0.95ppm, 在數(shù)秒鐘的校準(zhǔn)窗口中獲得。
  • 用于時(shí)間保存的時(shí)間戳功能(1個(gè)事件)。
  • 入侵檢測(cè):
       —  2個(gè)帶可配置過濾器和內(nèi)部上拉的入侵事件。
  • 20個(gè)備份寄存器(80字節(jié))。發(fā)生入侵檢測(cè)事件時(shí),將復(fù)位備份寄存器。
  • 復(fù)用功能輸出(RTC_OUT),可選擇以下兩個(gè)輸出之一:

      — RTC_CALIB:512Hz或1Hz時(shí)鐘輸出(LSE頻率為32.768kHZ)?赏ㄟ^將RTC_CR寄存器中的COE【23】位置1來使能此輸出。該輸出可連接到器件RTC_AF1功能。
      — RTC_ALARM(鬧鐘A、鬧鐘B或喚醒)?赏ㄟ^配置RTC_CR寄存器的OSEL【1:0】位選擇此輸出。該輸出可連接到器件RTC_AF1功能。
  • RTC復(fù)用功能輸入:

     — RTC_TS:時(shí)間戳事件檢測(cè)。該輸入可連接到器件RTC_AF1和RTC_AF2功能。
     — RTC_TAMP1:TAMPER1 事件檢測(cè)。該輸入可連接到器件RTC_AF1和RTC_AF2功能。
     — RTC_TAMP2:TAMPER2 事件檢測(cè)。
     — RTC_REFIN:參考時(shí)鐘輸入(通常為市電,50Hz或60Hz)。
二、硬件電路
1、時(shí)鐘源
      iCore3異構(gòu)雙核心工控板采用32.768K無源晶體為系統(tǒng)提供RTC實(shí)時(shí)時(shí)鐘,其電路連接圖如下所示。32.768KHz外部無源晶體連接 OSC32_IN和OSC32_OUT兩引腳之間,為獲得穩(wěn)定的頻率必須加兩個(gè)電容構(gòu)成外部震蕩電路。
                   圖10_0 外部振蕩電路
2、備用電源
     RTC實(shí)時(shí)時(shí)鐘在iCore3電路中具有備用電源,時(shí)刻保證時(shí)鐘通電。
         圖10_1 備用電池電路
三、實(shí)驗(yàn)原理
       STM32的實(shí)時(shí)時(shí)鐘(RTC)是一個(gè)獨(dú)立的定時(shí)器,有一組連續(xù)計(jì)數(shù)的計(jì)時(shí)器,通過軟件來對(duì)其進(jìn)行相關(guān)的配置,可以提供時(shí)鐘功能,通過修改計(jì)數(shù)器的值可以調(diào)整時(shí)鐘,最終通過串口在終端顯示時(shí)間。
四、源代碼
1、主函數(shù)
  1. /*
  2. * Name                : main
  3. * Description         : ---
  4. * Author              : ysloveivy.
  5. *
  6. * History
  7. * --------------------
  8. * Rev                 : 0.00
  9. * Date                : 11/23/2015
  10. *
  11. * create.
  12. * --------------------
  13. */
  14. int main(void)
  15. {
  16.         int i;
  17.         RTC_TimeTypeDef rtc_time;
  18.         RTC_DateTypeDef rtc_date;
  19.         int second_bak = 0;
  20.         led.initialize();
  21.         LED_RED_ON;
  22.         rtc.initialize();
  23.         usart4.initialize(115200);
  24.         usart4.printf("\x0c");                       //清屏        
  25.         usart4.printf("\033[1;32;40m");           //設(shè)置字體終端為綠色
  26.         usart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n");
  27.         while(1){
  28.         for(i = 0;i < 1000000;i++);
  29.         //讀取RTC日期和時(shí)間
  30.         RTC_GetTime(RTC_Format_BIN,&rtc_time);
  31.         RTC_GetDate(RTC_Format_BIN,&rtc_date);
  32.         //當(dāng)秒數(shù)據(jù)與備份不一致時(shí),向終端打印時(shí)間/日期
  33.         if(second_bak != rtc_time.RTC_Seconds){
  34.         usart4.printf("  %02d:%02d:%02d  ",rtc_time.RTC_Hours,rtc_time.RTC_Minutes,rtc_time.RTC_Seconds);
  35.         usart4.printf("20%02d-%02d-%02d  \r",rtc_date.RTC_Year,rtc_date.RTC_Month,rtc_date.RTC_Date);\
  36.         second_bak = rtc_time.RTC_Seconds;         //秒數(shù)據(jù)備份
  37.                 }
  38.         }
  39. }
復(fù)制代碼
2、RTC初始化
  1. /*
  2. * Name               : initialize
  3. * Description        : ---
  4. * Author             : ysloveivy.
  5. *
  6. * History
  7. * -------------------
  8. * Rev                : 0.00
  9. * Date               : 11/23/2015
  10. *
  11. * create.
  12. * -------------------
  13. */
  14. static int initialize(void)
  15. {
  16.         //判斷讀到的備份寄存器的值與寫入的值是否一樣
  17.         if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2){
  18.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   
  19.                   //使能PWR時(shí)鐘
  20.                 PWR_BackupAccessCmd(ENABLE);
  21. RCC_BackupResetCmd(ENABLE);
  22.                 RCC_BackupResetCmd(DISABLE);
  23.                 RCC_LSEConfig(RCC_LSE_ON);                                       //LSE 開啟   
  24. while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) ==RESET);            //檢查指定的RCC標(biāo)志位設(shè)置與否,等待低速晶振就緒
  25.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);            //設(shè)置RTC時(shí)鐘(RTCCLK),選擇LSE作為RTC時(shí)鐘   
  26.                 RCC_RTCCLKCmd(ENABLE);                                           //使能RTC時(shí)鐘
  27. RTC_WaitForSynchro();                                            
  28.                                                                                              //等待APB1和RTC等時(shí)鐘同步
  29.                 rtc_set_time(13,57,12,RTC_H12_PM);                               //設(shè)置時(shí)間
  30.                 rtc_set_date(15,11,28,6);                                        //設(shè)置日期
  31.                 RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);                    //向備份寄存器中寫入數(shù)值
  32.         }
  33.         return 0;
  34. }
  35. /*
  36. * Name               : initialize
  37. * Description        : ---
  38. * Author             : ysloveivy.
  39. *
  40. * History
  41. * -------------------
  42. * Rev                : 0.00
  43. * Date               : 11/23/2015
  44. *
  45. * create.
  46. * -------------------
  47. */
  48. static int rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec,unsigned char ampm)
  49. {
  50.         //設(shè)置時(shí)間
  51.         RTC_TimeTypeDef RTC_TimeTypeInitStructure;
  52.         RTC_TimeTypeInitStructure.RTC_Hours=hour;
  53.         RTC_TimeTypeInitStructure.RTC_Minutes=min;
  54.         RTC_TimeTypeInitStructure.RTC_Seconds=sec;
  55.         RTC_TimeTypeInitStructure.RTC_H12=ampm;
  56.         RTC_SetTime(RTC_Format_BIN,&RTC_TimeTypeInitStructure);
  57.         return 0;
  58. }
復(fù)制代碼
3、RTC配置介紹
  1. static int initialize(void)
  2. {
  3.         //判斷讀到的備份寄存器的值與寫入的值是否一樣
  4.         if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2){
  5.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   
  6.                   //使能PWR時(shí)鐘
  7.                 PWR_BackupAccessCmd(ENABLE);
  8. RCC_BackupResetCmd(ENABLE);
  9.                 RCC_BackupResetCmd(DISABLE);
  10.                 RCC_LSEConfig(RCC_LSE_ON);                                       //LSE 開啟   
  11. while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) ==RESET);         //檢查指定的RCC標(biāo)志位設(shè)置與否,等待低速晶振就緒
  12.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);           //設(shè)置RTC時(shí)鐘(RTCCLK),選擇LSE作為RTC時(shí)鐘   
  13.                 RCC_RTCCLKCmd(ENABLE);                                           //使能RTC時(shí)鐘
  14. RTC_WaitForSynchro();                                            
  15. //等待APB1和RTC等時(shí)鐘同步
  16.                 rtc_set_time(13,57,12,RTC_H12_PM);                               //設(shè)置時(shí)間
  17.                 rtc_set_date(15,11,28,6);                                        //設(shè)置日期
  18.                 RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);                    //向備份寄存器中寫入數(shù)值
  19.         }
  20.         return 0;
  21. }
  22. static int rtc_set_date(unsigned char year,unsigned char month,unsigned char date,unsigned char week)
  23. {
  24.         //設(shè)置日期
  25.         RTC_DateTypeDef RTC_DateTypeInitStructure;
  26.         RTC_DateTypeInitStructure.RTC_Date=date;
  27.         RTC_DateTypeInitStructure.RTC_Month=month;
  28.         RTC_DateTypeInitStructure.RTC_WeekDay=week;
  29.         RTC_DateTypeInitStructure.RTC_Year=year;
  30.         RTC_SetDate(RTC_Format_BIN,&RTC_DateTypeInitStructure);
  31.         return 0;
  32. }
復(fù)制代碼
4、結(jié)構(gòu)體介紹
  1. /**
  2.   * @brief  RTC Init structures definition  
  3.   */
  4. typedef struct
  5. {
  6.   uint32_t RTC_HourFormat;        指定RTC小時(shí)格式,
  7. 這個(gè)參數(shù)可以是@ref rtc_hour_format的值。
  8.   uint32_t RTC_AsynchPrediv;      指定RTC異步預(yù)分值,
  9. 此參數(shù)必須設(shè)置為低于0x7F的值。
  10.   uint32_t RTC_SynchPrediv;       指定RTC同步預(yù)分值,
  11. 此參數(shù)必須設(shè)置為低于0x7FFF的值。
  12. }RTC_InitTypeDef;
  13. /**
  14.   * @brief  RTC Time structure definition  
  15.   */
  16. typedef struct
  17. {
  18.   uint8_t RTC_Hours;        指定RTC時(shí)間小時(shí),此參數(shù)必須設(shè)置為0-12范圍內(nèi)的值。如果選擇RTC_HourFormat_12,則為0-23。該RTC_HourFormat_24被選中。
  19.   uint8_t RTC_Minutes;             指定RTC時(shí)間分鐘,
  20. 此參數(shù)必須設(shè)置為0-59范圍內(nèi)值。
  21.   uint8_t RTC_Seconds;             指定RTC時(shí)間秒,
  22. 此參數(shù)必須設(shè)置為0-59范圍內(nèi)的值。
  23.   uint8_t RTC_H12;                  指定RTC AM/PM時(shí)間,
  24. 這個(gè)參數(shù)可以是@ref rtc_am_pm_definition的值。
  25. }RTC_TimeTypeDef;
  26. /**
  27.   * @brief  RTC Date structure definition  
  28.   */
  29. typedef struct
  30. {
  31.   uint8_t RTC_WeekDay;           指定RTC日期工作日,這個(gè)參數(shù)可以是@refrtc_weekday_definition的值。
  32.   uint8_t RTC_Month;             指定RTC日期月(BCD格式),這個(gè)參數(shù)可以是@ref rtc_month_date_definition的值。
  33.   uint8_t RTC_Date;               指定RTC日期,此參數(shù)必須設(shè)置為1-31范圍內(nèi)的值。
  34.   uint8_t RTC_Year;               指定RTC日期年,此參數(shù)必須設(shè)置為0-99范圍內(nèi)的值。
  35. }RTC_DateTypeDef;
  36. /**
  37.   * @brief  RTC Alarm structure definition  
  38.   */
  39. typedef struct
  40. {
  41.   RTC_TimeTypeDef RTC_AlarmTime;     指定RTC警報(bào)時(shí)間成員。
  42.   uint32_t RTC_AlarmMask;             指定RTC報(bào)警面具,這個(gè)參數(shù)可以是@ref rtc_alarmmask_definition 的值。
  43.   uint32_t RTC_AlarmDateWeekDaySel;  指定RTC警報(bào)是在日期或工作日,
  44. 這個(gè)參數(shù)可以是@ref rtc_alarmdateweekday_definition的值。
  45.   uint8_t RTC_AlarmDateWeekDay;      指定RTC報(bào)警日期/工作日。
  46. 如果選擇了警報(bào)日期,則該參數(shù)。
  47. 必須設(shè)置為1-31范圍內(nèi)的值。
  48. 如果選擇了鬧鐘工作日,這個(gè)。
  49. 參數(shù)可以是@ref rtc_weekday_definition的值。
  50. }RTC_AlarmTypeDef;
復(fù)制代碼

五、實(shí)驗(yàn)現(xiàn)象

      在終端屏幕上可以看到顯示的時(shí)間和日期(如下圖所示)。

                圖10_3 實(shí)驗(yàn)現(xiàn)象圖

六、代碼包下載

     網(wǎng)盤:https://pan.baidu.com/s/1jHuZcnc



iCore3_10_RTC.rar

2.66 MB, 下載次數(shù): 127, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

ID:275094 發(fā)表于 2018-12-7 09:43 | 顯示全部樓層
學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:161151 發(fā)表于 2018-12-7 11:20 | 顯示全部樓層
有可以用按鍵設(shè)置時(shí)間的例程嗎?
回復(fù)

使用道具 舉報(bào)

ID:170847 發(fā)表于 2019-4-18 09:40 | 顯示全部樓層
學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:286761 發(fā)表于 2020-3-3 16:27 | 顯示全部樓層
太好了,正在學(xué)習(xí)這類內(nèi)容。
回復(fù)

使用道具 舉報(bào)

ID:696424 發(fā)表于 2020-4-28 12:22 | 顯示全部樓層
有仿真嗎?
回復(fù)

使用道具 舉報(bào)

ID:1117417 發(fā)表于 2024-4-20 03:28 | 顯示全部樓層
代碼全嗎
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表