51单片机--AT24C02数据存储

这篇具有很好参考价值的文章主要介绍了51单片机--AT24C02数据存储。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

存储器的介绍

存储器是计算机系统中的一种重要设备,用于存储程序和数据,它可以通过电子、磁性介质等技术来记录和保持数据。在这里,主要介绍的是随机存储器(RAM)和只读存储器(ROM)。
随机存储器(Random Access Memory,RAM)是一种可以读取和写入数据的存储器。 它的特点是可以随机访问其中的任意位置,并且读写速度较快。RAM通常由电子芯片制成,用于临时存储计算机运行时所需的程序和数据。
RAM可以分为静态随机存储器(Static RAM,SRAM)和动态随机存储器(Dynamic RAM,DRAM)两种类型。
静态随机存储器(SRAM):SRAM使用了触发器电路来存储数据,每个存储单元由多个触发器组成,具有较高的稳定性和快速的读写速度。由于使用了更多的电子元件,SRAM的密度较低,成本相对较高。它常用于高速缓存(Cache)等需要快速访问的场景。
动态随机存储器(DRAM):DRAM使用了电容器和开关电路来存储数据,每个存储单元由一个电容器和一个访问开关组成。由于电容器的电荷会随时间衰减,DRAM需要周期性地进行刷新操作来保持数据的稳定。DRAM具有较高的存储密度和较低的成本,但相对而言读写速度较慢。它常用于主存储器(内存)等需要较大容量的场景。
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储

只读存储器(Read-Only Memory,ROM)是一种只能读取数据而无法写入或修改数据的存储器。ROM中的数据在制造时被写入,通常用于存储固化的程序代码、系统设置、固件等不需要频繁修改的数据。ROM的数据在断电后依然可以保持,具有非易失性
ROM根据存储数据的方式可以分为多种类型,如只读存储器(ROM)、可编程只读存储器(PROM)、可擦除可编程只读存储器(EPROM)和电可擦除可编程只读存储器(EEPROM)等。这些ROM的特点是在制造或编程后,其存储的数据无法修改或只能经过特定方式修改。对于我们这款单片机来说,AT24C02就是E2PROM,电可擦除可编程ROM,可以通过编程来进行存储数据,数据根据具体的地址存储;断电之后,他还会保存在地址中,当我们需要读取时,可以通过相对应的地址取出数据;

AT24C02

AT24C02是一种2K位(256字节)的串行EEPROM(Electrically Erasable Programmable Read-Only Memory),常用于51单片机系统中的数据存储
AT24C02采用I2C总线协议进行通信,通过两根线路(SCL和SDA)与单片机进行连接。它具有8位的设备地址,可通过引脚A0、A1和A2进行编程设置,从而允许多个AT24C02共存在同一I2C总线上。
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
对于AT24C02,在读写速度上支持400kHz标准模式,数据保存能力可达10年之久,而且有写入保护,可以防止误操作;
在单片机系统中,可以使用AT24C02来存储各种数据,如配置参数、校准数据、历史记录等。单片机可以使用相应的I2C库函数来向AT24C02写入或读取数据,以实现对其存储空间的读写操作。

需要注意的是,AT24C02是一种非易失性存储器,即使在断电情况下也可以保持存储的数据。因此,它适用于需要长期保存数据的应用场景。
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
上图时AT24C02的内部结构框图,红色部分为它的存储位置;

I2C总线

I2C,全称为Inter-Integrated Circuit,是一种串行通信协议用于在电子设备之间进行数字数据传输。它由飞利浦半导体(现在的NXP半导体)公司在1980年代开发,并于1982年发布。I2C采用了两根导线(一根用于传输数据,另一根用于传输时钟信号)来连接设备,这使得多个设备可以通过同一组导线进行通信。
I2C协议有两个重要的角色:主设备(Master)和从设备(Slave)主设备负责控制通信的序列和时钟信号的生成,而从设备则被动响应主设备的指令。

