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

📄 time.asm

📁 ds1302和ds18b20和1602液晶显示
💻 ASM
字号:
;这是一个利用液晶屏幕作为显示终端,基于实时时钟芯片DS1302和数字温度传感器DS18B20,能同时显示当前年份、月份、日期、时间和当前室温的AT89S51单片机汇编语言源程序

;在硬件上将液晶屏的数据线接到AT89S51单片机的P0口,三根控制线RS、RW、E分别接到P2口的P2.5、P2.6、P2.7三个引脚

;DS1302的SPI串行通讯口三根线RST、I/O、SCLK分别接到AT89S51单片机的P1.0、P1.1、P1.2三个引脚

;DS18B20的单根数据线I/O接到AT89S51单片机的P1.3引脚

;DS1302用到单片机的30H、31H、32H,40H到47H共8个RAM单元、50H到57H共8个RAM单元、60H到6CH共13个RAM单元

;DS18B20用到单片机的70H、71H、72H、73H、74H、7AH共6个RAM单元

;椎栈顶定义在35H单元

;----------LCD的数据线和控制端引脚地址定义伪指令---------
LCD_RS BIT P2.5 ;RS为LCD寄存器选择端,高电平时选择数据寄存器,低电平时选择指令寄存器
LCD_RW BIT P2.6 ;RW为LCD读写选择控制端,高电平时进行读操作,低电平时进行写操作
LCD_E  BIT P2.7 ;E为LCD使能端,当该引脚电平由高电平跳变成低电平时,液晶模块执行单片机发出的指令
LCD_DATA EQU P0 ;定义LCD的数据线接口为P0口

;----------DS1302的通讯线引脚定义伪指令-----------
RST      BIT   P1.0  ;RST为DS1302的复位引脚
IO_DATA  BIT   P1.1  ;IO_DATA为DS1302的数据引脚
SCLK     BIT   P1.2  ;SCLK为DS1302的时钟引脚

;----------DS18B20的单根总线引脚定义伪指令--------

DQ BIT  P1.3 ;利用位地址符号命令将DS18B20数据线所连接的位地址P1.3赋给 DQ 字符,在程序中DQ即指向18B20的数据线



;------------定义DS1302数据缓冲单元-----------
BITCNT   DATA 30H  ;BITCNT为接收数据位数暂存缓冲单元
BYTECNT  DATA 31H  ;BYTECNT为接收字节数暂存缓冲单元
COMMAND  DATA 32H  ;COMMAND为命令字节数据缓冲单元
RCVDAT   DATA 40H  ;RCVDAT为从DS1302接收数据缓冲区首单元
XMTDAT   DATA 50H  ;XMTDAT为从单片机向DS1302发送数据缓冲区首单元






ORG 0000H           ;从0000H处开始
LJMP MAIN           ;跳转到MAIN处



ORG 0030H           ;主程序从0030H处开始

MAIN:MOV SP,#35H    ;堆栈指针指向35H

LCALL INITIAL      ;调用启动LCD子程序进行初始化

LCALL CLS         ;调用清除LCD子程序

MOV A,#80H          ;向A送立即数80H设定显示地址为第一行第一列
LCALL WRITE_COM     ;调用写指令到LCD子程序
MOV DPTR,#LINE1     ;将第一个字符串的启始地址送如DPTR中
LCALL DISP2          ;调用显示字符串到LCD子程序


MOV A,#8CH         ;向A送立即数8CH设定显示地址为第一行第十二列
LCALL WRITE_COM     ;调用写指令到LCD子程序
MOV DPTR,#LINE2     ;将第二个字符串的启始地址送如DPTR中
LCALL DISP2          ;调用显示字符串到LCD子程序


MOV A,#0CAH         ;向A送立即数0C0H设定显示地址为第二行第十列
LCALL WRITE_COM     ;调用写指令到LCD子程序
MOV DPTR,#LINE3     ;将第三个字符串的启始地址送如DPTR中
LCALL DISP2          ;调用显示字符串到LCD子程序



LOOP:MOV Command,#90h ;该段作用在于确保DS1302能进行走时,经试验只有在每次循环时重复写入这个程序段之后才能确保DS1302进行可靠走时,否则有时候DS1302会因为电源电压波动或其它一些原因停止走时
MOV ByteCnt,#1 ;字节写入数为1个
MOV R0,#XmtDat; 数据单元地址覆给R0
MOV XmtDat,#0A5H;写入数据为0A5H,意为主电源对备用电源充电时选择一个二极管,充电电阻为2K
ACALL Send_Byte ;调用写入1302子程序

