当前位置: 首页 > article >正文

51单片机-第九节-AT24C02存储器(I2C总线)

一、AT24C02存储器介绍:

AT24C02是存储器,且掉电不丢失,可存储单片机要永久保存的数据。

通讯接口:I2C总线。

容量:256字节。

二、存储器简化模型:

引脚及应用电路:

三、I2C总线:

1.介绍:

(1)I2C总线 (Inter IC BUS)是由Philips公司开发的一种通用数据总线

(2)两根通信线:SCL(Serial Clock)、SDA(Serial Data)

(3)同步、半双工,带数据应答

(4)通用的I2C总线,可以使各种设备的通信标准统一 。

2.  时序结构:

(1)起始,终止:

(2)发送和接收字节:

下面的SDA的两行是具体数据,可0可1,需要注意SCL拉高期间SDA不能变。

  

(3)发送和接收应答:

四、利用I2C操作AT24C02:

(1)发送一帧数据:

首先 发送 S 表示开始,即时序结构中的起始部分。

随后 发送地址,由8位构成,最后一位是读写标志位,前7位中的前4位是固定的,51单片机中为1010,后3位是可变地址,即存储器简化模型中的 E0,E1,E2 ,我们用不到,置000即可。

然后每发送一个字节需要接收应答。循环。

最后终止流程。

(2)其他流程见下图,拼接而已。

(3)注意:在每次将数据写入AT24C02后,需 Delay 5ms,因为写入时AT24C02需要操作时间。

五、I2C集成:

//I2C的开始和停止,接受和发送字节,接受和发送应答
sbit I2C_SDA = P2 ^ 0;
sbit I2C_SCL = P2 ^ 1;

void I2C_Start()
{
	I2C_SCL = 1;
	I2C_SDA = 1;//因为根据时序,Start前需要两个均为高
	I2C_SCL = 0;
	I2C_SDA = 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;
		//此处注意:拉高立马拉低,需要考虑单片机执行指令的速度
		//不过51本来就很慢,不用考虑,否则每行间需加入Delay
	}
}
unsigned char I2C_ReceiveByte()
{
	unsigned char Byte = 0x00;
	unsigned char i = 0;

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

六、AT24C02集成:

//AT24C02存储器写入和读取字节,WordAddress=0~256
void AT24C02_WriteByte(unsigned char WordAddress, unsigned char Data)
{
	I2C_Start();
	I2C_SendByte(0xA0);
	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(0xA0);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	//此处由写改为收,重新start
	I2C_Start();
	I2C_SendByte(0xA1);
	I2C_ReceiveAck();
	Data = I2C_ReceiveByte();
	I2C_SendAck(1);
	I2C_Stop();
	return Data;
}

七、实例:独立按键写入读出AT24C02:

按键1:Num加一;    按键2:Num减一;

按键3:Num写入;    按键4:Num读出;

unsigned char KeyNum;
unsigned int Num;
void main()
{
	LCD_Init();
	LCD_ShowString(1, 1, "Hello");
	while (1)
	{
		KeyNum = Key();
		if (KeyNum == 1)
		{
			Num++;
			LCD_ShowNum(1, 1, Num, 5);
		}		
		if (KeyNum == 2)
		{
			Num--;
			LCD_ShowNum(1, 1, Num, 5);
		}		
		if (KeyNum == 3)
		{
			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)
		{
			Num = AT24C02_ReadByte(1);
			Num = Num << 4;
			Num += AT24C02_ReadByte(0);
			LCD_ShowNum(1, 1, Num, 5);
		}
	}
}


http://www.kler.cn/news/288371.html

相关文章:

  • 代码随想录算法训练营第35天 | 416.分割等和子集
  • PLUTO: 推动基于模仿学习的自动驾驶规划的极限
  • AI智能电销机器人的优势是什么,有什么特点?
  • Python群发邮件:如何实现Python邮件群发?
  • 浅谈sizeof() 函数在Arduino中的使用
  • 代码随想录算法训练营_day35
  • ARM 异常处理(21)
  • dfs算法复习
  • Express与SQLite集成教程:轻松实现数据库操作
  • 【概率与统计 动态规划】 808. 分汤
  • Unity3D DOTS系列之BlobAsset核心机制详解
  • UFUG2601-OJ palindrome
  • idea便捷操作
  • Kubernetes 1.20 上将容器从 Docker Engine 改为 Containerd
  • Idea发布springboot项目无法识别到webapp下面的静态资源
  • <数据集>无人机识别数据集<目标检测>
  • 等保2.0通用部分 | 安全物理环境(三级)测评指导书
  • ai数字人音频停顿处理,删除无用音频段
  • 【C++拓展(一)】后端开发常用的技术栈
  • 在随机点实现凸包包围游戏地区
  • 产品概述Tektronix泰克TCP0030A电流探头TCP0030原装二手
  • 前端bug:v-show嵌套组件外层,页面扩大后,组件被遮挡
  • 使用支持UDP协议的IP是否更加快速?
  • 使用Python+docx+openpyxl将Word表格转换为Excel表格
  • EI论文被引多少次算高引?
  • div嵌套img,去除img下的小空隙
  • <Rust>egui学习之小部件(七):如何在窗口中添加颜色选择器colorpicker部件?
  • 笔记:《利用Python进行数据分析》之透视表和交叉表
  • 了解Python中如何实现多线程,并讨论GIL的影响
  • 机器学习:opencv--图像边缘检测