I2C支持多主设备和多从设备的连接,每个设备都有一个唯一的地址标识。主设备可以向从设备发送数据或者接收从设备的数据。在传输数据时,数据被分为多个字节,每个字节都会被从设备确认。
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储

在51单片机中,AT24C02通过I2C总线与单片机进行数据通信
通过I2C总线,单片机可以发送读取或写入命令给AT24C02,然后AT24C02会响应相应的操作。例如,单片机可以向AT24C02发送写入命令,并指定要写入的地址和数据,AT24C02会将数据写入指定地址的存储单元。而当单片机需要读取AT24C02中的数据时,它可以向AT24C02发送读取命令和要读取的地址,然后AT24C02会返回相应的数据给单片机。

I2C时序结构

I2C总线的时序结构一般分为6部分:起始条件、终止条件、发送数据、接收数据、接收应答和发送应答;

起始条件主设备通过SCL(串行时钟线)保持高电平的同时,将SDA(串行数据线)由高电平转换为低电平,表示要启动一次通信
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
代码:

void I2C_Start()
{
	I2C_SDA=1;//表示SCL高电平之前SDA就是高电平了
	I2C_SCL=1;//SCL高电平期间
	I2C_SDA=0;//SDA降为低电平
	I2C_SCL=0;//SCL回到低电平
	
}

发送一个字节:SCL低电平期间,主设备将数据位依次放到SDA线上(高位在前),然后拉高SCL,在SCL上升沿时从设备将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节;
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
代码:

void I2C_SendByte(unsigned char byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		I2C_SDA=byte&(0x80>>i);//先将数据放到SDA上
		I2C_SCL=1; //SCL为上升沿时,从设备读取数据
		I2C_SCL=0;
	}
}

接收一个字节:SCL低电平期间,从设备将数据位依次放到SDA线上(高位在前),然后拉高SCL,主设备将在SCL上升沿期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
代码:

unsigned char I2C_ReceiveByte()
{
	unsigned char i,byte=0x00;
	I2C_SDA=1; //释放SDA,规定置于高电平
	for(i=0;i<8;i++)
	{
	//在SCL上升沿期间,主设备读取SDA的数据,
		I2C_SCL=1;
		if(I2C_SDA){byte|=(0x80>>i);
		//通过判断SDA位的数据是否为1,进行位赋值
		//为1执行条件内容,将位变为1,为0则不变,仍为0;
		I2C_SCL=0;
	}
	
	return byte;
	
}

发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答 ;
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
代码:

void I2C_SendAck(unsigned char AckBit)
{
	I2C_SDA=AckBit;
	//SDA发送应答,应答或者不应答
	I2C_SCL=1;
	//在SCL上升沿期间,从设备接收主设备发送应答
	I2C_SCL=0;
	
}

接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA);主设备发送一个高电平的SDA并保持SCL线为高电平,使得从设备可以拉低SDA线来应答。如果接收方正确收到数据,它会发一个低电平的SDA信号应答
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
代码:

unsigned char I2C_ReceiveAck()
{
	unsigned char AckBit;
	I2C_SDA=1; //释放SDA
	I2C_SCL=1;  //在SCL高电平期间
	AckBit=I2C_SDA; //接收SDA的应答数据
	I2C_SCL=0; 
	return AckBit;
	
}

51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储

终止条件:将SCL线保持高电平的同时,将SDA线由低电平转换为高电平,表示通信结束;
51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储

代码:

void I2C_Stop()
{
	I2C_SDA=0;// 在SCL高电平之前SDA就为低电平
	I2C_SCL=1; //SCL处于高电平期间
	I2C_SDA=1;
}

AT24C02数据帧

数据帧是在通信中用于传输数据的基本单元
对于AT24C02,数据帧包括一个地址字节和一个或多个数据字节

