;Thermometer ; ; Written by:Steven Easley ; Email: seasley@robotdungeon.com ; Webpage: www.robotdungeon.com ; ; ; LIST p=16F84a INCLUDE "p16f84a.inc" ERRORLEVEL -302,-224 __CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF & _CP_OFF ;Define the needed values CONSTANT DATA_PIN=4 #DEFINE check PORTA, 0 #DEFINE dp PORTA, 3 ;1-wire varibles index equ 21 ; o_byte equ 18 ;Address of output byte i_byte equ 19 ;Address of input byte temp equ 20 ;Temp location ;Define variables that will be stored in RAM CBLOCK 0CH seg_a ;Holds seg_a present value seg_b ;Holds seg_b present value seg_c ;Holds seg_c present value seg_d ;Holds seg_d present value bin ;Holds binary to be converted hundreds ;Holds hundreds after conversion tens_and_ones ;Holds tens and ones after conversion count ;Loop variable loop1 ;Loop variable temp_lsb ;Holds tempuratue LSB temp_msb ;Holds tempuratue MSB ENDC ORG 0000 ;Skip to main program goto Main ;Initialize the ports Init: movlw B'00010000' ;Load MSnibble with value to select digit movwf seg_a ;Also blank the display movlw B'00100000' movwf seg_b movlw B'01000000' movwf seg_c movlw B'10000000' movwf seg_d movlw D'55' ;Load LSB of tempurature with 55 movwf temp_lsb movlw B'00000000' ;Clear tens and one places movwf tens_and_ones clrf PORTA ;Clear ports A ans B clrf PORTB movlw B'00010001' ;Set A0 and A3 to inputs all others outputs tris PORTA movlw B'00000000' ;Set port B to outputs tris PORTB return ;Return to caller ;------------------------------------- ;Do the binary to BCD conversion ;------------------------------------- binary_to_bcd; clrf hundreds swapf bin, W addwf bin, W andlw B'00001111' skpndc addlw 0x16 skpndc addlw 0x06 addlw 0x06 skpdc addlw -0x06 btfsc bin, 4 addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 btfsc bin, 5 addlw 0x30 btfsc bin, 6 addlw 0x60 btfsc bin, 7 addlw 0x20 addlw 0x60 rlf hundreds, f btfss hundreds, 0 addlw -0x60 movwf tens_and_ones btfsc bin, 7 incf hundreds, f return ;------------------------------------- ;Display on the dipsplay ;------------------------------------- Display: ;Clear seg_a movlw B'00011111' movwf seg_a ;Clear seg_b movlw B'00100000' movwf seg_b ;Clear seg_c movlw B'01000000' movwf seg_c ;Clear seg_d movlw B'10000000' movwf seg_d ;Check to see what value should be displayed btfsc PORTA, 0 ;If port A0 is one goto celcius ;Show celcius tempuratue goto ferin ;Else show ferinheit ;Display the tempuratue in celcius celcius: bcf STATUS, C ;Load the segments rrf temp_lsb, F ;with the temp in btfsc STATUS, C ;celcius goto got5 ;Check if .5 needs to be displayed movlw b'10000000' movwf seg_d ;Set seg_d goto rest got5: movlw b'10000101' ;Add .5 to segment d movwf seg_d goto rest ;Display the tempuratue in ferenheight ferin: movf temp_lsb, w ;Load temp_lsb in f sublw d'40' ;Subtract 40 to create jump (40-lsb) subwf 0, W ;Invert value to be -(40-lsb) call fertable ;Call conversion table movwf temp_lsb ;Store tempurateu in ferheinght bcf STATUS, C ;Clear carry bit rrf temp_lsb, F ;Rotate F into carry btfsc STATUS, C ;If carry is 1 need to add .5 to seg d goto got5b movlw b'10000000' ;Blank d if .5 not displayed movwf seg_d ;Set seg_d goto rest ;Load the rest of the values got5b: movlw b'10000101' ;Load .5 in d movwf seg_d goto rest ;Jump table for conversion factor fertable: addwf PCL, F ; b'nnnnnnnd' retlw b'10001000' ;68f 20c retlw b'10001010' ;69f 20.5c retlw b'10001100' ;70f 21c retlw b'10001101' ;70.5f 21.5c retlw b'10001111' ;71.5f 22c retlw b'10010001' ;72.5f 22.5c retlw b'10010011' ;73.5f 23c retlw b'10010100' ;74f 23.5c retlw b'10010110' ;75f 24c retlw b'10011000' ;76f 24.5c retlw b'10011010' ;77f 25c retlw b'10011100' ;78f 25.5c retlw b'10011110' ;79f 26c retlw b'10100000' ;80f 26.5c retlw b'10100001' ;80.5f 27c retlw b'10100011' ;81.5f 27.5c retlw b'10100101' ;82.5f 28c retlw b'10100111' ;83.5f 28.5c retlw b'10101000' ;84f 29c retlw b'10101010' ;85f 29.5c retlw b'10101100' ;86f 30c retlw b'10101110' ;87f 30.5c retlw b'10110000' ;88f 31c retlw b'10110010' ;89f 31.5c retlw b'10110100' ;90f 32c ;Display values rest: bcf STATUS, C ;Clear carry bit movf temp_lsb, 0 ;Load temp LSB rrf temp_lsb, f ;Rotate with carry movwf bin ;Save in bin for conversion to BCD rest2: call binary_to_bcd ;Convert to 3 segment BCD ; movf hundreds, W ;Set seg_a ; andlw B'00001111' ; iorwf seg_a, F movf tens_and_ones, W ;Set seg_b swapf tens_and_ones, W andlw B'00001111' iorwf seg_b, F movf tens_and_ones, W ;Set seg_c andlw B'00001111' iorwf seg_c, F Display_1: movf seg_a, W movwf PORTB movlw d'20' call delay_10 movf seg_b, W movwf PORTB movlw d'20' call delay_10 movf seg_c, W movwf PORTB bcf dp movlw d'20' call delay_10 bsf dp movf seg_d, W movwf PORTB call test btfss STATUS, Z goto Display_1 goto Main2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This is the main routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Main: call Init ;Initilize the display Main1: call initds1820 ;Initilize the ds1820 movlw h'CC' ;Send skip ROM command movwf o_byte call out_byte movlw h'44' ;Send start conversion command movwf o_byte call out_byte goto Display ;Loop in display until DS1820 is done ;reading in the tempurature Main2: call initds1820 ;Reinitilize the DS1820 movlw h'CC' ;Send skip ROM command movwf o_byte call out_byte movlw h'BE' ;Send command movwf o_byte call out_byte call in_byte ;Read in tempurature LSB movwf temp_lsb call in_byte ;Read in tempurature MSB movwf temp_msb goto Main1 ;Goto main and start next conversion ;The following are standerd 1-wire routines. ;Initilize the DS1820 initds1820: call pin_hi call pin_lo movlw d'50' ;delay 500us call delay_10 call pin_hi movlw d'50' ;delay 500us call delay_10 return ;Check if the DS1820 is done converting test: call in_byte movlw h'FF' subwf i_byte, W return ;Recieve a byte in_byte: movlw d'8' movwf index clrf i_byte in_byte_1: call pin_lo nop nop nop call pin_hi nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop movf PORTA, W movwf temp btfss temp, 4 bcf STATUS, C btfsc temp, 4 bsf STATUS, C rrf i_byte, f movlw d'6' call delay_10 decfsz index, f goto in_byte_1 movfw i_byte return ;Output a byte on the one wire out_byte: movlw d'8' movwf index out_byte_1: rrf o_byte, f btfss STATUS, C goto out_0 goto out_1 out_byte_2: decfsz index, f goto out_byte_1 return out_0: call pin_lo movlw d'6' call delay_10 call pin_hi goto out_byte_2 out_1: call pin_lo call pin_hi movlw d'6' call delay_10 goto out_byte_2 ;;;;;;;;;;;;;;;;;; pin_hi: bsf STATUS, RP0 bsf TRISA, DATA_PIN bcf STATUS, RP0 return pin_lo: bcf PORTA, DATA_PIN bsf STATUS, RP0 bcf TRISA, DATA_PIN bcf STATUS, RP0 return ;These are the delay routines ;This should delay W * 10us delay_10: movwf loop1 delay_10us: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop decfsz loop1, F goto delay_10us return end