> On Mon, 3 Dec 2001, Vasile Surducan wrote:
>
> > Thanks Gerhart and Tony
> >
> > On Mon, 3 Dec 2001, [Iso-8859-1] K|bek Tony wrote:
> >
> > > Hi,
> > > Perhaps if you would elaborate a bit on the actual
> > > formula you intend to use I can give some hints.
> > >
> > OK here is:
> >
> > temperature = temp_read - 1/2LSB + [ (count_per_degree - count_remain /
> > count_per_degree) ]
>
> I think your right most ')' is in the wrong place.
> As I recall, count_per_degree is ~50.
>
> Notice that the above formula can be reduced:
>
> temperature = temp_read + [(count_per_degree - count_remain) /
> count_per_degree] - count_per_degree/(2*count_per_degree)
>
> = temp_read + [(2*count_per_degree - 2*count_remain) /
> 2*count_per_degree] - count_per_degree/(2*count_per_degree)
>
> = temp_read + [(count_per_degree - 2*count_remain) /
> 2*count_per_degree]
>
>
> or another form that may even be more useful:
>
> temperature = temp_read + 1/2LSB - count_remain / count_per_degree
>
>
>
> I doubt you really need more than a few bits from the division. If not
> then you can try the routine below. Note that this does a 4-bit division
> for the low byte of the temperature. Also, for clarity I included some
> debug code to illustrate its use. It should be clear from the variable
> names on how to change this to a real interface to a ds1820.
>
>
> include /usr/local/share/gpasm/header/p16f84.inc
>
> cblock 0x0c
> temp_read
> temp_hi
> temp_lo
> count_remain
> count_per_degree
> x
> endc
>
>
>
>
> movlw 0x20
> movwf temp_read
>
> ; debug loop
> l1
>
> movlw 0x40
> movwf count_per_degree
> movf x,w
> movwf count_remain
>
> call div
>
> ; increment the temperature
> incf x,f
> movf x,w
> addlw -0x40
> skpc
> goto l1
>
> incf temp_read,f
> clrf x
>
> goto l1
>
> ; convert the temperature into a 12 bit result: 8-bit integer
> ; plus a 4-bit fraction. Note, negative temperatures are not handled
>
> div:
> movf temp_read,w ; Get the high 8 bits
> movwf temp_hi
>
>
> ; 4-bit division
>
> movlw 0x08 ;Quotient of division is stored
> movwf temp_lo ;here. Also used as a loop counter
>
> movf count_per_degree,w ;Keep divisor in W
>
> div_loop:
> clrc
> rlf count_remain,f ;Shift dividend
>
> subwf count_remain,f ;If divisor is <= dividend
> rlf temp_lo,f ;then C is set
> btfss temp_lo,0 ;If C was not set then
> addwf count_remain,f ;we need to restore the subtraction
>
> btfss temp_lo,7 ;If msb is clear (the loop count bit)
> goto div_loop ; we're done, else loop more
>
>
> ; through division. Low 4 bits of temp_lo contain result.
> ; we need to << 4, and subtract from "1/2" or 0x80/0x100.
> ; If the subtraction causes a borrow, then we need to
> ; decrement the high byte as well.
>
> swapf temp_lo,w ;<<4
> andlw 0xf0 ;get rid of loop count bit
> addlw 0x80 ;"subtract" 1/2 note -1/2=0x80
> movwf temp_lo ;save the low temperature
>
> skpc ;If the division is less than 1/2
> decf temp_hi,f ;get the borrow bit from the high byte
>
>
> return
>
> end
>
>
> This routine works in this contrived example. There's a little room for
> optimization too...
>
> >
> > All values are 9 bit numbers,
> > Truncated half-degree bit ( temp_read - 1/2LSB ) its a simple task:
> > rrf temp_read_lo, f
> > bcf status_c
> > rlf temp_read_lo, f
>
> The same can be accomplished with:
>
> bcf temp_read_lo,0
>
> But neither of these are the same for subtracting a 1/2 LSB.
>
> You're going to need a whole other byte to store that extra bit.
>
> If you want to subtract a half LSB do this:
>
> decf HI_BYTE,F
> movlw 0x80
> movwf LO_BYTE
>
>
> You can now think of the LO_BYTE as a fraction of 0x80/0x100 = 1/2.
>
> > The new value ( 9 bit too ) will have resolution of only 1 C degree
> > instead of 0.5 C and will be contained in temp_read_lo, temp_read_hi
> > ( the sign )
> > Application note 105 from Dallas said :
> > "convert truncated value from 2's complement to signed integer"
> > This is the problem I have.
> > Application note does say nothing more about.
> > But also it seems that measuring only positive temperatures I will not
> > have errors even I will not perform that conversion.
> > About division, I've plan to use a standard 16bit division routine,
> > maybe Nikolay will point to a 9 bit division one ?
>
> The last time I checked, Nikolai was too busy working on his foos serve.
>
> Scott
>
> --
>
http://www.piclist.com hint: The list server can filter out subtopics
> (like ads or off topics) for you. See
http://www.piclist.com/#topics
>
>