;-------------以下为秒、分、时、日、月、年、星期的数值显示码计算及查表处理程序段---------------
MOV Command,#0BFH ;命令字节为BFh,意为连续读取
MOV ByteCnt,#8 ;多字节读出模式此模块为8 个
MOV R1,#RcvDat ;数据地址赋给R1
ACALL Receive_Byte; 调用读出数据子程序



mov a,40h  ;秒位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh ;用与指令屏蔽高4位,即只留下秒位个位数值
mov dptr,#table;将显示码表格首地址送DPTR,准备查表
movc a,@a+dptr;用查表指令查得秒位显示码送到A中
mov 60h,a;将秒位显示码送显示缓冲单元60H
mov a,40h;再将秒值送到A中
swap a;秒值高低位交换,将秒值十位数放到低四位
anl a,#0fh;用与指令屏蔽高4位,只留下秒值的十位数
mov dptr,#table;表格首地址送DPTR,准备查表
movc a,@a+dptr;用查表指令查得秒值十位数的显示码送到A中
mov 61h,a;将十秒位显示码送到显示缓冲单元61H

mov a,41h   ;分位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 62h,a
mov a,41h
swap a
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 63h,a

mov a,42h   ;小时位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 64h,a
mov a,42h
swap a
anl a,#0fh
mov dptr,#htable
movc a,@a+dptr
mov 65h,a


mov a,45h  ;星期位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 66h,a


mov a,43h   ;日期位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 67h,a
mov a,43h
swap a
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 68h,a


mov a,44h   ;月份位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 69h,a
mov a,44h
swap a
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 6ah,a


mov a,46h   ;年份位显示码查询,先用与指令得到个位数值,再用查表指令查得显示码。
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 6bh,a
mov a,46h
swap a
anl a,#0fh
mov dptr,#table
movc a,@a+dptr
mov 6ch,a



;------------------以下为DS18B20温度数感器的温度值读取及计算查表程序段----------------

ACALL  RST18B20 ;调用DS18B20复位子程序
         MOV A,#0CCH  ;准备写入DS18B20的ROM命令代码0CCH,功能是跳过ROM识读匹配
         ACALL WR18B20 ;调用写入子程序
         MOV    A,#44H ;准备写入DS18B20的RAM命令代码44H,功能是启动DS18B20进行温度转换
         ACALL  WR18B20 ;调用写入子程序

         SETB  DQ  ;释放DS18B20的单根数据总线

         ACALL  DEL ;延时1002ms左右,以便等待DS18B20完成温度转换,最快转换时间约为750ms

         ACALL  RST18B20 ;调用DS18B20复位子程序
         MOV A,#0CCH ;准备写入DS18B20的ROM命令代码0CCH,功能是跳过ROM识读匹配
         ACALL WR18B20 ;调用写入子程序
         MOV A,#0BEH  ;准备写入DS18B20的RAM命令代码0BEH,功能是读9字节的高速暂存器内容
         ACALL WR18B20 ;调用写入子程序

         MOV   R0,#2 ;利用R0作为2字节读取的计数器
         MOV   R1,#70H ;70H和71H作为温度值低8位和高8位的缓冲单元,70H放低8位
LOOP1:ACALL  RD18B20   ;读18B20低8位温度值
         MOV @R1,A ;用寄存器间接寻址方式将温度值低8位送入70H缓冲单元
         INC  R1    ;将R1寄存器内容加1,指向41H单元
         DJNZ  R0,LOOP1 ;利用R0计数器数值,再读取温度值高8位
         SETB DQ ;释放数据线

         MOV   A,70H ;将70H单元存放的温度值低8位送入A累加器
         ANL   A,#0FH ;利用与指令只留下低4位,低4位为温度值的小数位,准备进行四舍五入判断
         CJNE  A,#12,LOOP2 ;将小数位与立即数12比较,不相等则转移到LOOP2处,如果是小于12就不要进位,直接跳到LOOP3处进行高低位温度值合成
         JMP   LOOP3 ;如相等则不进位直接转到LOOP3处进行高低位温度值合成

