📄 more_18b20.asm
字号:
RS EQU P0.0
E EQU P0.1
K00 EQU P2.0
K01 EQU P2.1
K02 EQU P2.2
K03 EQU P2.3
FLAG1 EQU 20H.7 ;是否检测到DS18B20的标志位
ZHENGSHU EQU 21H ;AD实测结果原始值(8位
DOT EQU 22H
CUN EQU 23H ;暂存单元
TEM EQU 24H ;存放温度设定值
COM EQU 25H ;指令暂存器
DAT EQU 26H ;数据暂存器
TEMP1 EQU 27H
;27H,28H,29H暂存
DIS_0 EQU 2AH ;符号
HUN EQU 2BH ;存放百位BCD码
TEN EQU 2CH ;十位BCD
ONE EQU 2DH ;个位BCD
POINT EQU 2EH ;小数点后第一位
DIS_5 EQU 2FH ;小数点后第二位
S_HUN EQU 30H
S_TEN EQU 31H
S_ONE EQU 32H
H_HUN EQU 33H
H_TEN EQU 34H
H_ONE EQU 35H
L_HUN EQU 36H
L_TEN EQU 37H
L_ONE EQU 38H
ALR_L EQU 39H ;报警低温设定值
ALR_H EQU 3AH
S_FLAG EQU 3BH ;设置选择标志
DATA_1 EQU 40H
WDDATA EQU P0.2 ;定义DS18B20的数据脚为P0.2端口
ORG 0H
LJMP MAIN
MAIN:
LCALL SET_LCD
LOOP:
LCALL GETWENDU ;第一次测量,
MOV R5,#15
LCALL DELAY
LCALL DISP
JNB K00,PP1
LJMP LOOP
PP1:
JNB K00,$
MOV A,S_FLAG
INC A
CJNE A,#04H,SS1
SS1:
JC SS2
MOV A,#00H
SS2:
MOV S_FLAG,A
CJNE A,#02H,SS3
LJMP S_L
SS3:
JNC SS4
MOV R5,#10
LCALL DELAY
QQ1:
JNB K01,PP12
JNB K02,PP13
JNB K03,PP14
LCALL GETWENDU
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ1
PP12:
JNB K01,$
MOV A,TEM
INC A
MOV TEM,A
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ1
PP13:
JNB K02,$
MOV A,TEM
DEC A
MOV TEM,A
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ1
PP14:
JNB K03,$
MOV R5,#10
LCALL DELAY
LJMP LOOP
SS4:
LJMP S_H
S_L:
MOV R5,#10
LCALL DELAY
QQ2:
JNB K01,PP22
JNB K02,PP23
JNB K03,PP24
LCALL GETWENDU
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ2
PP22:
JNB K01,$
MOV A,ALR_L
INC A
MOV ALR_L,A
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ2
PP23:
JNB K02,$
MOV A,ALR_L
DEC A
MOV ALR_L,A
MOV R5,#20
LCALL DELAY
LCALL DISP
LJMP QQ2
PP24:
JNB K03,$
LJMP LOOP
S_H:
MOV R5,#10
LCALL DELAY
QQ3:
JNB K01,PP32
JNB K02,PP33
JNB K03,PP34
LCALL GETWENDU
MOV R5,#10
LCALL DELAY
LCALL DISP
LJMP QQ3
PP32:
JNB K01,$
MOV A,ALR_H
INC A
MOV ALR_H,A
MOV R5,#14
LCALL DELAY
LCALL DISP
LJMP QQ3
PP33:
JNB K02,$
MOV A,ALR_H
DEC A
MOV ALR_H,A
MOV R5,#14
LCALL DELAY
LCALL DISP
LJMP QQ3
PP34:
JNB K03,$
BB:
MOV R5,#14
LCALL DELAY
LJMP LOOP
/*****************************/
DISP:
/* 温度设定值的转化*/
MOV A,TEM
MOV B,#100
DIV AB
MOV S_HUN,A
MOV A,B
MOV B,#10
DIV AB
MOV S_TEN,A
MOV S_ONE,B
/*报警(低)设定值的转化*/
MOV A,ALR_L
MOV B,#100
DIV AB
MOV L_HUN,A
MOV A,B
MOV B,#10
DIV AB
MOV L_TEN,A
MOV L_ONE,B
/*报警(高)设定值的转化*/
MOV A,ALR_H
MOV B,#100
DIV AB
MOV H_HUN,A
MOV A,B
MOV B,#10
DIV AB
MOV H_TEN,A
MOV H_ONE,B
MOV A,DIS_0
CJNE A,#0,TT
ADD A,#2DH
MOV B,#3 ;设置要显示的位置
LCALL LCDP1
LJMP TT01
TT:
MOV A,HUN ;选择要显示的字符
CJNE A,#0,TT0
MOV A,#50H
TT0:
ADD A,#30H
MOV B,#3 ;设置要显示的位置
LCALL LCDP1
MOV A,HUN
CJNE A,#0,TT00
TT01: MOV A,TEN ;选择要显示的字符
CJNE A,#0,TT1
MOV A,#50H
LJMP TT1
TT00:
MOV A,TEN
TT1:
ADD A,#30H
MOV B,#4 ;设置要显示的位置
LCALL LCDP1
MOV A,ONE ;选择要显示的字符
ADD A,#30H
MOV B,#5 ;设置要显示的位置
LCALL LCDP1
MOV A,POINT ;选择要显示的字符
ADD A,#30H
MOV B,#7 ;设置要显示的位置
LCALL LCDP1
MOV A,DIS_5 ;选择要显示的字符
ADD A,#30H
MOV B,#8 ;设置要显示的位置
LCALL LCDP1
MOV A,S_HUN ;选择要显示的字符
CJNE A,#0,TT2
MOV A,#50H
TT2:
ADD A,#30H
MOV B,#15 ;设置要显示的位置
LCALL LCDP1
MOV A,S_TEN ;选择要显示的字符
ADD A,#30H
MOV B,#16 ;设置要显示的位置
LCALL LCDP1
MOV A,S_ONE ;选择要显示的字符
ADD A,#30H
MOV B,#17 ;设置要显示的位置
LCALL LCDP1
MOV A,L_HUN ;选择要显示的字符
CJNE A,#0,TT3
MOV A,#50H
TT3:
ADD A,#30H
MOV B,#3 ;设置要显示的位置
LCALL LCDP2
MOV A,L_TEN ;选择要显示的字符
ADD A,#30H
MOV B,#4 ;设置要显示的位置
LCALL LCDP2
MOV A,L_ONE ;选择要显示的字符
ADD A,#30H
MOV B,#5 ;设置要显示的位置
LCALL LCDP2
MOV A,H_HUN ;选择要显示的字符
CJNE A,#0,TT4
MOV A,#50H
TT4:
ADD A,#30H
MOV B,#15 ;设置要显示的位置
LCALL LCDP2
MOV A,H_TEN ;选择要显示的字符
ADD A,#30H
MOV B,#16 ;设置要显示的位置
LCALL LCDP2
MOV A,H_ONE ;选择要显示的字符
ADD A,#30H
MOV B,#17 ;设置要显示的位置
LCALL LCDP2
RET
;---------------------------------
;调读温度子程序
;---------------------------------
GETWENDU:
LCALL INIT_1820 ;调用复位DS18B20子程序
LCALL READ_S ;读出ds1820序列号应用程序
LCALL GET_TEMPER;调用读温度子程序
LCALL FORMULA ;通过公式计算,小数点后显示两位
LCALL BCD ;转换成十进制数
RET
;-------------------------
; DS18B20复位初始化程序
;-------------------------
INIT_1820:
CLR EA
SETB WDDATA
NOP
CLR WDDATA
;主机发出延时540微秒的复位低脉冲
MOV R1,#3
TSR1:
MOV R0,#100
DJNZ R0,$
DJNZ R1,TSR1
SETB WDDATA;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25h
TSR2:
JNB WDDATA,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR6
TSR5:
MOV R0,#117
DJNZ R0,$
;复位成功!时序要求延时一段时间
TSR6:
SETB WDDATA
SETB EA
RET
;-------------------
; 读出转换后的温度值
;-------------------
GET_TEMPER:
SETB WDDATA ; 定时入口
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 DELAY2 ;等待1S
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ; 跳过ROM匹配
; mov a,#55h
LCALL WRITE_1820
;mov r7,#8
;mov r1,#57h
;sss3:
;mov a,@r1
;LCALL WRITE_1820
;dec r1
;djnz r7,sss3
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_1820; 将读出的2个字节数据保存到37H-38H
RET
;|--------------------------------------
;| 读出ds1820序列号应用程序,DQ接ds1820
;|--------------------------------------
READ_S:
CLR EA ;使用ds1820一定要禁止任何中断产生
SETB WDDATA ; 定时入口
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,READS_1
RET ; 判断DS1820是否存在?若DS18B20不存在则返回
READS_1:
MOV A,#33H
LCALL WRITE_1820 ;送入读ds1820的ROM命令
MOV R1,#DATA_1 ;结果存入data_1以后的8个单元内
MOV R7,#9
LOOP_S:
LCALL READS_1820 ;开始读出当前ds1820序列号
MOV @R1,A
INC R1
DJNZ R7,LOOP_S
SETB EA
RET
/************************************/
READS_1820:
CLR EA
MOV R2,#8
RES01:
CLR C
SETB WDDATA
NOP
CLR WDDATA
NOP
SETB WDDATA
MOV R3,#4
RES10:
DJNZ R3,RES10
MOV C,WDDATA
MOV R3,#30
RES20:
DJNZ R3,RES20
RRC A
DJNZ R2,RES01
SETB WDDATA
SETB EA
RET
;----------------------------------
;写DS18B20的子程序(有具体的时序要求)
;----------------------------------
WRITE_1820:
CLR EA
MOV R2,#8 ;一共8位数据
CLR C
WR1:
CLR WDDATA
MOV R3,#6
DJNZ R3,$
RRC A
MOV WDDATA,C
MOV R3,#20
DJNZ R3,$
SETB WDDATA
NOP
DJNZ R2,WR1
SETB WDDATA
SETB EA
RET
;--------------------------------------------------
; 读DS18B20的程序,从DS18B20中读出2个字节的数据
;--------------------------------------------------
READ_1820:
CLR EA
MOV R4,#2
MOV R0,#TEMP1 ; 存入TEMP1开始的2个单元
RE00:
MOV R2,#8
RE01:
CLR C
SETB WDDATA
NOP
CLR WDDATA
NOP
SETB WDDATA
MOV R3,#4
RE10:
DJNZ R3,RE10
MOV C,WDDATA
MOV R3,#30
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R0,A
INC R0
DJNZ R4,RE00
SETB WDDATA
SETB EA
RET
;------------------------
;温度计算子程序
;------------------------
FORMULA: ;计算出实际温度,整数部分和小数部分分别存于ZHENGSHU单元和DOT单元
MOV 29H,28H
MOV A,27H
MOV C,29H.0
RRC A
MOV C,29H.1
RRC A
MOV C,29H.2
RRC A
MOV C,29H.3
RRC A
MOV ZHENGSHU,A
MOV A,27H
ANL A,#0FH
MOV DOT,A ;暂存一下
;注:这时的小数格式为0000.0000 D1D2D3D4 (二进制)
MOV A,ZHENGSHU
CJNE A,#80H,MM1 ;判断正负
MM1: JC ZHENG ;正数转ZHENG
;负数的情况
MOV DIS_0,#0H; 零度以下时,第一位显示"-"号
MOV A,ZHENGSHU
CPL A
MOV ZHENGSHU,A
CLR C
MOV A,DOT
SWAP A
CPL A
ADD A,#1
MOV DOT,A
MOV A,ZHENGSHU
ADDC A,#0
MOV ZHENGSHU,A
LJMP MM4
ZHENG:
MOV DIS_0,#1 ; 零度以上时,第一位不显示,表示"+"号
MOV A,DOT
ANL A,#0FH
SWAP A
MOV DOT,A
MM4:
;入口条件:待转换的单字节十六进制小数在累加器A中。
;影响资源:PSW、A、B 堆栈需求: 2字节
;注:这时的小数格式为0000.D1D2D3D4 0000
MOV A,DOT
SWAP A
MOV B,#100 ;原小数扩大一百倍
MUL AB
SWAP A
ANL A,#0FH
MOV CUN,A
MOV A,B
SWAP A
ORL A,CUN
MOV DOT,A ;将转化后的小数存入dot中
RET
;---------------------
;转换成非压缩的BCD码
;---------------------
BCD:
MOV A,ZHENGSHU
CJNE A,#100,BB1 ;百位存于HUN中
BB1:JC XX1
MOV HUN,#1
LJMP BB2
XX1:
MOV HUN,#0
BB2:
MOV A,ZHENGSHU
MOV B,#100
DIV AB
MOV A,B
MOV B,#10
DIV AB
MOV TEN,A
MOV ONE,B
MOV A,DOT
MOV B,#0AH
DIV AB
MOV POINT,A
MOV DIS_5,B
RET
/***************************************************/
LCDP1:
PUSH ACC
MOV A,B
ADD A,#80H
LCALL WCOM
POP ACC
LCALL WDATA
RET
LCDP2:
PUSH ACC
MOV A,B
ADD A,#0C0H
LCALL WCOM
POP ACC
LCALL WDATA
RET
SET_LCD:
mov 50h,#30h
mov 51h,#0b8h
mov 52h,#00h
mov 53h,#8eh
mov 54h,#0ffh
mov 55h,#0ffh
mov 56h,#0ffh
mov 57h,#0ffh
/*********************/
MOV S_FLAG,#00H
LCALL GETWENDU
MOV TEM,#45
MOV ALR_L,#10
MOV ALR_H,#180
CLR E
LCALL INIT_LCD
MOV R5,#50
LCALL DELAY
MOV DPTR,#TAB1
MOV A,#1
LCALL LCD_PRINT
MOV DPTR,#TAB2
MOV A,#2
LCALL LCD_PRINT
MOV R5,#200
LCALL DELAY
MOV DPTR,#TAB3
MOV A,#1
LCALL LCD_PRINT
MOV DPTR,#TAB4
MOV A,#2
LCALL LCD_PRINT
MOV R5,#180
LCALL DELAY
MOV DPTR,#TAB6
MOV A,#1
LCALL LCD_PRINT
MOV DPTR,#TAB7
MOV A,#2
LCALL LCD_PRINT
MOV A,#0DFH ;选择要显示的字符
MOV B,#9 ;设置要显示的位置
LCALL LCDP1
MOV A,#0DFH ;选择要显示的字符
MOV B,#18 ;设置要显示的位置
LCALL LCDP1
MOV A,#0DFH ;选择要显示的字符
MOV B,#6 ;设置要显示的位置
LCALL LCDP2
MOV A,#0DFH ;选择要显示的字符
MOV B,#18 ;设置要显示的位置
LCALL LCDP2
RET
LCD_PRINT:
CJNE A,#1,LINE2
LINE1:
MOV A,#80H
LCALL WCOM
LCALL CLR_LINE
MOV A,#80H
LCALL WCOM
LJMP FILL
LINE2:
MOV A,#0C0H
LCALL WCOM
LCALL CLR_LINE
MOV A,#0C0H
LCALL WCOM
FILL:
CLR A
MOVC A,@A+DPTR
CJNE A,#0,L1
RET
L1:
LCALL WDATA
INC DPTR
LJMP FILL
RET
CLR_LINE:
MOV R0,#40
C1:
MOV A,#' '
LCALL WDATA
DJNZ R0,C1
RET
INIT_LCD:
MOV P0,#3CH
LCALL EN1
LCALL EN1
LCALL EN1
MOV P0,#2CH ; 设置工作方式*
LCALL EN1
LCALL INIT_LCD1
RET
EN1:
SETB E
LCALL DE
CLR E
LCALL DE
RET
DE:
MOV R7,#5
DJNZ R7,$
RET
INIT_LCD1: ;4 bit init
MOV A,#2CH ;双列显示 ,5*7点阵
LCALL WCOM
MOV A,#0CH ;光标出现不闪烁
LCALL WCOM
MOV A,#06H ;
LCALL WCOM
MOV A,#01H ;清
LCALL WCOM
RET
WCOM:; 写指令代码子程序
MOV COM,A
ORL A,#0FH
MOV P0,A ; 写入指令代码高 4位
CLR RS
LCALL EN1
MOV A,COM
SWAP A
ORL A,#0FH
MOV P0,A ; 写入指令代码低 4位
CLR RS
LCALL EN1
RET
WDATA: ;写显示数据子程序
MOV DAT,A
ORL A,#0FH
MOV P0,A
SETB RS
LCALL EN1
MOV A,DAT
SWAP A
ORL A,#0FH
MOV P0,A
SETB RS
LCALL EN1
RET
DELAY:
MOV R6,#50
D1:
MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
DELAY2: MOV R5,#5 ;延时5ms
D2: MOV R6,#248
DJNZ R6,$
DJNZ R5,D2
RET
TAB1:
DB ' Welcome to use ',0 ;0表示光标不显示
TAB2:
DB "temperature CTRLLER ",0
TAB3:
DB ' AUTHOR ZHANG YADONG ',0
TAB4:
DB ' 1:SET,2:+,3:-,4:OK ' ,0
TAB5:
DB ' ',0
TAB6:
DB 'CT: . C RT: C',0
TAB7:
DB 'LT: C HT: C',0
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -