原创文章,如有转载,请注明出处:http://blog.csdn.net/desert2009sz/article/details/6878106
3. 中断服务程序
中断服务程序,需要注意的是:进中断时现场的保护,中断结束前的现场恢复。需要保护的主要是A和X寄存器。有一点我比较迷惑,为什么该部分的程序要放在SRAM_PG0区域,这段地址应该是RAM区,这样做有什么意义?望知道的朋友告之,谢谢!邮箱:desert.lau#gmail.com,将#换成@即可。
SRAM_PG0:.section
vIrq:
pha ;保护现场
phx
lda IntFlag
sta IntFlag ;清中断标志,写1清除
.include .\IR\nec.asm ;nec解码
lIrqIrExit:
lda rVfdPollingTm ;rVfdPollingTm时间变量处理
beq lIrqExit
dec rVfdPollingTm
lIrqExit:
plx ;恢复现场
pla
vNmi:
rti
四、nec解码程序
在看这部分代码前,首先需要对NEC协仪熟悉,可以去这个网站看看:http://www.sbprojects.com/knowledge/ir/nec.php
简单点说:IR电平没有信号时为常高,有信号进来时,会先低9ms,然后高4.5或2.5ms,然后就是数据,数据0是先低560us,再高560us,数据1是先低560us,再高1680us。
注:以下流程图引导码中的72ms,40ms,20ms是错误的,正确的是应再除以10,图片因为是用在线流程图工具制作,改起来麻烦,因此就在此说明一下不再更新。
为方便理解,将流程图拆成了几个小块分块说明:
1. 主程序
任务:
① 监控IR脚的信号变化
② 如果IR脚一直不变化,且时长超过108ms,则将“收数据的步骤”设为HEAD,并将IR脚上次信号变化到这次信号变化的时间(以后简称“保持时间”)清零。
③ 如果IR脚发生了变化,则根据“收数据的步骤”分开处理,主要包括:HEAD为9ms低电平,OFF为4.5ms或2.5ms高电平,ADDR_DAT就是收数据了,共32位。
2. HEAD部分
任务:
监控IR脚状态,只有在HEAD步骤下(IR脚由高变低),开始累计“保持时间”,在监控到IR脚变化(由低变高)时,比较“保持时间”是否大于7.2ms,如果为真,则到OFF步骤,否则重置。
![](http://hi.csdn.net/attachment/201110/17/0_1318833818T4Uz.gif)
3. OFF部分
任务:
① 在IR脚由高变低时,根据“保持时间”分别处理
② 大于4ms,则是收到的是全码,即包括引导码,地址码,数据码,所以需要将“收步骤”设置为ADDR_DATA,并将存数据的SRAM清空
③ 大于2ms,则是收到的是重复码,重复码的正确条件是:大于2ms,上次按下后没有释放过(rReqValid为1),重复间隔时间为0(vIrReqRepeateRate为0)
4. ADDR_DATA部分
任务:
① 0和1的数据都是先低后高,低都是560us,高如果是560us,是为0;1680us,为1。 ② IR脚由低变高,如果大于560us,则开始累计高电平的时间,否则收数据出错,重置
③ IR脚由高变低,根据时间长度设置SRAM对应位为0或1。
④ 设置READY位,表示数据正常接收完
⑤ 设置rReqValid,用于重复码判断;并重置RepeatRate时间
注:以下流程图中的“置C标志”后就跳到“循环左移rIrReceiver数组”
![](http://hi.csdn.net/attachment/201110/17/0_1318833876Q66g.gif)