以下过程是RTC的更新周期结束的中断处理。
(1)保护现场。。。。没啥说的,push就完事了
(2)读取RTC寄存器A(各个位如下表),检查UIP位的状态来决定是等待更新周期结束还是继续向下执行。UIP位为0时,表明此时访问CMOS RAM中的日期和时间是安全的。注意,这里依然阻断NMI。
具体的代码如下:
.w0:
mov al,0x0a ;阻断NMI。当然,通常是不必要的
or al,0x80
out 0x70,al
in al,0x71 ;读寄存器A
test al,0x80 ;测试第7位UIP
jnz .w0
test指令跟and指令一样,都是将两个操作数相与,然后根据结果设置相应的标志位,但是test指令执行后,运算结果被丢弃,不会改变两个操作数的内容。
(3)访问CMOS RAM的第0,2,4号单元,读取时分秒,按顺序压栈,等待后续处理
比如:读取分:
mov al,2
or al,0x80
out 0x70,al
in al,0x71 ;读RTC当前时间(分)
push ax
(4)读取结束后,还需要读一下RTC的寄存器C,使得所有的中断表示复位,这等于告诉RTC,中断已经得到了处理。
注意:
一旦相应了中断,8259中断控制器无法知道该中断什么时候才能处理结束,同时,如果不清除相应的位,那么下一次同一个引脚出现的中断将得不到处理,所以,需要程序在中断处理过程的结尾,显示的队8259进行清除该标志,方法是发送中断结束命令,它的代码是0X20
mov al,0x20 ;中断结束命令EOI
out 0xa0,al ;向从片发送
out 0x20,al
注意:如果是中断是8259主片处理的,那么只需要给主片发送即可,如果是从片处理的,那么既要发给主片,也要发送给从片