Termometro

Aqui una foto donde tenemos dos sondas y una esta en la calle y otra dentro de casa.

Nos marca la minima y la maxima.

max-min

OTRA FOTO

actual

Esquema, pica sofre la foto para descargar mas grande.

 

***************************************

CODIGO HEX

:10000000262A10302D2133302D21AA302D21BA304F
:100010002D2100302D2108302D2100302D213D30A3
:100020002D21080010302D2138302D219D302D211B
:10003000BA302D2100302D2108302D2100302D2106
:1000400010302D2108004430BC204530BC204E30FB
:10005000BC205430BC205230BC204F30BC2020305B
:10006000BC202030BC2008004130BC204630BC20E1
:100070005530BC204530BC205230BC204130BC2023
:100080002030BC202030BC2008003A08C1003808CD
:10009000C000E7212030BC203B08C1003908C00067
:1000A000E72108003E08C1003C08C000E7212030DD
:1000B000BC203F08C1003D08C000E72108008400C3
:1000C0000008A500840A0008A600840A0008A7000A
:1000D000840A0008A8000800840025088000840A1B
:1000E00026088000840A27088000840A28088000E7
:1000F00008006730BC207030BC205430BC20683011
:10010000BC206530BC207230BC206D30BC2020305B
:10011000BC205630BC202030BC203130BC202E30DA
:10012000BC203730BC202E30BC203030BC20080032
:100130000130C52008000230C5200800033904380A
:10014000C520080007390838C52008003F39403865
:10015000C52008008038C52008008316FF308600BF
:100160008312051085140515060805117F398510C1
:1001700083168601831208009000E720851005147D
:10018000051510088600051108009000E72085106D
:100190000510051510088600051108004108031D0B
:1001A000D4282B30960008002D30960008009000CF
:1001B000100E0F39F63E0318073E3A3E9400100821
:1001C0000F39F63E0318073E3A3E930008008316A7
:1001D000FF308600831205108514051506080511E9
:1001E0008039031DE72885108316860183120800D5
:1001F000A5309100910BFA2808009200F820920B8C
:10020000FE28080085011E30FD203830C520003052
:10021000A22098200430A22002309E200800000076
:100220000000A20B0F2908000830A0000512831659
:10023000051283120130A2000F21831605168312C6
:100240000000000005081039FF3EA10C0B30A20091
:100250000F21A00B162921080800A1000830A000DA
:1002600005128316051283120130A2000F21A10C82
:10027000031805160D30A2000F21831605168312F0
:100280000000A00B30290800051283160512831206
:100290007730A2000F218316051683120C30A200BE
:1002A0000F210000000005081039A3003B30A20018
:1002B0000F2123080800410803190800C003C009E2
:1002C00008004421031D8E296D2955302D21012060
:1002D000742955302D211220742917186529971873
:1002E0006929CC302D217429BE302D210930A3007D
:1002F0004030840014218000840AA30B7A29442111
:10030000CC302D2144302D211421031D8429410896
:1003100003198D29013E031D8E2900340134442127
:1003200033302D210830A3003030840014218000A8
:10033000840AA30B96290800FF30B800B900BB005F
:10034000BC00BD00BF00BA01BE0108002808031DA3
:10035000B1294108031D080026084002031C0800BB
:10036000B82941080319B8292608400203180800D3
:100370004008A6004108A80008002708031DC82956
:100380004108031DCF2925084002031CCF2908007E
:1003900041080319080025084002031C0800400812
:1003A000A5004108A70008002030BC204330BC2035
:1003B00008000830A300303084000008D72014085B
:1003C000BC201308BC20840AA30BDD290800CE2022
:1003D0001608BC204008CD003530950001304D0591
:1003E000031DF429303095000310CD0CCC010422FC
:1003F00030304A07BC2030304B07BC202E30BC20A8
:100400001508BC20D42108004C08F13E4C07C90057
:1004100049074907FD3ECA004D0E0F39CA07CA07F2
:100420004C07FB3CCB00CB07CB07CB074D080F3964
:10043000CB070A30CB07CA03031C1A2ACA07C90311
:10044000031C1E2AC907031C222A080083018B01F2
:100450008A01850186018316F83085000030860008
:100460008117831281150114811401159C2101301B
:1004700098000221982061210030AA207920403084
:10048000AA208F21D92164006300640063009820B2
:10049000011081100130970061215B2138305F200D
:1004A000A621BD2138306C200030AA20181C5B2A00
:1004B0002320E7215E2A981C5E2A452002309700FF
:1004C00061215B213C305F20A621BD213C306C20A6
:1004D0004030AA20181C6F2A3420E721722A981C69
:1004E000722A5220640063000310980D181D4A2AD6
:0604F000013098004A2AC9
:02400E00FD3F74
:00000001FF
 

