2. 操作滴答定時(shí)器
TICNT
TICNT
RTC計(jì)時(shí)器是一個(gè)遞增計(jì)數(shù)器,并引發(fā)計(jì)時(shí)中斷。TICNT寄存器包含32位目標(biāo)計(jì)數(shù)值,并且CURTICCNT寄存器包含32位當(dāng)前計(jì)時(shí)計(jì)數(shù)。如果當(dāng)前滴答數(shù)達(dá)到TICNT中指定的目標(biāo)值時(shí),計(jì)時(shí)中斷發(fā)生。
一秒鐘計(jì)數(shù)的次數(shù),由RTCCON[7:4]即TICCKSEL位決定:
TICCKSEL
因?yàn)槲覀兊木д耦l率也是32768,為方便計(jì)數(shù),所以我們?cè)O(shè)置RTCCON[7:4]為0,開啟滴答計(jì)時(shí)器需要設(shè)置RTCCON[8]位1:
TICEN
代碼如下:
RTCCON = RTCCON & (~(0xf << 4)) | (1 << 8);
TICCNT = 32768;
3. 操作ALARM鬧鐘
RTCALM
RTCALM寄存器控制報(bào)警功能的啟用和報(bào)警時(shí)間。請(qǐng)注意,RTCALM寄存器在斷電模式下將同時(shí)生成ALARM_INT和ALARM_WK信號(hào),但在正常模式下僅生成ALARM_INT信號(hào)。設(shè)置ALMEN[6]為1以產(chǎn)生ALARM_INT和ALARM_WK信號(hào)。
「舉例:」
比如我們想每個(gè)小時(shí)的25分58秒產(chǎn)生一個(gè)中斷信號(hào),那我們需要設(shè)置RTCALM[1]、RTCALM[0]為1,同時(shí)設(shè)置RTCALM[6]為1以開啟alarm功能,然后將BCD格式的時(shí)間設(shè)置到寄存器ALMSEC、ALMMIN。
代碼如下:
RTCALM.ALM = (1 << 6)|(1 << 0)|(1 << 1);//使能bite:MINEN、SECEN
RTCALM.SEC = 0x58;
RTCALM.MIN = 0x25; //每小時(shí)25:58產(chǎn)生一次中斷
alarm功能設(shè)置鬧鐘時(shí)間寄存器如下:
寄存器操作,采用BCD格式。
五、完整代碼實(shí)現(xiàn)
滴答計(jì)時(shí)器和alarm鬧鐘會(huì)產(chǎn)生內(nèi)部中斷信號(hào),所以我們必須給這兩個(gè)中斷信號(hào)進(jìn)行中斷相關(guān)的初始化,并在中斷處理函數(shù)中增加相應(yīng)的處理代碼。
中斷號(hào)
參考datasheet 9.2.2 GIC Interrupt Table
rtc中斷號(hào)
關(guān)于中斷的初始化的寄存器配置,我們可以參考《11. 從0開始學(xué)ARM-基于Exynos4412中斷詳解、key程序編寫》
區(qū)別是,key連接在了第一級(jí)中斷控制器,而rtc的這兩個(gè)中斷則沒有。清中斷需要設(shè)置的寄存器如下:
「滴答計(jì)時(shí)器清中斷:」
RTCINTP = RTCINTP | (1 << 0);
//清GIC中斷標(biāo)志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13);
//清cpu中斷標(biāo)志位
CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num;
「alarm計(jì)時(shí)器清中斷:」
RTCINTP = RTCINTP | (1 << 1);
//清GIC中斷標(biāo)志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12);
//清cpu中斷標(biāo)志位
CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num;
「滴答計(jì)時(shí)器中斷初始化:」
void rtc_tic(void)
{
RTCCON = RTCCON & (~(0xf << 4)) | (1 << 8);
TICCNT = 32768;
ICDDCR = 1; //使能分配器
ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 13); //使能相應(yīng)中斷到分配器
ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xff << 8))|(0x1 << 8); //選擇CPU接口
CPU0.ICCPMR = 255; //中斷屏蔽優(yōu)先級(jí)
CPU0.ICCICR = 1; //使能中斷到CPU
}
「alarm初始化」
void rtc_alarm(void)
{
RTCALM.ALM = (1 << 6)|(1 << 0)|(1 << 1);
RTCALM.SEC = 0x58;
RTCALM.MIN = 0x25; //每小時(shí)25:58產(chǎn)生一次中斷
ICDDCR = 1; //使能分配器
//使能相應(yīng)中斷到分配器
ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 12);
//選擇CPU接口
ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xff << 0))|(0x1 << 0);
CPU0.ICCPMR = 255; //中斷屏蔽優(yōu)先級(jí)
CPU0.ICCICR = 1; //使能中斷到CPU
}
「中斷處理函數(shù)」
void do_irq(void)
{
static int a = 1;
int irq_num;
irq_num = CPU0.ICCIAR&0x3ff; //獲取中斷號(hào)
switch(irq_num)
{
case 57: //按鍵key
printf("in the irq_handler\\n");
//清GPIO中斷標(biāo)志位
EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1));
//清GIC中斷標(biāo)志位
ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25);
break;
case 76:
printf("in the alarm interrupt!\\n");
RTCINTP = RTCINTP | (1 << 1);
//清GIC中斷標(biāo)志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12);
break;
case 77:
printf("in the tic interrupt!\\n");
RTCINTP = RTCINTP | (1 << 0);
//清GIC中斷標(biāo)志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13);
break;
}
//清cpu中斷標(biāo)志位
CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num;
}
「其他代碼:」
void rtc_init(void)
{
RTCCON = 1;//使能RTC控制寫功能
RTC.BCDYEAR = 0x20;// 2020年11月11日, 15:24:50.以BCD碼格式寫入
RTC.BCDMON = 0x11;
RTC.BCDDAY = 0x11;
RTC.BCDHOUR = 0x15;
RTC.BCDMIN = 0x24;
RTC.BCDSEC = 0x50;
RTCCON = 0;//關(guān)閉RTC控制寫功能
}
int main (void)
{ rtc_init();
rtc_alarm();
rtc_tic();
//每隔一秒打印以下當(dāng)前時(shí)間
while(1)
{
printf("%x-%x-%x %x:%x:%x\\n",RTC.BCDYEAR,
RTC.BCDMON,
RTC.BCDDAY,
RTC.BCDHOUR,
RTC.BCDMIN,RTC.BCDSEC);
delay_ms(1000);
}
}
-
集成電路
+關(guān)注
關(guān)注
5391文章
11599瀏覽量
362649 -
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3614瀏覽量
129624 -
時(shí)鐘芯片
+關(guān)注
關(guān)注
2文章
252瀏覽量
39923 -
RTC
+關(guān)注
關(guān)注
2文章
542瀏覽量
66826
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論