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闹钟rtcalmrtcalm寄存器控制报警功能的启用和报警时间。请注意,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); }}
高通新手机芯片 台积抢先吃大单
韦尔股份并购北京豪威正在推进中_金额仍未公布
浙江移动完成客户中心异构数据库集群服务器迁移工作
广东省2020年将全面加速5G网络建设争取全省5G用户数达到2000万
电源设计说明:常见的开关模式拓扑
一文搞懂Cortex-A9 RTC(下)
江苏路芯半导体建设130nm-28nm制程半导体掩膜版
得益于Mac和iPad需求,苹果9月季度营收创下纪录
OPPO R11曝光OPPO R11什么时候上市? 下半年还有Find 9
夏普AQUOS S2搭载的骁龙630是什么来头?联发科P25当真没有活路了吗?
汇聚产业力量,共谋产业发展-广东省虚拟与增强现实产业协会筹备大会与亚洲VR&AR博览会高峰论坛盛大召开
LED显示屏场景应用如此的酷炫
赛灵思正式进军高端服务器芯片市场 将打造全球逻辑密度最高的7nm平台
RFID技术在卷烟厂物流管理中的应用
aigo突破推出新型的三合一混合充电器
AI带给我们的是机遇还是威胁
一文搞懂TencentOS Tiny实时操作系统
什么是智能大棚控制系统,它的应用优势是什么
吉利全新帝豪GS上市 新增远程控制系统
三星显示Q2大逆转财报扭亏为盈7000亿韩元!