51单片机--AT24C02数据存储,51单片机,51单片机,AT24C02,数据存储
上图为AT24C02数据帧的格式:

  1. 起始位(Start Bit):数据传输开始时,为低电平。
  2. 7位地址(Address):表示要访问的内存地址。AT24C02共有256个地址,即0x00到0xFF。
  3. R/W位(Read/Write Bit):用于选择读(高电平)或写(低电平)操作。
  4. 数据字节(Data Byte):在写操作中,数据字节表示要写入到指定地址的数据。在读操作中,数据字节表示从指定地址读取到的数据。
  5. 应答位(Acknowledge Bit):用于发送方向接收方确认数据传输的成功。

而这些数据帧的格式是遵循I2C总线的通信协议的;所以我们只需要运用I2O的时序结构,将它们对应进AT24C02的数据帧即可;

对于读操作,数据帧的格式如下:
起始位 + 7位地址 + R/W位(设置为高电平)+ 应答位 + 存储的地址标识 + 应答位 + 数据字节 + 应答位 + 起始位 +读取数据+ 应答位 + 停止位

对于写操作,数据帧的格式如下:
起始位 + 7位地址 + R/W位(设置为低电平)+ 应答位 + 存储的地址标识 + 应答位 + 数据字节 + 应答位 + 停止位

代码(利用到I2C总线时序写的代码):

写入字节:

#define AT24C02_ADDRESS 0xA0 //AT24C02的写操作地址
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
	
	I2C_Start(); //起始条件
	I2C_SendByte(AT24C02_ADDRESS); //主设备发送AT24C02的地址
	I2C_ReceiveAck(); //从设备接收应答(确认地址)
	I2C_SendByte(WordAddress); // 主设备向从设备发送地址
	I2C_ReceiveAck(); //从设备接收应答
	I2C_SendByte(Data); //主设备向从设备发送数据
	I2C_ReceiveAck(); //从设备接收应答
	I2C_Stop(); //终止条件
}

读取字节:

unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
	unsigned char Data;
	I2C_Start(); //起始条件
	I2C_SendByte(AT24C02_ADDRESS); //主设备发送AT24C02的地址
	I2C_ReceiveAck();//从设备接收应答(确认地址)
	I2C_SendByte(WordAddress);// 主设备向从设备发送要读取字节的地址
	I2C_ReceiveAck();//从设备接收应答
	//以上操作完成了主设备向从设备要读取字节的地址的操作,是主设备
	//告诉从设备的地址
	//下面操作是从设备向主设备发送对应的字节操作,主设备从写入变
	//为读取,所以要重新开始定起始条件
	I2C_Start(); //起始条件
	I2C_SendByte(AT24C02_ADDRESS|0x01); //主设备发送AT24C02的读取地址
	I2C_ReceiveAck(); //从设备接收应答(确认地址
	Data=I2C_ReceiveByte();//读取从设备对应地址的数据字节
	I2C_SendAck(1); //主设备发送应答(地址对应正确发送回应给从设备)
	I2C_Stop(); //终止条件
	return Data;
	
}

AT24C02数据存储实例

写一个能通过独立按键让数字逐渐增加或者减少的程序,并且让这个程序能记住某一个数字,断电或者置0的时候可以恢复到这个数字
代码:
Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__
//获取一个毫秒为单位的延迟函数,填入对应数字表示延迟多少毫秒
void Delay(unsigned int xms);

#endif

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif

Key.c

#include <REGX52.H>
#include "Delay.h"

/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
	unsigned char KeyNumber=0;
	
	if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
	if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
	if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
	if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
	
	return KeyNumber;
}

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

LCD1602.c

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

AT24C02.h

#ifndef __KEY_H__
#define __KEY_H__

void AT24C02_WriteByte(unsigned char WordAddress,Data);
unsigned char AT24C02_ReadByte(unsigned char WordAddress);
#endif

AT24C02.c

#include <REGX52.H>
#include"I2C.h"

