📄 text1.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 综合实验:LCD显示时间和温度 ;;
;; ;;
;;1302引脚定义:P2.0-----DIO 数据端 ;;
;; P2.1-----SCLK 时钟端 ;;
;; P2.2-----RST 复位端 ;;
;;1602引脚定义:P2.5----E ;;
;; P2.6----RW ;;
;; P2.7----RS ;;
;; P0 ----数据口 ;;
;;18B20引脚定义:P3.3----DQ ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TEMPER_L EQU 29H ;用于保存读出温度的低8位
TEMPER_H EQU 28H ;用于保存读出温度的高8位
FLAG1 EQU 38H ;是否检测到DS18B20标志位
DQ BIT P3.3
RS EQU P2.7
RW EQU P2.6
E EQU P2.5
LCD_DB EQU P0
DAT EQU 7EH ;用于MCU与LCD传送的数据
DIO EQU P2.0
SCLK EQU P2.1
RST EQU P2.2
ORG 0000H
MOV SP,#60H
LCALL LCDRESET
LCALL WRITE
MAIN: LCALL GET_TEMPER ;调用读温度子程序
LCALL TEMPER_COV ;调用温度转换子程序
LCALL READ
LCALL DONE
LCALL DISP ;调用显示子程序
LCALL DEL200
SJMP MAIN
; 这是DS18B20复位初始化子程序
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV R1,#3 ;主机发出延时537微秒的复位低脉冲
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB DQ ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2: JNB DQ,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
CLR P1.7 ;检查到DS18B20就点亮P1.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
CLR P1.1
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:
SETB DQ
RET
; 读出转换后的温度值
GET_TEMPER:
SETB DQ
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2: MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
LCALL D1MS ;等待AD转换结束,12位的话750微秒
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ; 读出温度数据
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8 ;一共8位数据
CLR C
WR1: CLR DQ
MOV R3,#5
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#21
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8 ;数据一共有8位
RE01:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#8
RE10: DJNZ R3,RE10
MOV C,DQ
MOV R3,#21
RE20: DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;1MS延时
D1MS: MOV R7,#80
DJNZ R7,$
RET
TEMPER_COV: ;温度数据转换
CLR 7FH
MOV A,28H ;判断温度的正,负
SWAP A
ANL A,#0FH
JZ QQ2
MOV A,28H
CPL A
MOV 28H,A
MOV A,29H
CPL A
INC A
MOV 29H,A
SETB 7FH ;负温度标志
QQ2: MOV A,29H
ANL A,#0FH
MOV 30H,A ;提取小数
MOV A,28H
SWAP A
MOV 28H,A
MOV A,29H
SWAP A
ANL A,#0FH
ADD A,28H
MOV 29H,A ;提取整数
LCALL XSZH
LCALL HBCD
RET
XSZH: MOV DPTR,#TAB ;小数查表,4位BCD存放在34H,35H,36H,37H
MOV A,30H
RL A
MOV B,A
MOVC A,@A+DPTR
MOV 35H,A
MOV A,B
INC DPTR
MOVC A,@A+DPTR
MOV 37H,A
MOV A,35H
SWAP A
ANL A,#0FH
MOV 34H,A
ANL 35H,#0FH
MOV A,37H
SWAP A
ANL A,#0FH
MOV 36H,A
ANL 37H,#0FH
RET
HBCD: MOV A,29H
MOV B,#100
DIV AB
MOV 31H,A ;31H中存放百位
MOV A,B
MOV B,#10
DIV AB
MOV 32H,A ;32H中存十位
MOV 33H,B ;33H中存个位
JB 7FH,HH1
MOV A,31H
JNZ HH2
MOV 31H,#70H ;31H为0则不显示
MOV A,32H
JNZ HH2
MOV 32H,#70H ;32H为0则不显示
HH2: RET
HH1: MOV A,32H
JNZ HH3
MOV 32H,#80H ;32H为0则显示-
MOV 31H,#70H ;31H则不显示
RET
HH3: MOV 31H,#80H ;31H显示-
RET
TAB:
DB 00H,00H
DB 06H,25H,12H,50H,18H,75H,25H,00H,31H,25H,37H,50H,43H,75H,50H,00H
DB 56H,25H,62H,50H,68H,75H,75H,00H,81H,25H,87H,50H,93H,75H
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 时钟置数据 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WRITE:NOP
MOV A,#8EH ;写保护寄存器写
MOV 7FH,#00H ;写保护寄存器内容
LCALL WBYTE
MOV A,#90H ;充电寄存器写
MOV 7FH,#0A5H ;充电寄存器内容
LCALL WBYTE
MOV A,#81H ;秒寄存器读操作,检查1302是否第一次工作
MOV R0,#2FH
LCALL RBYTE
JB 7FH,YUZHI
SJMP READ
YUZHI:NOP
MOV A,#80H ;秒寄存器写
MOV 7FH,#00H ;秒寄存器内容
LCALL WBYTE
MOV A,#82H ;分寄存器写
MOV 7FH,#00H ;分寄存器内容
LCALL WBYTE
MOV A,#84H ;时寄存器写
MOV 7FH,#12H ;时寄存器内容
LCALL WBYTE
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 从内部寄存器读数据 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ: NOP
MOV A,#81H ;秒寄存器读
MOV R0,#50H
LCALL RBYTE
MOV A,#83H ;分寄存器读
MOV R0,#51H
LCALL RBYTE
MOV A,#85H ;时寄存器读
MOV R0,#52H
LCALL RBYTE
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 时钟数据处理 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DONE:MOV A,50H
ANL 50H,#0FH
MOV 47H,50H
SWAP A
ANL A,#0FH
MOV 46H,A
MOV A,51H
ANL 51H,#0FH
MOV 44H,51H
SWAP A
ANL A,#0FH
MOV 43H,A
MOV A,52H
ANL 52H,#0FH
MOV 41H,52H
SWAP A
ANL A,#0FH
MOV 40H,A
RET
DISP: MOV DAT,#01H ;显示清屏
LCALL LCDWC
MOV DAT,#080H ;显示第一行地址
LCALL LCDWC
MOV DAT,#"T"
LCALL LCDWD
MOV DAT,#"i"
LCALL LCDWD
MOV DAT,#"m"
LCALL LCDWD
MOV DAT,#"e"
LCALL LCDWD
MOV DAT,#":"
LCALL LCDWD
MOV A,40H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,41H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV DAT,#"-"
LCALL LCDWD
MOV A,43H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,44H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV DAT,#"-"
LCALL LCDWD
MOV A,46H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,47H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV DAT,#0C0H ;显示第二行地址
LCALL LCDWC
MOV DAT,#"T"
LCALL LCDWD
MOV DAT,#"e"
LCALL LCDWD
MOV DAT,#"m"
LCALL LCDWD
MOV DAT,#"p"
LCALL LCDWD
MOV DAT,#":"
LCALL LCDWD
MOV A,31H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,32H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,33H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV DAT,#"."
LCALL LCDWD
MOV A,34H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,35H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,36H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV A,37H
ADD A,#30H
MOV DAT,A
LCALL LCDWD
MOV DAT,#" "
LCALL LCDWD
MOV DAT,#0DFH
LCALL LCDWD
MOV DAT, #"C"
LCALL LCDWD
RET
;;;;;;;;;;;;;;;;;;;;;;;;
;; 1302单字节写操作 ;;
;;;;;;;;;;;;;;;;;;;;;;;;
WBYTE:CLR RST
NOP
CLR SCLK
NOP
SETB RST
NOP
MOV R1,#08H
LOOP: RRC A ;从D0位开始传送命令
MOV DIO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R1,LOOP
NOP
MOV A,7FH
MOV R1,#08H
LOOPP:RRC A ;从D0位开始传送数据
MOV DIO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R1,LOOPP
CLR RST
RET
;;;;;;;;;;;;;;;;;;;;;;;;
;; 1302单字节读操作 ;;
;;;;;;;;;;;;;;;;;;;;;;;;
RBYTE:CLR RST
NOP
CLR SCLK
NOP
SETB RST
MOV R1,#08H
LOOP2:RRC A
MOV DIO,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ R1,LOOP2
NOP
CLR A
CLR C
MOV R1,#08H
LOOP1:MOV C,DIO
RRC A ;从D0位开始传送
SETB SCLK
NOP
CLR SCLK
DJNZ R1,LOOP1
MOV @R0,A
CLR RST
RET
;显示子程序
;***LCD初始化程序***
LCDRESET:
LCALL DEL500 ;延时500MS
MOV DAT,#38H ;显示模式设置(不检测忙信号)
CALL LCDWCN ;共三次
CALL DEL10
MOV DAT,#38H
CALL LCDWCN
CALL DEL10
MOV DAT,#38H
CALL LCDWCN
MOV DAT,#38H ;显示模式设置(以后均检测忙信号)
CALL LCDWC
MOV DAT,#01H ;显示清屏
CALL LCDWC
MOV DAT,#06H ;显示光标移动设置
CALL LCDWC
MOV DAT,#0EH ;显示开及光标设置
CALL LCDWC
RET
;;*****写指令操作*****
LCDWC: ;送控制字子程序(检测忙信号)
LCALL CHK
LCDWCN: ;送控制字子程序(不检测忙信号)
MOV P0,DAT
CLR RS ;RS=0 RW=0 E=高脉冲
CLR RW
SETB E
NOP
NOP
CLR E
RET
;;*****写数据操作*****
LCDWD: ;写字符数据子程序
LCALL CHK
MOV P0,DAT
SETB RS ;RS=1 RW=0 E=高脉冲
CLR RW
SETB E
NOP
NOP
CLR E
RET
;;*****批量写数据*****
LCDWDP:
MOV R1,#00H
A1: MOV A,R1
MOVC A,@A+DPTR
CJNE A,#5EH,A2 ;检测到结束符"^"时,停止写操作
RET
A2: MOV DAT,A
LCALL LCDWD
INC R1
SJMP A1
RET
;;*****忙检测*****
CHK: ;正常读写操作之前必须检测LCD控制器状态
MOV P0,#0FFH
CLR RS ;RS=0 RW=1 E=高电平
SETB RW
SETB E
CHK1: NOP
NOP
JB P0.7,CHK1 ; DB7: 1 LCD控制器忙;0 LCD控制器空闲
CLR E
RET
;;*****延时程序(ms)*****
DEL1000:MOV 30H,#200
SJMP D3
DEL500:MOV 30H,#100
SJMP D3
DEL200:MOV 30H,#40
SJMP D3
DEL100:MOV 30H,#20
SJMP D3
DEL50:MOV 30H,#10
SJMP D3
DEL20:MOV 30H,#4
SJMP D3
DEL10:MOV 30H,#2
SJMP D3
DEL5: MOV 30H,#1
D3: MOV 31H,#30
D4: MOV 32H,#128
D5: DJNZ 32H,D5
DJNZ 31H,D4
DJNZ 30H,D3
RET
CC:NOP
End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -