const MINIMUM_ADC_COUNT = 220; const MAXIMUM_ADC_COUNT = 468; const SPACING = 8; const TEMPERATURE_TABLE_NUM_ENTRIES = 32; var Temperature:integer; function ReadEeprom(TEMPERATURE_CAL_VALUE:integer):integer;forward; {---------------------------------------------------------------------- | MeasureTemperature | | Calculates the temperature in §C given the ADC count by lookup | table and linear interpolation of the diode circuit characteristic. | | Parameters: | AdcCount Raw ADC count. | | Returns: | Temperature in degC x 10. INVALID_TEMPERATURE if out of range. \--------------------------------------------------------------------- } function MeasureTemperature(AdcCount:integer):integer; var Index, InterpolationDistance, TempDiff : integer; const Table : array[0..TEMPERATURE_TABLE_NUM_ENTRIES] of integer = (1171, 1116, 1061, 1006, 952, 899, 846, 793, 741, 689, 638, 588, 537, 488, 438, 389, 341, 293, 246, 199, 152, 106, 61, 16, -29, -73, -116, -160, -202, -244, -286, -327); begin { Index is the index into the table. Each table entry is 8 ADC } { counts higher than the last one, so subtract the offset and } { divide by 8 to find the table index. InterpolationDistance } { is the linear distance between the the table entry ADC count } { and the actual ADC count. } { Check range of AdcCount and saturate index if out of range. } if AdcCount < MINIMUM_ADC_COUNT then begin { Underflow of ADC - saturate at minimum value } Index := 0; end else if AdcCount > MAXIMUM_ADC_COUNT then begin { Overflow of ADC - saturate at maximum value } Index := TEMPERATURE_TABLE_NUM_ENTRIES - 1; end else begin { Find the index of the table entry just below th e ADC value } Index := (AdcCount - MINIMUM_ADC_COUNT) div SPACING; end; { Calculate the interpolation between the table entries either side of } { the ADC value. This is the remainder of the difference between the } { ADC count and the minimum temperature ADC count divided by the } { spacing between table entries. Since the spacing is a power of 2, } { this can be achieved by simply masking all but the bottom 3 bits. } InterpolationDistance := (AdcCount - MINIMUM_ADC_COUNT) and (SPACING - 1); TempDiff := (Table[Index] - Table[Index+1]); { The temperature is then the base temperature minus the amount } { calculated by linear interpolation. The compiler is clever enough } { to know that dividing by 8 is a right shift of three bits. } Temperature := Table[Index] - ((TempDiff * InterpolationDistance) div SPACING); MeasureTemperature := Temperature; end;