|
;18B10溫度測量+LCD1602顯示溫度 ;實戰(zhàn)目的 ;1、學(xué)習(xí)18B20單總線溫度傳感器的使用。 ;2、學(xué)習(xí)LCD的使用。 ;3、學(xué)習(xí)10進(jìn)制轉(zhuǎn)10進(jìn)制的方法。 ;所有資源: ;1、TMRO定時器。產(chǎn)生溫度轉(zhuǎn)換所需要的延時時間。 ;2、PORTA口。即做LCD顯示時可控制端口,RA2同時做18B20的數(shù)據(jù)接口 ;3、PORTC口。做LCD顯示時的數(shù)據(jù)口。 ;功能說明 ;1、通過18B20采集當(dāng)前環(huán)境 ;最高溫度可顯示127.9375,最低溫度可顯示0.0625(無負(fù)溫度處理部分) ;2、將溫度在LCD上顯示(3位整數(shù),4位小數(shù)) ;硬件連接 ;1,在18B20按DEMO板上的標(biāo)識插在插座U8上 ;2,撥碼開關(guān)S13第4位置ON ;3,其他所有撥碼開關(guān)都置OFF ;源程序如下: LIST P=PIC16F877 TITLE="LCD DISPLAY" ERRORLEVEl -302 ;去掉編譯時的302號提示信息 ;__CONFIG B'000010010101' ;代碼保護(hù)開啟;WRT_ENABLE;CPD_ENABLE;LVP_DISABLE;BODEN_ENABLE ;PWRTE_ENABLE;WDT_ENABLE;OSC_XT ;*****************以下是暫存器的定義***************************** #INCLUDE<P16F877A.INC> #DEFINE RS PORTA,1 ;LCD控制信號 #DEFINE RW PORTA,2 ;LCD控制信號 #DEFINE E PORTA,3 ;LCD控制信號 #DEFINE DAT PORTC ;LCD數(shù)據(jù)線 #DEFINE DQ PORTA,2 ;18B20數(shù)據(jù)口 CBLOCK 20H DQ_DELAY1 DQ_DELAY2 TEMP TEMP1 TEMP2 ;存放采樣到的溫度值 COUNT COUNT1 ENDC TMR0_VALUE EQU 0AH ;寄存器初值為6,預(yù)分頻比1:4,中斷一次時間為4*(256-6)=1000us DQ_DELAY_VALUE1 EQU 0FAH DQ_DELAY_VALUE2 EQU 4H ;***********************以下是宏定義**************************** READ_STATE MACRO ;讀18B20的狀態(tài) BCF RS BSF RW BSF E ENDM WRITE_COMMAND MACRO ;寫命令 BCF RS BCF RW BCF E ENDM WRITE_DATA MACRO ;寫數(shù)據(jù) BSF RS BCF RW BCF E ENDM ;**********************以下是程序的開始************************ ORG 00H NOP GOTO MAIN ;入口地址 ORG 04H RETFIE ;在中斷入口出放置一條中斷返回指令,防止干擾產(chǎn)生中斷 ;***************************主程序******************************* MAIN CLRF PORTC CLRF PORTA BANKSEL TRISA CLRF TRISA ;A口所有先設(shè)置為輸出 CLRF TRISC MOVLW 01H MOVWF OPTION_REG ;分頻比1:4,定時器,內(nèi)部時鐘源 MOVLW 06H MOVWF ADCON1 ;關(guān)閉所有A/D口 BCF STATUS,RP0 MOVLW 00H MOVWF INTCON ;關(guān)閉所有中斷,且同時清零T0IF CLRF TEMP CLRF TEMP1 CLRF TEMP2 ;清零臨時寄存器 ;****************************循環(huán)處理部分************************ ;先啟動18B20溫度轉(zhuǎn)換程序,在判斷溫度轉(zhuǎn)換是否完成(需750us) ;未完成則調(diào)用顯示子程序,直到完成溫度轉(zhuǎn)換 ;完成后讀取溫度值 ;送LCD顯示 LOOP CALL RESET_18B20 ;調(diào)用復(fù)位18B20子程序 MOVLW 0CCH MOVWF TEMP CALL WRITE_18B20 ;SKIP ROM命令 MOVLW 44H MOVWF TEMP CALL WRITE_18B20 ;溫度轉(zhuǎn)換命令 CLRF STATUS BCF INTCON,T0IF CALL DELAY_750MS ;調(diào)用溫度轉(zhuǎn)換所需要的750MS延時 NOP CALL RESET_18B20 MOVLW 0CCH MOVWF TEMP CALL WRITE_18B20 ;SKIP ROM命令 MOVLW 0BEH MOVWF TEMP CALL WRITE_18B20 ;讀溫度命令 CALL READ_18B20 ;調(diào)用讀溫度低字節(jié) MOVFW TEMP MOVWF TEMP1 ;保存到TEMP1 CALL READ_18B20 ;調(diào)用讀溫度高字節(jié) MOVFW TEMP MOVWF TEMP2 ;保存到TMEP2 CALL RESET_18B20 CALL TEMP_CHANGE ;調(diào)用溫度轉(zhuǎn)換程序 CALL DISPLAY ;調(diào)用LCD顯示程序 GOTO LOOP ;循環(huán)工作 ;***************************LCD顯示子程序************************ DISPLAY ;LCD模塊初始化,由廠家提供的資料顯示,其初始化過程為: ;6----寫指令38H,此條指令是將LCD顯示模塊設(shè)置為8位數(shù)據(jù)線,雙行,5X7點陣顯示 ;7----檢測Busy信號; ;8----寫指令08H,關(guān)閉顯示 ;9----檢測Busy信號; ;10---寫指令01H,顯示清屏 ;以后寫入光標(biāo)等的控制指令. BANKSEL TRISA CLRF TRISA ;A口為LCD控制信號,全輸出 BANKSEL PORTA NOP MOVLW 38H CALL COMMAND_WRITE ;顯示模式設(shè)置:16*2顯示,5*7點陣,8位數(shù)碼接口 MOVLW 08H CALL COMMAND_WRITE ;顯示關(guān)閉,不顯示光標(biāo) MOVLW 01H CALL COMMAND_WRITE ;顯示清屏 MOVLW 06H CALL COMMAND_WRITE ;顯示光標(biāo)移動設(shè)置(右移),整屏顯示不移動 MOVLW 0CH CALL COMMAND_WRITE ;顯示開及光標(biāo)設(shè)置,不顯示光標(biāo) DISPLAY0 MOVLW 84H CALL COMMAND_WRITE ;設(shè)置顯示起始位置 CALL BUSY ;判忙 MOVLW 8H ;共8個數(shù)據(jù)需要顯示 MOVWF COUNT MOVLW 37H ;取數(shù)地址 MOVWF FSR DISPLAY1 INCF FSR,1 ;取數(shù)地址加1 MOVFW INDF CALL DATA_WRITE ;調(diào)用寫數(shù)據(jù)子程序 DECFSZ COUNT,1 GOTO DISPLAY1 RETURN ;*****************************寫命令子程序*********************** COMMAND_WRITE WRITE_COMMAND ;設(shè)置寫命令所需要的控制信號 MOVWF DAT ;把命令字送數(shù)據(jù)口 BSF E NOP BCF E CALL BUSY ;判忙 RETURN ;**************************判總線忙子程序************************ BUSY BSF STATUS,RP0 MOVLW 80H MOVWF TRISC ;數(shù)據(jù)口最高位置為輸入口 BCF STATUS,RP0 READ_STATE NOP BCF E BTFSC DAT,7 ;是否忙 GOTO BUSY ;是,繼續(xù)判斷 BANKSEL TRISC CLRF TRISC ;否,數(shù)據(jù)最高位恢復(fù)為輸出狀態(tài) BCF STATUS,RP0 RETURN ;*************************寫數(shù)據(jù)子程序*************************** DATA_WRITE WRITE_DATA MOVWF DAT BSF E NOP BCF E CALL BUSY RETURN ;*********************復(fù)位DS18B20子程序************************** RESET_18B20 ;根據(jù)DATASHEET介紹,寫數(shù)據(jù)時應(yīng)遵照如下規(guī)定: ;主控制器把總線拉低至少480us, ;18B20等待15-60us后,把總線拉低做為返回給控制器的應(yīng)答信號 BANKSEL TRISA BCF TRISA,2 BCF STATUS,RP0 BCF DQ MOVLW 0A0H MOVWF COUNT ;160US DECFSZ COUNT,1 GOTO $-1 ;拉低480us BSF DQ ;釋放總線 MOVLW 14H MOVWF COUNT DECFSZ COUNT,1 GOTO $-1 ;等待60us BANKSEL TRISA BSF TRISA,2 ;DQ設(shè)置為輸入 BCF STATUS,RP0 BTFSC DQ ;數(shù)據(jù)線是否為低 GOTO RESET_18B20 ;否則繼續(xù)復(fù)位 MOVLW 4H MOVWF COUNT DECFSZ COUNT,1 ;延時一段時間后再次判斷 GOTO $-1 BTFSC DQ GOTO RESET_18B20 MOVLW 4BH MOVWF COUNT DECFSZ COUNT,1 GOTO $-1 BANKSEL TRISA BCF TRISA,2 ;DQ設(shè)置為輸出 BCF STATUS,RP0 RETURN ;*********************寫DS18B20子程序**************************** WRITE_18B20 ;根據(jù)DATASHEET介紹,寫數(shù)據(jù)時應(yīng)遵照如下規(guī)定: ;寫數(shù)據(jù)0時,主控制器把總線拉低至少60us ;寫數(shù)據(jù)1時,主控制器把總線拉低,但必須在15us內(nèi)釋放 MOVLW 8H MOVWF COUNT ;8位數(shù)據(jù) BANKSEL TRISA BCF TRISA,2 BCF STATUS,RP0 BCF STATUS,C WRITE_18B20_1 BSF DQ ;先保持DQ為高 MOVLW 5H MOVWF COUNT1 BCF DQ ;拉低DQ15us DECFSZ COUNT1,1 GOTO $-1 RRF TEMP,1 BTFSS STATUS,C ;判斷寫的數(shù)據(jù)為0還是1 GOTO WRITE_0 BSF DQ ;為1,立即拉高數(shù)據(jù)線 GOTO WRITE_END WRITE_0 BCF DQ ;繼續(xù)保持?jǐn)?shù)據(jù)線為低 WRITE_END MOVLW 0FH MOVWF COUNT1 ;保持45ms DECFSZ COUNT1,1 GOTO $-1 BSF DQ ;釋放總線 DECFSZ COUNT,1 ;是否寫完8位數(shù)據(jù) GOTO WRITE_18B20_1 RETURN ;**********************讀DS18B20子程序**************************** READ_18B20 ;根據(jù)DATASHEET介紹,讀數(shù)據(jù)時應(yīng)遵照如下規(guī)定: ;讀數(shù)據(jù)0時,主控制器把總線拉低后,18B20再把總線拉低60us ;讀數(shù)據(jù)1時,主控制器把總線拉低后,保持總線狀態(tài)不變 ;主控制器在數(shù)據(jù)線拉低后15us內(nèi)讀區(qū)數(shù)據(jù)線上的狀態(tài)。 MOVLW 8H ;一次讀8位數(shù)據(jù) MOVWF COUNT READ_18B20_1 BANKSEL TRISA BCF TRISA,2 ;數(shù)據(jù)線先設(shè)為輸出 BCF STATUS,RP0 BCF DQ ;先拉低數(shù)據(jù)線 MOVLW 1H MOVWF COUNT1 DECFSZ COUNT1,1 ;拉低總線3us GOTO $-1 BSF DQ ;釋放總線 BANKSEL TRISA BSF TRISA,2 ;數(shù)據(jù)線設(shè)為輸入 BCF STATUS,RP0 MOVLW 2H MOVWF COUNT1 DECFSZ COUNT1,1 ;延時6ms GOTO $-1 BSF STATUS,C BTFSS DQ ;判斷數(shù)據(jù)線狀態(tài) BCF STATUS,C RRF TEMP,1 ;移位到TEMP中 MOVLW 12H MOVWF COUNT1 DECFSZ COUNT1,1 GOTO $-1 ;讀一位數(shù)據(jù)至少需要60us DECFSZ COUNT,1 ;是否讀完8位 GOTO READ_18B20_1 RETURN ;*******************溫度表示形式轉(zhuǎn)換程序************************** ;因為從18B20中讀出的溫度值是二進(jìn)制形式,必須把它轉(zhuǎn)換成對象ASCII才能在LCD上顯示 ;18B20中溫度的表示為:S S S S S 2的6次方 2的5次方 2的4次方 2的3次方 2的2次方 。。。。2的負(fù)4次方 ;結(jié)果整數(shù)放在38H開始的存儲器里,小數(shù)部分放在3B開始的單元里 ;38H(百位) 39H(十位) 3AH(個位) 3BH(小數(shù)點)3CH(十分位) 3DH(百分位) 3EH(千分位) 3FH(萬分位) TEMP_CHANGE ;整數(shù)部分 ;因為轉(zhuǎn)換后溫度值位于兩個單元內(nèi),所以必須先把它們組合到一個單元內(nèi)。 ;因為最大值為127.9375,所以只需判斷結(jié)果是否大于100來決定百位上的結(jié)果 ;用循環(huán)減0AH的方法得到十位的值,最后剩下的被減數(shù)即為個位的結(jié)果 MOVLW 7H ANDWF TEMP2,1 ;只保留低3位 SWAPF TEMP2,0 MOVWF 3AH ;轉(zhuǎn)存3AH MOVFW TEMP1 MOVWF TEMP2 ;轉(zhuǎn)存TEMP2 MOVLW 0F0H ANDWF TEMP2,1 ;清除低4位 SWAPF TEMP2,0 ;高低半字節(jié)交換 IORWF 3AH,1 ;組合得到結(jié)果的7位整數(shù)部分 MOVLW 64H ;計算整數(shù)部分百位的結(jié)果 SUBWF 3AH,W ; -100 BTFSS STATUS,C GOTO NEXT0 ;溫度小于100 MOVWF 3AH ;減后的結(jié)果覆蓋原來的數(shù)據(jù) MOVLW 1H MOVWF 38H ;整數(shù)部分最高位為1(不可能大于1) GOTO $+2 NEXT0 CLRF 38H ;溫度小于100,最高位為0 CLRF 39H ;計算整數(shù)部分十位的結(jié)果 MOVLW 0AH ; -10 SUBWF 3AH,1 BTFSS STATUS,C GOTO NEXT1 INCF 39H,1 ;夠減 十位上加1 GOTO $-5 NEXT1 MOVLW 0AH ADDWF 3AH,1 ;多減一次再加回來,剩下的值即為個位上的值 MOVLW '.' MOVWF 3BH ;小數(shù)點 ;小數(shù)部分 ;取四位精度 ;計算方法為從最低位開始依次判斷是否為1 ,若為1則分別加上: ;0.0625、0.125、0.25、0.5,而且只有百分位相加時有可能結(jié)果大于0AH CLRF 3CH CLRF 3DH CLRF 3EH CLRF 3FH BTFSS TEMP1,0 GOTO NEXT2 MOVLW 5H MOVWF 3FH MOVLW 2H MOVWF 3EH MOVLW 6H MOVWF 3DH ;萬分位 NEXT2 BTFSS TEMP1,1 GOTO NEXT3 MOVLW 5H ADDWF 3EH,1 MOVLW 2H ADDWF 3DH,1 MOVLW 1H MOVWF 3CH ;千分位 NEXT3 BTFSS TEMP1,2 GOTO NEXT5 MOVLW 5H ADDWF 3DH,1 MOVLW 0AH SUBWF 3DH,1 BTFSS STATUS,C GOTO NEXT4 INCF 3CH,1 GOTO $+3 NEXT4 MOVLW 0AH ADDWF 3DH,1 MOVLW 2H ADDWF 3CH,1 ;百分位 NEXT5 BTFSS TEMP1,3 GOTO NEXT6 MOVLW 5H ADDWF 3CH,1 ;十分位 NEXT6 MOVLW 30H ;各位加上30H,轉(zhuǎn)換成對應(yīng)的ASCII碼,以便能在LCD上顯示 ADDWF 38H,1 ADDWF 39H,1 ADDWF 3AH,1 ADDWF 3CH,1 ADDWF 3DH,1 ADDWF 3EH,1 ADDWF 3FH,1 RETURN ;**************************延時750ms****************************** DELAY_750MS MOVLW DQ_DELAY_VALUE2 MOVWF DQ_DELAY2 DELAY_750MS_2 MOVLW DQ_DELAY_VALUE1 MOVWF DQ_DELAY1 DELAY_750MS_1 MOVLW TMR0_VALUE MOVWF TMR0 ;開啟定時器 BTFSS INTCON,T0IF GOTO $-1 BCF INTCON,T0IF DECFSZ DQ_DELAY1,1 GOTO DELAY_750MS_1 DECFSZ DQ_DELAY2,1 GOTO DELAY_750MS_2 RETURN ;**************************程序結(jié)束****************************** END |