Proteus8 simulation: the use of 51 single-chip microcomputer 25AA020A (SPI interface EEPROM)

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
insert image description here
Experimental device

components name
51 MCU AT89C51
button BUTTON
Digital Tube 7SEG-BCD-BLUE
EEPROM 25AA020A

25AA020A pin function

insert image description here

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

insert image description here

/**********************************************************************************************************************************
作用: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

insert image description here

/**********************************************************************************************************************************
作用: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

insert image description here

/**********************************************************************************************************************************
作用:EEPROM写使能

**********************************************************************************************************************************/

void EEPROM_WriteData_ENABLE(void)
{
    
    
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_ENABLE);
	CS=1;
}

insert image description here

/**********************************************************************************************************************************
作用:EEPROM写不使能
**********************************************************************************************************************************/
void EEPROM_WriteData_DISENABLE(void)
{
    
    
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_DISABLE);
	CS=1;
}

EEPROM writes a Byte

insert image description here
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;
}


Project Files

Project Files

Guess you like

Origin blog.csdn.net/darlingqx/article/details/128513478