probado y funciona

Lo primero montamos el circuito y ponemos un ds1820
y en la linea de abajo de la pantalla lcd nos sale
el codigo de el ds1820, le copiamos y ponemos el otro
ds1820, reset y sale otro codigo en hex ,
este es el codigo del de este sonda.

vamos a codigo fuente del pic y metemos estos codigos
en las lineas

dswriterom0    este es afuera
dswriterom1    este es dentro

y los emsamblamos y lo grabamos.

;    gpTherm
;    Copyright (C) 2000-2001 Thomas
;    This program is free software; you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation; either version 2 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program; if not, write to the Free Software
;    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
;
;    OSC 4MHz -> 1us por ciclo
;    (0) DS1820 ROM 1033aaba0008003d    DENTRO
;    (1) DS1820 ROM 10389dba00080010 AFUERA
;
;    este programa esta basado en el trabajo de
;
;    Steve Lawther (Schema)
;    Nikolai Golovchenko (bin2dec999 function)
;    Peter Ouwehand (LCD Code)
;    Steve.Marchant (DS 1820 Code)
;
;    and all the other guys publishing samples
;    for pic user
;
;    bugfixes
;    Sat Nov 17 19:20:31 MET 2001 bug in sign calculation fixed
;    Sat Nov 24 16:46:36 MET 2001 minmax calculation
;    Wed Nov 28 21:53:34 MET 2001 bug in modeswitch code
;    Sun Dec  9 20:10:18 MET 2001 support for 4×16 display
;    Mon Dec 10 20:36:54 MET 2001 ifdef for switching between 2×16 and 4×16
;    Mon Jan 28 21:12:34 MET 2002 bug in max calculation fixed
;                               
;
;
#define LCD_2X16                      ; uncomment for 2 line display!!!!
;#define LCD_4X16                     ; uncomment for 4 line display!!!!
;
 list p=16f84
 include p16f84.inc
 __CONFIG _CP_OFF & _WDT_ON & _XT_OSC
;
VERSIONMAJOR    EQU     1
VERSIONMINOR    EQU     7
VERSIONRELEASE  EQU     0
;
LCD_DATA        EQU     PORTB          ; LCD data lines interface
LCD_DATA_TRIS   EQU     TRISB
LCD_CTRL        EQU     PORTA          ; LCD control lines interface
;
; LCD PORTA control bits
;
LCD_RS          EQU     0              ; LCD Register-Select control line
LCD_RW          EQU     1              ; LCD Read/Write control line
LCD_E           EQU     2              ; LCD Enable control line
LCD_LINE0       EQU     0x00           ; LCD Line Address
LCD_LINE1       EQU     0x40           ; LCD Line Address
LCD_LINE2       EQU     0x10           ; LCD Line Address
LCD_LINE3       EQU     0x50           ; LCD Line Address
;
; LCD PORTB data bits
;
LCD_DB7         EQU     7              ; LCD dataline 7 (MSB)
LCD_DB6         EQU     6              ; LCD dataline 6
LCD_DB5         EQU     5              ; LCD dataline 5
LCD_DB4         EQU     4              ; LCD dataline 4
LCD_DB3         EQU     3              ; LCD dataline 3
LCD_DB2         EQU     2              ; LCD dataline 2
LCD_DB1         EQU     1              ; LCD dataline 1
LCD_DB0         EQU     0              ; LCD dataline 0 (LSB)
;
; LCD variables
;
LCD_TEMP        EQU     0x10           ; lcd subroutines internal use
LCD_DELAY       EQU     0x11           ; Used in DELAYxxx routines
LCD_X_DELAY     EQU     0x12           ; Used in X_DELAYxxx routines
LCD_ASCHEXLO    EQU     0x13           ; lo ascii hex from lcdaschex routine
LCD_ASCHEXHI    EQU     0x14           ; hi ascii hex from lcdaschex routine
LCD_ASCHALF     EQU     0x15           ; 5 or 0 for half Celsius Degrees
LCD_ASCSIGN     EQU     0x16           ; sign, 0 -> ‘+’ 255 ‘-‘ else ‘ ‘
LCD_ACTDS       EQU     0x17           ; 0->one (no rom), 1->first,2->second
; display modes
BTN_ACTMODE     EQU     0x18           ; variable for actual display mode
BTN_MODENORMAL  EQU     0              ; bit for display temperature screen
BTN_MODEMINMAX  EQU     1              ; bit display minmax screen
;
; DS 1820 variables
;
DS_BIT          EQU     4              ; porta4 is connected to the ds1820 bus
DS_RWTMP0       EQU     0x20
DS_RWTMP1       EQU     0x21
DS_DLYTMP       EQU     0x22
DS_TMP0         EQU     0x23
DS_TMP1         EQU     0x24
; area for tmp min and max variables
DS_MINTMP       EQU     0x25
DS_MAXTMP       EQU     0x26
DS_SIGNMINTMP   EQU     0x27
DS_SIGNMAXTMP   EQU     0x28
; ds1820 rom
DS_ROM0         EQU     0x30           ; ds1820 1 byte rom family code
DS_ROM1         EQU     0x31           ; ds1820 6 byte rom serial number
DS_ROM2         EQU     0x32          
DS_ROM3         EQU     0x33          
DS_ROM4         EQU     0x34
DS_ROM5         EQU     0x35
DS_ROM6         EQU     0x36
DS_ROM7         EQU     0x37           ; ds1820 1 byte rom crc code
; area for min and max variables
DS_MIN0         EQU     0x38
DS_MAX0         EQU     0x39
DS_SIGNMIN0     EQU     0x3a
DS_SIGNMAX0     EQU     0x3b
DS_MIN1         EQU     0x3c
DS_MAX1         EQU     0x3d
DS_SIGNMIN1     EQU     0x3e
DS_SIGNMAX1     EQU     0x3f
; ds1820 ram
DS_RAM0         EQU     0x40           ; ds1820 ram temperature lsb (temp)
DS_RAM1         EQU     0x41           ; ds1820 ram temperature msb (sign)
DS_RAM2         EQU     0x42           ; ds1820 ram TH user1
DS_RAM3         EQU     0x43           ; ds1820 ram TL user2
DS_RAM4         EQU     0x44           ; ds1820 ram reserved
DS_RAM5         EQU     0x45           ; ds1820 ram reserved
DS_RAM6         EQU     0x46           ; ds1820 ram count remain
DS_RAM7         EQU     0x47           ; ds1820 ram count per celsius
DS_RAM8         EQU     0x48           ; ds1820 ram crc
;
; CONVERSION Variables
;
Hund            EQU     0x49
Tens            EQU     0x4a
Ones            EQU     0x4b
NumH            EQU     0x4c
NumL            EQU     0x4d
;
 goto main
