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官方文档