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

📄 clock-mine.asm

📁 电子钟的单片机实现,这里配合时钟芯片令时间更加准确,LCD界面更加人性化
💻 ASM
📖 第 1 页 / 共 5 页
字号:
                                  ;PCF8563日历芯片内日历时间单元
         MOV XmtDat,C_WEK

         MOV ByteCnt, #01H	  ;传送1字节
         MOV SlvAdr, #0A2H	  ;PCF8563日历时钟器件地址为A2H
         MOV SubAdr, #0CH	  ;从日历时钟的0CH单元开始
         LCALL SendData	          ;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                                  ;PCF8563日历芯片内日历时间单元
         RET



STOPWATCH:

          
          RET

C_STOP:
       SETB BEE
       MOV C_COUNT,#64H
       LJMP C_END      
RET



INT0:
     MOV ByteCnt,#07H	;接收7字节
     MOV SlvAdr,#0A2H	;PCF8563日历时钟器件地址为A2H
     MOV SubAdr,#02H	;从日历时钟的02H单元开始
     LCALL ReceData     ;调用读EEPROM多字节读入过程,将信息读入接收缓冲区
     ;PUSH PSW
     ;PUSH ACC
     LCALL LCDBUF       ;把时间缓冲区的内容按十位与个位分开存放
     LCALL DISPLAY      ;把数据输出液晶显示
     CLR IE0
     ;POP ACC
     ;POP PSW
     RETI
     RETI
     RETI

INT1:
     CLR BEE                    ;开蜂鸣器
     MOV TL0,#0B0H              ;设置T0初值,定时50ms
     MOV TH0,#3CH               
     ANL TMOD,#0F0H
     ORL TMOD,#00000001B        ;16位定时器
     SETB ET0
     SETB TR0     
     CLR EX1                    ;关闭中断     
     RETI
     RETI
     RETI

CTC0:
     JB C_5S,C_NEXT
     MOV TL0,#0B0H               ;手动重装,定时50ms
     MOV TH0,#3CH
     DJNZ C_COUNT,C_EXIT
     SETB C_5S    
     MOV C_COUNT,#64H
     SETB BEE
     MOV TL0,#0E0H               ;定时20ms
     MOV TH0,#0B1H
     ;CLR TF0
     JB C_2S,C_END
     SJMP C_EXIT
C_NEXT:
     MOV TL0,#0E0H               ;定时20ms
     MOV TH0,#0B1H
     DJNZ C_COUNT,C_EXIT
     MOV C_COUNT,#64H
     SETB C_2S
     CLR C_5S
     CLR BEE
     MOV TL0,#0B0H               ;手动重装,定时50ms
     MOV TH0,#3CH
     SJMP C_EXIT
C_END:
     CLR C_2S
     CLR C_5S
     CLR TR0
     CLR ET0
     MOV XmtDat,#00000010B        ;清除闹钟中断标志
     MOV ByteCnt, #01H	          ;传送1字节
     MOV SlvAdr, #0A2H	          ;PCF8563日历时钟器件地址为A2H
     MOV SubAdr, #01H	          ;从日历时钟的01H单元开始
     LCALL SendData	          ;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                                  ;PCF8563日历芯片内日历时间单元
     SETB EX1                     ;开闹钟中断                          
C_EXIT:
     CLR TF0
     RETI
     RETI
     RETI          

CTC2:
     PUSH PSW
     PUSH ACC
     SETB T40                         ;40ms时间到标志置1
     CLR TF2
     POP ACC
     POP PSW
     RETI
     RETI
     RETI

;键盘检测,检测有没有按键被按下
KEYCHK:
       MOV A,P1              ;读P1状态
       ANL A,#0F0H           ;屏蔽低4位
       CJNE A,#0F0H,NEXT1    ;高4位为1说明没有按键按下
       SETB C                ;C的作用是用来改写KEYSTU
       SJMP NEXT2
NEXT1:
       CLR C
NEXT2:
       MOV A,KEYSTU
       RLC A
       ANL A,#07H            ;保留按键状态
       MOV KEYSTU,A          ;保存按键状态
       ;判别按键状态,决定是否执行按键扫描,检查是否010态
       CJNE A,#2,NEXT3
       ;处于010态,视为干扰,作000态处理
       ANL KEYSTU,#0F8H      ;重置按键状态
       SJMP NEXT4