;
dswriterom0                     ; romtable para mi primer ds1820
 movlw       0x10               ; retrieve yours? see main DENTRO
 call        dswrite  ; 1033aaba0008003d
 movlw       0x33
 call        dswrite
 movlw       0xaa
 call        dswrite
 movlw       0xba
 call        dswrite
 movlw       0x00
 call        dswrite
 movlw       0x08
 call        dswrite
 movlw       0x00
 call        dswrite
 movlw       0x3d
 call        dswrite
 return
;
dswriterom1
 movlw       0x10             ; romtable para mi segundo ds1820
 call        dswrite         ; retrieve yours? see main  AFUERA
 movlw       0x38  ; 10389dba00080010
 call        dswrite  ; ultimo de la linea en aparecer en el
 movlw       0x9d  ; display
 call        dswrite
 movlw       0xba
 call        dswrite
 movlw       0x00
 call        dswrite
 movlw       0x08
 call        dswrite
 movlw       0x00
 call        dswrite
 movlw       0x10
 call        dswrite
 return
;  linea superior
dsprinttitle0
 movlw   ‘D’
 call    lcdputchar
 movlw   ‘E’
 call    lcdputchar
 movlw   ‘N’
 call    lcdputchar
 movlw   ‘T’
 call    lcdputchar
 movlw   ‘R’
 call    lcdputchar
 movlw   ‘O’
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 return
;   linea inferior
dsprinttitle1
 movlw   ‘A’
 call    lcdputchar
 movlw   ‘F’
 call    lcdputchar
 movlw   ‘U’
 call    lcdputchar
 movlw   ‘E’
 call    lcdputchar
 movlw   ‘R’
 call    lcdputchar
 movlw   ‘A’
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 return
;
dsprintminmax0
 movf    DS_SIGNMIN0,W
 movwf   DS_RAM1
 movf    DS_MIN0,W
 movwf   DS_RAM0
 call    lcdprintdsdata
 movlw   ‘ ‘
 call    lcdputchar
 movf    DS_SIGNMAX0,W
 movwf   DS_RAM1
 movf    DS_MAX0,W
 movwf   DS_RAM0
 call    lcdprintdsdata
 return
;
dsprintminmax1
 movf    DS_SIGNMIN1,W
 movwf   DS_RAM1
 movf    DS_MIN1,W
 movwf   DS_RAM0
 call    lcdprintdsdata
 movlw   ‘ ‘
 call    lcdputchar
 movf    DS_SIGNMAX1,W
 movwf   DS_RAM1
 movf    DS_MAX1,W
 movwf   DS_RAM0
 call    lcdprintdsdata
 return
