单片机,要在双位数码管上显示R0的值,R0的值通过P0端口经过74LS47译码器送显,采用动态扫描的方式。定时器T1定时1秒,使R0自减,在数码管上就能显示倒计时的效果。用汇编语言,问题是如果一方面一直扫描P0端口(动态扫描是要循环的吧),同时又要让定时器T1工作,1秒时间到使R0减1,这两个部分怎么同时表达,汇编语言是逐条执行啊,下面程序中 根本不能进入定时器T1程序 ,只显示初始值20
;****************************************************************
ORG 0000H
LJMP MAIN
ORG 001BH ;定时器1入口地址
LJMP TIMER1
ORG 0100H
MAIN:MOV R2,#20 ;R2的值可以随时修改
DISP: MOV 01H,R2 ;南北方向显示初值R2=20秒
MOV R0,01H
MOV A,R0
MOV B,#10
DIV AB
MOV P0,A ;段选
MOV P2,#01 ;位选
ACALL D1ms ;延时
MOV P2,#00 ;清零
MOV P0,B
MOV P2,#02
ACALL D1ms
MOV P2,#00 ;清零
LJMP DISP ;这个地方就一直循环,怎样实现定时器的作用??
;*********** 定 时 1 秒 中 断 ***********
TIMER:
SETB EA ;开中断
SETB ET1 ;打开定时器1中断
MOV TMOD,#10H ;T1模式1(十六位定时器)
MOV TH1,#0D8H ;赋初值,定时10毫秒
MOV TL1,#0F0H
SETB TR1 ;启动T1
MOV R5,#64H ;循环100次
LP1: JNB TF1,$ ;TF1=0,等待,没有溢出
CLR TF1
LJMP LP2
LP2:
MOV TH1,#0D8H ;重新赋初值
MOV TL1,#0F0H
DJNZ R5,LP1 ;100次循环
SJMP TIMER
TIMER1:DEC R2 ; 定时1秒执行程序 南北方向倒计时减1
RETI
;************ 延 时 D1ms 程序***********
D1ms:
MOV R7,#02H
DL: MOV R6,#0FFH
DL1:DJNZ R6,DL1
DJNZ R7,DL
RET
;***************************************
END
如果是用 C语言 会不会有这个问题??
你那个入栈和出栈的语句有什么作用??我去掉之后执行效果一样
追答那是保存ACC和PSW的内容,因为中断程序使用了ACC,语句MOV A,R2会影响PSW的奇偶标志位
,而中断发生的时候主程序可能正在使用ACC寄存器,或者判断PSW的奇偶标志位,所以需要保存。当然你这个程序是没有用到奇偶标志位的,不过ACC是使用到的。
MOV B,#10
DIV AB例如程序在这里产生中断,如果中断程序中没有保存ACC,且正好R3减1为零
DJNZ R3,TIMER1_END
MOV R3,#100
MOV A,R2那么这条语句在中断程序中将被执行,返回的时候ACC的值将会等于R2
那么主程序中的语句MOV P0,A ;就不会得到你想要的结果了。
你去掉之后效果一样,是因为程序没有正好在那两条语句中产生中断,或者即使在那两条语句中产生中断,但R3-1不为零。所以效果是一样的,但不保证每次都能这样。所以要保证程序能长期正常运行,那几条语句是必不可少的。至少ACC的压栈/出栈在你的程序中不能省略
确实是。还在修改