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