您的位置:首页 > 其它

Exynos4412裸机开发 —— RTC 实时时钟单元

2016-06-19 20:09 405 查看
RTC(Real-Time Clock) 实时时钟。RTC是集成电路,通常称为时钟芯片。在一个嵌入式系统中,通常采用RTC来提供可靠的系统时间,包括时分秒和年月日等,而且要求在系统处于关机状态下它也能正常工作(通常采用后备电池供电)。它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32.768kHz 晶体和电阻电容等。

一、RTC 控制器

实时时钟(RTC)单元可以通过备用电池供电,因此,即使系统电源关闭,它也可以继续工作。RTC可以通过STRB/LDRB 指令将8位BCD码数据送至CPU。这些BCD数据包括秒、分、时、日期、星期、月和年。RTC单元通过一个外部的32.768kHz 晶振提供时钟。RTC具有定时报警的功能。

其功能说明如下:

1 -- 时钟数据采用BCD编码。

2 -- 能够对闰年的年月日进行自动处理。

3 -- 具有告警功能,当系统处于关机状态时,能产生警告中断。

4 -- 具有独立的电源输入。

5 -- 提供毫秒级时钟中断,该中断可以用于作为嵌入式操作系统的内核时钟。

二、RTC 控制器寄存器详解

1 、Time Tick Generator

下面是示例程序:

头文件定义:

[cpp] view
plain copy







/**********************************RTC independ register********************************/

#define RTCINTP __REG(0X10070030)

#define RTCCON __REG(0X10070040)

#define TICCNT __REG(0X10070044)

#define CURTICCNT __REG(0X10070090)

typedef struct {

unsigned int ALM;

unsigned int SEC;

unsigned int MIN;

unsigned int HOUR;

unsigned int DAY;

unsigned int MON;

unsigned int YEAR;

}rtclam;

#define RTCALM (* (volatile rtclam *)0X10070050)

typedef struct {

unsigned int BCDSEC;

unsigned int BCDMIN;

unsigned int BCDHOUR;

unsigned int BCDWEEK;

unsigned int BCDDAY;

unsigned int BCDMON;

unsigned int BCDYEAR;

}rtcbcd;

#define RTC (* (volatile rtcbcd *)0X10070070)

C程序如下:

[cpp] view
plain copy







#include "exynos_4412.h"

void mydelay_ms(int time)

{

int i, j;

while(time--)

{

for (i = 0; i < 5; i++)

for (j = 0; j < 514; j++);

}

}

//*(volatile unsigned int *)(0x11000c20) = 0;

/*

* 裸机代码,不同于LINUX 应用层, 一定加循环控制

*/

void do_irq(void)

{

static int a = 1;

int irq_num;

irq_num = CPU0.ICCIAR&0x3ff; //获取中断号

switch(irq_num)

{

case 57:

printf("in the irq_handler\n");

EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1)); //清GPIO中断标志位

ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25); //清GIC中断标志位

break;

case 76:

printf("in the alarm interrupt!\n");

RTCINTP = RTCINTP | (1 << 1);

ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12); //清GIC中断标志位

break;

case 77:

printf("in the tic interrupt!\n");

RTCINTP = RTCINTP | (1 << 0);

ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13); //清GIC中断标志位

break;

}

CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num; //清cpu中断标志位

}

void rtc_init(void)

{

RTCCON = 1;

RTC.BCDYEAR = 0x16;

RTC.BCDMON = 0x2;

RTC.BCDDAY = 0x25;

RTC.BCDHOUR = 0x15;

RTC.BCDMIN = 0x24;

RTC.BCDSEC = 0x50;

RTCCON = 0;

}

void rtc_tic(void)

{

RTCCON = RTCCON & (~(0xf << 4)) | (1 << 8);

TICCNT = 32768;

ICDDCR = 1; //使能分配器

ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 13); //使能相应中断到分配器

ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xff << 8))|(0x1 << 8); //选择CPU接口

CPU0.ICCPMR = 255; //中断屏蔽优先级

CPU0.ICCICR = 1; //使能中断到CPU

}

void rtc_alarm(void)

{

RTCALM.ALM = (1 << 6)|(1 << 0);

RTCALM.SEC = 0x58;

ICDDCR = 1; //使能分配器

ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 12); //使能相应中断到分配器

ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xff << 0))|(0x1 << 0); //选择CPU接口

CPU0.ICCPMR = 255; //中断屏蔽优先级

CPU0.ICCICR = 1; //使能中断到CPU

}

int main (void)

{

rtc_init();

rtc_alarm();

rtc_tic();

while(1)

{

printf("%x %x %x %x %x BCDSEC = %x\n",RTC.BCDYEAR,

RTC.BCDMON,

RTC.BCDDAY,

RTC.BCDHOUR,

RTC.BCDMIN,RTC.BCDSEC);

mydelay_ms(1000);

}

return 0;

}

执行结果如下:

[cpp] view
plain copy







16 2 5 15 24 BCDSEC = 50

in the tic interrupt!

16 2 5 15 24 BCDSEC = 51

in the tic interrupt!

16 2 5 15 24 BCDSEC = 52

in the tic interrupt!

16 2 5 15 24 BCDSEC = 53

16 2 5 15 24 BCDSEC = 53

16 2 5 15 24 BCDSEC = 54

in the tic interrupt!

16 2 5 15 24 BCDSEC = 55

in the tic interrupt!

16 2 5 15 24 BCDSEC = 56

in the tic interrupt!

in the alarm interrupt!

16 2 5 15 24 BCDSEC = 58

in the tic interrupt!

16 2 5 15 24 BCDSEC = 59

in the tic interrupt!

16 2 5 15 25 BCDSEC = 0

in the tic interrupt!

16 2 5 15 25 BCDSEC = 1

in the tic interrupt!

16 2 5 15 25 BCDSEC = 2

in the tic interrupt!

16 2 5 15 25 BCDSEC = 3

in the tic interrupt!

16 2 5 15 25 BCDSEC = 4

in the tic interrupt!

16 2 5 15 25 BCDSEC = 5

in the tic interrupt!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: