Encoder Front Page
SRS Home | Front Page | Monthly Issue | Index
Search WWW Search seattlerobotics.org

Serial Memories

By Kevin Ross



Many of us like to use small, single chip microcontrollers. They are relatively cheap, easy to wire up to make run, and over all just mighty convienent to use. One down side to using these single chip controllers is the lack of large amounts of memory. Sure, you can hook up external memory to most of them, but that requires a lot of work, and usually consumes other valuable resources, mainly the I/O pins that make the chip useful.

There is help out there! There are several forms of memory that don't require the standard address bus and data bus wiring. These memories are called serial memories, and they are just the ticket to allow you to store large amounts of information without giving up those precious I/O lines. There are several different styles of serial EEPROM. The focus of this article is going to be SPI based devices. There are also 1, 2, and 3 wire serial EEPROM devices that function in a similar way, but have different interface logic.

This article is going to introduce the basics of serial memories, and present the driver software needed to make it operate.

Missing the Bus

The big advantage to using a Serial EEPROM is that the wiring only requires 4 signal lines from the CPU to operate it. Compare this with a more standard memory, which requires an address bus and a data bus! The amount of glue logic required to make a Serial EEPROM operate is extremely low.

For example, check out the following two packages. A traditional memory, such as a 27256, requires a 28-pin part to be wired into your circuit. There are 15 address lines, 8 output lines, plus assorted control lines. On the other hand, a serial EEPROM can be purchased using in a 8-pin package. There is 1 input line, 1 output line, 1 control line, and 1 clock line required. There are a couple of other control lines available, but are not actually required if you wish to avoid them. As you can imagine, these parts a lot easier to wire in, much smaller, and best of all are mighty cheap!  An 8kx8 part costs about $1.61 at Digikey.

27256.gif (3303 bytes) eepackage.gif (3487 bytes)

Of course, there are tradeoffs. Since the memory of the serial EEPROM is accessed one bit at a time, there is a speed penalty to be paid. However, these are still extremely fast parts. They can output their data at over 2 million bits per second, which is quite reasonable for many applications. So, for a small amount of software overhead and only 4 I/O pins, you can have yourself some substantial data storage!

Would you like to Super Size that?

Serial EEPROM's are available in a variety of different sizes. They seem to range from 128 bytes all the way up to 32k bytes. Atmel also has a 128k byte device that fits the same form factor. All of these parts are electrically compatible. However, some require minor software changes. For example, some allow writes of 32 bytes at a time, where others allow 64 bytes at a time. These minor differences are easily dealt with in software.

It turns out that serial EEPROM's are available from several different manufacturers. At least two, Microchip and Atmel, have compatible chips. I haven't looked into the other manufacturers, but I would expect theirs may be as well.

They are also available in several package sizes, including an 8pin DIP as well as SOIC surface mount.

The Basics

There are 8 pins on one of these parts. Here is a list and their functions

1 CS* Chip select. This is a crictical pin on these parts. The CS line not only enables the part, but it also acts as the end of operation marker. More about this pin later
2 SO Serial Output pin. In SPI terminology, this would be the Slave Out, and should be connected to the MISO pin of the SPI port. Data being output from the serial EEPROM is clocked out on this line.
3 WP* The WP pin allows for hardware write protection. If appropriate bits in the control register are set, then the WP pin will disable any write operations when the pin is held low. This would be appropriate when you want to have extra protection against software bugs, or when you intend for the part to be read only. The other option is to wire it high and leave it that way.
4 GND Power supply GND
5 SI Serial Input pin. In SPI terminology, this would be the Slave In, and should be connected to the MOSI pin of the SPI port. Data being output by the CPU is clocked in on this line.
6 SCK Serial Clock. This is the SPI serial clock line. Each cycle of this clock causes the data registers to shift both in and out 1 bit.
7 HOLD* This interesting pin places the state of the part on 'HOLD'. This is useful if you have interrupt driven routines that need to access other parts on the SPI bus. By holding this line low, the part will ignore the SCK line, which in affect causes the part to hold its current state. Your interrupt routine can then use the SPI bus to access a different part, then return to the current operation by raising the HOLD line. If you don't plan on doing this, just wire it high.
8 VCC The power lsupply line. Usually connected to +5 volts, though the range of voltages go as low as 2.2volts, depending on the part you are using

