AT24C02存储与读取数据

本文档详细介绍了如何利用I2C通信协议,通过AT24C02芯片在LCD1602液晶屏上显示无符号整数,并通过按键实现数值增减和数据存储。实验中,当按下K1键数值减一,K2键数值加一,K3键将数值写入AT24C02,断电后K4键可以从存储器读取。程序中展示了I2C起始、停止信号、数据发送与接收等关键函数的实现,以及与AT24C02交互的读写操作。
摘要由CSDN通过智能技术生成

1.前言

项目资源:

https://download.csdn.net/download/YLG_lin/86541001

1.1实验现象

在LCD1602液晶屏上显示一个无符号整型数字,按下K1按键数字减一,按下K2数字加一,按下K3数字向AT24C02写入该数据,断电重启后按下K4可以从AT24C02中读取该数据。

1.2 AT24C02介绍

AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息
存储介质:E2PROM
通讯接口:I2C总线
容量:256字节

2. 相关程序及解释

2.1 引脚定义

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

2.2 I2C起始信号

起始条件:SCL高电平期间,SDA从高电平切换到低电平

空闲状态下 SDA与SCL默认置高电平;值得注意的是在应答之后SDA有可能为高电平也有可能为低电平(复合格式如下图),所以开始时要置高电平;

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

 2.3 I2C停止信号

终止条件:SCL高电平期间,SDA从低电平切换到高电平

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

 2.4 I2C主机向从机发送一个字节数据

SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节

SCL置高后立马置低,不用加延迟,从机是能在高电平期间读到数据的;如果换到更快的单片机的话就要考虑它能承受的最快时间了,具体参考芯片手册;

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;
	}
}

2.5 I2C主机接收一个字节数据

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

unsigned char I2C_ReceiveByte(void)
{
	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;
}

2.6 发送应答

发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答

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

2.7 接收应答

接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

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

 2.8 主机向从机发数据(多字节)

 AT24C02的固定地址为1010,可配置地址本开发板上为000
 所以SLAVE ADDRESS+W为0xA0,SLAVE ADDRESS+R为0xA1

字节写:在WORD ADDRESS处写入数据DATA

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();
}

2.9 从机向主机发数据(多字节)

随机读:读出在WORD ADDRESS处的数据DATA

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;
}

3.0 main.c

读取数据的时候不用Delay(5);写的时候要加延时函数,写的时候需改变AT24C02的物理特性,让它永久保存数据,所以需要的时间长一点;具体时间可以查用户手册;ROM比RAM慢一些,就与ROM有个写入时间有关;keynum==3 中num是16位数据,在地址0写入num低8位,在地址1写入高八位;

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);   //延迟5ms,查芯片手册可知
			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,"        ");
		}
	}
}

  • 3
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记忆&碎片

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值