求程序用AT89C51单片机......用八位数码管实现数字时钟用定时器做

时分秒中间需要显示一个横杠,只需显示时间即可

第1个回答  推荐于2018-03-10

ORG 0000H
AJMP MAIN              //  ;跳转到主程序                   
ORG 000BH                 //  ;T0中断入口
AJMP PTF0                   // ;中断处理首地址
 
//主程序
MAIN:
      MOV SP,#05FH     
      MOV 30H,#0             // ;缓冲单元设置初值12:00:00
      MOV 31H,#0
      MOV 32H,#0
      MOV 36H,#0FH          //     ; 设置4000次中断计数
      MOV 37H,#0A0H
      MOV TMOD,#02H               // ;定时器启动
      MOV TL0,#6
      MOV TH0,#6
      SETB TR0    // 启动T0计时器
      MOV IE,#82H
      MOV IP,#20H
//数码管动态显示
LED6:
      LCALL DISPLAY
      JNB P1.0,CLEAR                //;判断键盘输入
      JNB P1.1,SET_MINUTE
      JNB P1.2,SET_HOUR
      AJMP LED6
CLEAR:
      LCALL DISPLAY
      JNB P1.0,CLEAR
      MOV 30H,#12H              //;时钟显示复位  A键
      MOV 31H,#0
      MOV 32H,#0
      SJMP LED6
SET_MINUTE:
      LCALL DISPLAY
      JNB P1.1,SET_MINUTE
      MOV A,31H            //;调节分加1  B键
      CJNE A,#59H,MIN
      MOV 31H,#0
      SJMP LED6
SET_HOUR:
      LCALL DISPLAY
      JNB P1.2,SET_HOUR
      MOV R1,#30H          //;调节时加1   C键
      MOV A,@R1
      CJNE A,#23H,HOUR    // 比较立即数和A,不相等则转移
      MOV 30H,#0
MIN: 
      ADD A ,#1   //将1加到累加器
      DA A     // 累加器十进制调整
      MOV 31H,A
      LCALL DELAY1
      AJMP LED6
HOUR:
      ADD A,#1
      DA A
      MOV 30H,A
      LCALL DELAY1
      AJMP LED6
DISPLAY:
      MOV DPTR,#TAB    //;表的首地址给16位数据指针寄存器DPTR
      MOV A,30H           // ;时为的十位显示
      SWAP A  // A的高四位和低四位互换
      ANL A,#0FH     //  A与00001111相与
      MOVC A,@A+DPTR    // 程序存储器代码字节传送到累加器
      MOV P2,#7FH
      MOV P0,A
      LCALL DELAY     //调用延时子程序
      MOV A,30H           //  ;时位的个位显示
      ANL A,#0FH
      MOVC A,@A+DPTR
      MOV P2,#0BFH
   JB 00H,DIS01
   ORL A,#80H
DIS01:
      MOV P0,A
      LCALL DELAY
      MOV A,31H              // ;分位的十位显示
      SWAP A
      ANL A,#0FH
      MOVC A,@A+DPTR
      MOV P2,#0EFH
      MOV P0,A
      LCALL DELAY
      MOV A,31H                //;分位的个位显示
      ANL A,#0FH
      MOVC A,@A+DPTR
      MOV P2,#0F7H
   JB 00H,DIS02
   ORL A,#80H
DIS02:
      MOV P0,A
      LCALL DELAY
      MOV A,32H                // ;秒位的十位显示
      SWAP A
      ANL A,#0FH
      MOVC A,@A+DPTR
      MOV P2,#0FDH
      MOV P0,A
      LCALL DELAY
      MOV A,32H                    //;秒位的个位显示
      ANL A,#0FH
      MOVC A,@A+DPTR
      MOV P2,#0FEH
      MOV P0,A
      LCALL DELAY
   RET
//中断程序
PTF0:
      PUSH PSW                      ;中断处理
      PUSH ACC
      MOV PSW,#8
      DJNZ 37H,PTF0R
      DJNZ 36H,PTF0R
      MOV 36H,#0FH
      MOV 37H,#0A0H
      MOV R0,#32H                     //;定时到一秒
      MOV A,@R0
      ADD A,#1
      DA A
      MOV @R0,A
   CPL 00H
      CJNE A,#60H,PTF0R             
      MOV @R0,0
      DEC R0
      MOV A,@R0
      ADD A,#1
      DA A
      MOV @R0,A
      CJNE A,#60H,PTF0R
      MOV  @R0,#0
      DEC R0
      MOV A,@R0
      ADD A,#1
      DA A
      MOV @R0,A
      CJNE A,#24H,PTF0R
      MOV @R0,#0
PTF0R:
      POP ACC    // 保护现场
      POP PSW
      RETI   //  中断返回
DELAY:
      MOV R6,#10                 //;动态显示延时
L0:  
      MOV R7,#250
     
      DJNZ R7,$
      DJNZ R6,L0     //  寄存器减一,不为0则转移
      RET    //  子程序返回
DELAY1:
      MOV R5,#1BH               //;调整时、分显示延时
L1:
      MOV R6,#9H
L2:
      MOV R7,#19H
      DJNZ R7,$
      DJNZ R6,L2
      DJNZ R5,L1
      RET
 //数码显示表
TAB:  DB 3FH,06H,5BH,4FH,66H     //  ; 0,1,2,3,4    
      DB 6DH,7DH,07H,7FH,6FH     // ;  5,6,7,8,9
      END

本回答被网友采纳
相似回答