(* denotes active LOW)

The Block Diagram

As always, engineers love to see the block diagram! Here is the block diagram you will find in the documentation for the Microchip 25C640:

eeblock.gif (9184 bytes)

As you can see, there are a few different parts called out in the block diagram. Of particular interest to us are the EEPROM Array, which is the actual EEPROM memory cells, the Status Register, which is a register that holds configuration and status information, and of course the Page Latches, which are the temporary 'holding' areas for data being written. The other parts are also interesting, but I am going to ignore them for this article.

A Schematic

Connecting a serial EEPROM is really quite straight forward. I have been offering a board based on the 68HC912B32 Microcontroller for some time now (see www.nwlink.com/~kevinro/products.html ). I recently added a spot for a serial EEPROM to the backside of the board. The following snipet of the schematic shows the 25xxx series EEPROM connected to the SPI port for this board. Note that on my 912B32 board, this is an optional device. I left several cut jumpers (these are areas where the trace can be cut, and the wiring done differently) on the board, and they are shown on the schematic.

eeschm.gif (15786 bytes)

Connecting up a serial EEPROM is pretty straight forward, and it can be added to almost any CPU that supports the SPI bus. Note that I have chosen to leave the WP (Write Protect) and HOLD lines wired high. I don't use them in my software, but you are certainly welcome to use them. On my board, you merely cut the trace on the jumper, and wire up the appropriate pins to a port for control.

Table of commands

There are a small number of commands that you can issue to the serial EEPROM. The following table is a quick summary.

Instruction Instruction Code



0000 0011 Read data from memory array beginning at selected address
WRITE 0000 0010 Write data to memory array beginning at selected address
WREN 0000 0110 Set the write enable latch (enable writing)
WRDI 0000 0100 Clear the write enable latch (disable writing)
RDSR 0000 0101 Read status register
WRSR 0000 0001 Write status register

Each instruction code has its own argument requirements. Read/Write, for example, are followed by an address. Writing the status register requires an 8 bit argument, and so on. A complete set of instructions and their formats are available in the data sheet for your particular part. Most of these SPI parts have extremely similar manuals!  You can find a list of data sheets on the Microchip website at http://www.microchip.com/10/Lit/Memory/SPI/index.htm which will provide you with a lot of extra detail.

Speed issues

Most parts can operate with transfer speeds in excess of 1 megabit per second. Some parts can go up to 8 megabits per second. You need to take this into consideration when you are selecting a part. Luckily, most of the SPI implementations, such as the 68HC11 and 68HC12 SPI ports, allow you to adjust the clock speed for the SPI port with a clock scalar. Thus, if you are connecting a 25LC640, for example, to a 16mhz 68HC12, you will need to select an SPI prescale that slows the SPI bus down to 2mhz. This is a common oversight, and a good source of bugs!

Cycle life

Serial EEPROMs are typically rated to endure 1 million write operations per byte. Thats pretty decent. However, you still need to be careful here that you are not constantly writing data to the part. EEPROM is not a substitute for general purpose RAM. If you write to these parts in a tight loop, it would only take an hour or so to exceed the 1million write operations. Your software needs to be written to take that into account.


As you can see, wiring up an SPI based EEPROM to the SPI port is relatively simple. Nothing comes for free, however, and you will find the software commands needed to work with the SPI memory is a little more complex than just doing memory writes.

The basic operation of the SPI based EEPROM's is to lower the CS line, send a command, such as WRITE, followed by an address and the data, then raise the CS line. In a WRITE operation, raising the CS line causes the EEPROM to actually store the data. That is an important point you don't want to miss!

