|
;************************************************************************ ;<<溫度計(jì)-基于DS18B20>> ;時(shí)間:2006.3.6 ;程序文件名:“DS18B20.asm” ;功能實(shí)現(xiàn):通過DS18B20來(lái)讀取溫度,顯示在2位LED上,精確到1度 ;硬件連接:(1)RC0-RC7接共陽(yáng)數(shù)碼管的段碼A-H ; RA0-RA3接共陽(yáng)數(shù)碼管的位碼DIG0-DIG3 ;***********************************************************************
;*********************************************************************** ;定義單片機(jī)型號(hào)為PIC16F877A ;程序包含文件:P16F877A.INC ;定義配置字 ;*********************************************************************** LIST P=16F877A ;定義本程序所使用的芯片為PIC16F877A #INCLUDE "P16F877A.INC" ;定義本程序包含該文件
__CONFIG 3F72H ;晶振配置HS,看門狗禁止,上電延時(shí)使能,掉電復(fù)位使能 ;低電壓編程禁止,代碼不保護(hù)
#DEFINE DQ PORTB,2 #DEFINE DIR TRISB,2 CBLOCK 20H Y1 Y2 COUNT1 COUNT2 COMD DATE BIN_L ;要進(jìn)行轉(zhuǎn)換的字節(jié) GE ;轉(zhuǎn)換后的個(gè)位 SHI ;轉(zhuǎn)換后的十位 DATE_L DATE_H ENDC
;*********************************************************************** ;復(fù)位矢量定義(對(duì)于16F877A) ;*********************************************************************** ORG 0000H ;復(fù)位矢量地址 GOTO MAIN ;程序跳轉(zhuǎn)到MAIN主程序 ;----------------------------------------------------------------------
;*********************************************************************** ;主程序區(qū) ;*********************************************************************** ORG 0005H MAIN NOP CALL INTIAL START BTFSS DQ ;數(shù)據(jù)線空閑狀態(tài)為高電平 GOTO $-1 CALL RESET ;復(fù)位DS18B20 MOVLW 0CCH ;跳過讀ROM命令 CALL WR18B20 MOVLW 44H ;溫度轉(zhuǎn)換 CALL WR18B20 CALL DELAY_750US ;延時(shí)750us CALL RESET ;復(fù)位DS18B20 MOVLW 0CCH ;跳過讀ROM命令 CALL WR18B20 MOVLW 0BEH ;讀內(nèi)部RAM中的9字節(jié)內(nèi)容 CALL WR18B20 NOP CALL RE18B20 ;讀數(shù)據(jù) MOVF DATE,W MOVWF DATE_L ;讀低8位 CALL RE18B20 ;讀數(shù)據(jù) MOVF DATE,W MOVWF DATE_H ;讀高8位 MOVF DATE_L,W ;------------------------顯示處理-------------------------------------- RRF DATE_H,F RRF DATE_L,F RRF DATE_H,F RRF DATE_L,F RRF DATE_H,F RRF DATE_L,F RRF DATE_H,F RRF DATE_L,F MOVF DATE_L,W MOVWF BIN_L ;把高8位的低4位和低8位的高4位組合起來(lái) CALL DISPLAY ;調(diào)用數(shù)碼管顯示程序 GOTO START ;=======================================================================
;*********************************************************************** ;初始化和消影 ;*********************************************************************** INTIAL BSF STATUS,RP0 ;定義當(dāng)前體為體1,對(duì)方向寄存器進(jìn)行修改 MOVLW 07H MOVWF ADCON1 ;關(guān)閉A口的模擬通道 MOVLW 00H MOVWF TRISC ;段碼顯示口為輸出口 MOVLW 0F0H ANDWF TRISA,1 ;使位碼(RA0-RA3)為輸出口 BSF DIR ;使數(shù)據(jù)線為輸入 BCF STATUS,RP0 ;使當(dāng)前體為體0 MOVLW 0FFH ;關(guān)閉段碼 MOVWF PORTC MOVLW 0FFH ;關(guān)閉位碼 MOVWF PORTA BTFSS DQ ;數(shù)據(jù)線空閑狀態(tài)為高電平 GOTO $-1 CALL RESET ;復(fù)位DS18B20 MOVLW 0CCH ;跳過讀ROM命令 CALL WR18B20 MOVLW 44H ;溫度轉(zhuǎn)換 CALL WR18B20 CALL DELAY_750US ;延時(shí)750us CALL RESET ;復(fù)位DS18B20 MOVLW 0CCH ;跳過讀ROM命令 CALL WR18B20 MOVLW 0BEH ;讀內(nèi)部RAM中的9字節(jié)內(nèi)容 CALL WR18B20 NOP NOP CALL RE18B20 ;讀數(shù)據(jù) CALL RE18B20 ;讀數(shù)據(jù) CALL DELAY_MAX ;延時(shí)600ms CALL DELAY_MAX CALL DELAY_MAX RETLW 00H ;=======================================================================
;*********************************************************************** ;顯示所測(cè)得的溫度子程序 ;*********************************************************************** DISPLAY CALL _BCD MOVF SHI,W ANDLW 0FH CALL TABLE ;調(diào)用查表指令 MOVWF PORTC ;顯示十位段碼 BCF PORTA,0 ;選通十位顯示位碼 CALL DELAY BSF PORTA,0 ;關(guān)閉十位顯示位碼 MOVF GE,W ANDLW 0FH CALL TABLE ;調(diào)用查表指令 MOVWF PORTC ;顯示個(gè)位段碼 BCF PORTA,1 ;選通個(gè)位顯示位碼 CALL DELAY BSF PORTA,1 ;關(guān)閉個(gè)位顯示位碼 RETLW 00H ;======================================================================= ;*********************************************************************** ;二進(jìn)制轉(zhuǎn)BCD碼 ;*********************************************************************** _BCD CLRF SHI ;保存地址清零 CLRF GE MOVF BIN_L,F ;組合碼自己給自己賦值,測(cè)試是否為0 SKPNZ ;不為0則跳到下一步 RETLW 00H SHI_ MOVLW D'10' SUBWF BIN_L,W ;BIN_L減10,結(jié)果存到W寄存器 BTFSS STATUS,C ;執(zhí)行減法后,如果無(wú)借位 GOTO GE_ MOVWF BIN_L INCF SHI GOTO SHI_ GE_ MOVF BIN_L,W MOVWF GE RETLW 00H ;=======================================================================
;*********************************************************************** ;延時(shí)200ms ;*********************************************************************** DELAY_MAX MOVLW 0FFH MOVWF Y1 MOVLW 0FFH MOVWF Y2 DECFSZ Y2 GOTO $-1 DECFSZ Y1 GOTO $-5 RETLW 00H ;=======================================================================
;*********************************************************************** ;延時(shí)6ms ;*********************************************************************** DELAY MOVLW 03FH MOVWF Y1 MOVLW 020H MOVWF Y2 DECFSZ Y2 GOTO $-1 DECFSZ Y1 GOTO $-5 RETLW 00H ;=======================================================================
;*********************************************************************** ;延時(shí)750us子程序 ;*********************************************************************** DELAY_750US MOVLW 09H MOVWF Y1 MOVLW 01AH MOVWF Y2 DECFSZ Y2 GOTO $-1 DECFSZ Y1 GOTO $-5 RETLW 00H ;=======================================================================
;*********************************************************************** ;查表子程序,用于顯示段碼數(shù)字 ;數(shù)碼管為共陽(yáng)數(shù)碼管 ;*********************************************************************** TABLE ADDWF PCL,F RETLW 0C0H ;"0" RETLW 0F9H ;"1" RETLW 0A4H ;"2" RETLW 0B0H ;"3" RETLW 99H ;"4" RETLW 92H ;"5" RETLW 82H ;"6" RETLW 0F8H ;"7" RETLW 80H ;"8" RETLW 90H ;"9" ;=======================================================================
;*********************************************************************** ;DS18B20復(fù)位和應(yīng)答子程序 ;*********************************************************************** RESET BSF STATUS,RP0 ;使當(dāng)前體為體1 BCF DIR ;使數(shù)據(jù)位為輸出 BCF STATUS,RP0 ;使當(dāng)前體為體0 BSF DQ ;拉高數(shù)據(jù)位 NOP ;空循環(huán) BCF DQ ;拉低數(shù)據(jù)位 MOVLW D'200' ;延時(shí)600us MOVWF Y1 DECFSZ Y1 GOTO $-1 BSF STATUS,RP0 ;使當(dāng)前體為體1 BSF DIR ;使數(shù)據(jù)位為輸入 BCF STATUS,RP0 ;使當(dāng)前體為體0 MOVLW D'30' ;延時(shí)90us MOVWF Y1 DECFSZ Y1 GOTO $-1 BTFSC DQ ;主機(jī)接收到低電平應(yīng)答脈沖,跳轉(zhuǎn)到下一句 GOTO RESET MOVLW D'80' ;延時(shí)240us MOVWF Y1 DECFSZ Y1 GOTO $-1 BTFSS DQ ;主機(jī)接收到高電平應(yīng)答脈沖,跳轉(zhuǎn)到下一句 GOTO RESET RETLW 00H ;返回00H,復(fù)位應(yīng)答結(jié)束 ;========================================================================
;*********************************************************************** ;寫DS18B20子程序 ;*********************************************************************** WR18B20 MOVWF COMD ;把要寫的數(shù)據(jù)寫到COMD內(nèi) MOVLW D'8' MOVWF COUNT2 ;大循環(huán)8次 WR0 BSF STATUS,RP0 ;使當(dāng)前體為體1 BCF DIR ;使數(shù)據(jù)位為輸出 BCF STATUS,RP0 ;使當(dāng)前體為體0 BCF DQ ;拉低數(shù)據(jù)線 NOP NOP MOVLW D'2' MOVWF COUNT1 ;延時(shí)9us WR1 DECFSZ COUNT1,1 GOTO WR1 BTFSC COMD,0 ;COMD最低位為0則跳轉(zhuǎn)到下一句 BSF DQ ;拉高數(shù)據(jù)線 BTFSC COMD,0 ;COMD最低位為0則跳轉(zhuǎn)到下一句 NOP BCF STATUS,C ;進(jìn)位位置0 RRF COMD,1 ;帶進(jìn)位位,COMD向右移一位 MOVLW D'20' ;延時(shí)60us MOVWF COUNT1 WR2 DECFSZ COUNT1,1 GOTO WR2 BSF DQ ;拉高數(shù)據(jù)線,空閑狀態(tài) BSF STATUS,RP0 ;使當(dāng)前體為體1 BSF DIR ;使數(shù)據(jù)位為輸入 BCF STATUS,RP0 ;使當(dāng)前體為體0 DECFSZ COUNT2,1 ;8次循環(huán)到了則跳出 GOTO WR0 RETLW 00H ;======================================================================= ;*********************************************************************** ;讀18B20子程序 ;*********************************************************************** RE18B20 MOVLW 8 MOVWF COUNT2 RE0 BSF STATUS,RP0 ;使當(dāng)前體為體1 BCF DIR ;使數(shù)據(jù)位為輸出 BCF STATUS,RP0 ;使當(dāng)前體為體0 BCF DQ MOVLW 2 MOVWF COUNT1 RE1 DECFSZ COUNT1,1 GOTO RE1 BSF STATUS,RP0 ;使當(dāng)前體為體1 BSF DIR ;使數(shù)據(jù)位為輸入 BCF STATUS,RP0 ;使當(dāng)前體為體0 NOP BTFSS DQ ;如果數(shù)據(jù)線為高電平,則C=1 BCF STATUS,C BTFSC DQ ;如果數(shù)據(jù)線為低電平,則C=0 BSF STATUS,C RRF DATE,1 ;數(shù)據(jù)依次存在DATE上 MOVLW D'20' ;延時(shí)60us MOVWF COUNT1 RE2 DECFSZ COUNT1,1 GOTO RE2 DECFSZ COUNT2,1 GOTO RE0 BSF DQ RETLW 00H ;=======================================================================
;======================================================================= END ;程序結(jié)束 |