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