;
dsminmax2tmp
 movwf   FSR
 movf    INDF,W
 movwf   DS_MINTMP
 incf    FSR,F
 movf    INDF,W
 movwf   DS_MAXTMP
 incf    FSR,F
 movf    INDF,W
 movwf   DS_SIGNMINTMP
 incf    FSR,F
 movf    INDF,W
 movwf   DS_SIGNMAXTMP
 return
;
dstmp2minmax
 movwf   FSR
 movf    DS_MINTMP,W
 movwf   INDF
 incf    FSR,F
 movf    DS_MAXTMP,W
 movwf   INDF
 incf    FSR,F
 movf    DS_SIGNMINTMP,W
 movwf   INDF
 incf    FSR,F
 movf    DS_SIGNMAXTMP,W
 movwf   INDF
 return
;
dsprintcopyright
 movlw   ‘g’
 call    lcdputchar
 movlw   ‘p’
 call    lcdputchar
 movlw   ‘T’
 call    lcdputchar
 movlw   ‘h’
 call    lcdputchar
 movlw   ‘e’
 call    lcdputchar
 movlw   ‘r’
 call    lcdputchar
 movlw   ‘m’
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 movlw   ‘V’
 call    lcdputchar
 movlw   ‘ ‘
 call    lcdputchar
 movlw   VERSIONMAJOR + 0x30
 call    lcdputchar
 movlw   ‘.’
 call    lcdputchar
 movlw   VERSIONMINOR + 0x30
 call    lcdputchar
 movlw   ‘.’
 call    lcdputchar
 movlw   VERSIONRELEASE + 0x30
 call    lcdputchar
 return
;
lcdclear
 movlw   0x01
 call    lcdputcmd
 return
;
lcdhome
 movlw   0x02
 call    lcdputcmd
 return
;
lcdemode
 andlw   0x03               ; strip upper bits
 iorlw   0x04               ; function set
 call    lcdputcmd
 return
;
lcddmode
 andlw   0x07               ; strip upper bits
 iorlw   0x08               ; function set
 call    lcdputcmd
 return
;
lcdscga
 andlw   0x3f               ; strip upper bits
 iorlw   0x40               ; function set
 call    lcdputcmd
 return
;
lcdsdda
 iorlw   0x80               ; function set
 call    lcdputcmd
 return
;
lcdgaddr
 bsf     STATUS,RP0          ; select register page 1
 movlw   0xff                ; set PORTB for input
 movwf   LCD_DATA_TRIS
 bcf     STATUS, RP0         ; select Register page 0
 bcf     LCD_CTRL, LCD_RS    ; set LCD for command mode
 bsf     LCD_CTRL, LCD_RW    ; setup to read busy flag
 bsf     LCD_CTRL, LCD_E     ; LCD E-line high
 movf    LCD_DATA, W         ; read busy flag + RAM address
 bcf     LCD_CTRL, LCD_E     ; LCD E-line Low
 andlw   0x7f                ; strip upper bit
 bcf     LCD_CTRL, LCD_RW
 bsf     STATUS, RP0         ; select register page 1
 clrf    LCD_DATA_TRIS       ; set PORTB for output
 bcf     STATUS, RP0         ; select register page 0
 return
;
lcdputchar
 movwf   LCD_TEMP            ; character to send is in W
 call    lcdbusy             ; wait for LCD to be ready
 bcf     LCD_CTRL, LCD_RW    ; set LCD in read mode
 bsf     LCD_CTRL, LCD_RS    ; set LCD in data mode
 bsf     LCD_CTRL, LCD_E     ; LCD E-line High
 movf    LCD_TEMP, W
 movwf   LCD_DATA            ; send data to LCD
 bcf     LCD_CTRL, LCD_E     ; LCD E-line Low
 return
;
lcdputcmd
 movwf   LCD_TEMP            ; command to send is in W
 call    lcdbusy             ; wait for LCD to be ready
 bcf     LCD_CTRL, LCD_RW    ; set LCD in read mode
 bcf     LCD_CTRL, LCD_RS    ; set LCD in command mode
 bsf     LCD_CTRL, LCD_E     ; LCD E-line High
 movf    LCD_TEMP, W
 movwf   LCD_DATA            ; send data to LCD
 bcf     LCD_CTRL, LCD_E     ; LCD E-line Low
 return
;
lcdascsign
 movf    DS_RAM1,W
 btfss   STATUS,Z
 goto    lcdascsignminus
 movlw   ‘+’
 movwf   LCD_ASCSIGN
 return
