Overview
The DS2430 1-W 256-bit EEPROM might be used as a silicon serial number to uniquely identify a product and also to store site dependent data and calibration data.
A more complete discussion in the context of a PIC12C509 appears elsewhere.
// Program 2430_1.C (CCS PCM - PIC16F84) // // Illustrates use of DS2430A 1-W 256 bit EEPROM. // // Writes 8 bytes to DS2430A beginning at address 0x06 and then // reads them back and displays them on serial LCD on RA.0. // // 16F84 DS2430A // RB.0 (term 6) ------------------------------ DQ (term 2) // // copyright, P. H. Anderson, Baltimore, MD, Apr, '99 #case #include <16F84.h> #include <defs_f84.h> #define TxData 0 // RA.0 for LCD display void write_ds2430(int sensor, int adr, int *buff, int num_vals); void read_ds2430(int sensor, int adr, int *buff, int num_vals); // 1-wire prototypes void _1w_init(int sensor); int _1w_in_byte(int sensor); void _1w_out_byte(int d, int sensor); void _1w_pin_hi(int sensor); void _1w_pin_low(int sensor); void _1w_strong_pull_up(int sensor); // not used in this routine // 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 d[8]={0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e}; // data to write to EEPROM int buff[8], n; lcd_init(); write_ds2430(0, 6, d, 8); // sensor 0, adr 6, array d, 8 bytes read_ds2430(0, 6, buff, 8); // sensor 0, adr 6, array buff, 8 bytes for(n=0; n<8; n++) { if ((!(n%4)) && (n!=0)) // 4 bytes to a line { lcd_new_line(); } lcd_hex_byte(buff[n]); lcd_char(' '); } lcd_new_line(); } void write_ds2430(int sensor, int adr, int *buff, int num_vals) // write num_vals in array buff beginning at address adr { int n; _1w_init(sensor); _1w_out_byte(0xcc, sensor); // skip ROM _1w_out_byte(0xf0, sensor); // read memory into scratch pad _1w_init(sensor); _1w_out_byte(0xcc, sensor); // skip ROM _1w_out_byte(0x0f, sensor); // write scratch pad _1w_out_byte(adr, sensor); // starting address for(n=0; n<num_vals; n++) { _1w_out_byte(buff[n], sensor); } _1w_init(sensor); _1w_out_byte(0xcc, sensor); // skip ROM _1w_out_byte(0x55, sensor); // copy scratch pad _1w_out_byte(0xa5, sensor); // validation key _1w_strong_pull_up(sensor); // while programming } void read_ds2430(int sensor, int adr, int *buff, int num_vals) // reads num_vals bytes into array buff beginning at address adr { int n; _1w_init(sensor); _1w_out_byte(0xcc, sensor); // skip ROM _1w_out_byte(0xf0, sensor); // read memory into scratch pad _1w_out_byte(adr, sensor); for(n=0; n<num_vals; n++) { buff[n]=_1w_in_byte(sensor); } } // The following are standard 1-Wire routines. void _1w_init(int sensor) { _1w_pin_hi(sensor); _1w_pin_low(sensor); delay_10us(50); _1w_pin_hi(sensor); delay_10us(50); } int _1w_in_byte(int sensor) { int n, i_byte, temp, mask; mask = 0xff & (~(0x01<<sensor)); for (n=0; n<8; n++) { PORTB=0x00; TRISB=mask; TRISB=0xff; #asm CLRWDT NOP NOP #endasm temp=PORTB; if (temp & ~mask) { i_byte=(i_byte>>1) | 0x80; // least sig bit first } else { i_byte=i_byte >> 1; } delay_10us(6); } return(i_byte); } void _1w_out_byte(int d, int sensor) { int n, mask; mask = 0xff & (~(0x01<<sensor)); for(n=0; n<8; n++) { if (d&0x01) { PORTB=0; TRISB=mask; // momentary low TRISB=0xff; delay_10us(6); } else { PORTB=0; TRISB=mask; delay_10us(6); TRISB=0xff; } d=d>>1; } } void _1w_pin_hi(int sensor) { TRISB = 0xff; } void _1w_pin_low(int sensor) { PORTB = 0x00; TRISB = 0xff & (~(0x01 << sensor)); } void _1w_strong_pull_up(int sensor) // bring DQ to strong +5VDC { PORTB = 0x01 << sensor; TRISB = 0xff & (~(0x01 << sensor)); delay_ms(250); TRISB = 0xff; } // 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 } 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); }