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

📄 10000clock.asm

📁 具有显示时分秒年月日和星期以及识别闰年得功能
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        MOV P0,A                ;写入毫秒十位
        LCALL WR_DATA           ;调用LCD数据写入子程序

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

        MOV DPTR,#NUM_TAB
        MOV A,S_SEC1
        MOVC A,@A+DPTR
        MOV P0,A                ;写入秒十位
        LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV DPTR,#NUM_TAB
        MOV A,S_SEC0
        MOVC A,@A+DPTR
        MOV P0,A                ;写入秒个位
        LCALL WR_DATA           ;调用LCD数据写入子程序

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

        MOV DPTR,#NUM_TAB
        MOV A,S_MIN1
        MOVC A,@A+DPTR
        MOV P0,A                ;写入分十位
        LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV DPTR,#NUM_TAB
        MOV A,S_MIN0
        MOVC A,@A+DPTR
        MOV P0,A                ;写入分个位
        LCALL WR_DATA           ;调用LCD数据写入子程序

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

        MOV DPTR,#NUM_TAB
        MOV A,S_HOU1
        MOVC A,@A+DPTR
        MOV P0,A                ;写入时十位
        LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV DPTR,#NUM_TAB
        MOV A,S_HOU0
        MOVC A,@A+DPTR
        MOV P0,A                ;写入时个位
        LCALL WR_DATA           ;调用LCD数据写入子程序

        RET

PATTERN:
        MOV A,P_COUNT
E_PATTERN:
        CJNE A,#0,E_PATTERN1
        MOV P0,#0CCH            ;写入显示起始地址(第2行第13个位置)
        LCALL ENABLE_LCD        ;调用写入命令子程序
        MOV P0,#11111111B       ;写入图案
        LCALL WR_DATA           ;调用LCD数据写入子程序
        INC P_COUNT
        LJMP P_EXIT
E_PATTERN1:
        CJNE A,#1,E_PATTERN2
        MOV P0,#0CDH            ;写入显示起始地址(第2行第14个位置)
        LCALL ENABLE_LCD        ;调用写入命令子程序
        MOV P0,#11111111B       ;写入图案
        LCALL WR_DATA           ;调用LCD数据写入子程序
        INC P_COUNT
        LJMP P_EXIT

E_PATTERN2:
        CJNE A,#2,E_PATTERN3
        MOV P0,#0CEH            ;写入显示起始地址(第2行第15个位置)
        LCALL ENABLE_LCD        ;调用写入命令子程序
        MOV P0,#11111111B       ;写入图案
        LCALL WR_DATA           ;调用LCD数据写入子程序
        INC P_COUNT
        LJMP P_EXIT

E_PATTERN3:
        CJNE A,#3,E_PATTERN4
        MOV P0,#0CFH            ;写入显示起始地址(第2行第16个位置)
        LCALL ENABLE_LCD        ;调用写入命令子程序
        MOV P0,#11111111B       ;写入图案
        LCALL WR_DATA           ;调用LCD数据写入子程序
        INC P_COUNT
        SJMP P_EXIT

E_PATTERN4:
        MOV P0,#0CCH            ;写入显示起始地址(第2行第13个位置)
        LCALL ENABLE_LCD        ;调用写入命令子程序


        MOV P0,#00100000B       ;写入空值
        LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV P0,#00100000B       ;写入空值
        LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV P0,#00100000B       ;写入空值
       LCALL WR_DATA           ;调用LCD数据写入子程序

        MOV P0,#00100000B       ;写入空值
        LCALL WR_DATA           ;调用LCD数据写入子程序
        MOV P_COUNT,#0
P_EXIT:
        RET

