51驱动74HC164I/O扩展驱动LED移位亮灭,发现灭的LED也会闪

2020-02-05 09:10发布

我用51驱动74HC164来驱动跑马灯发现灭的灯也会闪。附上程序望高手指点迷津。
SDA1 BIT P1.0;74hc164的串行数据输入端
SCL1 BIT P1.1;74hc164的串行CLK端,上升沿有效
SDA2 BIT P1.2;74hc164的串行数据输入端
SCL2 BIT P1.3;74hc164的串行CLK端,上升沿有效
SDA3 BIT P1.4;74hc164的串行数据输入端
SCL3 BIT P1.5;74hc164的串行CLK端,上升沿有效
SDA4 BIT P1.6;74hc164的串行数据输入端
SCL4 BIT P1.7;74hc164的串行CLK端,上升沿有效
DDS  EQU 48H;数据初值
org 0000h
ljmp main
org 0003h
ljmp intto
org 0013h
ljmp intt1
ORG 1000H
LJMP MAIN
main:
mov sp,#60h
mov IE,#10000101b
setb it0
setb it1
mov A,#01h
mov p2,A
mov DDS,#01h
ACALL  shift
ACALL DELAY
MOV R0,#7
qq:mov a,dds
RL A
mov dds,a
ACALL shift
ACALL DELAY
DJNZ R0,qq
nop
MOV A,#02H
MOV P2,A
MOV DDS,#01H
lCALL shift1
ACALL DELAY
mov R0,#7
qq1:mov a,dds
RL A
mov dds,a
ACALL shift1
ACALL DELAY
DJNZ R0,qq1
MOV A,#04H
MOV P2,A
MOV DDS,#01H
ACALL shift2
ACALL DELAY
MOV R0,#7
qq2:mov a,dds
RL A
mov dds,a
ACALL shift2
ACALL DELAY
DJNZ R0,qq2
MOV A,#08H
MOV P2,A
MOV DDS,#01H
ACALL shift3
ACALL DELAY
MOV R0,#7
qq3:mov a,dds
RL A
mov dds,a
ACALL shift3
ACALL DELAY
DJNZ R0,qq3
RESET:LJMP MAIN
;74HC164移位子程序
shift: push acc;将A进栈保护数据
       mov a,dds
       mov r2,#8;串输出8位数据
                 clr c    ;清C
loop:  
       CLR SCL1   ;拉低SCL1,以便下次拉高产生上升沿
       RLC A      ;A的最高位移到C,C原值移到A的最低位
                 nop
       MOV SDA1,C  ;C中的数据输入74HC164,等待CLK上升沿的到来
                 SETB SCL1 ;低电平到高电平边沿触发到来,并行数据输出至164至Q0-Q7
                 DJNZ r2,loop
                 pop acc
                 ret
shift1: push acc;将A进栈保护数据
       mov a,dds
       mov r2,#8;串输出8位数据
                 clr c    ;清C
loop1:  
       CLR SCL2   ;拉低SCL1,以便下次拉高产生上升沿
       RLC A      ;A的最高位移到C,C原值移到A的最低位
                 nop
       MOV SDA2,C  ;C中的数据输入74HC164,等待CLK上升沿的到来
                 SETB SCL2 ;低电平到高电平边沿触发到来,并行数据输出至164至Q0-Q7
                 DJNZ r2,loop1
                 pop acc
                 ret
shift2: push acc;将A进栈保护数据
       mov a,dds
       mov r2,#8;串输出8位数据
                 clr c    ;清C
loop2:  
       CLR SCL3   ;拉低SCL1,以便下次拉高产生上升沿
       RLC A      ;A的最高位移到C,C原值移到A的最低位
                 nop
       MOV SDA3,C  ;C中的数据输入74HC164,等待CLK上升沿的到来
                 SETB SCL3 ;低电平到高电平边沿触发到来,并行数据输出至164至Q0-Q7
                 DJNZ r2,loop2
                 pop acc
                 ret
shift3: push acc;将A进栈保护数据
       mov a,dds
       mov r2,#8;串输出8位数据
                 clr c    ;清C
loop3:  
       CLR SCL4   ;拉低SCL1,以便下次拉高产生上升沿
       RLC A      ;A的最高位移到C,C原值移到A的最低位
                 nop
       MOV SDA4,C  ;C中的数据输入74HC164,等待CLK上升沿的到来
                 SETB SCL4 ;低电平到高电平边沿触发到来,并行数据输出至164至Q0-Q7
                 DJNZ r2,loop3
                 pop acc
                 ret

;延迟程序
DELAY:;延时子程序,12M晶振延时1.002035秒
MOV R4,#10
L3: MOV R2 ,#180  ;1指令周期
L1: MOV R3 ,#249  ;1指令周期
L2: DJNZ R3 ,L2   ;2指令周期
DJNZ R2 ,L1       ;2指令周期
DJNZ R4 ,L3       ;2指令周期
RET               ;2指令周期
;循环体延时时间: [(249*2+1+2)*200+1+2]*10*12/12000000=1.002030s
;加上ACALL指令和第一条mov指令以及最后一条RET指令算出来整个函数的时间为1.002035s
intto:push acc
clr ex0
acall delay5
setb ex0
acall delay
mov ie, #10000101b
setb it0
setb it1
pop  acc
reti
intt1:
clr ex1
acall delay5
setb ex1
mov ie, #10000101b
setb it0
setb it1
mov a,#0fh
mov p2,a
mov dds,#0ffh
acall shift
acall delay
acall shift1
acall delay
acall shift2
acall delay
acall shift3
acall delay
reti
;延迟100ms
delay5:mov r7,#82h
dl1:mov r6,#0ffh
dl2:nop
    djnz r6,dl2
         djnz r7,dl1
         ret
end
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。