The DS1867 Dual Pot is discussed in the context of the BASIC Stamp 2 and Microchip assembly elsewhere on this web site.
// DS1867.C (CCS PCM, 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 settings 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 // // copyright, Peter H. Anderson, Baltimore, MD, Apr, '99 #case #include <16f84.h> #include <defs_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 TxData 0 // RA.0 - interface to serial LCD #define IN 1 #define OUT 0 void set_pot_values(int stack_bit, int setting_0, int setting_1); void get_pot_values(int *p_stack, int *p_setting_0, int *p_setting_1); void ds1867_out_8(int val); int ds1867_in_8(void); // 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 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(); } void set_pot_values(int stack_bit, int setting_0, int 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; ds1867_out_8(setting_1); ds1867_out_8(setting_0); RST_PIN = 0; } void get_pot_values(int *p_stack, int *p_setting_0, int *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 = ds1867_in_8(); *p_setting_0 = ds1867_in_8(); RST_PIN = 0; DQ_DIR = OUT; // this is simply housekeeping } void ds1867_out_8(int val) // shift out, most sig bit first { int n; for (n=0; n<8; n++) { DQ_PIN = (val>>7) & 0x01; // most sig bit first CLK_PIN = 1; CLK_PIN = 0; val = val << 1; } } int ds1867_in_8(void) { int n, val=0; for (n=0; n<8; n++) { val = (val << 1) | DQ_PIN; CLK_PIN = 1; // post clock CLK_PIN = 0; } return(val); } // delay routines 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); } // LCD routines 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); } 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 } // LCD routines 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); }