#define AT24C02_ADDRESS 0xA0
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
	
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_SendByte(Data);
	I2C_ReceiveAck();
	I2C_Stop();
}

unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
	unsigned char Data;
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS|0x01);
	I2C_ReceiveAck();
	Data=I2C_ReceiveByte();
	I2C_SendAck(1);
	I2C_Stop();
	return Data;
	
}

I2C.h

#ifndef __KEY_H__
#define __KEY_H__

void I2C_Start();//¶ÔI2C³õʼ»¯
void I2C_Stop();//¶ÔI2CÄ©¶Ë
void I2C_SendByte(unsigned char byte);//I2CÖ÷»ú·¢ËÍÒ»¸ö×Ö½Ú
unsigned char I2C_ReceiveByte();  //½ÓÊÕÒ»¸ö×Ö½Ú
void I2C_SendAck(unsigned char AckBit);  //·¢ËÍÓ¦´ð
unsigned char I2C_ReceiveAck();   //½ÓÊÕÓ¦´ð
#endif

I2C.c

#include <REGX52.H>


sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

void I2C_Start()
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2C_SDA=0;
	I2C_SCL=0;
	
}

void I2C_Stop()
{
	I2C_SDA=0;
	I2C_SCL=1;
	I2C_SDA=1;
}

void I2C_SendByte(unsigned char byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		I2C_SDA=byte&(0x80>>i);
		I2C_SCL=1;
		I2C_SCL=0;
	}
}

unsigned char I2C_ReceiveByte()
{
	unsigned char i,byte=0x00;
	I2C_SDA=1;
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA){byte|=(0x80>>i);}
		I2C_SCL=0;
	}
	
	return byte;
	
}

void I2C_SendAck(unsigned char AckBit)
{
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
	
}

unsigned char I2C_ReceiveAck()
{
	unsigned char AckBit;
	I2C_SDA=1;
	I2C_SCL=1;
	AckBit=I2C_SDA;
	I2C_SCL=0;
	return AckBit;
	
}


main.c

#include <REGX52.H>
#include"AT24C02.h"
#include"I2C.h"
#include"LCD1602.h"
#include"Delay.h"

unsigned char KeyNum;
unsigned short Num;
void main()
{
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)  //K1按键,Num自增
		{
			Num++;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==2)   //K2按键,Num自减
		{
			Num--;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==3)  //K3按键,向AT24C02写入数据
		{
			AT24C02_WriteByte(0,Num%256);
			Delay(5);
			AT24C02_WriteByte(1,Num/256);
			Delay(5);
			LCD_ShowString(2,1,"Write OK");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
	
		}
		if(KeyNum==4)  //K4按键,从AT24C02读取数据
		{
			Num=AT24C02_ReadByte(0);
			Num|=AT24C02_ReadByte(1)<<8;
			LCD_ShowNum(1,1,Num,5);
			LCD_ShowString(2,1,"Read OK ");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
		}
		
	}
}

对于无符号的short类型数字,范围是0~65535,对应的有两个字节,所以写入数据要分别两部分,前8位和后8位,存储的地址可由自己选取,但在写入多个数据之间要延迟5ms,否则将会报错文章来源地址https://www.toymoban.com/news/detail-602716.html