lcdascsignminus
 movlw   ‘-‘
 movwf   LCD_ASCSIGN
 return
;
lcdaschex
 movwf   LCD_TEMP
 swapf   LCD_TEMP,W
 andlw   B’00001111′
 addlw   -0x0a
 btfsc   STATUS,C
 addlw   0x07
 addlw   0x3a
 movwf   LCD_ASCHEXHI
 movf    LCD_TEMP,W
 andlw   B’00001111′
 addlw   -0x0a
 btfsc   STATUS,C
 addlw   0x07
 addlw   0x3a
 movwf   LCD_ASCHEXLO
 return
;
lcdbusy
 bsf     STATUS,RP0         ; Select Register page 1
 movlw   0xff               ; Set PORTB for input
 movwf   LCD_DATA_TRIS
 bcf     STATUS,RP0         ; Select Register page 0
 bcf     LCD_CTRL,LCD_RS    ; Set LCD for command mode
 bsf     LCD_CTRL,LCD_RW    ; Setup to read busy flag
 bsf     LCD_CTRL,LCD_E     ; LCD E-line High
 movf    LCD_DATA,W         ; Read busy flag + DDram address
 bcf     LCD_CTRL,LCD_E     ; LCD E-line Low
 andlw   0x80               ; Check Busy flag, High = Busy
 btfss   STATUS,Z
 goto    lcdbusy
 bcf     LCD_CTRL,LCD_RW
 bsf     STATUS,RP0         ; Select Register page 1
 clrf    LCD_DATA_TRIS      ; Set PORTB for output
 bcf     STATUS,RP0         ; Select Register page 0
 return
;
lcddelay500us
 movlw   D’165′          ; +1            1 cycle
 movwf   LCD_DELAY       ; +2            1 cycle
 decfsz  LCD_DELAY,F     ; step 1        1 cycle
 goto    $-1             ; step 2        2 cycles
 return                      ; +3            2 cycles
;
lcdxdelay500us     
 movwf   LCD_X_DELAY     ; +1            1 cycle
 call    lcddelay500us   ; step1         wait 500uSec
 decfsz  LCD_X_DELAY, F  ; step2         1 cycle
 goto    $-2             ; step3         2 cycles
 return
;
lcdinit
 clrf    LCD_CTRL        ; ALL PORT output should output Low.
 movlw   0x1e
 call    lcdxdelay500us  ; 30 * 0.5mS = 15mS
 movlw   0x38            ; 8-bit-interface, 2-lines
 call    lcdputcmd
 movlw   0x00            ; disp.off, curs.off, no-blink
 call    lcddmode
 call    lcdclear
 movlw   0x04            ; disp.on, curs.off
 call    lcddmode
 movlw   0x02            ; auto-inc (shift-cursor)
 call    lcdemode
 return
;
dssetlow macro
 bcf     PORTA,DS_BIT    ; dq bit ready lo
 bsf     STATUS,RP0
 bcf     TRISA,DS_BIT    ; dq bit now o/p
 bcf     STATUS,RP0
 endm
;
dssethigh macro
 bsf     STATUS,RP0
 bsf     TRISA,DS_BIT    ; dq bit now i/p
 bcf     STATUS,RP0
 endm
;
pause macro dlyf
 movlw   (dlyf / D’5′) – D’1′
 movwf   DS_DLYTMP
 call    dly5n
 endm
;
dly5n 
 nop
 nop
 decfsz  DS_DLYTMP,F
 goto    dly5n
 return
;
dsread
 movlw   D’8′
 movwf   DS_RWTMP0
dsrxlp
 dssetlow
 pause   D’10’
 dssethigh
 nop
 nop
 movf    PORTA,W
 andlw   B’00010000′
 addlw   0xff         
 rrf     DS_RWTMP1,F
 pause   D’60’
 decfsz  DS_RWTMP0,F
 goto    dsrxlp
 movf    DS_RWTMP1,W
 return
;
dswrite
 movwf   DS_RWTMP1       ; data to tx
 movlw   D’8′
 movwf   DS_RWTMP0       ; loop counter
dstxlp
 dssetlow
 pause   D’10’
 rrf     DS_RWTMP1,F
 btfsc   STATUS,C
 bsf     PORTA,DS_BIT    ; dq high if bit was 1
 pause   D’70’
 dssethigh
 nop
 decfsz  DS_RWTMP0,F
 goto    dstxlp
 return
;
dsreset
 dssetlow
 pause   D’600′
 dssethigh
 pause   D’65’           ;wait 67us for response bit
 nop
 nop
 movf    PORTA,W
 andlw   1 << DS_BIT
 movwf   DS_TMP0         ;save w
 pause   D’300′
 movf    DS_TMP0,W       ;restore stored w for return value
 return
