;************************************************************************ ; Digital Thermometer * ;************************************************************************ list p=16f628 #include errorlevel 0,-302 CBLOCK 0x20 DS_DAT DS_SIGN DUMMY0 DUMMY1 DUMMY2 DUMMY3 DUMMY4 SEND COUNT NUM1 NUM2 NUM3 DATA1 HALF endc #define DAT_PIN PORTB,0 ; 74595 DATA pin #define LATCH PORTB,4 ; 74595 LATCH pin #define CLK PORTB,5 ; 74595 CLK pin #Define DQ PORTA,0 org 0x000 goto Start Table_ addwf PCL,f dt 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f Start clrf PORTA ; Set port A for digital I/O movlw 0x07 movwf CMCON bsf STATUS,RP0 movlw b'00000110' ; Set port B for displaying via LED 7 segments movwf PORTB bcf STATUS,RP0 Main call RD_Temp ; Read data from DS1820 clrf HALF ; A Half digit bcf STATUS,C rrf DS_DAT,w ; Use 7-bit upper rlf HALF,f ; Store a half degree movwf DATA1 ; Data for convert to decimal call Convert ; Convert data to decimal call Delay3 ; Display data delay goto Main ;********************************************************************** ; Display On 7 Segment * ;********************************************************************** Delay3 clrf DUMMY4 ; Display data delay DelayLp call Disp decfsz DUMMY4,f goto DelayLp return Delay2 clrf DUMMY3 ; Delay for scanning LED 7 segments decfsz DUMMY3,f goto $-1 return Disp movf NUM1,w ; Load data to DSP1 call Table_ ; Convert btfsc HALF,0 ; Show a half degree on dot-point LED addlw 0x80 call Send_Dat ; Send data to LED 7 segments bcf PORTB,6 ; ON DSP1 Display call Delay2 bsf PORTB,6 movf NUM2,w ; Load data to DSP2 call Table_ ; Convert call Send_Dat ; Send data to LED 7 segments bcf PORTB,7 ; On DSP2 call Delay2 bsf PORTB,7 ; Off DSP2 return Send_Dat movwf SEND ; Load data movlw 0x08 ; Loop 8 times for sending 8-bit data movwf COUNT Chk_Bit bcf DAT_PIN ; btfsc SEND,7 ; Check bit 7 "0" or "1" bsf DAT_PIN ; Send bit 7 to shift register Clock bsf CLK ; Clock pulse bcf CLK Rotate rlf SEND,f ; Rotate bit for sending next bit decfsz COUNT,f ; Test loop 8 times ? goto Chk_Bit ; If no, send bit again Latch bsf LATCH ; Latch data for displaying bcf LATCH return ;********************************************************************** ; Macro for DS1820 * ;********************************************************************** DQLOW macro bcf DQ ; DQ bit ready bsf STATUS,RP0 bcf DQ ; Set DQ to output bcf STATUS,RP0 endm DQHIZ macro bsf STATUS,RP0 bsf DQ ; Set DQ to input bcf STATUS,RP0 endm PAUSE macro DELAY ; Generate delay time movlw DELAY movwf DUMMY0 call Delay5 endm ;********************************************************************** ; DS1820 1-Wire bus * ;********************************************************************** RD_Temp call DS_Rx ; Check chip status addlw 0x01 btfss STATUS,Z ; Z set = ready return ; W is not zero = not ready Get_Temp call DS_Reset movlw 0xcc ; Skip ROM call DS_Tx movlw 0xbe ; Read scratch pad RAM of DS1820 call DS_Tx call DS_Rx ; Read 8-bit data movwf DS_DAT call DS_Reset ; Restart movlw 0xcc ; Skip ROM call DS_Tx movlw 0x44 ; Start conversion call DS_Tx Delay5 nop ; Delay for PAUSE macro nop decfsz DUMMY0,f goto Delay5 return DS_Reset DQLOW PAUSE 0x77 ; 600 microcsecond delay DQHIZ PAUSE 0x0c ; Wait for response pulse (67 microsecond) nop nop movf PORTA,w ; Read response andlw 0x01 ; Use RA0 only movwf DUMMY1 PAUSE 0x3b ; 300 microcsecond delay movf DUMMY1,w ; Response in W return DS_Tx movwf DUMMY2 ; Transmission data movlw 0x08 ; Prepare 8-bit counter for sending data movwf DUMMY1 ; Define loop counter Tx_Loop DQLOW ; Macro of DQ pin to low, This is start bit PAUSE 0x01 ; 10 microsecond delay rrf DUMMY2,f ; Rotate data to Carry flag btfsc STATUS,C ; Test Carry flag bsf DQ ; If Carry flag = "1" , set DQ to high PAUSE 0x0d ; 70 microsecond delay DQHIZ nop decfsz DUMMY1,f ; 8 times ? goto Tx_Loop ; No, send again return DS_Rx movlw 0x08 ; Recieve 8-bit data movwf DUMMY1 Rx_Loop DQLOW ; Macro of DQ pin to low, this is start bit PAUSE 0x01 ; 10 microsecond delay DQHIZ ; Back to high for receiving nop nop movf PORTA,w ; Read data andlw 0x01 ; Get data bit 0 only addlw 0xff ; Move data bit 0 to Carry flag with addition method rrf DUMMY2,f ; Move data bit 0 to DUMMY bit 7 PAUSE 0x0b ; 60 microsecond delay decfsz DUMMY1,f ; Loop 8 times goto Rx_Loop ; Read again movf DUMMY2,w ; Save data to W register return ;********************************************************************** ; Convert Hex to Decimal (3 Digit) * ;********************************************************************** Convert clrf NUM2 ; Clear register of 10's unit Check movlw 0x0A ; subwf DATA1,w ; Subtract with 10 until lower 10 btfss STATUS,C ; Check subtraction result lower 10 ? goto Less1 ; If yes then return incf NUM2,f ; If no, increase 10's unit value movlw 0x0A ; subwf DATA1,f ; Subtract with 10 until lower 10 and check result again goto Check Less1 movf DATA1,w ; movwf NUM1 ; Send data to 1's unit display clrf NUM3 ; Check hundred unit Check2 movlw 0x0A subwf NUM2,w ; btfss STATUS,C ; 10's unit over 10 ? return ; If no then return incf NUM3,f movlw 0x0A ; If yes, subtract again and check until the result is lower 10 subwf NUM2,f goto Check2 ;********************************************************************** end