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

📄 12.asm

📁 万年历.rar
💻 ASM
字号:
;=====液晶屏通信引脚定义=====
      RS      BIT   P2.0
      RW      BIT   P2.1
      E       BIT   P2.2
      DB0_DB7 EQU   P0

;=====DS1302通信引脚定义=====
      RST     BIT   P3.0
      SCLK    BIT   P3.1
      IO      BIT   P3.2

;=====数据设定引脚定义========
      MODE    BIT   P3.3
      JIA     BIT   P3.4
      JIAN    BIT   P3.5

;=====定义数据存储地址========
      DS1302_ADDR  DATA   30H   ;地址寄存器
		DS1302_DATA  DATA   31H   ;数据寄存器
		TIME_YEAR   DATA   32H   ;年寄存器
		TIME_MONT   DATA   33H   ;月寄存器
		TIME_DAY    DATA   34H   ;天寄存器
		WEEK_DATA   DATA   35H   ;星期寄存器
		HOUR        DATA   36H   ;小时寄存器
		MINTUE      DATA   37H   ;分钟寄存器
		SECOND      DATA   38H   ;秒钟寄存器

;=========显示数据缓冲地址============
      YEAR_HBUF   DATA   40H
		YEAR_LBUF   DATA   41H
		MONT_HBUF   DATA   42H
		MONT_LBUF   DATA   43H
		DAY_HBUF    DATA   44H
		DAY_LBUF    DATA   45H
		WEEK_HBUF   DATA   46H
		WEEK_LBUF   DATA   47H
		HOUR_HBUF   DATA   48H
		HOUR_LBUF   DATA   49H
		MINTUE_HBUF DATA   4AH
		MINTUE_LBUF DATA   4BH
		SECOND_HBUF DATA   4CH
		SECOND_LBUF DATA   4DH

;============程序开始==============
      ORG    00H
      AJMP  START
;==================================
      ORG   0050H
START:
      MOV SP,#70H
      LCALL  INITIALZE   ;调用初始化液晶屏幕
      LCALL  INIT_P     ;调用初始画面
      MOV  A, #00000001B  ;清液晶屏,写成空白
		LCALL WRITE_COM

;============主程序================
MAIN:
       LCALL  RD_DS1302
		 LCALL  DATA_BUF
       LCALL  DISPLAY
 		 AJMP   MAIN

;==========读1302子程序=================
RD_DS1302:
          MOV DS1302_ADDR,#8DH   ;读DS1302中的年
          LCALL  READ     ;调用读DS1302子程序
	       MOV TIME_YEAR, DS1302_DATA   ;把读出的年数据存入年寄存器中

	       MOV DS1302_ADDR,#8BH   ;读DS1302中的星期
          LCALL  READ     
	       MOV WEEK_DATA, DS1302_DATA   ;把读出的星期数据存入星期寄存器中

          MOV DS1302_ADDR,#89H   ;读DS1302中的月
          LCALL  READ     
	       MOV TIME_MONT, DS1302_DATA   ;把读出的月数据存入月寄存器中

          MOV DS1302_ADDR,#87H   ;读DS1302中的天
          LCALL  READ     
	       MOV TIME_DAY, DS1302_DATA   ;把读出的天数据存入天寄存器中

          MOV DS1302_ADDR,#85H   ;读DS1302中的小时
          LCALL  READ     
	       MOV HOUR, DS1302_DATA   ;把读出的天数据存入小时寄存器中

          MOV DS1302_ADDR,#83H   ;读DS1302中的分钟
          LCALL  READ     
     	    MOV MINTUE, DS1302_DATA   ;把读出的天数据存入分钟寄存器中

          MOV DS1302_ADDR,#81H   ;读DS1302中的秒钟
          LCALL  READ     
          MOV SECOND, DS1302_DATA   ;把读出的天数据存入秒钟寄存器中
          RET
;===========按键子程序=================

;=========数据分离后送显示缓存==================
DATA_BUF:
	   	 MOV R0,TIME_YEAR     ;年数据分离,送显示缓存
		    LCALL DIVIDE
          MOV YEAR_HBUF,R1
		    MOV YEAR_LBUF,R2

          MOV R0,TIME_MONT     ;月数据分离,送显示缓存
		    LCALL DIVIDE
          MOV MONT_HBUF,R1
		    MOV MONT_LBUF,R2

          MOV R0,TIME_DAY     ;日数据分离,送显示缓存
		    LCALL DIVIDE
          MOV DAY_HBUF,R1
		    MOV DAY_LBUF,R2

          MOV R0,WEEK_DATA     ;星期数据分离,送显示缓存
		    LCALL DIVIDE
          MOV WEEK_HBUF,R1
	    	 MOV WEEK_LBUF,R2  

          MOV R0,HOUR         ;小时数据分离,送显示缓存
		    LCALL DIVIDE
          MOV HOUR_HBUF,R1
		    MOV HOUR_LBUF,R2

          MOV R0,MINTUE        ;分钟数据分离,送显示缓存
		    LCALL DIVIDE
          MOV MINTUE_HBUF,R1
		    MOV MINTUE_LBUF,R2

          MOV R0,SECOND        ;秒钟数据分离,送显示缓存
		    LCALL DIVIDE
          MOV SECOND_HBUF,R1
		    MOV SECOND_LBUF,R2
			 RET
        