Serial EEPROMs allow you to write in 'page' mode, which means you can send up to 1 PAGE of data at a time. The number of bytes in a PAGE depends on the specific part. For example, the Atmel 25128 uses a 64 byte PAGE. The Microchip 25C640 uses a 32 byte PAGE. The idea is that each time the address spans a PAGE boundary, you need to raise the CS line so that the chip can write is page into memory.

The key thing to watch for is when the address crosses that page boundary. You can write between one and the PAGE size bytes, which means if you only want to write a single byte, that is fine. If you continue to write after crossing the page boundary, then the subsequent writes will wrap around on the current page and overwrite previously written data, which isn't what you wanted to do!

I have written a set of routines in Imagecraft 'C' that deal with the serial EEPROM's. I have included links to the source below.

The software is structured in a simple way. There is an initialization routine, which sets up the SPI port approprately. It also defines read and write operations.

The read/write operations function the same basic way. You start the operation by calling the sermem_StartRead() function, giving the initial address. Then, you issue a series of sermem_Read() commands. When you are done, sermem_StopRead() is called. For ease of use, I have also defined a function called sermem_ReadBlock() that does the entire operation at once.

The Write versions do the same basic functions. Here are the function prototypes from the sermem files:

// sermem.h - Copyright 1998 (c) Kevin W Ross, all rights reserved
// Accompanies sermem.c and defines some of the basic information needed to
// deal with the serial EEPROM memories.
// Device Profiles - Here are the variables needed for each specific type of
// chip. Some have different page sizes and data sizes
void sermem_Initialize();
void sermem_StartRead(int iAddress);
void sermem_Read(unsigned char *pBuf,int cBuf);
void sermem_StopRead(void);
void sermem_ReadBlock(int iAddress,unsigned char *pBuf,int cBuf);

void sermem_StartWrite(int iAddress);
void sermem_Write(unsigned char *pBuf,int cBuf);
void sermem_StopWrite(void);
void sermem_WriteBlock(int iAddress,unsigned char *pBuf,int cBuf);

void sermem_Fill(int iAddress,unsigned char byte,int count);


You can find the full source code in sermem.c and sermem.h which are fairly well commented and pretty easy to follow. This code is written for the 68HC12 series of chips, but is really trivial to port to the 68HC11 (an excersize left to the reader!).

Another file is called memtest.c which is a test program that uses the routines.

The Status Register

An important part of the serial EEPROM is the status register. I thought it important to point it out that you need to use this register. This register not only holds some configuration data that you will need to write to, it also contains an important bit called the WIP bit standing for "Write In Progress". Serial EEPROM requires a burn time while it is saving data to the array. This can take up to 5 milliseconds, though it might be less. Rather than relying on a timer on your microcontroller, you can check the status of this WIP flag to know when the part has finished writing the page and is ready for new data.


void sermem_StopWrite(void)
         // Raise the CS line. That makes the memory part start its write cycle
         // Then wait for the WIP bit to be cleared

                 // Need to select the EEPROM for the read status operation
                 // The Write In Progress (WIP) flag is bit 1. Wait for it to go low
         } while (spi_in(SERMEM_INST_RDSR) & 0x01);

         // Disallow further writes to the EEPROM. Prevents rouge clock signals
         // from corrupting your data!


Above I show my implementation of the sermem_StopWrite() function. This functions job is to cause the serial EEPROM to commit a previously transferred page to EEPROM. The function rases the CS line, then issues a RDSR instruction and loops waiting for the WIP bit to go to zero. Note that the spi_deselect() and spi_select() instructions needed to be there. The state transition is important because the CS line is used as the primary handshake between the microcontroller that the serial EEPROM. It signals the start and stop of operations.



Serial EEPROM provide a great way to store non-volatile data on a small microcontroller project. They require few I/O lines, relatively fast read/write operations, and most operate from a single 5volt power supply. The software routines to drive these parts is not very complex. Next time you need to store some non-volatile data, such as configuration information or navigation maps, consider serial EEPROM.