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.
OTRA FOTO
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