;**********************************************************************
;晶振為12MHZ,顯示實(shí)時(shí)時(shí)間,溫度
;測(cè)量溫度范圍為-55~+99攝氏度
;***********************************************************************
T_RST EQU P1.5 //DS1302復(fù)位線引腳
T_CLK EQU P1.6 //DS1302時(shí)鐘線引腳
T_IO EQU P1.7 //DS1302數(shù)據(jù)線引腳
TEM_L EQU 40H //存放從DS18B20中讀出的高、低位溫度值
TEM_H EQU 41H
TEM_NUM EQU 42H //存放溫度轉(zhuǎn)換后的整數(shù)部分
FLAG0 EQU 45H //FLAG0存放溫度的符號(hào)
DQ EQU P2.3 //DS18B20數(shù)據(jù)線
RS BIT P2.0 //LCD控制線定義
RW BIT P2.1
E BIT P2.2
SKIP_B20 EQU 0CCH //DS18B20跳過(guò)ROM命令
START_B20 EQU 44H //DS18B20溫度變換命令
READDS EQU 0BEH //DS18B20讀暫存器命令
ORG 0000H
AJMP MAIN
ORG 0100H
MAIN: MOV SP,#90H
ACALL LCD_INT //進(jìn)行LCD初始化
MOV A,#8BH //在LCD第一行第12列顯示W(wǎng)EEK
LCALL W_COM
MOV A,#57H //字母'W'的字符庫(kù)為01010111
LCALL W_DAT
MOV A,#45H //字母'E'的字符庫(kù)為01000101
LCALL W_DAT
MOV A,#45H
LCALL W_DAT
MOV A,#4BH //字母'K’的字符庫(kù)為01001011
LCALL W_DAT
MOV A,#0C0H //第二行第一列顯示TIME
LCALL W_COM
MOV A,#54H //字母'T'的字符庫(kù)為01010100
LCALL W_DAT
MOV A,#49H //字母'I'的字符庫(kù)為01001001
LCALL W_DAT
MOV A,#4DH //字母'M'的字符庫(kù)為01001101
LCALL W_DAT
MOV A,#45H //字母'E'的字符庫(kù)為01000101
LCALL W_DAT
MOV 60H,#00H //設(shè)置秒存儲(chǔ)單元
MOV 61H,#00H //設(shè)置分存儲(chǔ)單元
MOV 62H,#16H //設(shè)置時(shí)存儲(chǔ)單元
MOV 63H,#05H //設(shè)置日存儲(chǔ)單元
MOV 64H,#01H //設(shè)置月存儲(chǔ)單元
MOV 65H,#03H //設(shè)置星期存儲(chǔ)單元
MOV 66H,#18H //設(shè)置年存儲(chǔ)單元
LCALL SET1302 //向DS1302寫(xiě)入時(shí)間
REP: LCALL GET1302 //讀出時(shí)間
LCALL GET_TEM //讀出轉(zhuǎn)換后的溫度值
LCALL TEM_COV
;;;;;;;;;;在LCD第一行顯示年月日和星期;;;;;;;;;;
MOV A,#80H //顯示在LCD第一行第一列
LCALL W_COM //調(diào)用LCD寫(xiě)命令子程序
MOV A,#'2'
ACALL W_DAT //調(diào)用LCD寫(xiě)數(shù)據(jù)子程序
MOV A,#'0'
ACALL W_DAT
MOV A,56H //年拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H //數(shù)字的字符庫(kù)從00110000B即30H開(kāi)始
ACALL W_DAT
MOV A,B
ADD A,#30H
ACALL W_DAT
MOV A,#'-'
ACALL W_DAT
MOV A,54H //月拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H
ACALL W_DAT
MOV A,B
ADD A,#30H
ACALL W_DAT
MOV A,#'-'
ACALL W_DAT
MOV A,53H //日拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H
ACALL W_DAT
MOV A,B
ADD A,#30H
ACALL W_DAT
MOV A,#8FH //設(shè)置LCD顯示星期的位置為第一行第十六列
LCALL W_COM
MOV A,55H //顯示星期
ADD A,#30H
LCALL W_DAT
;;;;;;;;;;在LCD第二行顯示時(shí)分秒和溫度;;;;;;;;;;;;;
MOV A,#0C4H //寫(xiě)入顯示緩沖區(qū)的起始地址為第二行第五列開(kāi)始
LCALL W_COM
MOV A,52H //小時(shí)拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H
LCALL W_DAT
MOV A,B
ADD A,#30H
LCALL W_DAT
MOV A, #':'
LCALL W_DAT
MOV A,51H //分拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H
LCALL W_DAT
MOV A,B
ADD A,#30H
LCALL W_DAT
MOV A, #':'
LCALL W_DAT
MOV A,50H //秒拆分成十位與個(gè)位,轉(zhuǎn)換字符顯示
MOV B,#10H
DIV AB
ADD A,#30H
LCALL W_DAT
MOV A,B
ADD A,#30H
LCALL W_DAT
MOV A,#0CDH //溫度顯示在LCD第二行第十四列
LCALL W_COM
MOV A,FLAG0 //顯示溫度正負(fù)號(hào)
ACALL W_DAT
MOV A,TEM_NUM //溫度整數(shù)拆分成十位和個(gè)位顯示
MOV B,#0AH
DIV AB //商送給A,余數(shù)送給B
ADD A,#30H
CJNE A,#30H,REP1 //如果十位為0,則不顯示
MOV A,#20H //字符庫(kù)中00100000B(20H)為空白
REP1: ACALL W_DAT //調(diào)用LCD寫(xiě)數(shù)據(jù)子程序
MOV A,B //將求得的余數(shù)送給A
ADD A,#30H
ACALL W_DAT //調(diào)用LCD寫(xiě)數(shù)據(jù)子程序
LJMP REP
/******************時(shí)間**************************/
;;;;;;;;累加器A寫(xiě)一字節(jié)到DS1302;;;;;;;;;;;;;
WE: MOV 70H,#08H //一個(gè)字節(jié)八位,移動(dòng)八次
INB1: MOV A,B //將命令字送給A
RRC A //通過(guò)A移入進(jìn)位標(biāo)志位C
MOV B,A
MOV T_IO,C //移入到芯片內(nèi)
SETB T_CLK
CLR T_CLK
DJNZ 70H,INB1
RET
;;;;;;;;讀一字節(jié)到累加器A中;;;;;;;;;;;;;;;;;
READ: MOV 70H,#08H //一個(gè)字節(jié)八位,移動(dòng)八次
OUTB1: MOV C,T_IO //從芯片內(nèi)移動(dòng)到進(jìn)位標(biāo)志位C
RRC A //通過(guò)C再移入累加器A中
SETB T_CLK
CLR T_CLK
DJNZ 70H,OUTB1
RET
;;;;;;;;;向DS1302寫(xiě)入時(shí)間子程序;;;;;;;;;;;;;;
SET1302:CLR T_RST //RST引腳為低電平,數(shù)據(jù)傳送終止
CLR T_CLK //清零時(shí)鐘總線
SETB T_RST //RST引腳為高電平,邏輯控制有效
MOV B,#8EH //控制命令字(10001110-進(jìn)行存取時(shí)間,寫(xiě)操作)
LCALL WE //調(diào)用寫(xiě)字節(jié)命令
MOV B,#00H //寫(xiě)操作前清寫(xiě)保護(hù)位W
LCALL WE
SETB T_CLK
CLR T_RST
MOV R0,#60H //秒 分 時(shí) 日 月 星期 年 數(shù)據(jù)存儲(chǔ)在60-66H單元
MOV R7,#07H //共7個(gè)字節(jié)
MOV R1,#80H //寫(xiě)秒寄存器命令
S1: CLR T_RST
CLR T_CLK
SETB T_RST
MOV B,R1 //寫(xiě)入寫(xiě)秒指令
LCALL WE
MOV A,@R0 //將秒存儲(chǔ)單元中的數(shù)值送給A
MOV B,A
LCALL WE
INC R0 //R0加一,指向下一個(gè)寫(xiě)入的日歷、時(shí)鐘數(shù)據(jù)
INC R1 //指向下一個(gè)時(shí)間寄存器
INC R1
SETB T_CLK
CLR T_RST
DJNZ R7,S1
CLR T_RST
CLR T_CLK
SETB T_RST
MOV B,#8EH //控制命令字(10001110-進(jìn)行存取時(shí)間,寫(xiě)操作)
LCALL WE
MOV B,#80H //控制寄存器中WP置1
LCALL WE
SETB T_CLK
CLR T_RST //結(jié)束寫(xiě)過(guò)程
RET
;;;;;;;;;;;;;;;讀時(shí)間子程序;;;;;;;;;;;;;;;;;
GET1302:MOV R0,#50H
MOV R7,#7
MOV R1,#81H //讀秒寄存器命令
G1: CLR T_RST
CLR T_CLK
SETB T_RST
MOV B,R1 //寫(xiě)入讀秒寄存器命令
LCALL WE
LCALL READ
MOV @R0,A //存入讀出數(shù)據(jù)
INC R0 //指向下一個(gè)存放日歷、時(shí)鐘的存儲(chǔ)單元
INC R1 //指向下一個(gè)日歷、時(shí)鐘寄存器
INC R1
SETB T_CLK
CLR T_RST
DJNZ R7,G1 //未讀完,繼續(xù)讀下一個(gè)
RET
/********************溫度************************/
;;;;;;;;;;;;;;DS18B20復(fù)位程序;;;;;;;;;;;;;;;;;
B20_INT:SETB DQ //將數(shù)據(jù)線置高電平“1”
NOP //延時(shí)
NOP
CLR DQ //數(shù)據(jù)線拉到低電平“1”
MOV R7,#0CH //延時(shí)60*12=720US
INT_DEL:ACALL DEL60US
DJNZ R7,INT_DEL
SETB DQ //數(shù)據(jù)線拉到高電平“1”
ACALL DEL60US //延時(shí)等待
ACALL DEL60US
MOV C,DQ //將數(shù)據(jù)線的狀態(tài)送給C,判斷初始化是否成功,是否產(chǎn)生一個(gè)低電平
JC ERROR //如果C等于1,則跳出,初始化失敗
ACALL DEL60US //初始化成功,CPU讀到數(shù)據(jù)線上的低電平,繼續(xù)延時(shí)
ACALL DEL60US
ACALL DEL60US
ACALL DEL60US
RET
ERROR: CLR DQ //初始化未成功,繼續(xù)進(jìn)行初始化
SJMP B20_INT
RET
;;;;;;;;;;;;;;;;;讀DS18B20一個(gè)字節(jié)到累加器A子程序;;;;;;;;;;;;
R_BYTE: MOV R7,#08H //讀取8位為一字節(jié)
SETB DQ
NOP
NOP
LOOP: CLR DQ //將數(shù)據(jù)線從高電平拉為低電平時(shí),作為一個(gè)讀周期的開(kāi)始
NOP //延時(shí),保證低電平至少為1US
NOP
NOP
SETB DQ
MOV R6,#07H //循環(huán)到A的最高位
DJNZ R6,[ DISCUZ_CODE_1 ]nbsp;
MOV C,DQ //將數(shù)據(jù)線中的值送給進(jìn)位標(biāo)志位C
ACALL DEL60US
RRC A //累加器A帶進(jìn)位右移
SETB DQ
DJNZ R7,LOOP //將一字節(jié)讀到累加器A
ACALL DEL60US
ACALL DEL60US
RET
;;;;;;;;;;;;;累加器A寫(xiě)到DS18B20子程序;;;;;;;;;;
W_BYTE: MOV R7,#08H //將8位連續(xù)數(shù)據(jù)(一字節(jié))寫(xiě)入A
SETB DQ //拉高數(shù)據(jù)線
NOP
NOP
LOOP1: CLR DQ //將數(shù)據(jù)線拉到低電平,作為寫(xiě)周期的開(kāi)始
MOV R6,#07H //循環(huán)到累加器A的最高位Acc.7
DJNZ R6,$
RRC A //從累加器A的最高位開(kāi)始寫(xiě)入
MOV DQ,C //將進(jìn)位C送給DS18B20(寫(xiě)入時(shí)序,0或者1時(shí)序)
ACALL DEL60US //保持60US
SETB DQ //在15US內(nèi)將數(shù)據(jù)線拉為高電平
DJNZ R7,LOOP1 //將一字節(jié)寫(xiě)入A
RET
DEL60US:MOV R6,#1EH //延時(shí)(30*2)us
DJNZ R6,$
RET
;;;;;;;;;;;讀溫度子程序;;;;;;;;;;;;;;;;;;
GET_TEM:ACALL B20_INT //DS18B20復(fù)位程序
MOV A,#0CCH //DS18B20跳過(guò)ROM命令
ACALL W_BYTE //調(diào)用寫(xiě)DS18B20子程序
ACALL DEL60US
ACALL DEL60US
MOV A,#44H //DS18B20溫度轉(zhuǎn)換命令,開(kāi)始裝換溫度
ACALL W_BYTE //調(diào)用寫(xiě)DS18B20子程序
ACALL DEL60US
ACALL B20_INT //寫(xiě)完之后,將DS18B20復(fù)位
MOV A,#0CCH //DS18B20跳過(guò)ROM命令
ACALL W_BYTE //調(diào)用寫(xiě)DS18B20子程序
ACALL DEL60US
MOV A,#0BEH //DS18B20讀暫存器命令
ACALL W_BYTE //調(diào)用寫(xiě)DS18B20子程序
ACALL DEL60US
ACALL R_BYTE //讀溫度低字節(jié)
MOV TEM_L,A //將讀出的溫度低字節(jié)保存在40H
ACALL R_BYTE //讀溫度高字節(jié)
MOV TEM_H,A // 將讀出的溫度高字節(jié)保存在41H
RET
;;;;;將從DS18B20中讀出的溫度轉(zhuǎn)換成整數(shù)顯示;;;;;;;;;;;;
TEM_COV:MOV FLAG0,#'+' //設(shè)置當(dāng)前溫度為正,并且存放在45H
MOV A,TEM_H //將讀取的溫度高字節(jié)送給A
SUBB A,#0F8H //判斷C的值是否為1,為1則為正,為0則為負(fù)
JC TEM0 //看溫度值是否為負(fù),不是(C=1),轉(zhuǎn)
MOV FLAG0,#'-' //是,置FLAG0為負(fù)
MOV A,TEM_L //將讀取的溫度低字節(jié)送給A
CPL A //求此時(shí)負(fù)值溫度的補(bǔ)碼
ADD A,#01H
MOV TEM_L,A //將求得的補(bǔ)碼存放在40H
MOV A,TEM_H //將讀取的溫度高字節(jié)送給A
CPL A
ADDC A,#01H
MOV TEM_H,A //在將其補(bǔ)碼放在41H
TEM0: MOV A,TEM_L //存放整數(shù)部分到TEMPER_NUM
ANL A,#0F0H //取出溫度低字節(jié)的高四位
SWAP A //將取出的高四位存放在A中低四位位置
MOV TEM_NUM,A //將其存放在42H
MOV A,TEM_H
SWAP A
ORL A,TEM_NUM
MOV TEM_NUM,A
RET
/***************LCD顯示*******************/
;;;;;;LCD初始化子程序;;;;;;;;;;;;
LCD_INT:MOV A,#00000001H //清屏
ACALL W_COM //調(diào)用讀命令子程序
MOV A,#00111000B //傳輸8位數(shù)據(jù),顯示兩行,使用5*7的字符
LCALL W_COM
MOV A,#00001100B //顯示器開(kāi),光標(biāo)關(guān),字符不閃爍
LCALL W_COM
MOV A,#00000110B //字符不動(dòng),光標(biāo)自動(dòng)右移一格
LCALL W_COM
RET
;;;;;寫(xiě)入命令子程序(RS=0,RW=0);;;;;;
W_COM: ACALL F_BUSY
CLR E
CLR RS
CLR RW
SETB E
MOV P0,A
CLR E
RET
;;;;;寫(xiě)入數(shù)據(jù)子程序(RS=1,RW=0);;;;;
W_DAT: ACALL F_BUSY
CLR E
SETB RS
CLR RW
SETB E
MOV P0,A
CLR E
RET
;;;;;查忙子程序;;;;;;;;;;;;;
F_BUSY: PUSH ACC
MOV P0,#0FFH
CLR RS //忙標(biāo)志
SETB RW
WAIT: CLR E //給使能端有效信號(hào)(下降沿觸發(fā))
SETB E
JB P0.7,WAIT //直接尋址位P0.7是否為1,為1則忙,繼續(xù)等待
POP ACC
RET
END
|