RTC-Real Time Clock是430單片機的實時時鍾模塊,可以配置成實時時鍾模式(萬年歷)或者一般目的的32位計數器模式,其中實時時鍾模式提供了年月日、時分秒,可以選擇BCD碼或者二進制格式,並且具有可編程的鬧鍾。RTC模塊支持中斷。相關寄存器請參閱430系列單片機user's guide(我用的是5438A)。
1.計數器模式
實時時鍾控制器寄存器1 RTCMODE位被重置時,計數器模式被選擇,通過軟件設置可以得到一個32位的計數器。從時鍾模式切換到計數器模式是通過重置計數值:RTCNT1、RTCNT2、RTCNT3、RTCNT4 和 預換算計數器:RT0PS、RT1PS。
計數器的增量計數器來自ACLK、SMCLK或者分頻之后的ACLK、SMCLK。分頻系數來自分頻除法器RT0PS、RT1PS。RT0PS的輸出可以和RT1PS的輸出級聯構成32位計數器的時鍾源。4個獨立的8位計數器級聯成為32位的計數器。這能提供計數時鍾的8位、16位、24位、32位溢出中斷。RTCTEV位選擇各自的觸發,通過設置RTCTEVIE位,一個RTCTEV能夠觸發一個中斷。計數器RTCNT1到RTCNT4都可以單獨訪問,並可能被寫入數值。
2.日歷模式
當RTCMODE被置位時,萬年歷模式被選中。值得一提的是,萬年歷模式有能夠計算能否被4整除的閏年算法,這個算法范圍是1901年到2099年。
2.1預分頻
分頻器自動將RT0PS和RT1PS配置成為實時時鍾提供一秒間隔的時鍾,RT0PS源於ACLK,一般來說ACLK為32768Hz,是為了實時時鍾的運行。從日歷模式切換到計數器模式時,會將年月日、時分秒全部被置位1,RT0PS和RT1PS也會被置位。當RTCBCD=1時,日歷寄存器會被選為BCD碼,必須在時間設置之前選擇好格式,改變RTCBCD的狀態和切換到計數器模式影響一樣。
2.2鬧鍾功能
用戶可編程鬧鍾只有在日歷模式下有效。每一個鬧鍾寄存器都包括都包括一個鬧鍾使能位,AE用來修改每一個鬧鍾寄存器,通過設置鬧鍾寄存器的AE位,可以產生多種鬧鍾。無效的鬧鍾不會通過硬件的檢測,所以用戶有必要檢查所設鬧鍾是否正確。
2.3讀寫實時時鍾寄存器
系統時鍾和實時時鍾的時鍾源異步,因而讀寫實時時鍾寄存器的時候要注意。此時實時時鍾寄存器每秒鍾更新一次,為了防止在更新的時候讀取實時時鍾數據而造成錯誤數據的讀取,應該設置一個禁止進入的窗口,在禁止進入窗口和窗口外期間,只有RTCRDY復位有效才可以讀取。在RTCRDY復位的時候,讀取操作是錯誤的並且讀取的時間數據也無效被忽略。
2.4時鍾中斷
由於我做的部分只涉及實時時鍾顯示,中斷部分沒有過多涉及,就不在討論了。
RTC實時時鍾顯示部分程序結構如下:

1 //只是部分代碼,遠未完整,只是說明一下框架 2 void Init_RTC(void)//初始化RTC 3 { 4 RTCCTL01 = RTCSSEL_0 + RTCMODE; // 時鍾模式,每分鍾中斷, BCD格式 5 unsigned int hour,min,sec; 6 7 hour=key[0]*10+key[1]; 8 min =key[2]*10+key[3]; 9 sec =key[4]*10+key[5]; 10 11 SetRTCYEAR(2012); 12 SetRTCMON(6); 13 SetRTCDAY(1); 14 SetRTCHOUR(hour); //按鍵設定時間 15 SetRTCMIN(min); 16 SetRTCSEC(sec); 17 } 18 19 while(key_C) //掃描按鍵 20 { 21 22 if(key_stime_ok) 23 { 24 char str[4]; 25 key_stime_ok=0; 26 key_temp=Read_Key();//讀取按鍵數值 27 if(key_temp != No_key) 28 { 29 key[key_C-1]=key_temp; 30 sprintf(str,"%d",key_temp); 31 PutStringEN24(60,k,str); 32 k-=16; 33 key_C--; 34 } 35 } 36 } 37 38 void Show_Clock(void) 39 { 40 unsigned int Hour ,Minute,Second; 41 char p1[10],p2[10],p3[10]; 42 for(;RTCCTL01&RTCRDY;) _NOP(); // 等待RTC有效 43 for(;RTCCTL01&RTCRDY;) _NOP(); 44 45 Hour = GetRTCHOUR(); 46 Minute = GetRTCMIN(); 47 Second = GetRTCSEC(); 48 49 sprintf(p1,"%02d",Hour); 50 sprintf(p2,"%02d",Minute); 51 sprintf(p3,"%02d",Second); 52 53 PutStringEN24(1,2,p1); //用的TFT屏顯示時鍾 54 PutStringEN24(1,34,":"); 55 PutStringEN24(1,50,p2); 56 PutStringEN24(1,82,":"); 57 PutStringEN24(1,98,p3); 58 }