单片机汇编语言
程序执行到SJMP $ 是不是等到定时器0溢出之后跳转到ORG 000BH 执行中断程序
还有就是 CJNE A ,#20,LOOP
是当A≠20的时候跳转到loop
执行完loop这个子程序之后 就跳到SJMP $ ,这个程序不就相当于结束了
但是一开始A的值就为1
A≠20 ,就要跳到loop 不能达到满足计数20次的要求吧
还是我哪个地方理解错了呀
COUNTER EQU 30H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP ITT0
ORG 0100H
MAIN: MOV TMOD, #01H
MOV TH0, #3CH
MOV TL0, #0B0H ;定时 50ms
MOV COUNTER, #00H
SETB EA
SETB ET0
SETB TR0
SJMP $
ITT0: PUSH PSW
PUSH ACC
MOV TH0, #3CH
MOV TL0, #0B0H
INC COUNTER
MOV A, COUNTER
CJNE A, #20, LOOP
CPL P1.0
MOV COUNTER, #00H
LOOP: POP ACC
POP PSW
RETI
END
对于第一个问题,确实是这样的。SJMP命令可以让程序跳转到当前语句位置,并继续执行下去。此处的SJMP $指的是程序跳转回当前地址,等待TIMER0中断事件的发生。
对于第二个问题,CJNE A,#20,LOOP指的是如果A不等于20,则跳转到LOOP标签处执行LOOP子程序。在LOOP子程序中,可能会有一些处理递增计数器COUNTER和更新P1.0输出端口状态的代码。函数执行完后,会回到CJNE语句进行条件测试,只要A仍然不等于20,就会跳转到LOOP继续执行。直到A等于20时,CJNE A,#20,LOOP指令才会跳转到当前位置下一行的代码执行,也就是CPL P1.0,从而实现按照计数器计数到一定值后改变P1.0电平的操作。随后通过MOV COUNTER,#00H将计数器COUNTER清零,并重新回到TIMER 0中断处理程序等待下一次TIMER0溢出中断事件的发生,重新开始计数。
不知道你这个问题是否已经解决, 如果还没有解决的话:在单片机汇编语言中,当执行到SJMP $时,不是等待定时器0溢出后再跳转到ORG 000BH执行中断程序,而是直接跳转到ORG 000BH执行中断程序。
关于CJNE A,#20,LOOP的问题,如果A一开始就为1,需要将计数器初始化为0,即将COUNTER的初始值设为0。修改后的代码如下:
COUNTER EQU 30H ORG 0000H LJMP MAIN ORG 000BH LJMP ITT0 ORG 0100H SETB EA SETB ET0 SETB TR0 MOV COUNTER, #0 ; 初始化计数器为0 INC COUNTER CJNE COUNTER, #20, LOOP ; 判断计数器是否达到20 CPL P1.0 RET LOOP: LJMP ITT0 END
以上汇编程序存在两个问题:
COUNTER EQU 30H COUNT EQU 31H ; 定义一个RAM变量用来保存计数器的值 ORG 0000H LJMP MAIN ORG 000BH LJMP ITT0 ORG 0100H MOV COUNT, #0 ; 初始化计数器为0 SETB EA SETB ET0 SETB TR0 INC COUNT CJNE COUNT, #20, LOOP ; 判断计数器是否达到20 CPL P1.0 MOV COUNT, #0 ; 计数器清零 RET LOOP: LJMP ITT0 END
在中断程序ITT0中添加清除定时器0中断标志的代码:
ITT0: CLR TF0 ; 清除定时器0中断标志 ... ; 其他中断程序的代码 RET