【STM32学习笔记】硬件I2C读写EEPROM(AT24C02)的工作时序和编程指南

目录

前言

一、硬件IIC的基本工作流程

1、发送一个字节 ByteWrite

 2、按页连续发送多字节PageWrite

 3、读取一个字节 RandomRead

4、按页连续读取多字节 SequentialRead

二、几种实用的连续读写函数

1、多字节连续发送函数

2、多字节连续读取函数

3、半字(u16)字(u32)数据写入函数 

4、半字(u16)字(u32)数据读取函数 

5、支持跨页和循环写入的函数

5、支持跨页和循环读取的函数

前言

本章主要介绍了硬件I2C读写EEPROM的实现过程,结合I2C的两种工作模式(主机发送、主机接收)和AT24Cxx的四种基本读写模式ByteWrite、RandomRead、PageWrite、SequentialRead),给出了对应的四个基本传送序列图;并根据序列图进行了代码的编写;此外,还基于四种基本读写函数,给出了一些更为实用的读写函数。

基于STM32F103ZET6的完整工程代码,请到资源页下载:https://download.csdn.net/download/yy199806/88359854

一、硬件IIC的基本工作流程

硬件IIC的工作流程可以划分为三个基本操作:(1)写CR,读SR,清除标志位

(2)写DR(OAR),读SR,清除标志位。

(3)读SR,读DR,清除标志位。

以上三个基本操作的排列组合即可实现四种工作模式(主机发送、主机接收、从机发送、从机接收)的传送序列。

下面重点介绍本项目涉及的主机发送和主机接受两种模式。

同时一定要理解的是:1、3的单字节发送和接收对应的是EEPROM的ByteWrite和RandomRead工作模式;2、4的按页连续发送和读取对应的是EEPROM的PageWrite和SequentialRead模式。

1、发送一个字节 ByteWrite

 AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

下图为STM32F1xx中文参考手册中IIC作为主发送器传送序列图的简化版本,是特别针对发送一个字节的情况绘制,只需严格按照以下时序编写程序即可。

【BusyCheck】:检查总线是否繁忙,每一次IIC通信前都需要检查。具体实现代码如下:

    I2CTimeout = 0x10000;
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))   
    {
		if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
    } 

【S---EV5】(写CR,读SR,清除标志位):发送起始信号;检测事件5,SB=1;注意:下一步的设备地址写入才会清除SB标志位。

    I2C_GenerateSTART(I2C1,ENABLE);//发送起始信号  
    //检测EV5事件,SB=1,起始信号已发送
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))
	{
		Timeout--;
		if(Timeout==0) {return I2C_TIMEOUT_UserCallback(0);}//超时返回错误代码0
	}

【设备地址--A--EV6】(写OAR,读SR,清除标志位);发送设备地址(寻址),检测事件6,收到ACK后ADDR=1,代表地址已发送且收到了应答信号ACK;读SR1后再读SR2清除ADDR标志位。

    I2C_Send7bitAddress(I2C1,0xA0);
	//检测EV6事件并清除标志:收到ACK后ADDR=1,地址已发送;再读SR2来清除ADDR标志
	Timeout=0x1000;
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//检查最近一次 I2C 事件是否是EV6事件
	{
		Timeout--;
		if(Timeout==0) {return I2C_TIMEOUT_UserCallback(1);}//超时返回错误代码1
	}

【数据地址--A--EV8】(写DR,读SR,清除标志位)写入第一个数据(实际上是存储单元的地址);检测事件8,数据寄存器为空且收到ACK时,TXE=1,代表地址已发送且收到了应答信号ACK;下一句DR的写入会清除TXE标志。

    I2C_SendData (I2C1,WriteAddr);
	//检测EV8事件并清除标志:DataReg为空时且收到ACK时TXE=1,下一句DR的写入会清除TXE标志
	Timeout=0x1000;
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING))
	{
		Timeout--;
		if(Timeout==0) {return I2C_TIMEOUT_UserCallback(2);}//超时返回错误代码2
	}	

【发送数据_A_EV8_2】(写DR,读SR,清除标志位)写入要发送的数据;检测事件8_2,数据寄存器为空时且收到ACK时TXE=1,移位寄存器已发完最后一个字节时BTF=1,代表数据已发送且收到了应答信号ACK;下一句停止信号的发送会清除TXE、BTF标志位。

	I2C_SendData (I2C1,DataToWrite);
	//检测EV8_2事件并清除标志:DataReg为空时且收到ACK时TXE=1,移位寄存器已发完最后一个字节BTF=1;下一句STOP的发送会清除TXE、BTF标志
	Timeout=0x1000;
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))
	{
		Timeout--;
		if(Timeout==0) {return I2C_TIMEOUT_UserCallback(3);}//超时返回错误代码3
	}		

【P】:发送停止信号。注意根据AT24Cxx手册,完成一次读写后需要延时一段时间tWR,来 等待WriteCircle完成。

	I2C_GenerateSTOP (I2C1,ENABLE);
	delay_ms(10);	 //tWR 等待WriteCircle完成

 2、按页连续发送多字节PageWrite

 AT24CXX_Page_Write(u16 WriteAddr,u8 *pBuffer,u8 NumToWrite);

下图为STM32F1xx中文参考手册中IIC作为主发送器传送序列图的简化版本,是特别针对连续发送的情况绘制,和单字节发送的区别就是:(1)发送完存储单元地址后,循环执行【发送数据_A_EV8】即可实现连续发送数据(2)只需指定第一个数据的地址,后续的数据写入,地址会自动递增(3)注意最多连续发一页8、16个数据(由AT24Cxx型号决定)(4)发完最后一个数据的检测事件和之前不同,为EV8_2。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值