at89c51单片机怎么用汇编语言写“多个延时程序”

做流水灯要很多不同的延时程序
我现在用下面的延时程序
DELAY:MOV R7,#10
D0: MOV R6,#50
D1: MOV R5,#200
D2: DJNZ R5,D2
DJNZ R6,D1
DJNZ R7,D0
RET
想多写几个延时程序发现D和R不够用,也太麻烦

所以求个适合写多个延时的延时程序(要用汇编语言)

单片机汇编语言中要使一个延时程序可以被不同情况下调用而延时不同的时间,可以通过类似于C语言中传递参数的方式来实现,举例如下:
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:
MOV P0,#5AH ;P0上的LED灯间隔点亮
MOV R7,#50 ;R7是延时传递参数
LCALL DELAY ;调用延时函数
MOV P0,#0A5H ;P0上LED灯另一半点亮
MOV R7,#100 ;延时时间加长
LCALL DELAY
MOV P0,#00H ;LED等全部点亮
MOV R7,#150 ;延时再次加长
LCALL DELAY
MOV P0,#0FFH ;灯灭
MOV R7,#200 ;延时时间再次加长
LCALL DELAY
SJMP MAIN ;循环
DELAY:
MOV R2,#100
DLY:
MOV R3,#250
DJNZ R3,$
DJNZ R2,DLY
DJNZ R7,DELAY ;R7是调用前赋值的传递参数。
RET
END
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2016-03-06
标号可以用 $ 代替。
每使用一个 $,就可以少写一个标号。

下面的写法,和你原来的,转移功能完全相同,
但却节约了三个标号。

DELAY:MOV R7,#10
MOV R6,#50
MOV R5,#200
DJNZ R5, $ ; = D2: DJNZ R5, D2
DJNZ R6, $ - 4 ; = DJNZ R6, D1
DJNZ R7, $ - 8 ; = DJNZ R7, D0
RET追问

这个程序可以只修改DELAY的编号不修改R就可以用的吗?

追答

可以如下编写:
(但是这两个子程序,使用同一组R,不能同时使用。)
DL1:

MOV R7,#10
MOV R6,#50
MOV R5,#20
DJNZ R5, $ ; = D2: DJNZ R5, D2
DJNZ R6, $ - 4 ; = DJNZ R6, D1
DJNZ R7, $ - 8 ; = DJNZ R7, D0
RET

DL2:
MOV R7,#100
MOV R6,#150
MOV R5,#220
DJNZ R5, $ ; = D2: DJNZ R5, D2
DJNZ R6, $ - 4 ; = DJNZ R6, D1
DJNZ R7, $ - 8 ; = DJNZ R7, D0
RET

也可以使用不同的R。
DL3:
MOV R2,#1
MOV R3,#15
MOV R4,#20
DJNZ R4, $
DJNZ R3, $ - 4
DJNZ R2, $ - 8
RET

你可以试试看。

本回答被提问者采纳
第2个回答  2013-10-18
;晶振24M
DELAY1s:  ;子程序
        mov   A,R4
        jz    enddelay
        MOV   R5,#10H           ; ∵ 1s=2000000*0.5us 
        MOV   R6,#43H          ; ∴ 2000000/2=1000000
        MOV   R7,#40H           ; 1000000用16进制表示为: 0f4240
                                ; 所以 R5=0fH+1=10H
                                ;     R6=042H+1=043H
                                ;     R7=40H
loop:   DJNZ  R7,$              ; 延时时间≈2×[(R5-1)×256+R6-1]×256+R7
        DJNZ  R6,loop           ; 当R5、R6等于0,相当于256参与运算
        DJNZ  R5,loop           ; 当R5、R6等于0,相当于256参与运算
        DJNZ  R4,DELAY1s
enddelay: RET

   


上面是延时子程序,基础延时是1s,调用前给R4赋值,R4的值就是延时的秒数,比如:


mov  R4,#3      ;表示延时3秒

lcall   DELAY1s   



希望你能参考着用,这个用法有点像带参数的函数

追问

第一行的【DELAY1s:】后面是加【mov R4,#3】的吗?
还有这个程序要复制成2个只改DELAY后的1s,不改R。这样能行吗?

追答

你当这是c语言索

汇编不是这样的

DELAY1s是我写的延迟程序,其延迟时间长度受R4决定

所以调用DELAY1s程序前给R4赋值,就能决定延时为几秒

第3个回答  2013-10-18
如果延时时间是成倍数关系 的,可以以一个为基数 。比如10ms的子程序 ,调用10次就是100ms。
R不够用,也可以用内存单元
第4个回答  2013-10-18
例如
DELAY_R7: ;DELAY=R7*10MS

DE10MS: ;@12M
MOV R6,#01H
DL1:
MOV R5,#26H
DL0:
MOV R4,#82H
DJNZ R4,$
DJNZ R5,DL0
DJNZ R6,DL1
DJNZ R7,DE10MS
RET
使用延时10MS: MOV R7,#1
LCALL DELAY_R7

使用延时100MS:MOV R7,#10
LCALL DELAY_R7

使用延时2.5S: MOV R7,#250
LCALL DELAY_R7