Overview
The Microchip Technology Inc. 25XX010A is a 1-Kbit (8-bit x 127) Serial Electrically Erasable PROM (EEPROM). The memory is accessed via a simple Serial Peripheral Interface (SPI) compatible serial bus. The bus signals required are a clock input (SCK) plus separate data in (SI) and data out (SO) lines. Access to the device is controlled through a Chip Select (CS) input.
Since it uses the SPI interface it can handle the clock rate up to 10MHz faster than other I2C(TWI) serial EEPROM. Its read/write cycles is up to 1M times.
It has various device's package including a DIP-8 package for hobbyists prototyping.
![]() |
| Device Selection Table |
This chip also has a model in Proteus that enable the engineer to test its operation by software.
![]() |
| Package Types and Pin Function Table |
The SPI transfer and receive must have the following data bytes, instruction, address, and data.
![]() |
| Block Diagram, Instructions, and SPI Read Sequence |
The read command is 0x03 follows by the EEPROM address. The EEPROM 8-bit data will shift out by the SPI read routine issued by the microprocessor.
Writing data to the EEPROM requires around 5ms. It requires a write enable instruction before the data writing sequence able to process.
![]() |
| Write Enable and Disable Commands |
Write-enable command is 0x06 while the Write-disable command is 0x04. Additionally the Write Protect (WP) pin must pull high to enable data writing.
Byte
write sequence instruction is 0x02 follows by the EEPROM address and
the 8-bit data. It also has a page write sequence to write a burst of 16
bytes data package. The microprocessor needs to wait around 5ms to
complete data writing.
![]() |
| Byte and Page Write Sequences |
The Read Status Register Instruction is optional you can read the device datasheet for more detail.
It's useful the for a master MCU to determine when the next read or write operation will proceed. Some programmer just use a delay function that last around 100 micro-seconds instead of using this operation.
ATMega644 and 25AA010A Interfacing
Using a dedicated SPI interface of an MCU is very fast and reliable. The internal MCU serial communication module process this serial data transmission and reception tasks.
This example show a write and read operation to the 25AA010A from a master ATMega644P SPI. Data is written to the 25AA010A prior to reading back from this chip. Then they are shown on PORTC.
| Schematic |
Source Code "main.c":
- /*
- * 12-spi_25AA010A.c
- *
- * Created: 2/24/2026 2:16:04 PM
- * Author : Admin
- */
- #include <avr/io.h>
- #include <util/delay.h>
- #define F_CPU 16000000UL
- #define DDR_SPI DDRB
- #define PRT_SPI PORTB
- #define DD_SS 4
- #define DD_MOSI 5
- #define DD_MISO 6
- #define DD_SCK 7
- void SPI_MasterInit(void)
- {
- /* Set MOSI and SCK output, all others input */
- DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
- /* Enable SPI, Master, set clock rate fck/16 */
- SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
- }
- void SPI_MasterTransmit(char cData)
- {
- /* Start transmission */
- SPDR = cData;
- /* Wait for transmission complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- }
- void SPI_SlaveInit(void)
- {
- /* Set MISO output, all others input */
- DDR_SPI = (1<<DD_MISO);
- /* Enable SPI */
- SPCR = (1<<SPE);
- }
- char SPI_SlaveReceive(void)
- {
- /* Wait for reception complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- /* Return Data Register */
- return SPDR;
- }
- // 93AA46B SPI EEPROM
- void write_enable(void){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x06);
- PRT_SPI|=(1<<DD_SS);
- }
- unsigned char read_status(void){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x05);
- SPI_MasterTransmit(0x00);
- unsigned char temp=SPI_SlaveReceive();
- PRT_SPI|=(1<<DD_SS);
- return temp;
- }
- void write_93AA46B(unsigned char address, unsigned char data){
- unsigned char temp;
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x02);
- SPI_MasterTransmit(address);
- SPI_MasterTransmit(data);
- PRT_SPI|=(1<<DD_SS);
- //Check Write Busy Flag
- do
- {
- temp=read_status();
- } while ((temp&0x01)==1);
- }
- unsigned char read_93AA46B(unsigned char address){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x03);
- SPI_MasterTransmit(address);
- SPI_MasterTransmit(0xFF);
- unsigned char data=SPI_SlaveReceive();
- PRT_SPI|=(1<<DD_SS);
- return data;
- }
- int main(void)
- {
- /* Replace with your application code */
- SPI_MasterInit();
- PRT_SPI|=(1<<DD_SS);
- unsigned char temp=0, data=0;
- DDRC=0xFF;
- write_enable();
- while (1)
- {
- for (unsigned char i=0;i<8;i++)
- {
- write_93AA46B(i,1<<i);
- PORTC=read_93AA46B(i);
- _delay_ms(1000);
- }
- }
- }
I don't have a physical device for this chip. So I just tested it in a simulator.
Now I added a character LCD to display some ASCII data.
| Schematic |
Source Code "main.c":
- /*
- * 25AA010A_1602.c
- *
- * Created: 2/24/2026 9:36:19 PM
- * Author : Admin
- */
- #include <avr/io.h>
- #include <util/delay.h>
- #define F_CPU 16000000UL
- #define DDR_SPI DDRB
- #define PRT_SPI PORTB
- #define DD_SS 4
- #define DD_MOSI 5
- #define DD_MISO 6
- #define DD_SCK 7
- void SPI_MasterInit(void)
- {
- /* Set MOSI and SCK output, all others input */
- DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
- /* Enable SPI, Master, set clock rate fck/16 */
- SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
- }
- void SPI_MasterTransmit(char cData)
- {
- /* Start transmission */
- SPDR = cData;
- /* Wait for transmission complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- }
- void SPI_SlaveInit(void)
- {
- /* Set MISO output, all others input */
- DDR_SPI = (1<<DD_MISO);
- /* Enable SPI */
- SPCR = (1<<SPE);
- }
- char SPI_SlaveReceive(void)
- {
- /* Wait for reception complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- /* Return Data Register */
- return SPDR;
- }
- // 93AA46B SPI EEPROM
- void write_enable(void){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x06);
- PRT_SPI|=(1<<DD_SS);
- }
- unsigned char read_status(void){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x05);
- SPI_MasterTransmit(0x00);
- unsigned char temp=SPI_SlaveReceive();
- PRT_SPI|=(1<<DD_SS);
- return temp;
- }
- void write_25AA010A(unsigned char address, unsigned char data){
- write_enable();
- unsigned char temp;
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x02);
- SPI_MasterTransmit(address&0x7F);
- SPI_MasterTransmit(data);
- PRT_SPI|=(1<<DD_SS);
- //Check Write Busy Flag
- do
- {
- temp=read_status();
- } while ((temp&0x01)==1);
- }
- unsigned char read_25AA010A(unsigned char address){
- PRT_SPI&=~(1<<DD_SS);
- SPI_MasterTransmit(0x03);
- SPI_MasterTransmit(address&0x7F);
- SPI_MasterTransmit(0x00);
- _delay_us(100);
- unsigned char data=SPI_SlaveReceive();
- PRT_SPI|=(1<<DD_SS);
- return data;
- }
- int main(void)
- {
- /* Replace with your application code */
- SPI_MasterInit();
- PRT_SPI|=(1<<DD_SS);
- lcd_init();
- unsigned char temp[16]="ATMEGA644P SPI";
- for (unsigned char i=0;i<16;i++)
- {
- write_25AA010A(i,temp[i]);
- }
- for (unsigned char i=0;i<16;i++)
- {
- temp[i]=read_25AA010A(i);
- }
- lcd_text(temp);
- unsigned char temp_1[16]="25AA010A EEPROM";
- for (unsigned char i=16;i<32;i++)
- {
- write_25AA010A(i,temp_1[i]);
- }
- for (unsigned char i=16;i<32;i++)
- {
- temp_1[15-i]=read_25AA010A(i);
- }
- lcd_xy(1,2);
- lcd_text(temp_1);
- while (1)
- {
- }
- }
Click here to download this example.





No comments:
Post a Comment