ME300實(shí)例-DS18B20溫度控制實(shí)驗(yàn)(匯編語(yǔ)言源程序)
程序說明:
DS18B20的管腳定義:
1、GND
2,、DQ
3,、VCC
DQ → P3.3
K1 → P1.4
K2 → P1.5
K3 → P1.6
K4 → P1.7
JP2 用跳線帽短接1和2,,選用LCD。
溫度顯示用四位,,當(dāng)溫度>=100度時(shí),第四位才顯示。
檢測(cè) DS18B20 狀態(tài):
DS18B20正常顯示:
DS18B20 OK
TEMP: 25.8℃ ← 顯示實(shí)際溫度
DS18B20不正常顯示:
DS18B20 ERROR
TEMP: ----℃ ← 顯示----
這時(shí)你要檢查DS18B20是否連接好,、接對(duì),否則要更換一個(gè)新的 DS18B20 芯片,。
一,、查看溫度報(bào)警值:
K1 → 進(jìn)入查看溫度報(bào)警值狀態(tài)。
LCD 1602 顯示:
LOOK ALERT CODE
TH:028℃ TL:18℃
TH:028 高位報(bào)警值
TL:18 低位報(bào)警值
K3 → 退出查看溫度報(bào)警值狀態(tài),。
二,、設(shè)定溫度報(bào)警值:
K2 → 進(jìn)入設(shè)定溫度報(bào)警值狀態(tài)。
LCD 1602 顯示:
RESET ALERT CODE
TH:028℃ TL:18℃
K1 : 設(shè)定值加(UP),、減(DOWN)方式選擇鍵(默認(rèn)為減少)
K2 : TH值設(shè)定鍵
K3 : TL值設(shè)定鍵
K4 : 確定鍵 (退出設(shè)定狀態(tài))
K2 或 K3 以減(DOWN)方式設(shè)定,,當(dāng)設(shè)定數(shù)值減到“0”時(shí)自動(dòng)轉(zhuǎn)換為加(UP)方式,。
K2 或 K3 以加(UP)方式設(shè)定,當(dāng)設(shè)定數(shù)值 TH=120,、TL=99 時(shí),,設(shè)定數(shù)值均變?yōu)椤?”。
K4 → 確定并退出設(shè)定溫度報(bào)警值狀態(tài),。
將設(shè)定的溫度報(bào)警值自動(dòng)存入 DS18B20 的 EEROM 中,,可永久保存。
每次開機(jī)時(shí)自動(dòng)從 DS18B20 的 EEROM 讀出溫度報(bào)警值,。
三,、報(bào)警狀態(tài)的顯示:
1、當(dāng)實(shí)際溫度大于 TH 的設(shè)定值時(shí),,
LCD1602 顯示:
DS18B20 OK
TEMP: 88.8℃ > H
關(guān)閉繼電器,,蜂鳴器響,表示超溫,。
2,、當(dāng)實(shí)際溫度小于 TL 的設(shè)定值時(shí),
LCD1602 顯示:
DS18B20 OK
TEMP: 18.8℃ < L
蜂鳴器響,,表示加熱部分出現(xiàn)故障,。
3、當(dāng)實(shí)際溫度小于 TH 的設(shè)定值時(shí),,繼電器吸合,,開始加熱。
加熱標(biāo)記為“!”
源程序(匯編語(yǔ)言)
;* 描述: *
;* DS18B20溫度控制1602LCD顯示 *
;* *
;* 使用方法參考readme.txt文檔 *
;* *
;* *
TEMP_ZH DATA 24H ;實(shí)時(shí)溫度值存放單元
TEMPL DATA 25H ;
TEMPH DATA 26H ;
TEMP_TH DATA 27H ;高溫報(bào)警值存放單元
TEMP_TL DATA 28H ;低溫報(bào)警值存放單元
TEMPHC DATA 29H ;
TEMPLC DATA 2AH
K1 EQU P1.4
K2 EQU P1.5
K3 EQU P1.6
K4 EQU P1.7
BEEP EQU P3.7
RELAY EQU P1.3
LCD_X EQU 2FH ;LCD 地址變量
LCD_RS EQU P2.0
LCD_RW EQU P2.1
LCD_EN EQU P2.2
flag1 equ 20H.0 ;DS18B20是否存在標(biāo)記
KEY_UD EQU 20H.1 ;設(shè)定 KEY 的UP與DOWN 標(biāo)記
date_line equ p3.3
;=====================================================
ORG 0000H
JMP MAIN
MAIN: MOV SP,#60H
MOV A,#00H
MOV R0,#20H ;將 20H-2FH 單元清零
MOV R1,#10H
CLEAR: MOV @R0,A
INC R0
DJNZ R1,CLEAR
CALL SET_LCD
CALL RE_18B20
start: CALL RESET ;18B20復(fù)位子程序
JNB FLAG1,START1 ;DS1820不存在
CALL MENU_OK
CALL READ_E2
CALL TEMP_BJ ;顯示溫度標(biāo)記
JMP START2
START1: CALL MENU_ERROR
CALL TEMP_BJ ;顯示溫度標(biāo)記
JMP $
START2:
CALL RESET
JNB FLAG1,START1 ;DS1820不存在
MOV A,#0CCH ; 跳過ROM匹配
CALL WRITE
MOV A,#44H ; 發(fā)出溫度轉(zhuǎn)換命令
CALL WRITE
CALL RESET
MOV A,#0CCH ; 跳過ROM匹配
CALL WRITE
MOV A,#0BEH ; 發(fā)出讀溫度命令
CALL WRITE
CALL READ
call CONVTEMP
Call DISPBCD
CALL CONV
CALL TEMP_COMP
CALL PROC_KEY ; 鍵掃描
SJMP START2
;-----------------------------------------------------
PROC_KEY:
JB K1,PROC_K1 ; 按鍵K1處理
CALL BEEP_BL
JNB K1,$
MOV DPTR,#M_ALAX1
MOV A,#1
CALL LCD_PRINT
CALL LOOK_ALARM
JB K3,$
CALL BEEP_BL
JMP PROC_K2
PROC_K1: ; 按鍵K2處理
JB K2,PROC_END
CALL BEEP_BL
JNB K2,$
MOV DPTR,#RESET_A1
MOV A,#1
CALL LCD_PRINT
CALL SET_ALARM
CALL RE_18B20 ;將設(shè)定的TH,TL值寫入DS18B20內(nèi)
CALL WRITE_E2
PROC_K2:
CALL MENU_OK
CALL TEMP_BJ
PROC_END:
RET
;============================================
;設(shè)定報(bào)警值 TH,、TL
;============================================
SET_ALARM:
;CALL RESET_ALARM
CALL LOOK_ALARM
AS0:
JB K1,AS00
CALL BEEP_BL
JNB K1,$
CPL 20H.1 ;UP/DOWN 標(biāo)記
AS00: JB 20H.1,ASZ01 ;20H.1=1,,UP
JMP ASJ01 ;20H.1=0,DOWN
ASZ01: JB K2,ASZ02 ;TH值調(diào)整(增加)
CALL BEEP_BL
INC TEMP_TH
MOV A,TEMP_TH
CJNE A,#120,ASZ011
MOV TEMP_TH,#0
ASZ011: CALL LOOK_ALARM
MOV R5,#10
CALL DELAY
JMP ASZ01
ASZ02: JB K3,ASZ03 ;TL值調(diào)整(增加)
CALL BEEP_BL
INC TEMP_TL
MOV A,TEMP_TL
CJNE A,#99,ASZ021
MOV TEMP_TL,#00H
ASZ021: CALL LOOK_ALARM ;
MOV R5,#10
CALL DELAY
JMP ASZ02
ASZ03: JB K4,AS0 ;確定調(diào)整 OK
CALL BEEP_BL
JNB K4,$
RET
ASJ01:
JB K2,ASJ02 ;TH值調(diào)整 (減少)
CALL BEEP_BL
DEC TEMP_TH
MOV A,TEMP_TH
CJNE A,#0FFH,ASJ011
JMP ASJ022
ASJ011: CALL LOOK_ALARM
MOV R5,#10
CALL DELAY
JMP AS0
ASJ02: JB K3,ASJ03 ;TL值調(diào)整(減少)
CALL BEEP_BL
DEC TEMP_TL
MOV A,TEMP_TL
CJNE A,#0FFH,ASJ021
JMP ASJ022
ASJ021: CALL LOOK_ALARM ;
MOV R5,#10
CALL DELAY
JMP AS0
ASJ022: CPL 20H.1
JMP ASZ01
ASJ03: JMP ASZ03
RET
RESET_ALARM:
MOV DPTR,#RESET_A1 ;指針指到顯示信息區(qū)
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
RET
RESET_A1:
DB "RESET ALERT CODE"
;====================================================
;實(shí)際溫度值與標(biāo)記溫度值比較子程序
;====================================================
TEMP_COMP:
MOV A,TEMP_TH
SUBB A,TEMP_ZH ;減數(shù)>被減數(shù),,則
JC CHULI1 ;借位標(biāo)志位C=1,,轉(zhuǎn)
MOV A,TEMP_ZH
SUBB A,TEMP_TL ;減數(shù)>被減數(shù),則
JC CHULI2 ;借位標(biāo)志位C=1,,轉(zhuǎn)
MOV DPTR,#BJ5
CALL TEMP_BJ3
CLR RELAY ;繼電器吸合
RET
CHULI1:
MOV DPTR,#BJ3
CALL TEMP_BJ3
SETB RELAY ;繼電器關(guān)閉
CALL BEEP_BL
RET
CHULI2:
MOV DPTR,#BJ4
CALL TEMP_BJ3
CALL BEEP_BL
RET
;-----------------------------------------
TEMP_BJ3:
MOV A,#0CEH
CALL WCOM
MOV R1,#0
MOV R0,#2
BBJJ3: MOV A,R1
MOVC A,@A+DPTR
CALL WDATA
INC R1
DJNZ R0,BBJJ3
RET
BJ3:
DB ">H"
BJ4:
DB "<L"
BJ5:
DB " !"
;==================================================
;顯示溫度標(biāo)記子程序
;==================================================
TEMP_BJ:
MOV A,#0CBH
CALL WCOM
MOV DPTR,#BJ1 ;指針指到顯示消息
MOV R1,#0
MOV R0,#2
BBJJ1: MOV A,R1
MOVC A,@A+DPTR
CALL WDATA
INC R1
DJNZ R0,BBJJ1
RET
BJ1:
DB 00H,"C"
;=================================================
MENU_OK:
MOV DPTR,#M_OK1 ;指針指到顯示消息
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK2 ;指針指到顯示消息
MOV A,#2 ;顯示在第一行
CALL LCD_PRINT
RET
M_OK1:
DB " DS18B20 OK ",0
M_OK2:
DB " TEMP: ",0
;-----------------------------------------------
MENU_ERROR:
MOV DPTR,#M_ERROR1 ;指針指到顯示消息1
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_ERROR2 ;指針指到顯示消息1
MOV A,#2 ;顯示在第一行
CALL LCD_PRINT
RET
M_ERROR1:
DB " DS18B20 ERROR ",0
M_ERROR2:
DB " TEMP: ---- ",0
;====================================================
reset: setb date_line
nop
clr date_line
mov r0,#6bh ;主機(jī)發(fā)出延時(shí)復(fù)位低脈沖
mov r1,#04h
tsr1: djnz r0,$
mov r0,#6bh
djnz r1,tsr1
setb date_line ;然后拉高數(shù)據(jù)線
nop
nop
nop
mov r0,#32h
tsr2: jnb date_line,tsr3 ;等待DS18B20回應(yīng)
djnz r0,tsr2
jmp tsr4 ; 延時(shí)
tsr3: setb flag1 ; 置標(biāo)志位,表示DS1820存在
jmp tsr5
tsr4: clr flag1 ; 清標(biāo)志位,表示DS1820不存在
jmp tsr7
tsr5: mov r0,#06bh
tsr6: djnz r0,$ ; 時(shí)序要求延時(shí)一段時(shí)間
tsr7: setb date_line
ret
;=======================================================
RE_18B20:
JB FLAG1,RE_18B20A
RET
RE_18B20A:
CALL RESET
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE
MOV A,#4EH ;寫暫存寄存器
LCALL WRITE
MOV A,TEMP_TH ;TH(報(bào)警上限)
LCALL WRITE
MOV A,TEMP_TL ;TL(報(bào)警下限)
LCALL WRITE
MOV A,#7FH ;12位精確度
LCALL WRITE
RET
;------------------------------------------------------------
WRITE_E2:
CALL RESET
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE
MOV A,#48H ;把暫存器里的溫度報(bào)警值拷貝到EEROM
LCALL WRITE
RET
;--------------------------------------------------------------
READ_E2:
CALL RESET
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE
MOV A,#0B8H ;把EEROM里的溫度報(bào)警值拷貝回暫存器
CALL WRITE
RET
;--------------------------------------------------------------
;將自定義字符寫入LCD1602的CGRAM中
;--------------------------------------------------------------
STORE_DATA:
MOV A,#40H
CALL WCOM
MOV R2,#08H
MOV DPTR,#D_DATA
MOV R3,#00H
S_DATA:
MOV A,R3
MOVC A,@A+DPTR
CALL WDATA ;寫入數(shù)據(jù)
INC R3
DJNZ R2,S_DATA
RET
D_DATA:
DB 0CH,12H,12H,0CH,00H,00H,00H,00H
;====================================================
write: mov r2,#8 ;一共8位數(shù)據(jù)
CLR C
wr1:
clr date_line ;開始寫入DS18B20總線要處于復(fù)位(低)狀態(tài)
mov r3,#07
djnz r3,$ ;總線復(fù)位保持16微妙以上
rrc a ;把一個(gè)字節(jié)DATA 分成8個(gè)BIT環(huán)移給C
mov date_line,c ;寫入一個(gè)BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
setb date_line ;重新釋放總線
nop
djnz r2,wr1 ;寫入下一個(gè)BIT
setb date_line
ret
;--------------------------------------------------------------------
read: mov r4,#4 ; 將溫度低位,、高位、TH,、TL從DS18B20中讀出
mov r1,#TEMPL ; 存入25H、26H,、27H,、28H
re00: mov r2,#8
re01: clr cy
setb date_line
nop
nop
clr date_line ;讀前總線保持為低
nop
nop
nop
setb date_line ;開始讀總線釋放
mov r3,#09 ;延時(shí)18微妙
djnz r3,$
mov c,date_line ;從DS18B20總線讀得一個(gè)BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
rrc a ;把讀得的位值環(huán)移給A
djnz r2,re01 ;讀下一個(gè)BIT
mov @r1,a
inc r1
djnz r4,re00
ret
;*****************************************************
; 處理溫度 BCD 碼子程序
;****************************************************
CONVTEMP: MOV A,TEMPH ;判溫度是否零下
ANL A,#80H
JZ TEMPC1 ;溫度零上轉(zhuǎn)
CLR C
MOV A,TEMPL ;二進(jìn)制數(shù)求補(bǔ)(雙字節(jié))
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
SJMP TEMPC11
TEMPC1: MOV TEMPHC,#0AH ;+
TEMPC11: MOV A,TEMPHC
SWAP A
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH ;乘0.0625
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR
MOV TEMPLC,A ;TEMPLC LOW=小數(shù)部分 BCD
MOV A,TEMPL ;整數(shù)部分
ANL A,#0F0H ;取出高四位
SWAP A
MOV TEMPL,A
MOV A,TEMPH ;取出低四位
ANL A,#0FH
SWAP A
ORL A,TEMPL ;重新組合
MOV TEMP_ZH,A
LCALL HEX2BCD1
MOV TEMPL,A
ANL A,#0F0H
SWAP A
ORL A,TEMPHC ;TEMPHC LOW = 十位數(shù) BCD
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH
SWAP A ;TEMPLC HI = 個(gè)位數(shù) BCD
ORL A,TEMPLC
MOV TEMPLC,A
MOV A,R4
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R4,A
MOV A,TEMPHC ;TEMPHC HI = 百位數(shù) BCD
ANL A,#0FH
ORL A,R4
MOV TEMPHC,A
TEMPC12: RET
;---------------------------------------------------------------
HEX2BCD1:
MOV B,#064H ;十六進(jìn)制-> BCD
DIV AB ;B= A % 100
MOV R4,A ;R7 = 百位數(shù)
MOV A,#0AH
XCH A,B
DIV AB ;B = A % B
SWAP A
ORL A,B
RET
;-------------------------------------------------------------
; 小數(shù)部分碼表
;-------------------------------------------------------------
TEMPDOTTAB:
DB 00H,00H,01H,01H,02H,03H,03H,04H
DB 05H,05H,06H,06H,07H,08H,08H,09H
;=====================================================
LOOK_ALARM:
MOV DPTR,#M_ALAX2 ;指針指到顯示信息區(qū)
MOV A,#2 ;顯示在第二行
CALL LCD_PRINT
MOV A,#0C6H
CALL TEMP_BJ1
MOV A,TEMP_TH ;加載TH數(shù)據(jù)
MOV LCD_X,#3 ;設(shè)置位置
CALL SHOW_DIG2H ;顯示數(shù)據(jù)
MOV A,#0CEH
CALL TEMP_BJ1
MOV A,TEMP_TL ;加載TL數(shù)據(jù)
MOV LCD_X,#12 ;設(shè)置位置
CALL SHOW_DIG2L ;顯示數(shù)據(jù)
RET
;--------------------------------------------
M_ALAX1:
DB " LOOK ALERT CODE",0
M_ALAX2:
DB "TH: TL: ",0
;--------------------------------------------
TEMP_BJ1:
CALL WCOM
MOV DPTR,#BJ2 ;指針指到顯示信息區(qū)
MOV R1,#0
MOV R0,#2
BBJJ2: MOV A,R1
MOVC A,@A+DPTR
CALL WDATA
INC R1
DJNZ R0,BBJJ2
RET
BJ2:
DB 00H,"C"
;---------------------------------------------------
SHOW_DIG2H: ;在 LCD 的第二行顯示數(shù)字
MOV B,#100
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
MOV A,#0AH
XCH A,B
DIV AB
ADD A,#30H
INC LCD_X
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
CALL LCDP2
RET
SHOW_DIG2L: ;在 LCD 的第二行顯示數(shù)字
MOV B,#100
DIV AB
MOV A,#0AH
XCH A,B
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
CALL LCDP2
RET
;-------------------------------------------------------------
;顯示區(qū) BCD 碼溫度值刷新子程序
;-------------------------------------------------------------
DISPBCD:
MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小數(shù)位
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV 71H,A ;個(gè)位
MOV A,TEMPHC
ANL A,#0FH
MOV 72H,A ;十位
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,A ;百位
MOV A,TEMPHC
ANL A,#0F0H
CJNE A,#010H,DISPBCD0
SJMP DISPBCD2
DISPBCD0: MOV A,TEMPHC
ANL A,#0FH
JNZ DISPBCD2 ;十位數(shù)是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符號(hào)位不顯示
MOV 72H,A ;十位數(shù)顯示符號(hào)
DISPBCD2: RET
;==========================================================
; LCD 1602 顯示子程序
;==========================================================
CONV:
MOV A,73H ;加載百位數(shù)據(jù)
MOV LCD_X,#6 ;設(shè)置位置
CJNE A,#1,CONV1
JMP CONV2
CONV1: MOV A,#" "
MOV B,LCD_X
CALL LCDP2
JMP CONV3
CONV2: CALL SHOW_DIG2 ;顯示數(shù)據(jù)
CONV3: INC LCD_X ;
mov a,72h ;十位
CALL SHOW_DIG2
inc LCD_X
mov a,71h ;個(gè)位
CALL SHOW_DIG2
inc LCD_X
MOV A,#'.'
MOV B,LCD_X
CALL LCDP2
MOV A,70h ;加載小數(shù)點(diǎn)位
INC LCD_X ;設(shè)置位置
CALL SHOW_DIG2 ;顯示數(shù)據(jù)
RET
;-------------------------------------------------------
SHOW_DIG2: ;在 LCD 的第二行顯示數(shù)字
ADD A,#30H
MOV B,LCD_X
CALL LCDP2
RET
;---------------------------------------------------------
LCDP2: ;在LCD的第二行顯示字符
PUSH ACC ;
MOV A,B ;設(shè)置顯示地址
ADD A,#0C0H ;設(shè)置LCD的第二行地址
CALL WCOM ;寫入命令
POP ACC ;由堆棧取出A
CALL WDATA ;寫入數(shù)據(jù)
RET
;---------------------------------------------------------
SET_LCD: ;對(duì) LCD 做初始化設(shè)置及測(cè)試
CLR LCD_EN
CALL INIT_LCD ;初始化 LCD
CALL STORE_DATA ;將自定義字符存入LCD的CGRAM
RET
INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H ;雙列顯示,字形5*7點(diǎn)陣
CALL WCOM
call delay1
MOV A,#38H
CALL WCOM
call delay1
MOV A,#38H
CALL WCOM
call delay1
MOV A,#0CH ;開顯示,,顯示光標(biāo),,光標(biāo)不閃爍
CALL WCOM
call delay1
MOV A,#01H ;清除 LCD 顯示屏
CALL WCOM
call delay1
RET
;==================================================
CLR_LINE1: ;清除LCD的第一行字符
MOV A,#80H ;設(shè)置 LCD 的第一行地址
CALL WCOM ;
MOV R0,#24 ;設(shè)置計(jì)數(shù)值
C1: MOV A,#' ' ;載入空格符至LCD
CALL WDATA ;輸出字符至LCD
DJNZ R0,C1 ;計(jì)數(shù)結(jié)束
RET
;==================================================
LCD_PRINT: ;在LCD的第一行或第二行顯示字符
CJNE A,#1,LINE2 ;判斷是否為第一行
LINE1: MOV A,#80H ;設(shè)置 LCD 的第一行地址
CALL WCOM ;寫入命令
CALL CLR_LINE ;清除該行字符數(shù)據(jù)
MOV A,#80H ;設(shè)置 LCD 的第一行地址
CALL WCOM ;寫入命令
JMP FILL
LINE2: MOV A,#0C0H ;設(shè)置 LCD 的第二行地址