;日历初始化
LOAD8563:
     MOV R0, #XmtDat    ;发送缓冲区首地址送R0
     MOV @R0, #00H      ;秒初值
     INC R0
     MOV @R0, #59H      ;分初值
     INC R0
     MOV @R0, #23H      ;时初值
     INC R0
     MOV @R0, #28H      ;日初值
     INC R0
     MOV @R0, #01H      ;星期初值
     INC R0
     MOV @R0, #02H      ;世纪及月初值(21世纪)
     INC R0
     MOV @R0, #08H      ;年初值
     MOV ByteCnt, #07H	;传送7字节
     MOV SlvAdr, #0A2H	;PCF8563日历时钟器件地址为A2H
     MOV SubAdr, #02H	;从日历时钟的02H单元开始
     LCALL SendData	;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                        ;PCF8563日历芯片内日历时间单元
     RET

;闹钟初始化(闹钟无效)
LOADCLOCK:
     MOV R0,#XmtDat     ;发送缓冲区首地址送R0
     MOV @R0,#80H       ;闹钟分初值
     INC R0
     MOV @R0,#80H       ;闹钟时初值
     INC R0
     MOV @R0,#80H       ;闹钟时初值
     INC R0
     MOV @R0,#80H       ;闹钟星期初值
     INC R0
     MOV ByteCnt,#04H	;传送4字节
     MOV SlvAdr,#0A2H	;PCF8563日历时钟器件地址为A2H
     MOV SubAdr,#09H	;从日历时钟的09H单元开始
     LCALL SendData	;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                        ;PCF8563日历芯片内日历时间单元
     MOV R0,#XmtDat     ;发送缓冲区首地址送R0
     MOV @R0,#00000000B ;初始化状态控制寄存器2
     MOV ByteCnt,#01H	;传送1字节
     MOV SlvAdr,#0A2H	;PCF8563日历时钟器件地址为A2H
     MOV SubAdr,#01H	;从日历时钟的09H单元开始
     LCALL SendData	;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                        ;PCF8563日历芯片内日历时间单元
     RET

;压缩式BCD转非压缩式BCD,且把接收缓冲区的内容放入显示缓冲区
LCDBUF:
       MOV A,RcvDat
       ANL A,#7FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV SEC0,A        ;秒低四位送显示缓冲区
       MOV A,Rcvdat
       ANL A,#7FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV SEC1,A        ;秒高四位送显示缓冲区
       MOV A,RcvDat+1
       ANL A,#7FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV MIN0,A        ;分低四位送显示缓冲区
       MOV A,Rcvdat+1
       ANL A,#7FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV MIN1,A        ;分高四位送显示缓冲区
       MOV A,RcvDat+2
       ANL A,#3FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV HOU0,A        ;时低四位送显示缓冲区
       MOV A,Rcvdat+2
       ANL A,#3FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV HOU1,A        ;时高四位送显示缓冲区
       MOV A,RcvDat+3
       ANL A,#3FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV DAY0,A        ;日低四位送显示缓冲区
       MOV A,Rcvdat+3
       ANL A,#3FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV DAY1,A        ;日高四位送显示缓冲区
       MOV A,RcvDat+4
       ANL A,#07H        ;屏蔽数据无关位
       MOV WEK,A         ;星期送显示缓冲区
       MOV A,RcvDat+5
       ANL A,#1FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV MON0,A        ;月低四位送显示缓冲区
       MOV A,Rcvdat+5
       ANL A,#1FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV MON1,A        ;月高四位送显示缓冲区
       MOV A,RcvDat+6
       ANL A,#0FH
       MOV YER0,A        ;年低四位送显示缓冲区
       MOV A,Rcvdat+6
       SWAP A
       ANL A,#0FH
       MOV YER1,A        ;年高四位送显示缓冲区
       RET

