📄 18b20lcd.bak
字号:
;这是关于单个DS18B20的测温程序,数据脚为P2.2,晶振是12MHZ
;温度传感器18B20采用器件默认的12位转化,最大转化时间要750毫秒
;用1602液晶屏显示,显示温度从-55.0到127.9度,分辨率0.1度,精度0。05度
;内存分配声明
TEMPER_L EQU 29H;用于保存读出温度的低字节
TEMPER_H EQU 28H;用于保存读出温度的高字节
T_DF EQU 27H ;FORMAT后的小数部分(decimal fraction),半字节的温度小数(存在低四位)
FLAG1 BIT 50H;位地址50H是字节2AH的最低位,用作是否检测到DS18B20的标志位
A_BIT EQU 20h ;液晶十位数存放内存位置
B_BIT EQU 21h ;液晶个位数存放内存位置
C_BIT EQU 22H ;个位小数
D_BIT EQU 23H ;十位小数
S_BIT EQU 24H ;正负符号
RS BIT P3.7 ;这3位是液晶屏的控制信号,连接方式由具体硬件而定
RW BIT P3.6
E BIT P3.5
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: LCALL T_CONVERSION;调用读温度子程序
LCALL T_FORMAT;将读出的2字节温度格式化
LCALL DISPLAY;调用液晶显示子程序
LCALL D1S;延时1秒后再测
LJMP MAIN
;--------------DS18B20的温度转换子程序,具体时序请参考资料-------------------
T_CONVERSION:
LCALL INIT_1820;先复位DS18B20
JB FLAG1,T_C0
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
T_C0: MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
LCALL D1S ;这里等待AD转换结束,12位的话要延时750m秒
LCALL INIT_1820;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_1820; 将读出的温度数据保存到28H(TEMPER_H)和29H(TEMPER_L)处
RET
;这是DS18B20复位初始化子程序
INIT_1820:
SETB P2.2
NOP
CLR P2.2
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P2.2 ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2: JNB P2.2,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2 ;延时
LJMP TSR4
TSR3: SETB FLAG1 ;置标志位,表示DS1820存在
LJMP TSR5
TSR4: CLR FLAG1 ;清标志位,表示DS1820不存在
LJMP TSR7
TSR5: MOV R0,#117
TSR6: DJNZ R0,TSR6 ;时序要求延时一段时间
TSR7: SETB P2.2
RET
;------DS18B20复位初始化程序-----------------------------------------
;---------写DS18B20的子程序(有具体的时序要求)-------------------------------------
WRITE_1820:
MOV R2,#8;一共8位数据
WR0: CLR P2.2
MOV R3,#6 ;#4
DJNZ R3,$
RRC A
MOV P2.2,C
MOV R3,#20 ;#40
DJNZ R3,$
SETB P2.2
NOP
NOP
DJNZ R2,WR0
SETB P2.2
RET
;------读DS18B20的程序,从DS18B20中读出两个字节的温度数据--------------------------
READ_1820:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TEMPER_L ; 低位存入29H(TEMPER_L)
RE0: MOV R2,#8
RE1: SETB P2.2
NOP
NOP
CLR P2.2
NOP
NOP
SETB P2.2
MOV R3,#5
DJNZ R3, $
MOV C,P2.2
MOV R3,#20 ;#40
DJNZ R3, $
RRC A
DJNZ R2,RE1
MOV @R1,A
DEC R1 ; 高位存入28H(TEMPER_H)
DJNZ R4,RE0
RET
;-----整合读出的两字节温度(关于DS18B20读出的2字节温度格式请参考资料)----------
T_FORMAT:
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度的整数部份
;判别正负
MOV A,29H
MOV T_DF,A ;温度低字节暂存,待作小数处理
MOV A,#0FH ;取小数值
ANL A,T_DF
MOV D_BIT,A
MOV A,28H
JNB ACC.7,POSI
CLR C ;为负,求其绝对值
MOV A,29H
SUBB A,#01H
CPL A
MOV T_DF,A ;温度低字节暂存
MOV A,#0FH ;取小数值
ANL A,T_DF
MOV D_BIT,A
MOV A,28H
SUBB A,#00H
CPL A
MOV 28H,A
AJMP NEG
PROD: MOV A,T_DF
MOV C,40H ;将28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
RET
POSI: MOV S_BIT,#2BH ;“+”
ACALL PROD
AJMP OUT
NEG: MOV S_BIT,#2DH ;“-”
ACALL PROD
OUT: RET
;-------液晶显示的子程序(显示前先格式转换)---------------------------------------
DISPLAY:MOV A,29H ;将29H中的十六进制数转换成10进制
MOV B,#100
DIV AB
MOV A_BIT,A
MOV A,B
MOV B,#10
DIV AB
MOV B_BIT,A
MOV A,B
MOV B,#10
DIV AB
MOV C_BIT,B
MOV DPTR,#DFTAB
MOV A,D_BIT
MOVC A,@A+DPTR
MOV D_BIT,A
;----二进制到ASCII码转换--------------
MOV A, #30H
ORL A_BIT, A
ORL B_BIT, A
ORL C_BIT, A
ORL D_BIT, A
;-------------------------------------
LCALL INITIAL
MOV A, #10000000B ; LINE1: DB 'Now is:',00H
LCALL WRITE_INSTRUCTION
MOV DPTR, #LINE1
LCALL PR_STRING
MOV A, S_BIT
LCALL WRITE_LCDDATA
MOV A, A_BIT
LCALL WRITE_LCDDATA
MOV A, B_BIT
LCALL WRITE_LCDDATA
MOV A, C_BIT
LCALL WRITE_LCDDATA
MOV A, #2EH ;'.'字符
LCALL WRITE_LCDDATA
MOV A, D_BIT
LCALL WRITE_LCDDATA
MOV A, #0DFH ;下面两个是摄氏度的数字符号
LCALL WRITE_LCDDATA
MOV A, #43H
LCALL WRITE_LCDDATA
MOV A #11000000B ; LINE2: DB '47okey 2007.05',00H
LCALL WRITE_INSTRUCTION
MOV DPTR, #LINE2
LCALL PR_STRING
RET
;---液晶屏初始化,具体请参考资料-------------------------------------------------
INITIAL:MOV A, #01H
LCALL WRITE_INSTRUCTION
MOV A, #38H
LCALL WRITE_INSTRUCTION
MOV A, #0FH
LCALL WRITE_INSTRUCTION
MOV A, #06H
LCALL WRITE_INSTRUCTION
RET
;----写液晶指令的子程序------------------------------------------
WRITE_INSTRUCTION:
MOV P1, A
CLR RS ;写入控制命令
CLR RW
CLR E
LCALL DELAY
SETB E
RET
;----写液晶数据的子程序---------------------------------------------
WRITE_LCDDATA:
MOV P1, A
SETB RS ;写入数据
CLR RW
CLR E
LCALL DELAY ;判断液晶模块是否忙?
SETB E
RET
;-----写行字符的子程序---------------------------------------------------------------
PR_STRING:
CLR A
MOVC A,@A+DPTR
JZ END_PR
LCALL WRITE_LCDDATA
INC DPTR
LJMP PR_STRING
END_PR: RET
;----查看液晶忙碌信号的子程序---------------------------------------------------------
DELAY: MOV P1,#0FFH ;判断液晶显示器是否忙的子程序
CLR RS
SETB RW
CLR E
NOP
SETB E
JB P1.7,DELAY ;如果P1.7为高电平表示忙就循环等待
RET
;---1mS延时(按12MHZ算)-----------------------------------------------------------------
D1MS: MOV R7,#250
LOOP0: NOP
NOP
DJNZ R7,LOOP0
RET
;----1S延时(按12MHZ算)-----------------------------------------------------------------
D1S: MOV R6,#4
LOOP2: MOV R5,#250
LOOP1: LCALL D1MS
DJNZ R5,LOOP1
DJNZ R6,LOOP2
RET
;--------------------------------------------------------------------------------------
DFTAB: DB 00H,01H,01H,02H
DB 03H,03H,04H,04H
DB 05H,06H,06H,07H
DB 08H,08H,09H,09H
;--------------------------------------------------------------------------------------
LINE1: DB 'Now is:',00H
LINE2: DB '47okey 2007.05 ',00H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -