thy110 发表于 2014-12-17 16:52:43

我在用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:10

应该是位选的问题去查相关变量

thy110 发表于 2014-12-17 17:09:23

磊磊映画 发表于 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

磊磊映画 发表于 2014-12-17 17:19:43

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




完美幸 发表于 2014-12-17 17:25:41

貌似这年头用汇编的不多啊。。。

Eric_Xue 发表于 2014-12-17 17:27:42

怎么还用汇编啊,改用C吧

lxa0 发表于 2014-12-17 17:38:40

楼主的显示代码太乱
看我的:

;显示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;共阴

thy110 发表于 2014-12-17 18:16:38

磊磊映画 发表于 2014-12-17 17:19
P0口你作为位选了P1口作为 段选了,我看你P0口只是循环P0.0 和P0.1         了也就是只有这两位
参考一下我之前 ...

我和你的电路不太一样,我用了两个74hc573,p1口既当段选又当位选,p0.0,p0.是控制573的


不过谢谢了,我已经解决了

黑夜之狼 发表于 2014-12-17 21:22:15

不懂汇编,帮顶了

ZJetWay 发表于 2014-12-20 22:52:50

以前用汇编,好难入门.
页: [1]
查看完整版本: 我在用51做一个数字时钟,显示时老是串着显示(已解决)