;把时钟的压缩式BCD转非压缩式BCD,且把接收缓冲区的内容放入闹钟显示缓冲区
C_LCDBUF:
       MOV A,RcvDat
       ANL A,#7FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV C_MIN0,A      ;分低四位送显示缓冲区
       MOV A,Rcvdat
       ANL A,#7FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV C_MIN1,A      ;分高四位送显示缓冲区
       MOV A,RcvDat+1
       ANL A,#3FH        ;屏蔽数据无关位
       ANL A,#0FH
       MOV C_HOU0,A      ;时低四位送显示缓冲区
       MOV A,Rcvdat+1
       ANL A,#3FH        ;屏蔽数据无关位
       SWAP A
       ANL A,#0FH
       MOV C_HOU1,A      ;时高四位送显示缓冲区
       MOV A,RcvDat+3
       ANL A,#07H        ;屏蔽数据无关位
       MOV C_WEK,A        ;星期送显示缓冲区
       RET

;LCD写入控制命令的子程序
ENABLE_LCD:
        CLR RS
        CLR RW
        CLR E                   ;执行指令
        LCALL DELAY_LCD
        SETB E
        RET
;LCD写数据子程序
  WR_DATA:
  SETB RS
  CLR RW
  CLR E
  LCALL DELAY_LCD
  SETB E
  RET

;判断液晶显示器是否忙的子程序
DELAY_LCD:
        MOV P0,#0FFH
        CLR RS
        SETB RW
        CLR E                   ;执行指令
        NOP
        SETB E
        JB P0.7,DELAY_LCD       ;如果P0.7为高电平表示忙就循环等待
        RET



;------------------------串行EEPROM、日历时钟读写子程序------------
; 发送数据子程序
;名称:SendData
;描述:发送ByteCnt 个字节给从器件,如I2C总线串行EEPROM
;从器件地址在SlvAdr 中,存储单元地址在SubAdr 中
;所发送数据的字节数在ByteCnt中,发送的数据在XmtDat 缓冲区中
;成功发送数据,FHbit标志为0; 当FHbit为1时表示从器件无应答或损坏
;*************************************************************************************************

PROC SendData
SendData:
     PUSH PSW
     PUSH ACC
     CLR  RS0              ;使用2区(10)
     SETB RS1

     LCALL START           ;启动IC总线
     MOV A ,SlvAdr         ;将从器件地址放累加器A中
     LCALL SentByte        ;发送从器件总线地址
     JB FHBIT,SenReturn    ;从器件不应答返回
     ;--------对于存储器单元地址为16位的EEPROM存储器
;     MOV R0, #SubAdr+1
;     MOV A, @R0            ;存储单元地址高8位送累加器Acc,即先发送高8位地址A15~A8
;     LCALL SentByte        ;发存储单元地址
;     JB FHbit,SenReturn    ;从器件不应答返回

     ;--------对于存储单元地址为8位时,仅保留如下内容即可
     MOV R0, #SubAdr
     MOV A, @R0            ;存储单元地址低8位送累加器Acc,再发送低8位地址A7~A0
     LCALL SentByte        ;发存储单元地址
     JB FHbit,SenReturn    ;从器件不应答返回

     MOV R0,#XmtDat        ;取发送数据缓冲区首址
SentNext:
     MOV A,@R0
     LCALL SentByte ;发送一次数据
     JB FHbit,SenReturn ;出错返回
     INC R0 ;取下一个数据
     DJNZ ByteCnt,SentNext ;重复操作直到发送完最后一个数据
     LCALL STOP ;停止IC总线操作

;********查询方式检测内部写入周期是否已完成**********
LOOP:
     NOP                     ;两次操作之间的延迟
     NOP
     NOP
     NOP
     LCALL START ;启动IC总线
     MOV A ,SlvAdr ;将从器件地址放累加器A中
     LCALL SentByte ;发送从器件总线地址
     JB FHBIT,LOOP ;从器件不应答返回
     LCALL STOP ;停止IC总线操作
;***********************************************************
SenReturn:
     POP ACC
     POP PSW
     RET
END

