年前终于是稍微闲一点儿了,正愁着找点儿什么事情做,突然想起来这里还有个坑没有填,所以抄起板子测试了一下。
测试用单片机STC8H8K64U,未使能芯片的仿真功能,测试使用的中断 内置RTC的36号中断,使用内部32KRC时钟给RTC提供时钟(别问为啥不用外置的,懒的往上面焊了)。开启秒中断,其实只要证明中断可以正常触发,正常跳转到中断服务函数就可以了。下面是RTC初始化函数。
void MCURTC_Init(void (*SecIrq)(void))
{
EAXSFR();
MCURTCSecIrqProcessFunction = SecIrq;
// // 选择内部低速 IRC
IRC32KCR = 0x80; // 启动内部低速振荡器
while (!(IRC32KCR & 0x01))
; // 等待时钟稳定
RTCCFG |= 0x02; // 选择内部低速 IRC作为 RTC时钟源
// 选择外部 32K
// X32KCR = ENX32K | GAIN32K; // 启动外部 32K晶振
// while (!(X32KCR & X32KST))
// ; // 等待时钟稳定
// RTCCFG &= ~RTCCKS;
INIYEAR = 00; // Y:2021
INIMONTH = 1; // M:12
INIDAY = 1; // D:31
INIHOUR = 0; // H:23
INIMIN = 0; // M:59
INISEC = 0; // S:50
INISSEC = 0; // S/128:0
RTCCFG |= SETRTC; // 触发 RTC寄存器初始化
RTCCR |= RUNRTC; // 需要开启RTC RTC才会进行配置
/**
* @brief 等待初始化完成,设置RTC需要一个时钟周期。32K 时钟源下,一个时钟周期为 1/32768 秒 大约 30us
* 在次期间如果进入睡眠模式,则RTC会由于没有设置完成,停止计数。如果此时设置的是使用RTC中断唤醒,则会
* 导致系统无法唤醒。
*/
while (RTCCFG & SETRTC)
;
RTCCR &= ~RUNRTC; // 配置完成之后再关闭RTC
RTCIF = 0; // 清中断标志
RTCIEN = ESECI; // 使能秒中断
}
中断服务函数中判断秒中断标志位,然后清零,再执行一个回调函数。
void ISR_Number28(void) interrupt 15
{
#if defined(__MCURTC_H)
if (RTCIF & SECIF)
{
RTCIF &= ~SECIF; // 清中断标志
if (MCURTCSecIrqProcessFunction != NULL)
{
MCURTCSecIrqProcessFunction();
}
}
#endif
}
这个回调函数要执行一个,将一个全局变量置1的简单操作
uint8_t RTCFlag = 0;
void RTC_IRQ_Test(void)
{
RTCFlag = 1;
}
主函数中这样写
MCURTC_Init(RTC_IRQ_Test);
MCURTC_Start();
然后再while(1)循环中加入对标志位轮询检查再执行对应操作,这里当检查到标志位被置1后,清除标志位,并用printf语句打印一个信息到串口.
void RTC_Process(void)
{
if (RTCFlag != 0)
{
RTCFlag = 0;
printf("RTC IRQ Test!\r\n");
}
}
啊 关键的一个汇编文件展示了,,需要再工程中加入一个写有如下内容的.asm文件。AT 后面写入36号中断的向量地址 0123H 在 JMP 后面写入借用的中断地址号 这里测试了一个15号中断 他的中断向量地址为 007BH
CSEG AT 0123H
JMP 007BH
END
测试结果:

嘛嘛,,看起来似乎是正常输出了。
关于问题1: 14 15号中断可以占用么,就以上的条件下,似乎可以正常输出结果。。但是既然手册上标注了内部系统使用,我觉得还是放过这两个中断把。
关于问题2:在已知使用的单片机中没有的外设中断,可以随意使用,,比如果STC8H这个没有PCA,完全就可以吧PCA作为RTC中断来看,同样的这几个波形发生器(可能是那些有独立波特率发生器的片子使用的中断)也是一样的套路。
关于坛友的一个回复

成立!
应该可以完结撒花了吧。。