;=========日历显示子程序==========
DISPLAY:
         MOV  A,#10000001B  ;设定年第1位的显示地址为第1行,第1列
		   LCALL WRITE_COM
         MOV  A, #32H      ;数字2的ASCII码
         LCALL WRITE_DATA

         MOV  A,#10000010B  ;设定年第2位的显示地址为第1行,第2列
		   LCALL WRITE_COM
         MOV  A, #30H      ;数字0的ASCII码
         LCALL WRITE_DATA

         MOV  A,#10000011B  ;设定年第3位的显示地址为第1行,第3列
		   LCALL WRITE_COM
         MOV  A, YEAR_LBUF  ;年的底位缓存数据
         ADD A,#30H        ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#10000100B  ;设定年第4位的显示地址为第1行,第4列
		   LCALL WRITE_COM
         MOV  A, YEAR_HBUF  ;年的高位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

		   MOV  A,#10000101B   ;设定斜线的显示地址为第1行,第5列
		   LCALL WRITE_COM
		   MOV  A,#2FH      ;斜线的ASCII码
         LCALL WRITE_DATA

         MOV  A,#10000110B  ;设定月第1位的显示地址为第1行,第6列
		   LCALL WRITE_COM
         MOV  A, MONT_LBUF  ;月的低位缓存数据
         ADD A,#30H       ;加30H修正取ASCII码 
         LCALL WRITE_DATA

         MOV  A,#10000111B  ;设定月第2位的显示地址为第1行,第7列
		   LCALL WRITE_COM
         MOV  A, MONT_HBUF  ;月的高位缓存数据
         ADD A,#30H       ;加30H修正取ASCII码 
         LCALL WRITE_DATA

         MOV  A,#10001000B   ;设定斜线的显示地址为第1行,第8列
		   LCALL WRITE_COM
		   MOV  A,#2FH      ;斜线的ASCII码
         LCALL WRITE_DATA

         MOV  A,#10001001B  ;设定天第1位的显示地址为第1行,第9列
		   LCALL WRITE_COM
         MOV  A, DAY_LBUF   ;天的低位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#10001010B  ;设定天第2位的显示地址为第1行,第10列
		   LCALL WRITE_COM
         MOV  A, DAY_HBUF   ;天的高位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#10001101B  ;设定星期第2位的显示地址为第1行,第13列
	  	   LCALL WRITE_COM
         MOV  A, WEEK_DATA   ;星期的高位缓存数据
		   SUBB A,#1
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000000B  ;设定小时第1位的显示地址为第2行,第0列
		   LCALL WRITE_COM
         MOV  A, HOUR_LBUF   ;小时的低位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000001B  ;设定小时第2位的显示地址为第2行,第1列
		   LCALL WRITE_COM
         MOV  A, HOUR_HBUF   ;小时的高位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

		   MOV  A,#11000010B   ;设定冒号的显示地址为第2行,第2列
         LCALL WRITE_COM
         MOV  A, #3AH       ;冒号的ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000011B  ;设定分钟第1位的显示地址为第2行,第3列
		   LCALL WRITE_COM
         MOV  A, MINTUE_LBUF   ;分钟的低位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

		   MOV  A,#11000100B  ;设定分钟第2位的显示地址为第2行,第4列
		   LCALL WRITE_COM
         MOV  A, MINTUE_HBUF   ;分钟的高位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000101B   ;设定冒号的显示地址为第2行,第5列
         LCALL WRITE_COM
         MOV  A, #3AH       ;冒号的ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000110B  ;设定秒钟第1位的显示地址为第2行,第6列
		   LCALL WRITE_COM
         MOV  A, SECOND_LBUF   ;秒钟的低位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA

         MOV  A,#11000111B  ;设定秒钟第2位的显示地址为第2行,第7列
	   	LCALL WRITE_COM
         MOV  A, SECOND_HBUF   ;秒钟的高位缓存数据
         ADD A,#30H         ;加30H修正取ASCII码
         LCALL WRITE_DATA
			RET