;
; if DS_RAM1 is 255 -> «-«, than the temperature is
; complement(DS_RAM0 – 1)
;
dsminusconvertion
 movf    DS_RAM1,W
 btfsc   STATUS,Z
 return
 decf    DS_RAM0,F
 comf    DS_RAM0,F
 return
;
dstemperature
 call    dsreset
 btfss   STATUS,Z        ; zero flag set means resp. ok
 goto    badtmp

 ;movlw   0x00           ;uncomment for disabling romtable usage
 ;movwf   LCD_ACTDS      ;works only with one connected ds1820

 goto    switchbegin     ; switch betweeen different LCD_ACTDS values
switch0
 movlw   0x55            ; match rom first ds1820
 call    dswrite
 call    dswriterom0
 goto    switchend
switch1
 movlw   0x55            ; match rom second ds1820
 call    dswrite
 call    dswriterom1
 goto    switchend
switchbegin
 btfsc   LCD_ACTDS,0
 goto switch0
 btfsc   LCD_ACTDS,1
 goto switch1
 movlw   0xcc            ; default branch skip rom
 call    dswrite       
 goto    switchend
switchend

 movlw   0xbe            ; read scratch pad
 call    dswrite

 movlw   0x09            ; set counter to 9
 movwf   DS_TMP0
 movlw   DS_RAM0         ; indirect addressing
 movwf   FSR             ; put first byte (DS_RAM0) into FSR
dstemperatureloop
 call    dsread
 movwf   INDF            ; store read byte into INDF pointers target
 incf    FSR,F           ; increment FSR (now DS_RAM0 + n)
 decfsz  DS_TMP0,F
 goto    dstemperatureloop

 call    dsreset         ; ok, that’s all
 movlw   0xcc            ; skip prom, it is ok for multible ds1820, too
 call    dswrite
 movlw   0x44            ; start convert
 call    dswrite
tempnotready                 ; bugfix to ds1820.asm around
 call    dsread          ;
 btfss   STATUS,Z        ; – wait here till conversion has been done
 goto    tempnotready    ;
 ;
 ;       IF DSSIGN NOT 255 OR 0 THEN ERROR
 ;
 movf    DS_RAM1,W
 btfsc   STATUS,Z
 goto    oktmp
 addlw   0x01
 btfss   STATUS,Z
 goto    badtmp
oktmp
 retlw   0x00
badtmp
 retlw   0x01  
;
dsreadrom
 call    dsreset
 movlw   0x33                ; read rom command
 call    dswrite
 movlw   0x08                ; set counter to 8
 movwf   DS_TMP0
 movlw   DS_ROM0             ; indirect addressing
 movwf   FSR                 ; put first byte (DS_ROM0) into FSR
dsreadromloop
 call    dsread
 movwf   INDF                ; store read byte into INDF pointers target
 incf    FSR,F               ; increment FSR (now DS_ROM0 + n)
 decfsz  DS_TMP0,F
 goto dsreadromloop
 return
;
dsminmaxinit
 movlw   0xff                ; sign, 0 -> ‘+’ 255 ‘-‘
 movwf   DS_MIN0
 movwf   DS_MAX0
 movwf   DS_SIGNMAX0
 movwf   DS_MIN1
 movwf   DS_MAX1
 movwf   DS_SIGNMAX1
 clrf    DS_SIGNMIN0
 clrf    DS_SIGNMIN1
 return
;
; the are four decisions possible
;   max act
; 0 0   0     = max and act are +, newmax is the bigger value of both
; 1 0   255   = max is +, act value is not bigger
; 2 255 0     = max is -, act value is bigger
; 3 255 255   = max and act are -, newmax is the smaller value of both
;
dscalcmax
 movf    DS_SIGNMAXTMP,W
 btfss   STATUS,Z
 goto    maxisminus
maxisplus
 movf    DS_RAM1,W
 btfss   STATUS,Z
 return                      ; case 1
 movf    DS_MAXTMP,W         ; case 0
 subwf   DS_RAM0,W
 btfss   STATUS,C
 return
 goto    copyacttomax
maxisminus
 movf    DS_RAM1,W
 btfsc   STATUS,Z
 goto    copyacttomax        ; case 2
 movf    DS_MAXTMP,W         ; case 3
 subwf   DS_RAM0,W
 btfsc   STATUS,C
 return
copyacttomax
 movf    DS_RAM0,W
 movwf   DS_MAXTMP
 movf    DS_RAM1,W
 movwf   DS_SIGNMAXTMP
 return
