Interfacing with an LTC1298 dualchannel, 12-bit A/D
/* LTC1298_1.C (Flashlite V25)
**
** Illustrates how to interface with a Linear LTC1298 Dual 12-bit A/D.
**
** For a data sheet on the LTC1298, see http://www.linear.com.
**
** Flashlite LTC1298
** ------ Dout (term 6)
** |
** 1K |
** P2.2 DAT -------------------------- Din (term 5)
** P2.1 CLK -------------------------- Clk (term 7)
** P2.0 NOT_CS ------------------------ /CS (term 1)
**
** Routine performs an A/D conversion on Ch 0 (term 2 of LTC1298) and
** displays. Repeats for Ch 1 (term 3). Continually loops.
**
** Note the use of general functions put_bit and get bit to set a
** specified bit on a specified port to the specified state and to
** read a specific bit on a specified port.
**
** copyright, Peter H. Anderson, Baltimore, MD, Sept, '00
*/
#include <stdio.h>
#include <dos.h>
#define SEG 0xf000
#define P2_OFFSET 0xff10
#define PM2_OFFSET 0xff11
#define PMC2_OFFSET 0xff12
typedef unsigned char byte;
#define NOT_CS 0
#define CLK 1
#define DAT 2
#define OUT 0
#define IN 1
int LTC1298_get_adc(byte far *p, byte ch);
void put_bit(byte far *p, byte bit_num, byte state);
byte get_bit(byte far *p, byte bit_num);
byte dirs;
void main(void)
{
byte far *p2, *pm2, *pmc2;
int ad_val;
p2 = MK_FP(SEG, P2_OFFSET);
pm2 = MK_FP(SEG, PM2_OFFSET);
pmc2 = MK_FP(SEG, PMC2_OFFSET);
*pmc2 = 0x00; /* not special purpose */
dirs = 0xff;
*pm2 = dirs; /* all of port 2 are inputs */
while(1)
{
ad_val = LTC1298_get_adc(p2, 0); /* perform a meas on Ch 0 */
printf("Ch0 %4x\n", ad_val);
ad_val = LTC1298_get_adc(p2, 1); /* perform a meas on Ch 1 */
printf("Ch1 %4x\n", ad_val);
delay(1000);
}
}
int LTC1298_get_adc(byte far *p, byte ch)
{
int ad_val = 0x0000;
byte n, ad_command;
if (ch == 0)
{
ad_command = 0x0d;
}
else
{
ad_command = 0x0f;
}
dirs = dirs & (~0x07); /* make lower three bits outputs */
*(p+1) = dirs;
put_bit(p, NOT_CS, 1); /* initial conditions */
put_bit(p, CLK, 1);
put_bit(p, NOT_CS, 0); /* bring CS low - resets LTC1298 */
for (n=0; n<4; n++) /* send the 4-bit command, most sig bit first */
{
if (ad_command & 0x08)
{
put_bit(p, DAT, 1);
}
else
{
put_bit(p, DAT, 0);
}
put_bit(p, CLK, 0);
put_bit(p, CLK, 1);
ad_command = ad_command << 1;
}
put_bit(p, CLK, 0); /* dummy clock pulse */
put_bit(p, CLK, 1);
dirs = dirs | (0x01 << DAT); /* make DAT an input */
*(p+1) = dirs;
for (n=0; n<12; n++) /* fetch the result, most sig bit first */
{
put_bit(p, CLK, 0);
put_bit(p, CLK, 1);
ad_val = (ad_val << 1) | get_bit(p, DAT);
}
put_bit(p, NOT_CS, 1); /* turn off device */
return(ad_val);
}
void put_bit(byte far *p, byte bit_num, byte state)
{
byte mask_0, mask_1;
mask_1 = 0x01 << bit_num;
mask_0 = ~mask_1;
if (state == 0)
{
*p = *p & mask_0;
}
else
{
*p = *p | mask_1;
}
}
byte get_bit(byte far *p, byte bit_num)
{
byte mask_1;
mask_1 = 0x01 << bit_num;
if (*p & mask_1)
{
return(1);
}
else
{
return(0);
}
}