我在用51做一个数字时钟,显示时老是串着显示(已解决)
本帖最后由 thy110 于 2014-12-17 18:14 编辑我在用51做一个数字时钟,显示时老是串着显示,
我单独测试时,每个位都正常显示的是正确的时间,
但是一起显示时,显示很混乱,仔细观察了一下,秒钟个位同时在秒钟的十位和个位显示,秒钟的十位同时在秒钟的十位和分钟的个位显示,分钟的个位在分钟的各位和十位显示,造成了显示重叠了。但是我的程序逻辑上不应该这样啊
不知道怎么回事啊,求助
BUF_HOUR_H DATA 30H ; 小时十位
BUF_HOUR_L DATA 31H ; 小时个位
BUF_MIN_H DATA 32H ; 分十位
BUF_MIN_L DATA 33H ; 分个位
BUF_SEC_H DATA 34H ; 秒十位
BUF_SEC_L DATA 35H ; 秒个位
ORG 0000H
LJMP MAIN
ORG 001BH
AJMP SERVE1
ORG 0100H
MAIN:
MOV P1,#0FFH
MOV P0,#0FFH
MOV R0,#00H
MOV R1,#00H
MOV R2,#00H
MOV R3,#14H //20
MOV BUF_HOUR_H,#0FFH
MOV BUF_HOUR_L,#0FFH
MOV BUF_MIN_H,#0FFH
MOV BUF_MIN_L,#0FFH
MOV BUF_SEC_H,#0FFH
MOV BUF_SEC_L,#0FFH
MOV TMOD,#10H
MOV TL1,#0B0H //50MS
MOV TH1,#3CH
SETB TR1
SETB ET1
SETB EA
LJMP DISPLAY //显示函数
SERVE1:
MOV TL1,#0B0H
MOV TH1,#3CH
DJNZ R3,LOOP ;是否中断20次(达到1s)
MOV R3,#14H ; 达到1s
CPL P0.4
LCALL INC_SEC ;秒加1
LOOP:RETI
INC_SEC:INC R0 ;秒加1
MOV A, R0
SETB C
SUBB A,#59 ;如果秒等于60,则秒清0,分加1
JC L1 ;显示秒
MOV R0,#00H
LCALL INC_MIN
L1: MOV A,R0
MOV B,#10
DIV AB ; A = SEC / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_SEC_H,A ;
MOV A,R0
MOV B,#10
DIV AB
MOV A,B ; A = SEC % 10
MOVC A,@A+DPTR
MOV BUF_SEC_L,A
RET
INC_MIN:
INC R1 ; 分钟加1
MOV A,R1 ;
SETB C
SUBB A,#59
JC L2 ; 如果分钟等于60,则分清0,小时加1
MOV R1,#00H
LCALL INC_HOUR ; 小时加1
L2:MOV A,R1
MOV B,#10
DIV AB ; A = MIN / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 更新分十位
MOV A,R1
MOV B,#10
DIV AB
MOV A,B ; A = MIN % 10
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 更新分个位
RET
INC_HOUR:
INC R2 ; 小时加1
MOV A,R2
SETB C
SUBB A,#24
JC L3 ; 如果小时等于24,则小时清0
MOV R2,#00H ; 小时清0
L3: MOV A,R2
SETB C
SUBB A,#10
JC L4 ; 如果小时小于10,则十位0不显示
MOV A,R2//时 十位
MOV B,#10
DIV AB
MOV A,R2
MOV B,#10
DIV AB
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_HOUR_H,A
SJMP L5
L4:MOV BUF_HOUR_H,#0FFH //时 十位
L5:MOV A,R2 //时 个位
MOV B,#10
DIV AB
MOV A,B
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_HOUR_L,A
RET
DISPLAY: /*SETB P0.0
MOV P1,BUF_HOUR_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#01H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_HOUR_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#02H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_MIN_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#04H
CLR P0.1
ACALL DELAY_1MS */
SETB P0.0
MOV P1,BUF_MIN_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#08H
CLR P0.1
ACALL DELAY_1MS
/* SETB P0.0
MOV P1,BUF_SEC_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#10H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_SEC_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#20H
CLR P0.1
ACALL DELAY_1MS*/
SJMP DISPLAY
DELAY_1MS:MOV R7,#01H
TS1: MOV R6,#0FFH
TS2: DJNZ R6,TS2
DJNZ R7,TS1
RET
DIS_CODE:
DB 0C0H
DB 0F9H
DB 0A4H
DB 0B0H
DB 099H
DB 092H
DB 082H
DB 0F8H
DB 080H
DB 090H
DB 0FFH
END
应该是位选的问题去查相关变量 磊磊映画 发表于 2014-12-17 17:03
应该是位选的问题去查相关变量
位选我是一个一个设置的 啊
DISPLAY: /*SETB P0.0
MOV P1,BUF_HOUR_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#01H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_HOUR_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#02H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_MIN_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#04H
CLR P0.1
ACALL DELAY_1MS */
SETB P0.0
MOV P1,BUF_MIN_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#08H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_SEC_H
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#10H
CLR P0.1
ACALL DELAY_1MS
SETB P0.0
MOV P1,BUF_SEC_L
CLR P0.0
ACALL DELAY_1MS
SETB P0.1
MOV P1,#20H
CLR P0.1
ACALL DELAY_1MS
SJMP DISPLAY thy110 发表于 2014-12-17 17:09
位选我是一个一个设置的 啊
P0口你作为位选了P1口作为 段选了,我看你P0口只是循环P0.0 和P0.1 了也就是只有这两位
参考一下我之前做的代码
DISP:
MOV A,A_BIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P0,A
CLR P1.2
ACALL D1MS
SETB P1.2
MOV A,B_BIT
MOVC A,@A+DPTR
MOV P0,A
CLR P1.3
ACALL D1MS
SETB P1.3
MOV A,C_BIT
MOVC A,@A+DPTR
MOV P0,A
SETB P0.7
CLR P1.4
ACALL D1MS ;显示1ms
SETB P1.4
MOV A,D_BIT;取
MOVC A,@A+DPTR;
MOV P0,A
CLRP1.5
ACALL D1MS ;显示1ms
SETB P1.5
MOV A,E_BIT;取
MOVC A,@A+DPTR;
MOV P0,A
SETB P0.7
CLR P1.6
ACALL D1MS ;显示1ms
SETB P1.6
MOV A,F_BIT;取
MOVC A,@A+DPTR;
MOV P0,A
CLR P1.7
ACALL D1MS ;显示1ms
SETB P1.7
RET
貌似这年头用汇编的不多啊。。。 怎么还用汇编啊,改用C吧 楼主的显示代码太乱
看我的:
;显示xsz子程序<占用区0>********************************************
org 0020h
xsz:push dph
push dpl
push acc
push psw ;保护现场
clr psw.3 ;进入第0组工作寄存器
clr psw.4
mov r6,#00h
mov dptr,#00e0h
mov a,2ah ;取秒个位数据
movc a,@a+dptr
mov p1,a
clr p3.0 ;送秒个位
s01:djnz r6,s01 ;延时约0.5mS
setb p3.0 ;关闭显示
mov a,2bh ;取秒十位数据
movc a,@a+dptr
mov p1,a
clr p3.1 ;送秒十位
s02:djnz r6,s02 ;延时约0.5mS
setb p3.1
mov a,2ch ;取分个位数据
movc a,@a+dptr
mov p1,a
clr p3.2 ;送分个位
s03:djnz r6,s03 ;延时约0.5mS
setb p3.2 ;关闭显示
mov a,2dh ;取分十位数据
movc a,@a+dptr
mov p1,a
clr p3.4 ;送分十位
s04:djnz r6,s04 ;延时约0.5mS
setb p3.4 ;关闭显示
mov a,2eh ;取时个位数据
movc a,@a+dptr
mov c,07h
mov acc.7,c
mov p1,a
clr p3.5 ;送时个位
s05:djnz r6,s05 ;延时约0.5mS
setb p3.5 ;关闭显示
mov a,2fh ;取时十位数据
jz s07 ;时十位为0就跳转不显示
movc a,@a+dptr
mov p1,a
clr p3.7 ;送时十位
s06:djnz r6,s06 ;延时约0.5mS
setb p3.7 ;关闭显示
s07:pop psw ;回复现场
pop acc
pop dph
pop dpl
ret ;返回
org 00e0h
db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h ;共阳
org 00f0h
DB 03FH,06H,05BH,04FH,066H,06DH,07DH,07H,07FH,06FH;共阴 磊磊映画 发表于 2014-12-17 17:19
P0口你作为位选了P1口作为 段选了,我看你P0口只是循环P0.0 和P0.1 了也就是只有这两位
参考一下我之前 ...
我和你的电路不太一样,我用了两个74hc573,p1口既当段选又当位选,p0.0,p0.是控制573的
不过谢谢了,我已经解决了 不懂汇编,帮顶了 以前用汇编,好难入门.
页:
[1]