到了这里,关于51单片机--AT24C02数据存储的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 基于51单片机的FRID智能门禁系统(RFID,12864,AT24C02,步进电机......)

    基于51单片机的FRID智能门禁系统(RFID,12864,AT24C02,步进电机......)

    目录 门禁系统 需要的器件 设计思路 流程图实现 技术实现 实物接线图 实物接线图  函数设计 部分主程序代码,截取片段 12864显示模块 步进电机模块以及蜂鸣器 FRID射频模块 AT24C02模块 功能实现及其源代码 完整文件         STC89C52,MFRC-522 RFID射频模块,AT24C02存储电路,

    2024年02月07日
    浏览(13)
  • 【51单片机】AT24C20数据帧(I2C总线)

    【51单片机】AT24C20数据帧(I2C总线)

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Love Story】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 小吉先向大家道个歉,因为最近在期末突击,所以文章久久没有更新,也请大家多多见谅😥 目录   🎁I2C总线 🏳️‍🌈

    2024年02月08日
    浏览(12)
  • 蓝桥杯单片机之AT24C02模块的使用

    蓝桥杯单片机之AT24C02模块的使用

    EEPROM EEPROM (Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器。是一种 掉电后数据不丢失 的存储芯片。 可以参考ROM、PROM、EPROM、EEPROM、Flash ROM的区别 AT24C02 AT24C02 提供2048 位串行电可擦除可编程只读存储器(EEPROM ),内部有256个字,每个字8位,即2k Bit。通过

    2023年04月20日
    浏览(6)
  • 6、单片机与AT24C02的通讯(IIC)实验(STM32F407)

    6、单片机与AT24C02的通讯(IIC)实验(STM32F407)

    IIC简介 I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。 IIC是半双工通信方式。 多主机

    2024年02月20日
    浏览(10)
  • AT89C51单片机实现单片机串口互动(中断方式,单片机--单片机,应答)

    AT89C51单片机实现单片机串口互动(中断方式,单片机--单片机,应答)

     说一下功能:客户机发送0x01到服务机 2服务单片机应答0xf2到客户机 3客户机接收到0xf2,发送信息153432这6个数字到服务机 4client发送完信息后发送0xaa结束通信 5server接收到0xaa后回复0xaa结束通信,从此老死不相往来 看代码: 服务端代码:    

    2024年02月13日
    浏览(12)
  • 单片机语言--C51语言数据类型与存储类型以及C51的基本运算

    单片机语言--C51语言数据类型与存储类型以及C51的基本运算

    C51的基本语法与标准C相同,C51在标准C的基础上进行了适合于51系列单片机硬件的扩展。 深入理解Keil C51对标准C的扩展部分以及不同之处,是掌握C51语言的关键之一。 C51与标准C的主要区别如下: (1)库函数的不同。 (2)数据类型有一定的区别。 (3)C51的变量存储模式与标

    2024年04月10日
    浏览(12)
  • 24小时切换简易时钟-51单片机

    24小时切换简易时钟-51单片机

    1、本设计主要介绍用单片机内部的定时/计数器来实现电子时钟的方法,本设计由单片机STC89C51单片机和LED数码管为核心,辅以必要的电路,构成了一个单片机电子时钟。 2、本设计拟实现的性能指标如下: (1)键盘用于校正、调节数码管上显示的时间。 (2)单片机通过输出

    2024年02月11日
    浏览(8)
  • 51单片机(At89C51)组成,引脚介绍

    51单片机(At89C51)组成,引脚介绍

    一,单片机的发展史 单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/0口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路

    2023年04月13日
    浏览(21)
  • 基于AT89C51单片机的电子时钟设计

    基于AT89C51单片机的电子时钟设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87695258?spm=1001.2014.3001.5503 源码获取 主要内容: 1.设计出电子数字钟的电路,并用protus进行仿真画出对应的电路图 2.设计出电子数字钟的源程序,并用Keil进行编辑生成HEX文件 3.在protus中进行测试。

    2024年02月09日
    浏览(14)
  • 基于 AT89C51 单片机的数字时钟设计

    基于 AT89C51 单片机的数字时钟设计

    目录 1.设计目的、作用 2.设计要求 3.设计的具体实现 3.1 设计原理 3.2 硬件系统设计         3.2.1 AT89C51 单片机原理 3.2.2 晶振电路设计 3.2.3 复位电路设计 3.2.4 LED 数码管显示 3.3 系统实现 3.3.1 系统仿真与调试 3.3.2 演示结果 4.总结 附录 附录 1 附录 2 (1 )掌握 51 系列单片机的

    2024年02月01日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包