13. 从0学ARM-Cortex-A9 RTC裸机程序编写 (3)

滴答计时器和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); } }

更多 ARM Linux干货,请关注 一口Linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfdgz.html