;================定義字符===============================
RS BIT P2.6 ;RS=P2.6
RW BIT P2.5 ;RW=P2.5
E BIT P2.7 ;E=P2.7
DATALINE EQU P3.7 ;定義引腳
FLAG1 EQU 20H.0 ;20H單元可位尋址區(qū)
KEY1 BIT P3.0
KEY2 BIT P3.1
KEY3 BIT P3.2
KEY4 BIT P3.3
Y EQU 60H ;定義運行與否Y存儲單元
M EQU 61H ;定義模式M存儲單元
S EQU 62H ;定義風速S存儲單元
L EQU 63H ;定義類型L存儲單元
DDJ BIT P1.0 ;DDJ=P1.0
;====================主程序========================
ORG 0000H
AJMP MAIN
ORG 000BH ;T0中斷入口
LJMP TIME0
ORG 001BH
LJMP TIME1 ;T1中斷入口
ORG 0030H
MAIN: CLR A
MOV B,#00H
MOV 25H,#00H
MOV 26H,#00H
MOV 27H,#00H
MOV 28H,#00H
MOV 29H,#00H
MOV Y,#0 ;Y=0,不運行
MOV M,#1 ;模式為1,手動
MOV S,#1 ;風速為0
MOV L,#1 ;類型為1,正常
CLR DDJ ;將DDJ置0,風扇不轉動
LCALL LCDRESET ;液晶顯示器初始化
LCALL B20_INIT ;DS18B20初始化
LCALL FBLCHANGE ;改變溫度分辨率為9位
LCALL TMAIN ;讀取溫度并顯示
LCALL KEYA
JMP $
;======================掃描按鍵程序=================================
KEYA: MOV A,M
CJNE A,#2,KEYB
LCALL TMAIN
LCALL WENKONG
KEYB: MOV A,#0FFH ;掃描按鍵并處理
MOV P3,A ;P3口置1,使其為輸入模式
JNB KEY1,D1 ;KEY1=0,說明K1鍵按下,轉到D1
JNB KEY2,D2 ;KEY2=0,說明K1鍵按下,轉到D2
JNB KEY3,D3 ;KEY4=0,說明K1鍵按下,轉到D4
LJMP KEYA ;KEY3=0,說明K1鍵按下,轉到D3
JNB KEY4,D4
D1: LCALL DELAY12ms ;延時12ms,消抖
JNB KEY1,K1 ;再次判斷按鍵狀態(tài),若仍為0,轉到K1
LJMP KEYA ;若不為0,返回繼續(xù)查詢
D2: LCALL DELAY12ms ;延時12ms,消抖
JNB KEY2,K2 ;再次判斷按鍵狀態(tài),若仍為0,轉到K2
LJMP KEYA ;若不為0,返回繼續(xù)查詢
D3: LCALL DELAY12ms ;延時12ms,消抖
JNB KEY3,K3 ;再次判斷按鍵狀態(tài),若仍為0,轉到K3
LJMP KEYA ;若不為0,返回繼續(xù)查詢
D4: LCALL DELAY12ms ;延時12ms,消抖
JNB KEY4,K4 ;再次判斷按鍵狀態(tài),若仍為0,轉到K4
LJMP KEYA ;若不為0,返回繼續(xù)查詢
K1: LCALL EK1 ;調按鍵K1處理子程序EK1
LJMP KEYA
K2: LCALL EK2 ;調按鍵K2處理子程序EK2
LJMP KEYA
K3: LCALL EK3 ;調按鍵K3處理子程序EK3
LJMP KEYA
K4: LCALL EK4 ;調按鍵K4處理子程序EK4
LJMP KEYA
;===================== K1處理子程序EK1======================
EK1: JNB KEY1,EK1 ;再次判斷KEY1狀態(tài),KEY1=0,按鍵K1未釋放,等待
;之后判斷風扇工作狀態(tài),如果是運行狀態(tài),則按下K1后停止轉動;若是停止狀態(tài),則按下K2后開始轉動。
MOV A,Y ;P3.1=1,按鍵K1已釋放,則執(zhí)行按鍵K1功能
CJNE A,#0,STOP ;Y不為0,說明風扇在轉動,轉到STOP,使其停止轉動
MOV Y,#01H ;Y=0,說明風扇不轉動,之后判斷風扇停止前的狀態(tài),逐一恢復
MOV A,Y
MOV P0,#82H
LCALL LOAD
ORL A,#30H
LCALL SENDDATA ;改變顯示器上的Y=1
MOV A,M
CJNE A,#1,EK11 ;判斷M的狀態(tài),M不為1,則為溫控模式,轉到EK11
MOV A,S ;M=1,則為手動模式,繼續(xù)執(zhí)行,判斷S、L的狀態(tài)
CJNE A,#1,EK12
LCALL DANG1
LJMP EK14
EK12:CJNE A,#2,EK13
LCALL DANG2
LJMP EK14
EK13:LCALL DANG3 ;判斷了S的狀態(tài)并恢復
EK14:MOV A,L
CJNE A,#1,EK15
LCALL ZHENGCHANG
LJMP EK17
EK15:CJNE A,#2,EK16
LCALL ZIRAN
LJMP EK17
EK16:LCALL SHUIMIAN
LJMP EK17 ;判斷了L的狀態(tài)并恢復
EK11:LCALL WENKONG ;溫控模式
LJMP EK17
STOP:MOV Y,#0 ;停止運行程序
MOV A,Y
MOV P0,#82H
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器上的Y=0
CLR DDJ ;風扇停止轉動
EK17:RET
;=============================K2處理子程序EK2===========================
EK2: JNB KEY2,EK2 ;再次判斷KEY2狀態(tài),KEY2=0,按鍵K2未釋放,等待
;判斷風扇模式,若自動,則轉為手動;若手動,則轉為自動
MOV A,Y ;P3.0=1,按鍵K2已釋放,則執(zhí)行按鍵K2功能
CJNE A,#1,EK21 ;判斷風扇運行情況,若風扇不運行,此鍵無效,跳轉到EK21
MOV A,M ;Y=1,風扇運行,判斷M的狀態(tài)
CJNE A,#1,EK22 ;M=2,風扇為自動模式,則轉到EK22,變?yōu)槭謩?br />
MOV M,#2 ;M=1,風扇為手動模式,改為自動溫控
MOV A,M
MOV P0,#86H
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器上M=2
LCALL WENKONG
LJMP EK21
EK22: MOV M,#1
MOV A,M
MOV P0,#86H
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器上M=1
MOV A,S ;之后判斷S、L的狀態(tài)并恢復
CJNE A,#1,EK23
LCALL DANG1
LJMP EK25
EK23:CJNE A,#2,EK24
LCALL DANG2
LJMP EK25
EK24:LJMP DANG3 ;判斷了S的狀態(tài)并恢復
EK25:MOV A,L
CJNE A,#1,EK26
LCALL ZHENGCHANG
LJMP EK21
EK26:CJNE A,#2,EK27
LCALL ZIRAN
LJMP EK21
EK27:LCALL SHUIMIAN ;判斷了L的狀態(tài)并恢復
EK21: RET
;========================= K3處理子程序EK3=====================
EK3: JNB KEY3,EK3 ;再次判斷KEY3狀態(tài),KEY3=0,按鍵K3未釋放,等待
;判斷風扇是否運行,不允許此鍵無效。判斷風扇模式,手動模式下風扇變速,自動模式下此鍵無效。判斷當前風速,弱→中、中→強、強→弱
MOV A,Y ;P3.2=1,按鍵K3已釋放,則執(zhí)行按鍵K3功能
CJNE A,#1,EK31 ;Y=0,風扇不運行,此鍵無效跳轉到EK31
MOV A,M
CJNE A,#1,EK31 ;M=2,自動模式,此鍵無效,跳轉到EK31
MOV A,S
CJNE A,#1,EK32 ;S不為1,跳轉到EK32
MOV S,#2 ;S=1,風速為1檔,改為2檔
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器S=2
LCALL DANG2 ;調風速
LJMP EK31
EK32: CJNE A,#2,EK33 ;S不為2,跳轉到EK33
MOV S,#3 ;S=2,風速為2檔,調為3檔
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器上S=3
LCALL DANG3
LJMP EK31
EK33: MOV S,#1 ;S=3,風速為3檔,調到1檔
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;改變顯示器上S=1
LCALL DANG1
EK31: RET
;============================== K4處理子程序EK4=============================
EK4: JNB KEY4,EK4 ;再次判斷KEY4狀態(tài),KEY4=0,按鍵K4未釋放,等待
;判斷風扇模式,手動模式下風扇變類型, 判斷當前模式,正常→睡眠、睡眠→自然、自然→正常
MOV A,Y ;P3.3=1,按鍵K4已釋放,則執(zhí)行按鍵K4功能
CJNE A,#1,EK41 ;Y=0,風扇不運行,此鍵無效跳轉到EK41
MOV A,M
CJNE A,#1,EK41 ;M=2,自動模式,此鍵無效,跳轉到EK41
MOV A,L
CJNE A,#1,EK42
MOV L,#2
MOV A,L
MOV P0,#8EH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL SHUIMIAN
LJMP EK41
EK42: CJNE A,#2,EK43
MOV L,#3
MOV A,L
MOV P0,#8EH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL ZIRAN
LJMP EK41
EK43: MOV L,#1
MOV A,L
MOV P0,#8EH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL ZHENGCHANG
EK41: RET
;==================== 12ms延時子程序====================
DELAY12ms: MOV R7,#26 ;12ms延時子程序
DEL3: MOV R6,#200
DJNZ R6,$
DJNZ R7,DEL3
RET
;=====================溫度控制子程序====================
WENKONG:MOV A,29H
SUBB A,#20
JNC WEN1
MOV S,#1
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL DANG1
LJMP WEN2
WEN1:MOV A,29H
SUBB A,#20
JNC WEN3
MOV S,#2
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL DANG2
LJMP WEN2
WEN3:MOV S,#3
MOV A,S
MOV P0,#8AH
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA
LCALL DANG3
WEN2:RET
;===================調速程序DANG1、DANG2、DANG3=========
DANG1:MOV SP,#70H
SETB DDJ
MOV TMOD,#11H
MOV TH0,#0D8H
MOV TL0,#0F0H
SETB ET0
SETB EA
SETB TR0
RET
DANG2:MOV SP,#70H
SETB DDJ
MOV TMOD,#11H
MOV TH0,#0B1H
MOV TL0,#0E0H
SETB ET0
SETB EA
SETB TR0
RET
DANG3:SETB DDJ
CLR TR0
RET
;===================T0中斷服務子程序===================
TIME0:CLR EA
PUSH PSW
PUSH Acc
SETB EA
MOV A,S
CJNE A,#1,TIME01
JB DDJ,TIME02
CPL DDJ
MOV TH0,#0D8H
MOV TL0,#0F0H
LJMP TIME03
TIME02:CPL DDJ
MOV TH0,#0B1H
MOV TL0,#0E0H
LJMP TIME03
TIME01:JB DDJ,TIME04
CPL DDJ
MOV TH0,#0B1H
MOV TL0,#0E0H
LJMP TIME03
TIME04: CPL DDJ
MOV TH0,#0D8H
MOV TL0,#0F0H
TIME03:CLR EA
POP Acc
POP PSW
SETB EA
RETI
;=======================模式改變程序 正常、睡眠、自然================
ZHENGCHANG:CLR TR1
CLR ET1
RET
SHUIMIAN: MOV TMOD,#11H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV R7,#80
SETB EA
SETB TR1
SETB ET1
SETB PT1
RET
ZIRAN: MOV TMOD,#11H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV R7,#160
SETB EA
SETB TR1
SETB ET1
SETB PT1
RET
;=======================T1中斷服務子程序=====================
TIME1: CLR EA
PUSH PSW
PUSH Acc
SETB EA
MOV TH1,#3CH
MOV TL1,#0B0H
DJNZ R7,TIME11
MOV A,L
CJNE A,#2,TIME14
MOV R7,#80
LJMP TIME15
TIME14: MOV R7,#160
TIME15: MOV A,S
CJNE A,#3,TIME12
CPL DDJ
LJMP TIME11
TIME12: JB TR0,TIME13
SETB TR0
LJMP TIME11
TIME13: CLR TR0
CLR DDJ
TIME11: CLR EA
POP Acc
POP PSW
SETB EA
RETI
;=========================改變溫度分辨率=====================
FBLCHANGE:
LCALL B20_INIT ;復位
MOV A,#0CCH ;跳過ROM
LCALL WRITE
MOV A,#1FH ;改變分辨率為9
LCALL WRITE
RET
;========================= 液晶顯示器初始化==================
LCDRESET:
MOV P0,#01H ;清屏(命令1)
LCALL LOAD ;向LCD1602 寫入命令字 01H
MOV P0,#38H ;顯示設定,顯示兩行(命令 6)
LCALL LOAD ;向LCD1602寫入命令字38H
MOV P0,#0FH ;打開顯示和光標,光標閃爍(命令4)
LCALL LOAD ;向 LCD1602 寫入命令字 0FH
MOV P0,#14H ;光標右移(命令5)
LCALL LOAD ;向LCD1602寫人命令字 14H
MOV P0,#80H ;光標回到第1行00H位置(命令8)
LCALL LOAD ;向LCD1602寫人命令字80H(80H+00H)
MOV DPTR,#TABLE1 ;DPTR指向TABLE1的表
LCALL DISPLAY ;調用液晶屏顯示字程序
MOV P0,#0C0H ;光標回到第2行40H位置(命令8)
LCALL LOAD ;向LCD1602寫入命令字COH(80H+40H)
MOV DPTR,#TABLE2 ;DPTR指向 TABLE 2 的表
CALL DISPLAY ;調用液晶屏顯示字程序
RET ;返回主程序
;======================命令裝載子程序,對液晶屏下命令LOAD=========================
LOAD:
CLR RS ;RS=0,D0~D7 上的信號作為命令使用
CLR RW ;RW=0,寫數據
CLR E ;E=0,E引腳電平由1變0,數據被讀入
LCALL DELAY ;延時
SETB E ;E=1,屏蔽DO~D7的數據
RET ;返回
;============================初始化顯示子程序=============================
DISPLAY:
MOV R0,#00H ;取數據表時,用RO為指針
REFETCH:
MOV A,R0
MOVC A,@A+DPTR ;ACC裝載數據表中的數據
LCALL SENDDATA ;調用顯示數據發(fā)送子程序
INC R0 ;R0 增加 1
CJNE R0,#10H,REFETCH ;如R0=10H,取表結束,否則跳回REFETCH
RET ;返回
;============================顯示數據發(fā)送子程序===========================
SENDDATA:
MOV P0,A ;顯示數據從 P1口送出
SETB RS ;RS=1,D0~D7 上的信號作為顯示數據使用
CLR RW ;RW=0,寫數據
CLR E ;E=0,引腳電平由1變0,D0~D7數據被讀入
LCALL DELAY ;延時
SETB E ;E=1,屏蔽 D0~D7 的數據
RET ;返回
;=========================延時子程序=================================
DELAY:
MOV R5,#100
DEL1: MOV R6,#20
DEL2: DJNZ R6,DEL2
DJNZ R5,DEL1
RET
TABLE1: ;數據表,第1行字符 .
DB'Y:0 M:1 S:1 L:1 '
TABLE2: ;數據表,第2行字符
DB' T: . '
DB 0DFH
DB'C '
;=====================溫度讀取+顯示程序======================
TMAIN: MOV SP,#30H
LCALL B20_INIT ;復位與檢測DS18B20
SETB DATALINE
LCALL B20_INIT
JB FLAG1,START
RET
START:
MOV A,#0CCH ;跳過ROM 匹配
LCALL WRITE
MOV A,#44H ;發(fā)出溫度轉換命令
LCALL WRITE
;LCALL DISPLAYT
LCALL B20_INIT
MOV A,#0CCH ;跳過ROM 匹配
LCALL WRITE
MOV A,#0BEH ;發(fā)出讀溫度命令
LCALL WRITE
LCALL READ ;讀溫度數據
LCALL CTEMP ;計算溫度值
LCALL DISPLAYT ;顯示
RET
;=========================DS18B20初始化子程序======================
;DS18B20 復位與檢測子程序
;FLAG1-1OKFLAG1=0ERROR
B20_INIT:
SETB DATALINE
NOP
ClR DATALINE
MOV R0,#0FBH ;主機發(fā)出延時600us 的復位低脈沖
B20_INIT1:
DJNZ R0,B20_INIT1
SETB DATALINE ;拉高數據線
MOV R0,#25H
B20_INIT2:
JNB DATALINE,B20_INIT3 ;等待DS18B20 回應
DJNZ R0,B20_INIT2
;延時
B20_INIT3:
SETB FLAG1
MOV R0,#06BH ;置標志位,表示DS18B20 存在
B20_INIT4:DJNZ R0,B20_INIT4 ;清標志位,表示DS18B20 不存在
SETB DATALINE
RET
;====================讀字節(jié)子程序READ============================
READ: MOV R4,#2 ; 讀取兩個八位數據,外層循環(huán)次數
MOV R1,#29H ; 立即數尋址給定存儲位置
REE0: MOV R2,#8 ; 給定數據位數,是內層循環(huán)次數
REE1: CLR C ; 進位標志位初始置零
SETB C
NOP
NOP
CLR DATALINE
NOP
NOP
NOP
SETB DATALINE ; 輸入脈沖并持續(xù)2-3個機器周期
MOV R3,#7
DJNZ R3,$ ; 延時,等待傳感器響應
MOV C,DATALINE ; 按位讀出
MOV R3,#23
DJNZ R3,$ ; 延時
RRC A ; 把C存入A內
DJNZ R2,REE1 ; 循環(huán)8次
MOV @R1,A ; 在29H存儲A,數據的低八位
DEC R1 ; 更換地址為28H,存儲數據高八位
DJNZ R4,REE0 ; 循環(huán)2次
RET
;===================寫字節(jié)子程序WRITE==========================
WRITE:
MOV R2,#8 ; 寫入八位二進制碼,即循環(huán)次數
CLR C ; 進位標志位初始置零
WR1: CLR DATALINE ; 拉低總線為寫入做準備
MOV R3,#6
DJNZ R3,$ ; 延時
RRC A ; A的最低為給CY,使A從低到高寫入從機
MOV DATALINE,C ; 將A又循環(huán)寫入C,寫入總線以輸入到傳感器
MOV R3,#23
DJNZ R3,$ ; 延時
SETB DATALINE ; 釋放,表示此位寫入完畢
NOP
DJNZ R2,WR1 ; 循環(huán)八次,一次寫入八位
SETB DATALINE ; 釋放總線
RET
;=========================計算溫度值CTEMP========================
CTEMP:
MOV A,29H
MOV 26H,29H
MOV 25H,28H
MOV 24H,28H ; 在24H存儲原始數據防止丟失
MOV C,25H.7 ; 存儲符號位進C
JNC SN1 ; 判斷溫度的正負,正數則跳過轉補碼程序
MOV A,25H
CPL A ; 取補碼,由于無效位置1,25H不必擔心數據溢出
MOV 25H,A
MOV A,26H
CPL A
INC A ; 由于是末位,需要加一
MOV 26H,A
MOV 29H,26H
MOV 28H,25H ; 在26H,25H中操作后放回29H,28H
SN1:
MOV C,28H.0 ; 正負溫度到此均得到整數部分絕對值
RRC A
MOV C,28H.1
RRC A
MOV C,28H.2
RRC A
MOV C,28H.3 ; 分別循環(huán),存入A內,連續(xù)4次濾掉小數部分
RRC A ; 可分析A內八位恰為整數部分(最高位為0)
JC SL0
MOV 27H,#00H
AJMP SL5
SL0:
MOV 27H,#05H ;為小數部分顯示0和5做準備
SL5:
MOV 29H,A ;29H內存放的是溫度的整數部分
LCALL DISPLAYT ;27H內存放的是溫度的小數部分
RET
;=====================溫度顯示DISPLAYT=========================
DISPLAYT:
MOV P0,#0C9H
LCALL LOAD
MOV R1,#27H
CJNE @R1,#0,AAA
MOV A,#'0'
AJMP BBB
AAA:MOV A,#'5'
BBB:LCALL SENDDATA ;顯示小數部分
MOV A,29H
MOV B,#10
DIV AB
MOV P0,#0C6H
LCALL LOAD
ADD A,#'0'
LCALL SENDDATA ;顯示十位數
MOV P0,#0C7H
LCALL LOAD
MOV A,B
ADD A,#'0'
LCALL SENDDATA ;顯示個位數
MOV P0,#0CH
LCALL LOAD ;關掉光標
RET
END
|