;
; the are four decisions possible
;   min act
; 0 0   0     = min and act are +, newmin is the smaller value of both
; 1 0   255   = min is +, act value is smaller
; 2 255 0     = min is -, act value is not smaller
; 3 255 255   = min and act are -, newmin is the bigger value of both
;
dscalcmin
 movf    DS_SIGNMINTMP,W
 btfss   STATUS,Z
 goto    minisminus
minisplus
 movf    DS_RAM1,W
 btfss   STATUS,Z
 goto    copyacttomin        ; case 1
 movf    DS_MINTMP,W         ; case 0
 subwf   DS_RAM0,W
 btfss   STATUS,C
 goto    copyacttomin
 return
minisminus
 movf    DS_RAM1,W
 btfsc   STATUS,Z
 return                      ; case 2
 movf    DS_MINTMP,W         ; case 3
 subwf   DS_RAM0,W
 btfss   STATUS,C
 return
copyacttomin
 movf    DS_RAM0,W
 movwf   DS_MINTMP
 movf    DS_RAM1,W
 movwf   DS_SIGNMINTMP
 return
;   aqui se escribe lo despues de la temperatura Cº
lcdprintcelsius
 movlw   ‘ ‘           ; primer caracter   espacio blanco
 call    lcdputchar
 movlw   B’01000011’   ; segundo caracter  C
 call    lcdputchar
 return
;
lcdprintrom
 movlw   0x08                ; set counter to 8
 movwf   DS_TMP0
 movlw   DS_ROM0             ; indirect addressing
 movwf   FSR                 ; put first byte (DS_ROM0) into FSR
lcdprintromloop
 movf    INDF,W              ; load INDF pointers target into w
 call    lcdaschex           ; call hex->ascii conversion
 movf    LCD_ASCHEXHI,W
 call    lcdputchar
 movf    LCD_ASCHEXLO,W
 call    lcdputchar
 incf    FSR,F               ; increment FSR (now DS_ROM0 + n)
 decfsz  DS_TMP0,F
 goto    lcdprintromloop
 return
;
lcdprintdsdata
 call    lcdascsign          ; calculate the sign from DS_SIGN
 movf    LCD_ASCSIGN,W
 call    lcdputchar

 movf    DS_RAM0,W
 movwf   NumL
 movlw   ‘5’
 movwf   LCD_ASCHALF         ; insert asc ‘5’ into aschalf
 movlw   0x01
 andwf   NumL,W
 btfss   STATUS,Z
 goto    skipit
 movlw   ‘0’
 movwf   LCD_ASCHALF         ; insert asc ‘0’ into aschalf
skipit

 bcf     STATUS,C            ; clear carry, to avoid rrf problems
 rrf     NumL,F              ; divide ds1820 temp through 2
 clrf    NumH
 call    bin2dec999
 movlw   0x30
 addwf   Tens,W
 call    lcdputchar
 movlw   0x30
 addwf   Ones,W
 call    lcdputchar
 movlw   ‘.’
 call    lcdputchar
 movf    LCD_ASCHALF,W
 call    lcdputchar
 call    lcdprintcelsius
 return
;
;Binary to decimal conversion (0..999)
;
;Input: NumH:NumL
;Output Hund:Tens:Ones
;
;If Input > 999 Output will roll over, e.g.
;for input=5678 output=678.
;
;
;Size: 34 instructions
;Execution  time  (max) including return:
;22+5*9-1+5*6-1+4*3-1+2 = 108 cycles
;
;5-July-2000 by Nikolai Golovchenko
bin2dec999
 movf    NumH,W
 addlw   D’241′
 addwf   NumH,W
 movwf   Hund      ;b_2 = 2a_2 – 15
 addwf   Hund,W
 addwf   Hund,W
 addlw   D’253′
 movwf   Tens
 swapf   NumL,W
 andlw   0x0f
 addwf   Tens,F
 addwf   Tens,F   ;b_1 = 6a_2 + 2a_1 – 48
 addwf   NumH,W
 sublw   D’251′
 movwf   Ones
 addwf   Ones,F
 addwf   Ones,F
 addwf   Ones,F
 movf    NumL,W
 andlw   0x0f
 addwf   Ones,F   ;b_0 = a_0 – 4(a_2 + a_1) – 20
 movlw   D’10’
bin2dec999a                  ; 9 cycles max
 addwf   Ones,F
 decf    Tens,F
 btfss   STATUS,C
 goto    bin2dec999a
bin2dec999b                  ; 6 cycles max
 addwf   Tens,F
 decf    Hund,F
 btfss   STATUS,C
 goto    bin2dec999b
bin2dec999c                  ; 3 cycles max
 addwf   Hund,F
 btfss   STATUS,C
 goto    bin2dec999c
 return