LOOP2:JC   LOOP3 ;在CJNE语句中,如A中数值小于12,则进位标志 C 会被置1,表示温度值小数位不要向个位进位直接跳到LOOP3处执行温度值合成
                               ;如A中数值大于12,则进位标志 C 为0,    表示温度值小数位要向个位进位,顺序向下执行,将温度值个位加1

      MOV  A,70H ;70H单元中存放的是温度值的低8位,包括温度值的个位(高4位的二进制数)、小数位(低4位的二进制数)

      ADD  A,#10H ;在确认需要进位时,将A中存放的温度值低8位与10H相加,即高4位的温度值个位加1,小数位加0

      MOV  70H,A ;将处理好进位的温度值低8位重新回送到40H缓冲单元

      MOV  A,71H ;将71H单元中存放的温度值高8位(高5位均为符号位,后3位才是温度值的十分位)送到A中准备进行进位处理。
                 ;如果在上面二步中,70H单元的温度值个位正好为9,在接受了小数位的进位后,就等于10,它也要向温度值的
                 ;十分位进1位,所以在下面要将71H单元中的温度数值与0进行一次带进位的加法运算

      ADDC A,#00H ;带进位加0,主要是进行温度值个位向十分位的进位处理

      MOV  71H,A  ;将处理好进位的温度值高8位回送到71H单元

LOOP3:MOV   A,70H ;此处开始将温度值分别放在两个存储单元中的十分位和个位合并到1个字节单元,以便进行温度值计算查表
      ANL   A,#0F0H ;用与指令将小数位去除
      SWAP  A       ;高低半字节交换,将个位移到A中的低4位
      MOV   70H,A  ;回送到70H单元
      MOV   A,71H  ;将71H单元存放的温度值高8位送到A中,准备去除其中的高5位符号位
      ANL   A,#0FH ;用与指令去除高5位符号位
      SWAP  A  ;交换高低半字节
      ADD   A,70H ;将温度值高3位(十分位)和低4位(个位)合成到一个字节单元



      JNB  ACC.7,LOOP4 ;如果最高位符号位不为1,即为0,表示测得的温度是正值,转到LOOP4处直接计算查表。如为负温度,则向下执行补码变化处理
                        ;此处是正负温度的判断关键语句


      MOV  74H,#0B0H ;如果温度值为负数,先将最左面显示位(符号位)置负号的显示码0B0H。
      CPL  A  ;负温度数值处理方法是先取反,下一步再加1 ,即可得到原码数值,配合前面的负号即可指示出负温度数值。
      ADD  A,#01H
      MOV 7AH,A ;将A中温度值送到75H中暂存
      CLR C
      JMP  LOOP8 ;转到LOOP8处进行是否小于10的判断,如小于10,则十分位不显示任何字符



LOOP4:MOV 7AH,A
      CLR C
      CJNE A,#10,LOOP7 ;将A中温度值与10比较,如不相等转到LOOP7处继续判断是大于10还是小于10
LOOP5:MOV A,7AH
      MOV  B,#100  ;将立即数100送到B中,准备进行温度值的百分位计算查表
      DIV  AB     ;用除法指令,进行温度值的百分位的分离
      MOV  DPTR,#HTABLE ;将百分位的专用显示码表格首地址送DPTR,准备查表.特别用意是当温度值低于100度时,百分位的0不显示。
      MOVC A,@A+DPTR  ;用变址寻址指查找百分位的显示码
      MOV  74H,A  ;将百分位的显示码送到74H显示缓冲单元

LOOP6:MOV DPTR,#TABLE ;将十分位和个位的显示码表格首地址送DPTR,准备进行十分位和个位的查表。
      MOV  A,B  ;将 B 中存放的余数送到A中,准备进行二次计算,算出十分位和个数位的值再进行查表
      MOV  B,#10 ;将立即数10送寄存器B中。
      DIV  AB  ;用除法指令分离出十分位和个位。
      MOVC A,@A+DPTR ;用变址寻址指令查找十分位的显示码
      MOV 73H,A  ;将十分位的显示码送到73H显示缓冲单元
      MOV  A,B  ;将B中的余数即温度值的个位数送A中
      MOVC A,@A+DPTR ;用变址寻址指令查得温度值的个位数显示码
      MOV  72H,A ;将温度值的个位数显示码送72H缓冲单元
      JMP DISP ;转到DISP处显示

LOOP7:JNC LOOP5 ;A中温度值大于10就转到LOOP5处进行正常计算查表
      MOV 74H,#0A0H ;小于10就将百分位和十分位均不显示两个0,以免视觉效果不习惯
      MOV 73H,#0A0H ;十分位也不显示
      MOV A,7AH  ;将温度值

⌨️ 快捷键说明

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