以下再贴上上述代码的Keil反汇编代码,为便于大家阅读,我整理了下。大家可以发现变量MsuFqy其实是0x08(MSB)和0x09(LSB)组成的,当函数MsuReadFqy正在对变量MsuFqy进行读操作时,即语句: MOV R6,0x08 ;MSB MOV R7,0x09 ;LSB 若此时,只执行了“MOV R6,0x08”,“MOV R7,0x09”还没有执行,此时刚好产生计数器0中断,对变量MsuFqy进行写操作,改写单元0x08和0x09,写完毕后返回函数MsuReadFqy继续读操作即执行“MOV R7,0x09”,此时0x09单元的值已经被改写了,所以函数MsuReadFqy读取量MsuFqy的值其实是错误的,所以说我认为在读写变量时都有必要开关中断。不知各位大牛如何认为?
ORG 0000H LJMP start
ORG 000BH LJMP MsuTimer0Isr
;----------------------------------------------------- ; MsuReadFqy() ;----------------------------------------------------- MsuReadFqy: CLR EA
MOV R6,0x08 ;MSB MOV R7,0x09 ;LSB
SETB EA
RET
;----------------------------------------------------- ; MsuTimer0Isr() ;----------------------------------------------------- MsuTimer0Isr:
PUSH ACC ; 保护现场 PUSH PSW
MOV PSW,#0x00
;------------------------------------------- PUSH 0x04 ; 保护寄存器 PUSH 0x05 PUSH 0x06 PUSH 0x07 CLR EA CLR TR0
;------------------------------------------- CLR TR1
MOV R7,TH1 MOV A,R7 MOV R6,A MOV R5,TL1 MOV R4,#0x00
CLR A ADD A,R5 MOV 0x09,A
MOV A,R4 ADDC A,R6 MOV 0x08,A
SETB TR1 ;-------------------------------------------
MOV TH0,#0x9E MOV TL0,#0x58
SETB TR0 SETB EA
;------------------------------------------- POP 0x07 ; 恢复寄存器 POP 0x06 POP 0x05 POP 0x04
POP PSW ; 恢复现场 POP ACC
RETI
;----------------------------------------------------- ; MsuTimer0Init() ;----------------------------------------------------- MsuTimer0Init: ANL TMOD,#0xF0 ORL TMOD,#0x01 MOV TH0,#0x9E MOV TL0,#0x58 CLR TF0 SETB ET0
RET
;----------------------------------------------------- ; main() ;----------------------------------------------------- main: LCALL MsuTimer0Init SETB EA
loop1: LCALL MsuReadFqy MOV 0x0A,R6 ; R6 is MSB MOV 0x0B,R7 ; R7 is LSB SJMP loop1
;----------------------------------------------------- ; start() ;----------------------------------------------------- start: MOV R0,#0x7F CLR A
loop2: MOV @R0,A DJNZ R0,loop2 MOV SP,#0x0B LJMP MAIN |