嵌入式开发第49天(RTC)

来源:互联网 发布:发论文流程 知乎 编辑:程序博客网 时间:2024/05/02 17:17

RTC是什么鬼?

RTC ----  REAL Time Clock----->实时时钟(年、月、日、星期、时、分、秒)

RTC的使用:

1)设置当前的时间

2)RTC可以自动的工作(嵌入式平台中,RTC也会不准)--->获取网络时间校正          --->GPS和北斗校时                               

3)可以设置闹钟时间,产生闹钟中断。

ARM中的RTC模块


ARM的电源原理图  

既有电源供电,也有电池供电,但没电时就像电子表一样纽扣电池供电


S5PV210RTC的特点

1、Supports BCD Number, that is Second, Minute, Hour, Day of the week, Day, Month, and Year. 

BCD码(压缩型的BCD码)---> 32秒 --->second寄存器的内容 0x32

压缩型的BCD码是8位的,高4位是十位,第4位是各位。

 

2、Supports Leap Year Generator 支持闰年

 

3、Supports Alarm Function, that is ,Alarm-Interrupt or Wake-up from power down modes (idle, deep idle, stop,deep stop, and sleep) 支持闹钟功能,闹钟中断

 

4、Supports Tick Counter Function, that is Tick-Interrupt or Wake-up from power down modes (idle, deep idle,stop, deep stop, and sleep) 支持滴答功能,也就是每秒产生一次中断

 

5、Supports Independent Power Pin (RTCVDD) 支持独立电源,就是纽扣电池供电

 

6、Supports millisecond tick time interrupt for RTOS kernel time tick . 

RTC的TICK时钟,可以提供给实时操作系统的内核,作为实时操作系统内核时钟。



RTC的寄存器

配置寄存器    


闹钟的设置寄存器   


RTC时间设置和读取的寄存器


1、中断判断寄存器---INTP



1、RTC的控制寄存器----RTCCON



1、滴答时钟计数器寄存器----TICCNT


 

例:设置tick timer的周期是500ms,则频率2Hz

1)设置tick timerclock频率:

RTCCON &= ~(0xf<<4);  //tick timer的基准频率32768Hz

2)设置tick timer的计数值

TICNT = 32768/2;  //tick timer的工作频率2Hz

 

基准频率/计数值= 工作频率

基准频率/工作频率=计数值


4、RTC的闹钟寄存器---RTCALM


设置闹钟的比较时间。

四、RTC的程序


#include "main.h"#include "stdio.h"#include "int.h"extern unsigned int m;#define RTC_BASE (0xE2800000)#definerINTP       (*((volatile unsigned long *)(RTC_BASE + 0x30)))#definerRTCCON     (*((volatile unsigned long *)(RTC_BASE + 0x40)))#definerTICCNT     (*((volatile unsigned long *)(RTC_BASE + 0x44)))#definerRTCALM     (*((volatile unsigned long *)(RTC_BASE + 0x50)))#definerALMSEC     (*((volatile unsigned long *)(RTC_BASE + 0x54)))#definerALMMIN     (*((volatile unsigned long *)(RTC_BASE + 0x58)))#definerALMHOUR   (*((volatile unsigned long *)(RTC_BASE + 0x5c)))#definerALMDATE     (*((volatile unsigned long *)(RTC_BASE + 0x60)))#definerALMMON     (*((volatile unsigned long *)(RTC_BASE + 0x64)))#definerALMYEAR   (*((volatile unsigned long *)(RTC_BASE + 0x68)))#definerRTCRST      (*((volatile unsigned long *)(RTC_BASE + 0x6c)))#definerBCDSEC     (*((volatile unsigned long *)(RTC_BASE + 0x70)))#definerBCDMIN    (*((volatile unsigned long *)(RTC_BASE + 0x74)))#definerBCDHOUR     (*((volatile unsigned long *)(RTC_BASE + 0x78)))#definerBCDDATE     (*((volatile unsigned long *)(RTC_BASE + 0x7c)))#definerBCDDAY      (*((volatile unsigned long *)(RTC_BASE + 0x80)))#definerBCDMON      (*((volatile unsigned long *)(RTC_BASE + 0x84)))#definerBCDYEAR     (*((volatile unsigned long *)(RTC_BASE + 0x88)))#definerCURTICCNT   (*((volatile unsigned long *)(RTC_BASE + 0x90)))#definerRTCLVD     (*((volatile unsigned long *)(RTC_BASE + 0x94)))unsigned int alarm_flag = 1; //1---alarm没有工作;           // 函数功能:把十进制num转成bcd码,譬如把56转成0x56,num-->decstatic unsigned int num_2_bcd(unsigned int num){// 第一步,把56拆分成5和6 // 第二步,把5和6组合成0x56return (((num / 10)<<4) | (num % 10));}#if 1// 函数功能:把bcd码bcd转成十进制,譬如把0x56转成56static unsigned int bcd_2_num(unsigned int bcd){// 第一步,把0x56拆分成5和6 // 第二步,把5和6组合成56return (((bcd & 0xf0)>>4)*10 + (bcd & (0x0f)));}#endifvoid rtc_alarm_init(void){rALMMIN = num_2_bcd(1);  //闹钟的分是1rRTCALM |= 1<<1;//分钟匹配成功,产生闹钟中断rRTCALM |= 1<<6; //打开闹钟中断功能}void isr_rtc_alarm(void) //闹钟的ISR<--当RTC的分和ALARM分一致{static int i = -1; printf("rtc alarm, i = %d...\r\n", i++); //debugGPD0DAT |= (1<<0); //beep 响alarm_flag = 0;rINTP |= (1<<1); //清中断intc_clearvectaddr();}void rtc_tick_init(void){rRTCCON &= ~(0xf<<4); //clock = 32768rTICCNT = 26214;//32768/(1.25);printf("---rtc write time test  2016-9-13 2 15:59:03 ---\n\r");struct rtc_time tWrite = {.year = 2016,.month = 9,.date = 13,.hour = 15,.minute = 59,.second = 3,.day = 2,};rtc_set_time(&tWrite);rRTCCON |= (1<<8); //enable tick timer}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 isr_rtc_tick(void) //Tick timer 的ISR (800ms){if(alarm_flag == 0)m++;  //每800ms 加一次1if(m == 12) //10s{GPD0DAT &= ~(1<<0);  //beep不响m = 0;alarm_flag = 1;}struct rtc_time tRead;rtc_get_time(&tRead);printf("The time read is: %d:%d:%d:%d:%d:%d:%d.\r\n", tRead.year, tRead.month, tRead.date, tRead.hour, tRead.minute, tRead.second, tRead.day);rINTP |= (1<<0); //清中断intc_clearvectaddr();}



0 0
原创粉丝点击