汇编语言利用定时器完成跑马灯

利用定时器的方式补全下面的代码

........

ST: MOV SP,#60H
MOV R4,#20 ;20次50ms中断产生1s定时

........

MOV    DPTR,#TAB    ;查表地址
MOV    R1,#0
AJMP    $        ;等待中断

T0_INT:
........

DJNZ    R4,EXIT        ;20次没到先退出
MOV    R4,#20        ;保证连续20次50ms中断后执行灯的流水顺序变化
MOV    A,R1        ;第几个流水灯显示方式
MOVC    A,@A+DPTR    ;查表查出流水灯的显示字
MOV    P1,A        ;P1口接流水灯
INC    R1
CJNE    R1,#8,EXIT    ;八种显示方式循环显示完后重新开始
MOV    R1,#0

EXIT: RETI
TAB: DB 0FAH,......
END

ST: MOV SP,#60H
MOV R4,#20 ;20次50ms中断产生1s定时

MOV TMOD,#01H ;设置定时器0为模式1
MOV TH0,#3CH ;50ms中断
MOV TL0,#0 ;初值为0
SETB TR0 ;启动定时器0

MOV DPTR,#TAB ;查表地址
MOV R1,#0
AJMP $ ;等待中断

T0_INT:
CLR TF0 ;清除定时器0中断标志
DJNZ R4,EXIT ;20次没到先退出
MOV R4,#20 ;保证连续20次50ms中断后执行灯的流水顺序变化
MOV A,R1 ;第几个流水灯显示方式
MOVC A,@A+DPTR ;查表查出流水灯的显示字
MOV P1,A ;P1口接流水灯
INC R1
CJNE R1,#8,EXIT ;八种显示方式循环显示完后重新开始
MOV R1,#0
EXIT: RETI

TAB: DB 0FAH,......
END

解释:

首先设置栈指针 SP 和 R4 寄存器,SP 的值为 60H,R4 的值为 20。

然后设置定时器0为模式1,即16位定时器,TH0和TL0分别表示定时器的高8位和低8位,定时器初值为 3CH (60),每次中断后再次设置初值为 3CH,以产生50ms的中断,同时启动定时器0。

接着将查表地址 TAB 赋给 DPTR 寄存器,并将 R1 寄存器设置为0。

使用 AJMP 指令等待定时器0中断的发生。

当定时器0中断发生时,首先使用 CLR 指令清除定时器0的中断标志 TF0,然后使用 DJNZ 指令判断是否达到 20 次 50ms 中断,如果没有则跳转到 EXIT 标号处;否则,设置 R4 的值为 20,并执行流水灯的显示操作。

在流水灯显示操作中,首先使用 MOV 指令将 R1 的值赋给 A 寄存器,然后使用 MOVC 指令根据查表地址 DPTR 和 A 的值查出对应的流水灯显示字,并将其赋给 P1 口,最后使用 INC 指令将 R1 寄存器加1,以显示下一个流水灯。

在循环显示完八种流水灯效果后,使用 CJNE 指令判断 R1 的值是否等于8,如果不等于则跳转到 EXIT 标号处,重新开始循环显示;否则,将 R1 的值设置为 0,并执行 RETI 指令返回中断服务程序结束中断处理。

最后,使用 DB 指令定义了一个名为 TAB 的表格,其中存储了不同流水灯效果的显示字节码,可以在 MOVC 指令中使用该表格来查找对应的字节码。