### Measuring Temperature using an NTC Thermistor

```/* Program Therm_2.C (Flashlite V25)
**
** Measures temperature using a 10K NTC Thermistor in a voltage divider
** arrangement as illustrated.
**
** (1) V_therm = Vref/4096 * ad_val
** (2) V_therm = r_therm / (r_therm + 10.0K) * V_ref
**
** equating these and solving for r_therm;
**
** (3) r_therm = 10,0K / ((4096/ad_val) - 1)
**
** The temperature is then calculated using a two point model;
**
** (4) T_Kelvin = 1/(a + b*ln(r_therm))
** (5) T_C = T_K - 273.15
**
** Note that the program checks to see if calibration file "therm.dta"
** exists and if so, these values of "a" and "b" are used.  Otherwise,
** default values are used.
**
**
**  Flashlite                             TLC2543
**
** P2.3 (SDI) <--------------------------- D_OUT
**
** P2.2 (SDO) ---------------------------> D_IN
** P2.1 (CLK) ---------------------------> CLK
** P2.0 (/CS) ---------------------------> /CS
**
**                 +5
**                   |
**                   10K Fixed
**                   |
**                   |----------------- AIN0
**                   10K NTC        +
**                   |              V_therm
**                   GRD            -
**
**
** copyright, Peter H. Anderson, Baltimore, MD, Sept, 00
*/

#include <stdio.h>
#include <dos.h>
#include <math.h>

#define SEG 0xf000
#define P2_OFFSET 0xff10
#define PM2_OFFSET 0xff11
#define PMC2_OFFSET 0xff12

typedef unsigned char byte;

#define SDI 3
#define SDO 2
#define CLK 1
#define NOT_CS 0

/* #define D */   /* used for debugging */

float ad_meas_avg(byte far *p, byte channel, byte bipolar, int num_samps);
unsigned int ad_meas(byte far *p, byte channel, byte bipolar);
byte spi_io(byte far *p, byte o_byte);
void put_bit(byte far *p, byte bit_num, byte state);
byte get_bit(byte far *p, byte bit_num);
void delay_short(byte d);

void main(void)
{
byte far *p2, *pm2, *pmc2;
byte dirs, channel;

p2 = MK_FP(SEG, P2_OFFSET);
pm2 = MK_FP(SEG, PM2_OFFSET);
pmc2 = MK_FP(SEG, PMC2_OFFSET);
*pmc2 = 0x00;  /* not special purpose */
dirs = 0xf8;    /* lower three bits are outputs */
*pm2 = dirs;

put_bit(p2, NOT_CS, 1);  /* disable to device */
put_bit(p2, CLK, 0);     /* clock at zero */

while(1)
{
/* perform 100 unipolar A/D meas on channel 0 and return the average*/

printf("%.2f\n", T_C);
delay(500);
}
}

{
float r_therm, a, b, T_K, T_C;
FILE *f;

f = fopen("therm.dta", "rt");
if (f!=NULL)     /* if there is a calibration file */
{
fscanf("%f %f", &a, &b);
fclose(f);
}
else
{
a=0.000623;  b=0.000297; /* else, use a default */
}
T_K = 1.0 / (a = b*log(r_therm));
T_C = T_K - 273.15;
return(T_C);
}

float ad_meas_avg(byte far *p, byte channel, byte bipolar, int num_samps)
{
float sum=0.0;
for(n=0; n<num_samps; n++)
{
}
return(sum/num_samps);
}

unsigned int ad_meas(byte far *p, byte channel, byte bipolar)
/* perform measurement on specified channel */
{
byte high_byte, low_byte;

put_bit(p, NOT_CS, 0);
delay_short(20);
high_byte = spi_io(p, (channel << 4) | 0x0c + bipolar);
low_byte = spi_io(p, 0x00);
put_bit(p, NOT_CS, 1);

put_bit(p, NOT_CS, 0);
delay_short(20);
high_byte = spi_io(p, (channel << 4) | 0x0c + bipolar);
low_byte = spi_io(p, 0x00);
put_bit(p, NOT_CS, 1);
#ifdef D
printf(".. %2x  %2x\n", high_byte, low_byte);
#endif
ad_val = (ad_val << 8) | low_byte;  /* result is in high 12 bits */
ad_val = ad_val >> 4;               /* now in low 12 bits */
}

byte spi_io(byte far *p, byte o_byte)
{
byte i_byte, n;

for(n=0; n<8; n++)
{
if (o_byte & 0x80)  /* most sign bit first */
{
put_bit(p, SDO, 1);
}
else
{
put_bit(p, SDO, 0);
}
put_bit(p, CLK, 1); /* data sent on rising edge */
i_byte = (i_byte << 1) | get_bit(p, SDI) ;
/* read in the middle of the clock pulse */
put_bit(p, CLK, 0);
o_byte = o_byte << 1;
}
return(i_byte);
}

void put_bit(byte far *p, byte bit_num, byte state)
{

if (state == 0)
{
}
else
{
}
}

byte get_bit(byte far *p, byte bit_num)
{
{
return(1);
}
else
{
return(0);
}
}

void delay_short(byte d)
{
while(--d)     ;
}
```