⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 数字钟.asm

📁 AT89S52单片机程序50例(00-50)
💻 ASM
字号:
;数字钟
;P3.0、P3.1、P3.2接键盘;P1口接数码管的A-H;P2口接数码管的位码。

      SECOND EQU 30H  ;定义秒钟的内存地址为30H
      MINITE EQU 31H  ;定义分钟的内存地址为31H
      HOUR EQU 32H  ;定义小时的内存地址为32H 
      HOURK BIT P3.2  ;定义小时的加1按键为P3.2引脚
      MINITEK BIT P3.1  ;定义分钟的加1按键为P3.1引脚
      SECONDK BIT P3.0  ;定义秒钟的加1按键为P3.0引脚
      DISPBUF EQU 40H  ;DISPBUF=40H
      DISPBIT EQU 48H  ;位码值-
      T2SCNTA EQU 49H  ;定义T2SCNTA为计数单元,计数范围0-100
      T2SCNTB EQU 4AH  ;单元T2SCNTB为计数单元,计数范围0-5
      TEMP EQU 4BH  ;
      
      ORG 0000H  ;程序起始地址
      LJMP START  ;无条件跳转至START
      ORG 000BH  ;定时/计数器T0的矢量地址
      LJMP INT_T0  ;无条件跳转至INT_T0,定时/计数器T0中断服务子程序
START:MOV SECOND,#00H  ;秒钟初始化为0
      MOV MINITE,#00H  ;分钟初始化为0
      MOV HOUR,#12  ;小时初始化为12
      MOV DISPBIT,#00H  ;DISPBIT初始化为0
      MOV T2SCNTA,#00H  ;T2SCNTA初始化为0
      MOV T2SCNTB,#00H  ;T2SCNTB初始化为0
      MOV TEMP,#07H  ;第一个数码管(左边)的位码
      LCALL DISP  ;调用DISP子程序
      MOV TMOD,#01H  ;定时/计数器T0的工作方式为方式1,16为计数器
      MOV TH0,#(65536-2000)/256  ;计数器初值为0F830H,2ms
      MOV TL0,#(65536-2000) MOD 256
      SETB TR0  ;启动定时/计数器T0
      SETB ET0  ;定时/计数器T0开溢出中断
      SETB EA  ;CPU开总中断

   WT:JB SECONDK,NK1  ;SECONDK=1时,跳转至NK1
      LCALL DELY10MS  ;SECONDK=0时,调用10毫秒按键仿抖动延时子程序
      JB SECONDK,NK1  ;SECONDK=1时,跳转至NK1
      INC SECOND  ;SECOND加1
      MOV A,SECOND ;SECOND的值送A
      CJNE A,#60,NS60  ;A的值不为60,跳转至NS60
      MOV SECOND,#00H  ;A的值为60,则SECOND初始化为0
 NS60:LCALL DISP  ;调用DISP
      JNB SECONDK,$  ;SECONDK=0时,原地踏步

;SECONDK=1时,执行NK1
  NK1:JB MINITEK,NK2  ;MINITEK=1时,跳转至NK2
      LCALL DELY10MS  ;MINITEK=0时,调用10毫秒按键仿抖动延时子程序
      JB MINITEK,NK2  ;MINITEK=1时,跳转至NK2
      INC MINITE  ;MINITE加1
      MOV A,MINITE  ;MINITE的值送A
      CJNE A,#60,NM60  ;A的值不为60时,跳至NM60
      MOV MINITE,#00H  ;A的值为60时,MINITE初始化为0
 NM60:LCALL DISP  ;调用DISP
      JNB MINITEK,$  ;MINITE=0时,原地踏步

;MINITE=1时,执行NK2
  NK2:JB HOURK,NK3  ;HOURK=1时,跳转至NK3
      LCALL DELY10MS  ;HOURK=0时,调用10毫秒按键仿抖动延时子程序
      JB HOURK,NK3  ;HOURK=1时,跳转至NK3
      INC HOUR  ;HOUR加1
      MOV A,HOUR  ;HOUR的值送A
      CJNE A,#24,NH24  ;A的值不为24时,跳转至NH24
      MOV HOUR,#00H  ;A的值为24时,HOUR初始化为0
 NH24:LCALL DISP  ;调用DISP
      JNB HOURK,$  ;HOURK=0时,原地踏步
  
;HOURK=1时,执行NK3
  NK3:LJMP WT  ;无条件跳转至WT

;10毫秒按键仿抖动延时子程序
DELY10MS:MOV R6,#10
      D1:MOV R7,#248
         DJNZ R7,$
         DJNZ R6,D1
  RET

