PIC C - Interface with DS1867 Dual Potentiometer

copyright, Peter H. Anderson, Baltimore, MD, Feb, '99


// DS1867.C  (High Tech PICC, PIC16F84)
//
// DS1867 Dual Digital Potentiometer with EEPROM
//
// Illustrates how to set the two potentiometers and how to read
// them.
//
// Sets Stack bit to 0, Pot 1 to 80 (hex) and Pot 0 to 40H.
// Then reads pot setting and displays in hexadecimal on LCD on 
// RA.0.
//
//	PIC16F84		      DS1867
//
//	RB2, term 8 ----------------> DQ, term 8
//	RB1, term 7 ----------------> CLK, term 6	
//	RB0, term 6 ----------------> RST, term 5
//
//				  Terminal 9 connected to 8 through
//			          22K limiting resistor
// 
// Build with DS1867.C and LCD_F84.C
//
// copyright, Peter H. Anderson, Baltimore, MD, Feb, '99

#include <pic.h>
#include "lcd_f84.h"

#define DQ_PIN RB2
#define CLK_PIN RB1
#define RST_PIN RB0

#define DQ_DIR TRISB2
#define CLK_DIR TRISB1
#define RST_DIR TRISB0

#define IN 1
#define OUT 0

void set_pot_values(unsigned char stack_bit, unsigned char setting_0, 
                    unsigned char setting_1);
void get_pot_values(unsigned char *p_stack, unsigned char *p_setting_0,
                    unsigned char *p_setting_1);
void out_8(unsigned char val);	
unsigned char in_8(void);

void main(void)
{
   unsigned char stack_bit, setting_0, setting_1;
   
   DQ_DIR = OUT;
   CLK_DIR = OUT;
   RST_DIR = OUT;

   stack_bit = 0;
   setting_0 = 0x80;
   setting_1 = 0x40;
   
   set_pot_values(stack_bit, setting_0, setting_1);

   get_pot_values(&stack_bit, &setting_0, &setting_1);
   // note passing by reference

   lcd_init();

   lcd_char(stack_bit + '0');	// display the stack bit
   lcd_new_line();
   lcd_hex_byte(setting_0);	// display setting of pot 0
   lcd_char(' ');
   lcd_hex_byte(setting_1);	// display setting of pot 1
   lcd_new_line();
   lcd_delay_ms(2000);
}

void set_pot_values(unsigned char stack_bit, unsigned char setting_0, 
                    unsigned char setting_1)
{
   RST_PIN = 0;
   CLK_PIN = 0;
   RST_PIN = 1;	// bring RST high while CLK is low

   DQ_PIN = stack_bit & 0x01;
   CLK_PIN = 1;
   CLK_PIN = 0;

   out_8(setting_1);
   out_8(setting_0);

   RST_PIN = 0;
}

void get_pot_values(unsigned char *p_stack, unsigned char *p_setting_0,
                    unsigned char *p_setting_1)
{
   DQ_DIR = IN;	// turn around DQ so as to read data
   RST_PIN = 0;
   CLK_PIN = 0;
   RST_PIN = 1;

   *p_stack = DQ_PIN;
   CLK_PIN = 1;
   CLK_PIN = 0;
   *p_setting_1 = in_8();
   *p_setting_0 = in_8();
   RST_PIN = 0;
   DQ_DIR = OUT;	// this is simply housekeeping
}
   
void out_8(unsigned char val)	// shift out, most sig bit first
{
   unsigned char n;	
   for (n=0; n<8; n++)     
   {
      DQ_PIN = (val>>7) & 0x01;
      CLK_PIN = 1;
      CLK_PIN = 0;
      val = val << 1;
   }
}

unsigned char in_8(void)
{
   unsigned char n, val=0;
   
   for (n=0; n<8; n++)
   {   
      val = (val << 1) | DQ_PIN;
      CLK_PIN = 1;	// post clock
      CLK_PIN = 0;   
   }
   return(val);
}