;************************************************************************************************
; 接收数据子程序
;名称:ReceData
;描述:自从器件(如I2C总线串行EEPROM)读出ByteCnt个字节数据信息
;从器件地址在SlvAdr 中,待读出的存储单元地址在SubAdr 中
;所发送数据的字节数在ByteCnt中,接收的数据放在RevDat 缓冲区中
;成功接收数据,FHbit标志为0; 当FHbit为1时表示从器件无应答或损坏
;*************************************************************************************************
PROC ReceData
ReceData:
     PUSH PSW
     PUSH ACC
     CLR  RS0           ;使用2区(10)
     SETB RS1

     LCALL START        ;启动IC总线
     MOV A ,SlvAdr      ;将从器件地址放累加器A中
     LCALL SentByte     ;发送从器件总线地址
     JB FHBIT,RevReturn ;从器件不应答返回
     ;-----------对于存储器单元地址为16位的EEPROM存储器
;     MOV R0, #SubAdr+1
;     MOV A, @R0         ;存储单元地址高8位送累加器Acc,即先发送高8位地址A15~A8
;     LCALL SentByte     ;发存储单元地址
;     JB FHbit,RevReturn ;从器件不应答返回

     ;-----------对于存储单元地址为8位时,仅保留如下内容即可
     MOV R0, #SubAdr
     MOV A, @R0         ;存储单元地址低8位送累加器Acc,再发送低8位地址A7~A0
     LCALL SentByte     ;发存储单元地址(只完成存储单元定位功能
                        ;既不给数据,也没有给停止信号,因为停止总线后写操作
                        ;才被执行,故称为“哑写”
     JB FHbit,RevReturn ;从器件不应答返回
     ;*****完成“哑写”过程,将从器件地址计数器定位到将要读出的存储单元****

     LCALL START        ;重新启动IC总线
     MOV A ,SlvAdr      ;将从器件地址放累加器A中
     SETB ACC.0         ;将从器件地址改为读状态
     LCALL SentByte     ;发送从器件总线地址
     JB FHBIT,RevReturn ;从器件不应答返回
     ;****准备接收数据*****************************************
     CLR NOACK		;清除非应答标志
     MOV R0,#Rcvdat	;取接收数据缓冲区首地址
     DJNZ ByteCnt,Next  ;继续接受下一字节
     SJMP ReceLast	;减1为0,说明仅接收一个字节数据(也是最后一个字节)。
Next:
     LCALL ReceByte	;接收一个字节数据
     MOV @R0,A	        ;把接收到的数据放入接收缓冲区内。
     INC R0		;将指针移到缓冲区下一存储单元
     DJNZ ByteCnt,Next  ;重复进行直到最后一个字节
ReceLast:
     SETB NOACK		;已接收了最后一个字节,主器件无需应答
     LCALL ReceByte	;接收一个字节数据
     MOV @R0,A		;把接收到的数据放入接收缓冲区内
     LCALL STOP		;停止总线操作
RevReturn:
     POP ACC
     POP PSW
     RET
END

;字节发送(写入)子程序
;用于将从器件地址字节或数据字节发送到从器件(串行EEPROM)中
;入口参数:发送字节信息存放在寄存器A中
;出口参数:返回标志存放在Fhbit(位地址)中
           ;0—成功;1—失败(从器件不应答,发送失败)
PROC SentByte
SentByte:
     CLR FHbit	        ;清除失败标志。
     MOV R7,#08H	;初始化发送数据位长度R7
SentLOOP:
     CLR SCL            ;主器件输出时,在SCL下降沿后立即输出数据,以便接收
                        ;方(从器件)接收
     RLC A		;将Acc.7位移到进位标志C中,即先写高位。
     MOV SDA, C	        ;将数据位发送到SDA引脚。由于写入时用SCL上升沿同
                        ;步,因此要先送数据后将SCL置高电平。
     NOP		;SCL同步时钟低电平时间大于4.7uS
     NOP                ;根据CPU时钟频率可以插入0~6

⌨️ 快捷键说明

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