;各个位的数值分离子程序,均为段码值所对应的十进制数。
DISP:MOV A,#DISPBUF  ;DISPBUF的值给A=40H
     ADD A,#8  ;A加8后,给A=48H
     DEC A  ;A减1,即A=47H
     MOV R1,A  ;A的值给R1,即R1=47H

     MOV A,HOUR  ;HOUR的值给A
     MOV B,#10  ;10给B
     DIV AB  ;A除以B
     MOV @R1,A  ;商的值在A中,A的值给R1的值所对应的地址(47H)空间
     DEC R1  ;R1减1,即R1=46H
     MOV A,B  ;余数值在B中,B的值给A
     MOV @R1,A  ;A的值给R1的值所对应的地址(46H)空间
     DEC R1  ;R1减1

     MOV A,#10  ;10给A
     MOV @R1,A  ;A的值给R1的值所对应的地址(45H)空间
     DEC R1  ;R1减1

     MOV A,MINITE  ;MINITE的值给A
     MOV B,#10  ;10给B
     DIV AB  ;A除以B
     MOV @R1,A  ;商在A中,A的值给R1的值所对应的地址(44H)空间
     DEC R1  ;R1减1
     MOV A,B  ;余数在B中,B的值给A
     MOV @R1,A  ;A的值给R1的值所对应的地址(43H)空间
     DEC R1  ;R1减1

     MOV A,#10  ;10给B
     MOV @R1,A  ;A的值给R1的值所对应的地址(42H)空间
     DEC R1  ;R1减1

     MOV A,SECOND  ;SECOND的值给A
     MOV B,#10  ;10给B
     DIV AB  ;A除以B
     MOV @R1,A  ;商在A中,A的值给R1的值所对应的地址(41H)空间
     DEC R1  ;R1减1
     MOV A,B  ;余数在B中,B的值给A
     MOV @R1,A  ;A的值给R1的值所对应的地址(40H)空间
     DEC R1  ;R1减1
  RET

;定时/计数器T0中断服务子程序
INT_T0:MOV TH0,#(65536-2000)/256  ;重新初始化计数器为0F830H,2ms
       MOV TL0,#(65536-2000) MOD 256
       MOV A,#DISPBUF  ;DISPBUF的值送A=40H
       ADD A,DISPBIT  ;A的值加DISPBIT的值给A
       MOV R0,A  ;A的值送R0
       MOV A,@R0  ;把R0的值所对应的地址中的内容给A
       MOV DPTR,#TABLE  ;TABLE的首地址给DPTR
       MOVC A,@A+DPTR  ;查表,程序存储器
       MOV P0,A  ;A的值给P0口
       MOV A,DISPBIT  ;DISPBIT的值给A
       MOV DPTR,#TAB  ;TAB的首地址给DPTR
       MOVC A,@A+DPTR  ;查表,程序存储器
       MOV P2,A  ;A的值给P2口
       INC DISPBIT  ;DISPBIT加1
       MOV A,DISPBIT  ;DISPBIT的值给A
       CJNE A,#08H,KNA  ;A不为8,则跳转至KNA
       MOV DISPBIT,#00H  ;A=8,则DISPBIT初始化为0
   KNA:INC T2SCNTA  ;T2SCNTA加1
       MOV A,T2SCNTA  ;T2SCNTA的值给A
       CJNE A,#100,DONE  ;A不为100,则跳转至DONE
       MOV T2SCNTA,#00H  ;A=100时,T2SCNA初始化为0
       INC T2SCNTB  ;T2SCNTB加1
       MOV A,T2SCNTB  ;T2SCNTB的值给A
       CJNE A,#05H,DONE  ;A不为5时,跳转至DONE
       MOV T2SCNTB,#00H  ;A=5时,T2SCNTB初始化为0
       INC SECOND  ;SECOND加1
       MOV A,SECOND  ;SECOND的值给A
       CJNE A,#60,NEXT  ;A的值不为60,跳转至NEXT
       MOV SECOND,#00H  ;A=60时,SECOND初始化为0
       INC MINITE  ;MINITE加1
       MOV A,MINITE  ;MINITE的值给A
       CJNE A,#60,NEXT  ;A的值不为60时,跳转至NEXT
       MOV MINITE,#00H  ;A=60时,MINITE初始化为0
       INC HOUR  ;HOUR加1
       MOV A,HOUR  ;HOUR的值给A
       CJNE A,#24,NEXT  ;A的值不为24时,跳转至NEXT
       MOV HOUR,#00H  ;A=24时,HOUR初始化为0
  NEXT:LCALL DISP  ;无条件跳转至DISP
DONE:RETI  ;中断返回

;
TABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H  ;0-9以及-的段码值

TAB:DB 07H,06H,05H,04H,03H,02H,01H,00H  ;各个数码管的选中码即位码
  END  ;程序结束

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -