LTC1392 Data Acq Unit, CCS PCM


A more complete discussion of the operation of the LTC1392 in the context of the Parallax BASIC Stamp 2 appears here.

 

// LTC1392.C (CCS PCM - PIC16F84)
//
// Measures Temperature in degrees C, V_cc, V_diff (1.0 V Ref) and V_diff
// (0.5 V Ref).  Ten such measurment sequences performed.  Results are
// displayed on a serial LCD on RA.0.
//
//	PIC16F84	 			  LTC1392
//
//
//	RB.3 (term 9) <----RX_DATA ---------- (term 2) D_out
//
//	RB.2 (term 8) ---- TX_DATA ---------- (term 1) D_in
//	RB.1 (term 7) ----- CLK ------------- (term 3) CLK
//	RB.0 (term 6) ----- /CS ------------- (term 4) /CS
//
//
//					------- (term 6) +V_in
//					------- (term 7) -V_in
//
//
//					+5 ---- (term 8) V_cc
//					GRD --- (term 5) GRD
//
// copyright, Towanda Malone, Baltimore, MD, Apr, '99

#case
#include <16f84.h>
#include <string.h>
#include <defs_f84.h>

#define true 1
#define false 0

#define RX_D_DIR trisb3
#define TX_D_DIR trisb2
#define CLK_DIR trisb1
#define CS_DIR trisb0

#define RX_D_PIN rb3
#define TX_D_PIN rb2
#define CLK_PIN rb1
#define CS_PIN rb0

#define IN 1
#define OUT 0

long make_meas(int command);
void clk(void);

#define TxData 0	// RA.0 - output to serial LCD

// delay routines
void delay_ms(long t);
void delay_10us(int t);

// LCD routines
void lcd_init(void);
void out_RAM_str(int *s);
void lcd_hex_byte(int val);
void lcd_dec_byte(int val, int digits);
int num_to_char(int val);
void lcd_char(int ch);
void lcd_new_line(void);

void main(void)
{
   int n;
   char s[20];
   long T_c_100, V_cc_100, V_diff_100_0_pt_5, V_diff_100_1_pt_0, get_10;

   RX_D_DIR = IN;
   TX_D_DIR = OUT;
   CLK_DIR = OUT;
   CS_DIR = OUT;

   for(n=0; n<10; n++)
   {
      lcd_init();
      get_10 = make_meas(0x00); // temperature measurement
      T_c_100 = (25 * get_10)-13000;

      get_10 = make_meas(0x01);	// measure V_CC
      V_cc_100 = (60 * get_10)/128+242;

      get_10 = make_meas(0x02);
      V_diff_100_1_pt_0 = (100 * get_10)/1024;

      get_10 = make_meas(0x03);
      V_diff_100_0_pt_5 = (50 * get_10)/1024;

      // now display the results
      strcpy(s, "T_c=");
      out_RAM_str(s);
      if (T_c_100/10000)	// for example 105 degrees
      {
         lcd_dec_byte(T_c_100/100, 3);
      }
      else if (T_c_100/1000)	// for example 24 degrees
      {
         lcd_dec_byte(T_c_100/100, 2);
      }
      else
      {
 	 lcd_dec_byte(T_c_100/100, 1);	// for example in 5 degrees
      }
      lcd_char('.');
      lcd_dec_byte(T_c_100%100, 2);
      lcd_new_line();

      strcpy(s, "V_cc=");
      out_RAM_str(s);
      lcd_dec_byte(V_cc_100/100, 1);
      lcd_char('.');
      lcd_dec_byte(V_cc_100%100, 2);
      lcd_new_line();


      strcpy(s, "V_diff=");
      out_RAM_str(s);
      lcd_dec_byte(V_diff_100_1_pt_0/100, 2);
      lcd_char('.');
      lcd_dec_byte(V_diff_100_1_pt_0%100, 2);
      lcd_new_line();

      strcpy(s, "V_diff=");
      out_RAM_str(s);
      lcd_dec_byte(V_diff_100_0_pt_5/100, 2);
      lcd_char('.');
      lcd_dec_byte(V_diff_100_0_pt_5%100, 2);
      delay_ms(3000);
   }
}