NEXT3:
       CJNE A,#4,NEXT4
       ;处于100态,说明按键已稳定闭合,可进行按键扫描
       LCALL KEYSCAN          ;执行键盘扫描,确定哪一按键被按下
NEXT4:
       ;---键盘检测结束-----------
       RET

;键盘扫描程序,检查哪个按键被按下,P1.7-P1.4键值分别为81H,82H,83H,84H
KEYSCAN:
        ANL KEYNAME,#10000000B  ;保留b7位
        MOV A,KEYNAME
        CJNE A,#0,RETURN        ;若b7位为1,表明原键值未处理,返回
        JB P1.7,KEYSCAN1        ;若P1.7为1扫描P1.6
        MOV KEYNAME,#1
        SJMP KEYSCAN_DOEN
KEYSCAN1:
        JB P1.6,KEYSCAN2        ;若P1.6为1扫描P1.5
        MOV KEYNAME,#2
        SJMP KEYSCAN_DOEN
KEYSCAN2:
        JB P1.5,KEYSCAN3        ;若P1.5为1就肯定是P1.4
        MOV KEYNAME,#3
        SJMP KEYSCAN_DOEN
KEYSCAN3:
        MOV KEYNAME,#4
KEYSCAN_DOEN:
        ORL KEYNAME,#80H        ;按键有效标志置1
RETURN:
        RET

LOADLCD:
     MOV P0,#00000001B       ;清屏并光标复位
     LCALL ENABLE_LCD        ;调用写入命令子程序
     MOV P0,#00111000B       ;设置显示模式,8位2行5X7点阵
     LCALL ENABLE_LCD        ;调用写入命令子程序
     MOV P0,#00001100B       ;显示器开、光标关、光标不允许闪烁
     LCALL ENABLE_LCD        ;调用写入命令子程序
     MOV P0,#00000110B       ;文字不动,光标自动右移
     LCALL ENABLE_LCD        ;调用写入命令子程序
     MOV P0,#80H             ;写入显示起始地址(第一行第一个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00110010B       ;写入2
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#00110000B       ;写入0
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#84H             ;写入显示起始地址(第一行第五个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00101111B       ;写入/
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#87H             ;写入显示起始地址(第一行第八个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00101111B       ;写入/
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#0C2H             ;写入显示起始地址(第二行第三个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00111010B       ;写入:
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#0C5H             ;写入显示起始地址(第二行第六个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00111010B       ;写入:
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车
     ;输入ANUBIS(^_^)
ANUBIS:
     MOV P0,#0C9H            ;写入显示起始地址(第二行第十个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#01000001B       ;写入A
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01001110B       ;写入N
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01010101B       ;写入U
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01000010B       ;写入B
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01001001B       ;写入I
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01010011B       ;写入S
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#00100000B       ;写入空值
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车
RET

;显示字母SETTIME
DIS_TIME:
     MOV P0,#0C9H            ;写入显示起始地址(第二行第十个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#01010011B       ;写入S
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01000101B       ;写入E
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01010100B       ;写入T
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01010100B       ;写入T
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01001001B       ;写入I
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01001101B       ;写入M
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01000101B       ;写入E
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车
RET

;在第一行显示ALARM
DIS_ALARM:
     MOV P0,#00000001B       ;清屏并光标复位
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#0C2H            ;写入显示起始地址(第二行第三个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#00111010B       ;写入:
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#82H             ;写入显示起始地址(第一行第二个位置)
     LCALL ENABLE_LCD        ;调用写入命令子程序

     MOV P0,#01000001B       ;写入A
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01001100B       ;写入L
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01000001B       ;写入A
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据
     CLR E                   ;E=0 ;执行显示命令
     LCALL DELAY_LCD         ;判断液晶模块是否忙?
     SETB E                  ;E=1 ;显示完成,程序停车

     MOV P0,#01010010B       ;写入R
     SETB RS                 ;RS=1
     CLR RW                  ;RW=0 ;准备写入数据

⌨️ 快捷键说明

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