;=========初始画面==============
INIT_P:
      MOV  A,#10000000B  ;设定显示地址1000为第1行,1010为第0列
      LCALL  WRITE_COM   ;调用写液晶指令子程序
      MOV  DPTR,#LINE1   
      LCALL DISP
      MOV  A,#11000000B  ;设定显示地址1100为第2行,1010为第0列
      LCALL  WRITE_COM   ;调用写液晶指令子程序
      MOV  DPTR,#LINE2   
      LCALL DISP
      LCALL DELAY2      ;调用延时2秒程序
		RET
;=========显示的字符串============
LINE1: DB ' Welcome    To '
LINE2: DB ' WWW.5d6d.com  '
 
;========液晶初始化===============
INITIALZE: 
           MOV  A, #00111000B    ;8位数据,双行显示,5-7字型
           LCALL  WRITE_COM     ;调用写液晶指令
           MOV  A, #00001100B   ;显示屏开启,光标出现在地址计数器位置,光标不闪烁
           LCALL  WRITE_COM     ;调用写液晶指令
           MOV  A, #00000110B   ;光标右移一格,AC值加一,字符全部不动
           LCALL  WRITE_COM     ;调用写液晶指令
			  CLR  A

;========DS1302初始化===========
           MOV  DS1302_ADDR, #8EH   ;写DS1302控制指令
	        MOV  DS1302_DATA, #00H   ;写数据到DS1302的8E控制寄存器中,允许对其进行写操作
	        LCALL WRITE      ;调用写DS1302子程序

	        MOV  DS1302_ADDR, #90H   ;写DS1302控制指令
	        MOV  DS1302_DATA,#0A6H   ;写数据到DS1302的90控制寄存器中,对电池涓流充电,充电电流为1.1mA
           LCALL WRITE      ;调用写DS1302子程序
           RET

;=========查询忙碌标志============
CHECK_BUSY: 
           PUSH  ACC
BUSY_LOOP: 
           CLR  E
           SETB  RW
           CLR  RS
           SETB E
           MOV A, DB0_DB7
           JB p0.7,BUSY_LOOP
           POP  ACC
           LCALL  DEL
           RET

;=========写指令到液晶=============
WRITE_COM:
           LCALL  CHECK_BUSY
           CLR  E
           CLR  RS
           CLR  RW
           SETB  E
           MOV DB0_DB7,A
           CLR E
           RET

;==========写数据到液晶==============
WRITE_DATA:
           LCALL  CHECK_BUSY
           CLR E
           SETB RS
           CLR RW
           SETB E
           MOV DB0_DB7,A
           CLR E
           RET

;===========延时程序===================
  DEL:
       MOV R6,#5
  L1:
       MOV R7,#248
       DJNZ  R7,$
       DJNZ  R6,L1
       RET

;===========显示字符串到LCM==============
DISP:
          PUSH  ACC
DISP_LOOP:
          CLR  A
          MOVC A,@A+DPTR
          JZ END_DISP       ;若A的内容为0.则终止查表
          LCALL WRITE_DATA
          INC  DPTR
          SJMP  DISP_LOOP
END_DISP: 
         POP  ACC
         RET
			
       
;***********写1302程序*************
WRITE: 
        CLR SCLK
        NOP
        SETB RST
        NOP
        MOV A,DS1302_ADDR
        MOV R4,#8
WRITE1: 
        RRC A     ;送地址给1302
        NOP
        NOP
        CLR SCLK
        NOP
        NOP
        NOP
        MOV IO,C
        SETB SCLK         ;送入地址在时钟上升沿有效
        NOP
        NOP
        NOP
        NOP
        DJNZ R4,WRITE1
        CLR SCLK
        NOP
        MOV A,DS1302_DATA
        MOV R4,#8
WRITE2:
        RRC A
        NOP              ;送数据给1302,时钟上升沿,数据输入
        CLR SCLK
        NOP
        NOP
        MOV IO,C
        NOP
        NOP
        NOP
        SETB SCLK
        NOP
        NOP
        DJNZ R4,WRITE2
        CLR RST
		  CLR A
        RET
;**********读1302程序************
READ: 
        CLR SCLK
        NOP
        NOP
        SETB RST
        NOP
        MOV A,DS1302_ADDR
        MOV R4,#8
READ1: 
        RRC A
        NOP
        MOV IO,C
        NOP
        NOP
        NOP
        SETB SCLK       ;送入地址在时钟上升沿有效
        NOP
        NOP
        NOP
        CLR SCLK
        NOP
        NOP
        DJNZ R4,READ1     ;判断8位数据是否传送完

⌨️ 快捷键说明

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