51 MCU 25AA020A
Microchip's 25AA020A is a 2Kbit serial electrically erasable programmable read-only memory (EEPROM). The memory can be accessed through a simple Serial Peripheral Interface (SPI) compatible serial bus. The required bus signals are the clock input (SCK) plus separate data (SI) and data output (SO) lines. Access to the device is controlled through the Chip Select (CS) input.
Experimental content
Experimental content
Use 25AA020A to save the count value of the counter.
Experimental schematic
Experimental device
components | name |
---|---|
51 MCU | AT89C51 |
button | BUTTON |
Digital Tube | 7SEG-BCD-BLUE |
EEPROM | 25AA020A |
25AA020A pin function
pin | Function |
---|---|
SCK | SPI clock |
AND | SPI MOSI (Master Output Slave Input) |
SO | SPI MISO (Master Input Slave Output) |
SCK | SPI clock |
CS | SPI chip select signal |
WP | Read and write protection bit |
HOLD | Suspend transmission signal, pull high to ensure continuous transmission |
SPI signal simulation
8 bit write
/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输
**********************************************************************************************************************************/
void SPI_WriteByte(uint_8 Byte)
{
uint_8 i=0;
for(i=0;i<8;i++)
{
SCK=0;
if(Byte&0x80)SI=1;
else SI=0;
Byte <<=1;
SCK=1;
}
SCK=0;
}
8 bit read
/**********************************************************************************************************************************
作用:SPI一个Byte读取函数
返回:读取的一个Byte
从高位往低位,下降沿传输
**********************************************************************************************************************************/
uint_8 SPI_ReadByte(void)
{
uint_8 i;
uint_8 Byte;
SCK=0;
for(i=0;i<8;i++)
{
SCK=1;
Byte <<=1;
if(SO)Byte++;
SCK=0;
}
return Byte;
}
EEPROM read and write functions
EEPROM write enable
/**********************************************************************************************************************************
作用:EEPROM写使能
**********************************************************************************************************************************/
void EEPROM_WriteData_ENABLE(void)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_ENABLE);
CS=1;
}
/**********************************************************************************************************************************
作用:EEPROM写不使能
**********************************************************************************************************************************/
void EEPROM_WriteData_DISENABLE(void)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_DISABLE);
CS=1;
}
EEPROM writes a Byte
Before any attempt to write data to the 25AA020A, the write enable lock must be set using instructions by sending WREN. This is accomplished by setting CS low and then feeding the correct command into the 25AA020A. After all eight bits of the command are transmitted, CS must be driven high to set the write enable latch. If a write operation is initiated immediately after a WREN instruction without CS being driven high, data will not be written to the array since the write enable latch is not properly set.
/**********************************************************************************************************************************
作用:EEPROM写入一个Byte函数
HW_Address:EEPROM硬件地址
SW_Address:EEPROM软件地址即写出内存的地址
Data:写入的数据
**********************************************************************************************************************************/
void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data)
{
uint_8 status=0x01;
//打开EEPROM写使能
EEPROM_WriteData_ENABLE();
CS=1;
CS=0;
SPI_WriteByte(HW_Address);
SPI_WriteByte(SW_Address);
SPI_WriteByte(Data);
CS=1;
//读取EEPROM寄存器
//从寄存器最低位判断写是否完成
while((status&0x01)==0x01)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_Read_REGISTER);
status=SPI_ReadByte();
CS=1;
}
//关闭EEPROM写使能
EEPROM_WriteData_DISENABLE();
}
Experimental program routine
main.c
#include "REG51.h"
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit SCK=P3^0;
sbit SI=P3^1;
sbit SO=P3^2;
sbit CS=P3^3;
#define EEPROM_Address_W 0X02
#define EEPROM_Address_R 0X03
#define EEPROM_Address_ENABLE 0X06
#define EEPROM_Address_DISABLE 0X04
#define EEPROM_Address_Read_REGISTER 0x05
typedef unsigned char uint_8;
typedef unsigned int uint_16;
void SPI_WriteByte(uint_8 Byte);
uint_8 SPI_ReadByte(void);
void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data);
uint_8 EEPROM_ReadData(uint_8 HW_Address,uint_8 SW_Address);
void EEPROM_WriteData_ENABLE(void);
void get_key(void);
void SMG_output(uint_8 Data);
char num=5;
void main(void)
{
num=EEPROM_ReadData(EEPROM_Address_R,0x00);
while(1)
{
SMG_output(num);
EEPROM_WriteData(EEPROM_Address_W,0x00,num);
get_key();
}
}
/**********************************************************************************************************************************
作用:EEPROM写使能
**********************************************************************************************************************************/
void EEPROM_WriteData_ENABLE(void)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_ENABLE);
CS=1;
}
/**********************************************************************************************************************************
作用:EEPROM写不使能
**********************************************************************************************************************************/
void EEPROM_WriteData_DISENABLE(void)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_DISABLE);
CS=1;
}
/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输
**********************************************************************************************************************************/
uint_8 EEPROM_ReadData(uint_8 HW_Address,uint_8 SW_Address)
{
uint_8 Data=0;
CS=1;
CS=0;
SPI_WriteByte(HW_Address);
SPI_WriteByte(SW_Address);
Data=SPI_ReadByte();
CS=1;
return Data;
}
/**********************************************************************************************************************************
作用:EEPROM写入一个Byte函数
HW_Address:EEPROM硬件地址
SW_Address:EEPROM软件地址即写出内存的地址
Data:写入的数据
**********************************************************************************************************************************/
void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data)
{
uint_8 status=0x01;
//打开EEPROM写使能
EEPROM_WriteData_ENABLE();
CS=1;
CS=0;
SPI_WriteByte(HW_Address);
SPI_WriteByte(SW_Address);
SPI_WriteByte(Data);
CS=1;
//读取EEPROM寄存器
//从寄存器最低位判断写是否完成
while((status&0x01)==0x01)
{
CS=1;
CS=0;
SPI_WriteByte(EEPROM_Address_Read_REGISTER);
status=SPI_ReadByte();
CS=1;
}
//关闭EEPROM写使能
EEPROM_WriteData_DISENABLE();
}
/**********************************************************************************************************************************
作用:SPI一个Byte读取函数
返回:读取的一个Byte
从高位往低位,下降沿传输
**********************************************************************************************************************************/
uint_8 SPI_ReadByte(void)
{
uint_8 i;
uint_8 Byte;
SCK=0;
for(i=0;i<8;i++)
{
SCK=1;
Byte <<=1;
if(SO)Byte++;
SCK=0;
}
return Byte;
}
/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输
**********************************************************************************************************************************/
void SPI_WriteByte(uint_8 Byte)
{
uint_8 i=0;
for(i=0;i<8;i++)
{
SCK=0;
if(Byte&0x80)SI=1;
else SI=0;
Byte <<=1;
SCK=1;
}
SCK=0;
}
/**********************************************************************************************************************************
作用:按键扫描
**********************************************************************************************************************************/
void get_key(void)
{
if(KEY1==0)
{
num++;
if(num>=9)num=9;
while(KEY1==0);
}
else if(KEY2==0)
{
num--;
if(num<=0)num=0;
while(KEY2==0);
}
}
/**********************************************************************************************************************************
作用:数码管显示
**********************************************************************************************************************************/
void SMG_output(uint_8 Data)
{
P2=Data&0x0F;
}