;
main
 clrf    STATUS
 clrf    INTCON
 clrf    PCLATH
 clrf    PORTA
 clrf    PORTB
 bsf     STATUS, RP0
 movlw   0xf8
 movwf   TRISA
 movlw   0x00
 movwf   TRISB
 bsf     OPTION_REG, NOT_RBPU
 bcf     STATUS, RP0

 bsf     OPTION_REG,PSA       ; enable watchdog
 bsf     OPTION_REG,PS0       ; set prescaler to 1:128 = 2.3 seconds
 bsf     OPTION_REG,PS1
 bsf     OPTION_REG,PS2

 call    dsminmaxinit         ; reset minmax values
 
 movlw   1 << BTN_MODENORMAL
 movwf   BTN_ACTMODE

 call    lcdinit
 call    lcdclear
 call    dstemperature        ; read the temperature once and put into trash

 movlw   LCD_LINE0
 call    lcdsdda
 call    dsprintcopyright
 movlw   LCD_LINE1
 call    lcdsdda
 call    dsreadrom            ; use these routines to determine
 call    lcdprintrom          ; the rom codes of your ds1820
                              ; remember to connect only one ds1820 for
                              ; rom detection
 ; wait approx. 5 sec
 clrwdt                       ; clear watchdog timer
 sleep                        ; wait…
 clrwdt                       ; clear watchdog timer
 sleep                        ; wait…

 call    lcdclear             ; clear display
 bcf     OPTION_REG,PS0    
 bcf     OPTION_REG,PS1       ; set prescaler to 1:16 = 0.25 seconds
loop

 movlw   1                    ; set bit 1 of LCD_ACTDS
 movwf   LCD_ACTDS         
 call    dstemperature        ; get temperature values of first ds1820
 call    dsminusconvertion
 movlw   DS_MIN0              ; minmax calculation
 call    dsminmax2tmp         ; since we have not enough ram space
 call    dscalcmax            ; on 16f84, we can only have 2
 call    dscalcmin            ; minmax calculation areas
 movlw   DS_MIN0
 call    dstmp2minmax
 ifdef LCD_2X16               ; code to print values on 2×16 display
 movlw   LCD_LINE0            ; put output to line 1 of the lcd display
 call    lcdsdda
 btfss   BTN_ACTMODE,BTN_MODENORMAL
 goto    modeminmax0
 call    dsprinttitle0
 call    lcdprintdsdata
 goto    modeend0
modeminmax0
 btfss   BTN_ACTMODE,BTN_MODEMINMAX
 goto    modeend0
 call    dsprintminmax0
modeend0
 endif
 ifdef LCD_4X16               ; code to print values on 4×16 display
 movlw   LCD_LINE0
 call    lcdsdda
 call    dsprinttitle0
 call    lcdprintdsdata
 movlw   LCD_LINE1
 call    lcdsdda
 call    dsprintminmax0
 endif
 movlw   2                    ; set bit 2 of LCD_ACTDS
 movwf   LCD_ACTDS         
 call    dstemperature        ; get temperature values of second ds1820
 call    dsminusconvertion
 movlw   DS_MIN1              ; minmax calculation
 call    dsminmax2tmp
 call    dscalcmax
 call    dscalcmin
 movlw   DS_MIN1
 call    dstmp2minmax
 ifdef LCD_2X16               ; code to print values on 2×16 display
 movlw   LCD_LINE1            ; put output to line 2 of the lcd display
 call    lcdsdda
 btfss   BTN_ACTMODE,BTN_MODENORMAL
 goto    modeminmax1
 call    dsprinttitle1
 call    lcdprintdsdata
 goto    modeend1
modeminmax1
 btfss   BTN_ACTMODE,BTN_MODEMINMAX
 goto    modeend1
 call    dsprintminmax1
modeend1
 endif
 ifdef LCD_4X16               ; code to print values on 4×16 display
 movlw   LCD_LINE2
 call    lcdsdda
 call    dsprinttitle1
 call    lcdprintdsdata
 movlw   LCD_LINE3
 call    lcdsdda
 call    dsprintminmax1
 endif

 ; more ds1820 may follow if the lcd display has enough lines

 clrwdt                      ; clear watchdog timer
 sleep                       ; wait 0.50 seconds, for screen switching
 
 ; rotate through the display modes
 bcf     STATUS,C
 rlf     BTN_ACTMODE,F
 btfss   BTN_ACTMODE,BTN_MODEMINMAX + 1
 goto    loop                ; there are still modes available
 movlw   1 << BTN_MODENORMAL ; no modes left, start with first mode
 movwf   BTN_ACTMODE

 goto    loop              
end