S5PV210的timer–3 RTC:
1.从原理图看,RTC接的晶振是32.768KHz,一般情况下为了在系统关机时时间仍然在走,还会给RTC提供一个电池供电。
2.RTC可以定闹钟发生器,到时间点会发生RTC alarm interrupt,类似于我们定闹钟
3.比较重要的4类寄存器:
(1)INTP 中断挂起寄存器
(2)RTCCON RTC控制寄存器
(3)RTCALM ALMxxx 闹钟功能有关的寄存器
(4)BCDxxx 时间寄存器
4.RTC中所有的时间都是BCD编码的,什么是BCD编码?
例如10进制的56,编码成BCD码之后就是 56(5和6),在计算机之中就用0x56来表达。其实类似于这种转换:56(10) -> 0x56(16)
下面就是转换函数:
// 函数功能:把十进制num转成bcd码,譬如把56转成0x56
//56— (56 / 10) << 4 | 56 % 10 = 5 << 4 | 6 = 86(10) = 0x56(16)
static unsigned int num_2_bcd(unsigned int num)
{
// 第一步,把56拆分成5和6
// 第二步,把5和6组合成0x56
return (((num / 10)<<4) | (num % 10));
}
// 函数功能:把bcd码bcd转成十进制,譬如把0x56转成56
static unsigned int bcd_2_num(unsigned int bcd)
{
// 第一步,把0x56拆分成5和6
// 第二步,把5和6组合成56
return (((bcd & 0xf0)>>4)*10 + (bcd & (0x0f)));
}
5.RTC中所有的时间都是BCD编码的,所以我们写进去的要是BCD码,读出来的也是BCD码。RTC中所有的时间(年月日时分秒星期,包括闹钟)都是用BCD码编码的。
6.设置RTC时间和获取RTC时间:关于时间的寄存器:
rBCDYEAR 、rBCDMON 、rBCDDATE 、rBCDHOUR 、rBCDMIN 、rBCDSEC 、rBCDDAY 。
注意rBCDYEAR 是相对于2000的差值。
rRTCCON 这个是控制寄存器,0 bit是读写开关的控制位。
void rtc_set_time(const struct rtc_time *p)
{
// 第一步,打开RTC读写开关
rRTCCON |= (1<<0);
// 第二步,写RTC时间寄存器
rBCDYEAR = num_2_bcd(p->year - 2000);
rBCDMON = num_2_bcd(p->month);
rBCDDATE = num_2_bcd(p->date);
rBCDHOUR = num_2_bcd(p->hour);
rBCDMIN = num_2_bcd(p->minute);
rBCDSEC = num_2_bcd(p->second);
rBCDDAY = num_2_bcd(p->day); 这个应该是星期几
// 最后一步,关上RTC的读写开关
rRTCCON &= ~(1<<0);
}
void rtc_get_time(struct rtc_time *p)
{
// 第一步,打开RTC读写开关
rRTCCON |= (1<<0);
// 第二步,读RTC时间寄存器
p->year = bcd_2_num(rBCDYEAR) + 2000;
p->month = bcd_2_num(rBCDMON);
p->date = bcd_2_num(rBCDDATE);
p->hour = bcd_2_num(rBCDHOUR);
p->minute = bcd_2_num(rBCDMIN);
p->second = bcd_2_num(rBCDSEC);
p->day = bcd_2_num(rBCDDAY);
// 最后一步,关上RTC的读写开关
rRTCCON &= ~(1<<0);
}
下面是闹钟功能:
void rtc_set_alarm(void)
{
rALMSEC = num_2_bcd(23); //设置23s的定时时间
rRTCALM |= 1<<0; Enable Second alarm
rRTCALM |= 1<<6; Enable Alarm global
}
记得要在中断处理函数isr中清中断:rINTP |= (1<<1); //清中断