long make_meas(int command)
{
   int n;
   long get_10=0;
   CLK_PIN = 1;
   CS_PIN = 1;
   CS_PIN = 0;		// beginning of data

// send four bits
   TX_D_PIN = 1;  	// start bit
   clk();
   TX_D_PIN = (command >> 1) & 0x01;  // msbit of command
   clk();
   TX_D_PIN = command & 0x01;
   clk();
   TX_D_PIN = 1;  	// stop bit
   clk();
   delay_ms(10);
   clk();
   delay_ms(100);
// now fetch 10 bits
   for (n=0; n<10; n++)
   {
      CLK_PIN = 0;
      delay_ms(1);
      get_10 =  (get_10 << 1) | RX_D_PIN;
      CLK_PIN = 1;
   }
   CS_PIN = 1;
   return(get_10);
}

void clk(void)
{
   CLK_PIN = 0;
   CLK_PIN = 1;
}

void delay_10us(int t)
{
#asm
      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}

void delay_ms(long t)	// delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}

int num_to_char(int val)	// converts val to hex character
{
   int ch;
   if (val < 10)
   {
     ch=val+'0';
   }
   else
   {
     val=val-10;
     ch=val + 'A';
   }
   return(ch);
}


// lcd routines
void lcd_char(int ch)	// serial output to PIC-n-LCD, 9600 baud
{
   int n, dly;
   		// start bit + 8 data bits

#asm
   BCF STATUS, RP0
   MOVLW 9
   MOVWF n
   BCF STATUS, C

LCD_CHAR_1:

   BTFSS STATUS, C
   BSF PORTA, TxData
   BTFSC STATUS, C
   BCF PORTA, TxData
   MOVLW 32
   MOVWF dly

LCD_CHAR_2:
   DECFSZ dly, F
   GOTO LCD_CHAR_2
   RRF ch, F
   DECFSZ n, F
   GOTO LCD_CHAR_1

   BCF PORTA, TxData
   CLRWDT
   MOVLW 96
   MOVWF dly

LCD_CHAR_3:
   DECFSZ dly, F
   GOTO LCD_CHAR_3
   CLRWDT
#endasm
}

void lcd_init(void)	// sets TxData in idle state and resets PIC-n-LCD
{
#asm
   BCF STATUS, RP0
   BCF PORTA, TxData
   BSF STATUS, RP0
   BCF TRISA, TxData
   BCF STATUS, RP0
#endasm
   lcd_char(0x0c);
   delay_ms(250);
}

void lcd_new_line(void)	// outputs 0x0d, 0x0a
{
   lcd_char(0x0d);
   delay_ms(10);	// give the PIC-n-LCD time to perform the
   lcd_char(0x0a);	// new line function
   delay_ms(10);
}


void out_RAM_str(int s)
{
   while(*s)
   {
      lcd_char(*s);
      ++s;
   }
}

void lcd_hex_byte(int val) // displays val in hex format
{
   int ch;
   ch = num_to_char((val>>4) & 0x0f);
   lcd_char(ch);
   ch = num_to_char(val&0x0f);
   lcd_char(ch);
}

void lcd_dec_byte(int val, int digits)
// displays byte in decimal as either 1, 2 or 3 digits
{
   int d;
   int ch;
   if (digits == 3)
   {
      d=val/100;
      ch=num_to_char(d);
      lcd_char(ch);
   }
   if (digits >1)	// take the two lowest digits
   {
       val=val%100;
       d=val/10;
       ch=num_to_char(d);
       lcd_char(ch);
   }
   if (digits == 1)	// take the least significant digit
   {
       val = val%100;
   }

   d=val % 10;
   ch=num_to_char(d);
   lcd_char(ch);
}