en.radzio.dxp.pl

Why external EEPROM memory?
Sometimes small internal EEPROM memory in ST7 devices is not enough to application requirements. By connecting external EEPROM chips we can expand this small non-volatile memory space. Most popular EEPROMs are  24Cxx I2C bus memories.

We are use software I2C master routines from page : Software I2C master implementation

Pinout of M24C64 from STMicroelectronics (and other M24Cxx memories) is shown on below picture:

st7-mcu

Pins E0..E2 are chip enable inputs. In dependency of this pins state memory device slave address can be different. Look at below table:

st7-mcu

It can be up to eight different address of M24C64 memory, so we can connect up to eight of M24C64 memory devices to one I2C bus. Device select address is shown on below picture :

st7-mcu

Write single byte to EEPROM memory
Write single byte to specified address in EEPROM memory is realized by a M24C64_WriteByte routine. Before call to m24DstAddr variable write destination address (memory cell address in M24C64 device) and to A register write byte to write in EEPROM memory.
Byte write sequence is shown on below picture :

st7-mcu

Source code of M24C64_WriteByte routine is shown below :

Source code of M24C64_WriteByte routine

;-------------------------------------------------------------------------
; Parameters
; m24DstAddr : destination address
; A : data to write
;-------------------------------------------------------------------------
.M24C64_WriteByte
  PUSH A                   ; store data on stack
  CALL I2C_Start           ; START
  LD   A, #M24WRITEADDR    ;
  CALL I2C_Write           ; address of M24C64
  LD   A, {m24DstAddr + 0} ;
  CALL I2C_Write           ; MSB of memory address
  LD   A, {m24DstAddr + 1} ;
  CALL I2C_Write           ; LSB of memory address
  POP  A                   ; restore data from stack
  CALL I2C_Write           ; data write
  CALL I2C_Stop            ; STOP
  RET

Write buffer to EEPROM memory
When we want write many bytes from continuous memory space to EEPROM memory write byte-by-byte is very ineffective. M24C64 memory device can write up to 32 bytes in one programming cycle. Page write sequence is shown on below picture :

st7-mcu

Source code of M24C64_WriteBuffer routine is shown below:

Source code of M24C64_WriteBuffer routine

;-------------------------------------------------------------------------
; Parameters
; m24SrcAddr : source address (buffer in RAM)
; m24DstAddr : destination address (in EEPROM)
; A : buffer size (max. 32 bytes)
;-------------------------------------------------------------------------
.M24C64_WriteBuffer
  LD   m24Count, A            ; number of bytes to write
  CALL I2C_Start              ; START
  LD   A, #M24WRITEADDR       ;
  CALL I2C_Write              ; address of M24C64
  LD   A, {m24DstAddr + 0}    ;
  CALL I2C_Write              ; MSB destination address
  LD   A, {m24DstAddr + 1}    ;
  CALL I2C_Write              ; LSB destination address
  CLR  X                      ;
M24C64_WriteBufferLoop 
  LD   A,([m24SrcAddr.w],X)   ; read from buffer
  CALL I2C_Write              ; write to EEPROM
  INC  X                      ; X++
  CP   X, m24Count            ; if last byte?
  JRNE M24C64_WriteBufferLoop ; if not, jump to loop
  CALL I2C_Stop               ; STOP
  RET

Read single byte from EEPROM memory
Read single byte from M24C64 EEPROM memory is realized by a M24C64_ReadByte routine. Before call this routine place in m24SrcAddr address of read byte in memory. Single byte read sequence is shown on below picture:

st7-mcu

Source code of M24C64_ReadByte routine is shown below:

Source code of M24C64_ReadByte routine

;-------------------------------------------------------------------------
; Parameters
;   m24SrcAddr : source address (in EEPROM)
; Return value
;   A : read data
;-------------------------------------------------------------------------
.M24C64_ReadByte
  CALL I2C_Start             ; START
  LD   A, #M24WRITEADDR      ;
  CALL I2C_Write             ; slave address
  LD   A, {m24SrcAddr + 0}   ;
  CALL I2C_Write             ; MSB source address
  LD   A, {m24SrcAddr + 1}   ;
  CALL I2C_Write             ; LSB source address
  CALL I2C_Start             ; repeated START
  LD   A, #M24READADDR       ;
  CALL I2C_Write             ; slave address + Read
  SCF                        ; NOACK
  CALL I2C_Read              ; data read
  CALL I2C_Stop              ; STOP
  RET

Read buffer from EEPROM memory
Similar to write more than one byte, there are possibility to read more than one bytes from EEPROM memory. Continuous read sequence is shown on below picture :

st7-mcu

Source code of M24C64_ReadBuffer routine is shown below:

Source code of M24C64_ReadBuffer routine

;-------------------------------------------------------------------------
; Parameters
; m24SrcAddr : source address
; m24DstAddr : destination address
; A : buffer size (min. 2)
;-------------------------------------------------------------------------
.M24C64_ReadBuffer
  DEC  A                     ;
  LD   m24Count, A           ; buffer size - 1
  CALL I2C_Start             ; START
  LD   A, #M24WRITEADDR      ;
  CALL I2C_Write             ; slave address
  LD   A, {m24SrcAddr + 0}   ;
  CALL I2C_Write             ; MSB of source adress
  LD   A, {m24SrcAddr + 1}   ;
  CALL I2C_Write             ; LSB of source address
  CALL I2C_Start             ; START
  LD   A, #M24READADDR       ;
  CALL I2C_Write             ; slave address + R
  CLR  X
M24C64_ReadBufferLoop
  RCF                        ; ACK
  CALL I2C_Read              ; read byte from EEPROM
  LD   ([m24DstAddr.w],X), A ; write to bufer
  INC  X ; X++
  CP   X, m24Count           ; is one before last byte?
  JRNE M24C64_ReadBufferLoop ; if not jump to loop
  SCF                        ; NOACK
  CALL I2C_Read              ; read last byte from EEPROM
  LD   ([m24DstAddr.w],X), A ; write to buffer
  CALL I2C_Stop              ; STOP
  RET

Download
 
M24C64.asm

 

 

 
(c) Radosław Kwiecień