Interfacing with Microchip's 24LC32 EEPROM - Basic Stamp 2

Intoduction

Currently I have two undergraduate students who are developing material on interfacing with I2C devices. This includes Dallas Semiconductor DS1621 - Digital Thermometer and Microchip 24LC32 32K EEPROM.

At present, we have have implemented random read and write functions for the EEPROM. Future development will focus routines for sequential reads and writes and and an illustration on how this may be used as an inexpensive data logger. We also plan to look at the new 65K serial EEPROMs.

Another discussion deals with interfacing the 24LC32 with a PC Parallel Port

The 24LC32 is available in an 8-pin DIP from Digikey (Digikey 32LC32/P-ND). This provides 4K bytes of data storage for a mere $3.00. Note that eight of these may be cascaded on the same two signal leads so as to provide 32 K bytes. Pretty amazing!

The user is referred to Microchip's Home Page for a data sheet. Hopefully with the data sheet and the following snippet of code, the user can adapt the code to their specific application. Note that in order to enhance understanding I avoided such commands as shiftin and shiftout.

If there are other I2C devices that you would like us to look at, please send me e-mail.

I have just received a grant from the National Science Foundation to continue doing this kind of stuff with my students. If you find this material useful, an entry in my guest book or an e-mail would be greatly appreciated.


' 24LC32.BS2
'
' Illustrates how to write and read to and from 24LC32 32K EEPROM
'
' BS2					24LC32
'
' Pin5 (term 10) ------------------- SCL (term 6) ----- To Other 
' Pin4 (term 9) -------------------- SDA (term 5) ----- 24LC32 Devices
'
' Note that 10K pullup resistors to +5VDC are required on both signal
leads.
' 
' Note that the slave address is determined by A2 (term 3), A1 (term2)
' and A0 (term 1) on 24LC32.  The above SCL and SDA leads may be multipled
' to eight devices, each strapped for a unique A2 A1 A0 setting.
'
' Debug and Pause statements were included only to see what is going on.
'
' copyright Peter H. Anderson, MSU, March 1, '97
'

	address var word	' 000 0000 00000 - 111 1111 1111
	device var byte		' device 0-7
	dta var byte		' data to program

	o_byte var byte		' byte to send to memory
	i_byte var byte		' byte fetched from memory

	n var byte		' index
	b var bit		' bit 
	ack_bit var bit		

	SDA_PIN con 4
	SCL_PIN con 5
	SDA_OUT var out4
	SCL_OUT var out5
	SDA_IN  var in4
	SDA_DIR var dir4

	OUT con 1
	IN con 0

	dirs=$f0ff

main
        address=$341	' program data 55 into address $341
        device=0
	dta=$55

        gosub write_random_data	'write dta to address $341

	gosub read_random_data	'read from same location
	debug hex i_byte

	stop

write_random_data	'writes specified data to specified address
agn	

	gosub start

	o_byte=$a0 | (device << 1)		' 1 0 1 0 a2 a1 a0 0
	gosub out_byte
	gosub nack
	o_byte= address >> 8		' high byte of address
        gosub out_byte
	gosub nack
	o_byte= address & $ff		' low byte of address
	gosub out_byte
	gosub nack
	o_byte= dta			' data
	gosub out_byte
	gosub nack

	gosub sstop

	gosub ack			' ack polling
	if ack_bit=1 then agn
	return

read_random_data	' reads data from specified address
			' returns in variable in_byte

	gosub start
	o_byte=$a0 | (device << 1)	' 1 0 1 0 a2 a1 a0 0
	gosub out_byte
	gosub nack
	o_byte= address >> 8		' high byte of address
	gosub out_byte
	gosub nack
	o_byte= address & $ff		' low byte of address
	gosub out_byte
	gosub nack

	gosub start
	o_byte=$a0 | (device << 1) | $01' 1010 a2 a1 a0 1
	gosub out_byte
	gosub nack

	gosub get_byte
	gosub nack
	
	gosub sstop
	return

out_byte
	
        low SDA_PIN   
   	
	for n=0 to 7 
	   b= (o_byte >> 7) & 1       
	   if (b=1) then out_one
	   SDA_DIR=OUT 
           debug "0"
_clk	      
	   high SCL_PIN
           pause 100
           low SCL_PIN
           pause 100
           o_byte=o_byte << 1
        next
        SDA_DIR=IN
        return
out_one
        SDA_DIR=IN
        debug "I"
   	goto _clk
   

get_byte
    	SDA_DIR=IN	'input

   	i_byte=0
        for n=0 to 7
           pause 200
           high SCL_PIN
           pause 200
           i_byte=(i_byte << 1) | SDA_IN
           debug dec SDA_IN
           low SCL_PIN
      	      
        next
 
        SDA_DIR=OUT	'output
        return

nack
   	SDA_DIR=IN	' input just in case
	ack_bit=1
	high SCL_PIN
	ack_bit=SDA_IN
        debug "A"
        debug dec ack_bit
        debug $0d
        low SCL_PIN
        SDA_DIR=OUT	' output
        return

ack

 	debug "POLL"
	gosub start
        o_byte=$a0 | (device << 1)
	gosub out_byte
        gosub nack

        return	

start
	high SDA_PIN
	high SCL_PIN
	debug "START"
        debug $0d
        low SDA_PIN	'bring SDA low while clock is high
        low SCL_PIN
        return

sstop
	low SDA_PIN   
        high SCL_PIN
        pause 10
        high SDA_PIN 	'bring SDA high while clock is high
        debug "STOP"
        debug $0d
        return