TEMP_ZH EQU 24H ;實測溫度值存放單元
TEMPL EQU 25H
TEMPH EQU 26H
TEMP_TH EQU 27H ;高溫報警值存放單元
TEMP_TL EQU 28H ;低溫報警值存放單元
TEMPHC EQU 29H ;正、負溫度值標記
TEMPLC EQU 2AH
TEMPFC EQU 2BH
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寄存器選擇信號
LCD_RW EQU P2.1 ;LCD讀/寫信號
LCD_EN EQU P2.2 ;LCD 允許信號
FLAG1 EQU 20H.0 ;DS18B20是否存在標志
KEY_UD EQU 20H.1 ;設定按鍵的增、減標志
DQ EQU P3.3 ;DS18B20數據信號
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:MOV SP, #60H
MOV A, #00H
MOV R0, #20H ;將20H~2FH單元清零
MOV R1,#10H
CLEAR:MOV @R0,A
INC R0
DJNZ R1,CLEAR
LCALL SET_LCD ;調用LCD初始化,測試子程序
LCALL RE_18B20
START:LCALL RST
JNB FLAG1,START1 ;DS1820不存在
LCALL MENU_OK ;DS1820存在,調用顯示正確信息子程序
MOV TEMP_TH, #055H ;設置TH初值85度
MOV TEMP_TL, #019H ;設置TL初值25度
LCALL RE_18B20A ;調用暫存器操作子程序
LCALL WRITE_E2 ;寫入DS18B20
LCALL TEMP_BJ ;顯示溫度標記
JMP START2
START1:LCALL MENU_ERROR ;調用顯示出錯信息子程序
LCALL TEMP_BJ ;顯示溫度標記
SJMP $
START2:LCALL RST ;調用DS18B20復位子程序
JNB FLAG1,START1 ;DS18B20不存在
MOV A,#0CCH ;跳過ROM匹配命令
LCALL WRITE
MOV A,#44H ;溫度轉換命令
LCAll WRITE
LCALL RST
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE
MOV A,#0BEH ;讀溫度命令
LCALL WRITE
LCAlL READ ;調用DS18B20數據讀取操作子程序
LCAll CONVTEMP ;調用溫度數據BCD碼處理子程序
LCALL DISPBCD ;調用溫度數據顯示子程序
LCALL CONV ;調用LCD顯示處理子程序
LCALL TEMP_COMP ;調用實測溫度值與設定溫度值比較子程序
LCALL PROC_KEY ;調用鍵掃描子程序
SJMP START2 ;循環
; *******鍵掃描子程序
PROC_KEY:JB K1,PROC_K1
LCALL BEEP_BL;
JNB K1,$
MOV DPTR,#M_ALAX1
MOV A,#1
LCALL LCD_PRINT
LCALL LOOK_ALARM
JB K3,$
LCALL BEEP_BL
JMP PROC_K2
PROC_K1: JB K2,PROC_END
LCALL BEEP_BL
JNB K2,$
MOV DPTR,#RST_Al
MOV A,#1
LCALL LCD_PRINT
LCALL SET_ALARM
LCALL RE_18B20 ;將設定的TH, tl值寫入D18B20
LCALL WRITE_E2
PROC_K2:LCALL MENU_OK
LCALL TEMP_BJ
PROC_END:RET
;**********************************************設定溫度報警值TH,TL
SET_ALARM:LCALL LOOK_ALARM
AS0:JB K1,AS00
LCALL BEEP_BL
JNB K1,$
CPL 20H.1 ;UP/DOWN標記
AS00:JB 20H.1,ASZ01 ;20H.1=1,增加
JMP ASJ01 ;20H.1=0,減小
ASZ01:
JB K2,ASZ02 ;TH值調整(增加)
LCALL BEEP_BL
INC TEMP_TH
MOV A,TEMP_TH
CJNE A,#120,ASZ011
MOV TEMP_TH,#0
ASZ011:LCALL LOOK_ALARM
MOV R5,#10
LCALL DELAY
JMP ASZ01
ASZ02:JB K3,ASZ03 ;TL值調整(增加)
LCALL BEEP_BL
INC TEMP_TL
MOV A,TEMP_TL
CJNE A,#99,ASZ021
MOV TEMP_TL,#00H
ASZ021:LCAlL LOOK_ALARM
MOV R5,#10
LCALL DELAY
JMP ASZ02
ASZ03:JB K4,AS0 ;確定調整
LCALL BEEP_BL
JNB K4,$
RET
ASJ01:JB K2,ASJ02 ;TH值調整(減少)
LCALL BEEP_BL
DEC TEMP_TH
MOV A,TEMP_TH
CJNE A,#0FH,ASJ011
JMP ASJ022
ASJ011: LCALL LOOK_ALARM
MOV R5,#10
LCAll DELAY
JMP AS0
ASJ02:JB K3,ASJ03
LCALL BEEP_BL ;TL值調整(減少)
DEC TEMP_TL
MOV A,TEMP_TL
CJNE A,#0FFH,ASJ021
JMP ASJ022
ASJ021: LCALL LOOK_ALARM
MOV R5,#10
LCALL DELAY
JMP AS0
ASJ022: CPL 20H.1
JMP ASZ01
ASJ03:JMP ASZ03
RET
RST_Al:DB "SET ALERT CODE ",0
;**********************************************實測溫度值與設定溫度值比較子程序********.*
TEMP_COMP:MOV A,TEMP_TH
SUBB A,TEMP_ZH ;減數>被減數
JC CHULI1 ;借位標志位C=1,跳轉
MOV A,TEMPFC
CJNE A,#0BH,COMP
SJMP CHULI2
COMP: MOV A, TEMP_ZH
SUBB A, TEMP_TL ;減數>被減數
JC CHULI2 ;借位標志位C=1,跳轉
MOV DPTR,#BJ5
LCALL TEMP_BJ3
CLR RELAY ;點亮指示燈
RET
CHULI1: MOV DPTR,#BJ3
LCALL TEMP_BJ3
SETB RELAY ;熄滅指示燈
LCALL BEEP_BL ;蜂鳴器響
RET
CHULI2: MOV DPTR,#BJ4
LCAlL TEMP_BJ3
SETB RELAY ;熄滅指示燈
LCALL BEEP_BL ;蜂鳴器響
RET
;**********************************************
TEMP_BJ3: MOV A,#0CEH
LCALL WCOM
MOV R1,#0
MOV R0,#2
BBJJ3:
MOV A, R1
MOVC A,@A+DPTR
LCALL WDATA
INC R1
DJNZ R0,BBJJ3
RET
BJ3:DB ">H"
BJ4:DB "<L"
BJ5:DB "!"
;**********************************************p308顯示溫度標記子程序
TEMP_BJ: MOV A,#0CBH
LCALL WCOM
MOV DPTR,#BJ1 ;指針指到顯示消息
MOV R1,#0
MOV R0,#2
BBJJ1:MOV A,R1
MOVC A,@A+DPTR
LCALL WDATA
INC R1
DJNZ R0,BBJJ1
RET
BJ1:DB 00H,"C"
;**********************************************顯示正確信息子程序
MENU_OK:MOV DPTR,#M_OK1 ;指針指到顯示消息
MOV A,#1 ;顯示在第一行
LCALL LCD_PRINT
MOV DPTR, #M_OK2 ;指針指到顯示消息
MOV A,#2 ;顯示在第一~行
LCAlL LCD_PRINT
RET
M_OK1:DB "DS18B20 OK",0
M_OK2:DB "TEMP: ",0
;**********************************************顯示出錯信息子程序
MENU_ERROR:MOV DPTR,#M_ERROR1;指針指到顯示消息
MOV A,#1 ;顯示在第一行
LCALL LCD_PRINT
MOV DPTR, #M_OK2 ;指針指到顯示消息
MOV A,#2 ;顯示在第一行
LCAlL LCD_PRINT
RET
M_ERROR1:DB "DS18B20 ERROR",0
M_ERROR2:DB "TEMP:---- ",0
;**********************************************DS18B20復位子程序
RST: SETB DQ
NOP
CLR DQ
MOV R0,#6BH ;主機發出延時復位低脈沖
MOV R1,#04H
TSR1:DJNZ R0,$
MOV R0,#6BH
DJNZ R1,TSR1
SETB DQ ;拉高數據線
NOP
NOP
NOP
MOV R0,#32H
TSR2:
JNB DQ,TSR3 ;停待DS18B20回應
DJNZ R0,TSR2
JMP TSR4 ;延時
TSR3:SETB FLAG1 ;置1標志位,表示DS1820存在
JMP TSR5;
TSR4:CLR FLAG1 ;清0標志位,表示DS1820不存在
JMP TSR7
TSR5:MOV R0,#06BH
TSR6:DJNZ R0,$ ;時序要求延時一段時間
TSR7:SETB DQ
RET
;**********************************************DS18B20暫存器操作子程序
RE_18B20:JB FLAG1,RE_18B20A
RET
RE_18B20A:LCAlL RST
MOV A, #0CCH ;跳過ROM匹配
LCALL WRITE
WR_SCRAPD:
MOV A, #4EH ;寫暫存器
LCALL WRITE
MOV A, TEMP_TH ;TH (報警上限)
LCALL WRITE
MOV A, TEMP_TL ;TL (報警下限)
LCAlL WRITE
MOV A,#7FH ;12位精度
LCALL WRITE
RET
;**********************************************復制暫存器子程序
WRITE_E2:LCALL RST
MOV A, #0CCH ;跳過ROM匹配
LCALL WRITE
MOV A, #48H ;把暫存器里的溫度報警值復制到EROI
LCALL WRITE
RET
;**********************************************重讀BEROM子程序
READ_E2:LCALL RST
MOV A, #0CCH ;跳過ROM匹配
LCALL WRITE
MOV A, #0B8H ;把BBROM里的溫度報警值復制回暫
LCALL WRITE
RET
;**********************************************將自定義字符寫入LCD的CGRAM中
STORE_DATA:
MOV A,#40H
LCALL WCOM
MOV R2,#08H
MOV DPTR,#D_DATA
MOV R3,#00H
S_DATA:MOV A,R3
MOVC A,@A+DPTR
LCALL WDATA ;寫入數據
INC R3
DJNZ R2,S_DATA
RET
D_DATA: DB 0CH,12H,12H,0CH,00H,00H,00H,00H
;**********************************************DS18B20數據寫入操作子程序
WRITE: MOV R2,#8 ;一共8位數據
CLR C
WR1:CLR DQ ;開始寫入D18B20總線要處于復位(低)狀態
MOV R3,#07
DJNZ R3,$ ;總線復位保持16uS以上
RRC A ;把一個字節DATA分成8個BIT環移給C
MOV DQ,C ;寫入一位
MOV R3,#3CH
DJNZ R3,$ ;等待100us
SETB DQ ;重新釋放總線
NOP
DJNZ R2,WR1 ;寫入下一位
SETB DQ
RET
;**********************************************DS18B20數據讀取操作子程序
READ:MOV R4,#4 ;將溫度低位、高位、TH、 TL從DS18B20中讀
MOV R1,#TEMPL ;存入 25H、 26H、27H、28H單元
RE00:MOV R2,#8
RE01:CLR CY
SETB DQ
NOP
NOP
CLR DQ ;讀前總線保持為低
NOP
NOP
NOP
SETB DQ ;開始讀總線釋放
MOV R3,#09 ;延時18us
DJNZ R3,$
MOV C,DQ
MOV R3,#3CH ;從DS18B20總線讀得一位
DJNZ R3,$ ;等待100us
RRC A ;把讀得的位值環移給A
DJNZ R2,RE01 ;讀下一位
MOV @R1,A
DJNZ R4,RE00
RET
;;**********************************************溫度值BCD碼處理子程序
CONVTEMP:MOV A,TEMPH ;判溫度是否零下
ANL A,#08H
JZ TEMPC1 ;溫度為零上則跳轉
CLR C
MOV A,TEMPL ;二進制數求補(雙字節)
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
MOV TEMPHC,#0BH ;負溫度標志
MOV TEMPFC,#0BH
SJMP TEMPC11
TEMPC1: MOV TEMPHC,#0AH;正溫度標志
MOV TEMPFC,#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 ;TEMPLC Low=小數部分BCD
MOV TEMPLC,A
MOV A,TEMPL ;整數部分
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 ;TEMP HC LOW-十位數BCD
MOV TEMPHC,A
MOV A, TEMPL
ANL A,#0FH
SWAP A ;TEMPLC HI=個位數BCD
ORL A, TEMPLC
MOV TEMPLC,A
MOV A,R4
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R4,A;TEMPHC HI
MOV A, TEMPHC ;TEMPHC HI=百位數BCD
ANL A,#0FH
ORL A,R4
MOV TEMPHC,A
TEMPC12:RET
;**********************************************二-十迸制轉換子程序
HEX2BCD1 :MOV B, #064H
DIV AB
MOV R4,A
MoV A,#0AH
XCH A,B
DIV AB
SWAP A
ORL A,B
RET
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;指針指到昆示信息區
MOV A,#2 ;濕示在第二行
LCALL LCD_PRINT
MOV A, #0C6H
LCALL TEMP_BJ1
MOV A,TEMP_TH ;加載TH數據
Mov LCD_X,#3 ;沒置晁示位置
LCALL SHOW_DIG2H ;晁示數據
MOV A, #0CEH
LCALL TEMP_BJ1
MOV A,TEMP_TL ;加載TL數據
MoV LCD_X,#12 ;沒置晁示位置
LCALL SHOW_DIG2L ;濕示數據
RET
M_ALAX1:DB "L00K ALERT CODE",0
M_ALAX2:DB "TH: TL: ",0
TEMP_BJ1:LCALL WCOM
MOV DPTR, #BJ2 ;指針指到顯示信息區
MOV R1,#0
MOV R0,#2
BBJJ2: MOV A,R1
MOVC A, @A+DPTR
LCALL WDATA
INC R1
DJNZ R0, BBJJ2
RET
BJ2:DB 00H,"C"
;**********************************************LCD顯示子程序
SHOW_DIG2H:MOV B,#100
DIV AB
ADD A, #30H
PUSH B
MOV B,LCD_X
LCALL LCDP2
POP B
MOV A, #0AH
XCH A,B
DIV AB
ADD A,#30H
INC LCD_X
PUSH B
MOV B,LCD_X
LCALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
LCALL LCDP2
RET
SHOW_DIG2L:
MOV B,#100
DIV AB
MOV A,#0AH
XCH A,B
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
LCALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
LCALL LCDP2
RET
;**********************************************顯示區BCD碼溫度值刷新子程序
DISPBCD:MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小數位
MOV A,TEMPLC
SWAP A
ANL A, #0FH
MOV 71H,A ;個位
MOV A, TEMPHC
ANL A, #0FH
MOV 72H,A ;十位
MOV A, TEMPHC
SWAP A
ANL A, #0FH
MOV 73H,A ;百位
DISPBCD2 :RET
;**********************************************LCD顯示數據處理子程序***
CONV: MOV A,73H ;加載百位數據
MOV LCD_X,#6 ;設置位置
CJNE A,#1,CONV1
JMP CONV2
CONV1: CJNE A, #0BH, CONV11
MOV A,#"-" ;“_”號顯示
JMP CONV111
CONV11: MOV A,#" " ;“+”號不顯示
CONV111 :MOV B,LCD_X
LCALL LCDP2
JMP CONV3
CONV2: LCALL SHOW_DIG2 ;顯示數據
CONV3:INC LCD_X
MOV A, 72H
LCALL SHOW_DIG2
INC LCD_X
MOV A,71H;個位
LCALL SHOW_DIG2
INC LCD_X
MOV A,#'.'
MOV B,LCD_X
LCALL LCDP2
MOV A, 70H ;加載小數點位
INC LCD_X ;設置顯示位置
LCALL SHOW_DIG2 ;顯示數據
RET
;**********************************************第二行顯示數字子程序
SHOW_DIG2:ADD A,#30H
MOV B,LCD_X
LCALL LCDP2
RET
;**********************************************第二行顯示數字子程序**
LCDP2: PUSH ACC
MOV A,B ;設置顯示地址
ADD A, #0C0H ;設置LCD的第二行地址
LCAlL WCOM ;寫入命令
POP ACC ;由堆棧取出A
LCAlL WDATA ;寫入數據
RET
;**********************************************對LCD初始化設置及測試
SET_LCD:CLR LCD_EN
LCALL INIT_LCD ;初始化LCD
lCAll STORE_DATA ;將自定義字符存入LCD的CGRAM
RET
;**********************************************LCD初始化
INIT_LCD: MOV A, #38H ;2行顯示,字形5*7點陣
LCALL WCOM
LCALL DELAY1
MOV A,#38H
LCAll WCOM
LCALL DELAY1
MOV A, #38H
LCALL WCOM
LCALL DELAY1
MOV A, #0CH ;開顯示,顯示光標,光標不閃爍
LCAlL WCOM
LCALL DELAY1
MOV A,#01H ;清除LCD顯示屏
LCALL WCOM
LCALL DELAY1
RET
;**********************************************清除LCD的第一行字符
CLR_LINE1 :MOV A,#80H ;設置LCD的第一行地址
LCALL WCOM
MOV R0,#24 ;設置計數值
C1: MOV A,#' ' ;載入空格符至LCD
LCALL WDATA ;輸出字符至LCD
DJNZ R0,C1 ;計數結束
RET
;**********************************************LCD的第一行或第二行顯示一行
LCD_PRINT:CJNE A,#1,LINE2;判斷是否為第一行
LINE1 : MOV A, #80H ;設置LCD的第一行地址
LCALL WCOM ;寫入命令
LCALL CLR_LINE ;清除該行字符數據
MOV A, #80H ;設置LCD的第一行地址
LCALL WCOM ;寫入命令
JMP FILL
LINE2:MOV A, #0C0H ;設置LCD的第二行地址
LCALL WCOM ;寫入命令
lCAll CLR_LINE ;清除該行字符數據
MOV A, #0C0H ;設置LCD的第二行地址
LCALL WCOM
FILL: CLR A ;填入字符
MOVC A, @A+DPTR ;由消息區取出字符
CJNE A,#0,LC1 ;判斷是否為結束碼
RET
LC1: LCAlL WDATA ;寫入數據
INC DPTR ;指針加1
JMP FILL ;繼續填入字符
RET
;********************************************** 清除1行LCD的字符
CLR_LINE:MOV R0,#24
CL1:MOV A,#' '
LCALL WDATA
DJNZ R0,CL1
RET
DE:
MOV R7,#250
DJNZ R7,$
RET
;**********************************************LCD間接控制方式命令寫入
WCOM:MOV P0,A ;寫入命令
CLR LCD_RS ;RS=L,RW=L,D0-D7=指令碼,E=高脈沖
CLR LCD_RW
SETB LCD_EN
LCALL DELAY1
CLR LCD_EN
RET
;**********************************************LCD間接控制方式數據寫入
WDATA:MOV P0,A ;寫入數據
SETB LCD_RS
CLR LCD_RW
SETB LCD_EN
LCALL DE
CLR LCD_EN
LCALL DE
RET
;**********************************************在LCD的第一行顯示字符
LCDP1: PUSH ACC
MOV A,B ;設置顯示地址
ADD A,#80H ;設置LCD的第一行地址
LCALL WCOM ;寫入命令
POP ACC ;由堆棧取出A
LCALL WDATA ;寫入數據
RET
;**********************************************聲光報警子程序*********
BEEP_BL:MOV R6,#100
BL2:LCALL DEX1
CPL BEEP
CPL RELAY
DJNZ R6,BL2
MOV R5, #10
LCALL DELAY
RET
DEX1 : MOV R7, #180
DE2:NOP
DJNZ R7,DE2
RET
;**********************************************延時子程序
DELAY: MOV R6,#50
DL1:MOV R7,#100
DJNZ R7,$
DJNZ R6, DL1
DJNZ R5,DELAY
RET
DELAY1: MOV R6,#25;延時5ms
DL2:MOV R7,#100
DJNZ R7,$
DJNZ R6, DL2
RET
END
|