51单片机25AA020A
- 实验内容
- 25AA020A引脚功能
- SPI信号模拟
- 8位写
- 8位读
 
- EEPROM读写函数
- EEPROM写使能
- EEPROM写一个Byte
 
- 实验程序例程
- main.c
 
- 工程文件
Microchip的25AA020A是一个2Kbit串行电可擦除可编程只读存储器(EEPROM)。内存可以通过一个简单的串行外围接口(SPI)兼容的串行总线来访问。所需的总线信号是时钟输入(SCK)加上独立的数据(SI)和数据输出(SO)线。通过芯片选择(CS)输入来控制对设备的访问。
实验内容
实验内容
使用25AA020A完成对计数器的计数值的保存。
实验原理图
 
 实验器件
| 元器件 | 名称 | 
|---|---|
| 51单片机 | AT89C51 | 
| 按键 | BUTTON | 
| 数码管 | 7SEG-BCD-BLUE | 
| EEPROM | 25AA020A | 
25AA020A引脚功能

| 引脚 | 功能 | 
|---|---|
| SCK | SPI时钟 | 
| SI | SPI的MOSI(主机输出从机输入) | 
| SO | SPI的MISO(主机输入从机输出) | 
| SCK | SPI时钟 | 
| CS | SPI的片选信号 | 
| WP | 读写保护位 | 
| HOLD | 暂停传输信号,拉高保证连续传输 | 
SPI信号模拟
8位写

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

/**********************************************************************************************************************************
作用: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读写函数
EEPROM写使能

/**********************************************************************************************************************************
作用: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写一个Byte
在任何尝试将数据写入25AA020A之前,写启用锁必须通过发WREN来设置使用说明。这是通过设置CS较低来实现的然后把正确的指令输入到25AA020A.在所有的八位指令之后传输时,CS必须驱动到高才能设置写入启用锁存器。如果在没有CS驱动的高的情况下,在WREN指令后立即启动写操作,数据自写入后将不会被写入数组启用锁存器没有正确设置。
/**********************************************************************************************************************************
作用: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();
}
实验程序例程
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;
}
工程文件
工程文件+25AA020A官方文档




















