2. 操作滴答定時器
TICNT
TICNT
RTC計時器是一個遞增計數器,并引發計時中斷。TICNT寄存器包含32位目標計數值,并且CURTICCNT寄存器包含32位當前計時計數。如果當前滴答數達到TICNT中指定的目標值時,計時中斷發生。
一秒鐘計數的次數,由RTCCON[7:4]即TICCKSEL位決定:
TICCKSEL
因為我們的晶振頻率也是32768,為方便計數,所以我們設置RTCCON[7:4]為0,開啟滴答計時器需要設置RTCCON[8]位1:
TICEN
代碼如下:
RTCCON = RTCCON & (~(0xf << 4)) | (1 << 8);
TICCNT = 32768;
3. 操作ALARM鬧鐘
RTCALM
RTCALM寄存器控制報警功能的啟用和報警時間。請注意,RTCALM寄存器在斷電模式下將同時生成ALARM_INT和ALARM_WK信號,但在正常模式下僅生成ALARM_INT信號。設置ALMEN[6]為1以產生ALARM_INT和ALARM_WK信號。
「舉例:」
比如我們想每個小時的25分58秒產生一個中斷信號,那我們需要設置RTCALM[1]、RTCALM[0]為1,同時設置RTCALM[6]為1以開啟alarm功能,然后將BCD格式的時間設置到寄存器ALMSEC、ALMMIN。
代碼如下:
RTCALM.ALM = (1 << 6)|(1 << 0)|(1 << 1);//使能bite:MINEN、SECEN
RTCALM.SEC = 0x58;
RTCALM.MIN = 0x25; //每小時25:58產生一次中斷
alarm功能設置鬧鐘時間寄存器如下:
寄存器操作,采用BCD格式。
五、完整代碼實現
滴答計時器和alarm鬧鐘會產生內部中斷信號,所以我們必須給這兩個中斷信號進行中斷相關的初始化,并在中斷處理函數中增加相應的處理代碼。
中斷號
參考datasheet 9.2.2 GIC Interrupt Table
rtc中斷號
關于中斷的初始化的寄存器配置,我們可以參考《11. 從0開始學ARM-基于Exynos4412中斷詳解、key程序編寫》
區別是,key連接在了第一級中斷控制器,而rtc的這兩個中斷則沒有。清中斷需要設置的寄存器如下:
「滴答計時器清中斷:」
RTCINTP = RTCINTP | (1 << 0);
//清GIC中斷標志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13);
//清cpu中斷標志位
CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num;
「alarm計時器清中斷:」
RTCINTP = RTCINTP | (1 << 1);
//清GIC中斷標志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12);
//清cpu中斷標志位
CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num;
「滴答計時器中斷初始化:」
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
}
「alarm初始化」
void rtc_alarm(void)
{
RTCALM.ALM = (1 << 6)|(1 << 0)|(1 << 1);
RTCALM.SEC = 0x58;
RTCALM.MIN = 0x25; //每小時25:58產生一次中斷
ICDDCR = 1; //使能分配器
//使能相應中斷到分配器
ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 12);
//選擇CPU接口
ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xff << 0))|(0x1 << 0);
CPU0.ICCPMR = 255; //中斷屏蔽優先級
CPU0.ICCICR = 1; //使能中斷到CPU
}
「中斷處理函數」
void do_irq(void)
{
static int a = 1;
int irq_num;
irq_num = CPU0.ICCIAR&0x3ff; //獲取中斷號
switch(irq_num)
{
case 57: //按鍵key
printf("in the irq_handler\\n");
//清GPIO中斷標志位
EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1));
//清GIC中斷標志位
ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25);
break;
case 76:
printf("in the alarm interrupt!\\n");
RTCINTP = RTCINTP | (1 << 1);
//清GIC中斷標志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12);
break;
case 77:
printf("in the tic interrupt!\\n");
RTCINTP = RTCINTP | (1 << 0);
//清GIC中斷標志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 13);
break;
}
//清cpu中斷標志位
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;//關閉RTC控制寫功能
}
int main (void)
{ rtc_init();
rtc_alarm();
rtc_tic();
//每隔一秒打印以下當前時間
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);
}
}
-
集成電路
+關注
關注
5387文章
11534瀏覽量
361652 -
嵌入式系統
+關注
關注
41文章
3587瀏覽量
129438 -
時鐘芯片
+關注
關注
2文章
249瀏覽量
39879 -
RTC
+關注
關注
2文章
538瀏覽量
66471
發布評論請先 登錄
相關推薦
評論