1.模块原理
如图 ,RTC 由两个分频寄存器 RP0TS,RP1TS 对 RTOSSEL 选择的时钟源进行分频,在日历模式下,时钟源 ACLK=32768,经过 RP0TS,RP1TS 分别 256 和 128 分频率后频率为 1HZ ,提供给 32 位 RTC 寄存器时钟源,通过 RTCSSEL 选择 11 或者 10。每 1S ,RTCSEC(秒)加一秒,加到 60,秒从 0 开始计数,RTCMIN 加 1,RTCHOUR,RTCMON ,RTCYEAR ,RTCDOW(星期),RTCDAY等 依次这样。并且在日历模式下,RTC 可以设置为 BCD 码显示在存储器中。另外 RTC 提供闹钟功能,我们可以设置 Alarm 寄存器的 RTCAMIN ,RTCAHOUR,RTCADAY,RTCADOW(星期).另外 RTC 模块也可以作为 32 位计数器使用,其原理方法和 WDT,TA 一致。
2,RTC 内部框图
,
3,寄存器配置
在 F5XX 单片机硬件 RTC 可以工作在计数器模式也可以工作在日历模式,通过配置寄存器 RTCCTL01 的 RTCMODE 位来实现对工作模式的选择,当选择工作在日历模式的时候,RT0PS 时钟源自动选择 ACLK,TP0PS 分频系数自动为/256,RT1PS 时钟源来自 RT0PS 输出,RT1PS 分频系数自动配置为/128,因此配置 ACLK 时钟为 32768HZ。
闹钟可以配置分钟,小时,星期,以分钟为例子时间设置完毕后,比如 08:23 分钟设置完毕后,将最高位为 AE 设置为 1,就会闹钟有效果,每个小时的第 23 分钟闹钟响。
影响整个 RTC 模块的时间的误差和时钟关系很大,本硬件 RTC 对时钟可以进行校正,如寄存器。
RTCCALS 为 1,加计算,每个 LSB 加 4PPM,如果为 0,减计算,每 LSB 减 2。
RTCCTL3 寄存器中 RTCCALF 配置选择输出 512HZ,256HZ,1HZ 其中一个频率,然后将 RTCCLK引脚设置为特殊引脚输出,用示波器观察频率与标准比看相差多少PPM,然后通过寄存器RTCCTL2进行校正,例如我选择的是 512HZ 频率输出,观察最后的示数为 512.009HZ , 计算高出 18PPM,因此在校正时候要减去一个 18PPM,因此 RTCCTL2 中位 RTCCALS 位为 0,减计算。每 LSB 减 2,因此在 RTCCAL 中赋予数值 9。
4,实验代码:
#include "msp430x54x.h"
void Init_Rtc(void);
void Init_Clk(void);
void Init_System(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关看门狗
Init_System(); // 系统初始化
__bis_SR_register(LPM3_bits + GIE); // 进入低功耗 3
}
/************************ RTC 中断*****************************/
#pragma vector=RTC_VECTOR
__interrupt void basic_timer(void)
{
switch(RTCIV)
{
case 2 : P1OUT ^= BIT0;break; //RTCRDYIFG
case 4 : break;
case 6 : P1OUT |= BIT1;break; //RTCAIFG
case 8 : break;
case 10 : break;
}
}
void Init_System(void)
{
Init_Clk(); //调用时钟函数
Init_Rtc(); //RTC 初始化
P1DIR |= BIT1 + BIT0; //P1.1 P1.0 为输出
P1OUT &= ~(BIT1 + BIT0);
}
void Init_Rtc(void)
{ // BCD 码日历格式输出
RTCCTL01 = RTCBCD + RTCHOLD + RTCMODE + RTCTEV_0 ;
RTCPS0CTL = RT0PSHOLD ; //配置两个计数器分频
RTCPS1CTL = RT1PSHOLD ;
RTCSEC = 0x54; //初始化秒
RTCMIN = 0X59 ; //初始化分钟
RTCHOUR =0X21; //初始化小时
RTCDOW = 0X02 ;
//RTCTIM1 = 0X0421;
RTCDAY = 0x24; //日期初始化
RTCMON = 0X11 ; //初始化月份
RTCYEAR = 0x2005; //初始化年份
RTCAMINHR = 0X0180; //闹钟小时和分钟设置
RTCADOWDAY = 0X1203; //闹钟星期和日期设置
RTCCTL01 &= ~RTCHOLD; //打开 RTC 模块
RTCPS0CTL &= ~RT0PSHOLD; //打开 RTCPS0CTL
RTCPS1CTL &= ~RT1PSHOLD; //打开 RTCPS1CTL
RTCCTL0 |= RTCAIE + RTCRDYIE; //打开安全访问使能 ,闹钟使能
}
void Init_Clk(void)
{
P7SEL |= 0x03; //启动 XT1
UCSCTL1 = DCORSEL_2; //DCO 范围配置
UCSCTL4 = SELM_3 + SELA_0 + SELS_4; //设置时钟源
while (SFRIFG1 & OFIFG) //等待时钟系统正常工作
{
UCSCTL7 &= ~( XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}
}
5,实验现象