我用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
一周热门 更多>