STM32F4 通过IIC对 24C02 EEPROM 读写

因为以前学习 I2C 的时候就没有完全理清工作原理,所以后来再去看例程的时候发现有点懵,不管是AT24C02的内存上还是双方的工作方式和时序上都有些疑惑。通过查找手册以及看别人对 IIC 例程的理解,最终找到一个我觉得需要记录下来的一篇文章,因为里面有我容易混淆的内容,像AT24C02的内存,2K 指的是2Kbit,而不是2KByte。对IIC了解得相对熟之后回头来记录一下:
转自:https://blog.csdn.net/ohy3686/article/details/86723598

【1】24C02功能概述

24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节。在24C02里面有一个8字节的页写缓冲器。该设备的工作电压为1.8V到6.0V,芯片的第7引脚WP为写保护引脚,将该引脚接地允许正常的读写。
在这里插入图片描述在这里插入图片描述

【2】设备地址

24C02的设备地址包括固定部分和可编程部分。可编程部分需要根据硬件引脚A0、A1和A2来设置。设备地址的最后一位用于设置数据传输的方向,即读/写位。格式如下图:

在这里插入图片描述
在IIC总线协议中,设备地址是起始信号后第一个发送的字节。如果硬件地址引脚A0、A1、A2均接地,那么,24C02的设备的读操作地址为:0xA1;而写操作地址则为:0xA0。

【3】读写操作中的应答信号

在写操作中,24C02每接收一个8位字节后会产生一个应答信号。在读操作中,24C02在发送一个8位数据后会释放SDA线并监视应答信号。一旦收到应答信号,将继续发送数据。如果主机没有发送应答信号,从机则停止发送数据且等待一个停止信号。

【4】字节写操作

24C02接收完设备地址后,产生应答信号;然后接收8位内存字节地址,产生应答信号,接着接收一个8位数据,产生应答信号;最后主机发送停止信号,字节写操作结束。
【5】页写操作

24C02有一个8字节的页写缓冲器,也就是说可以一次连续写入8个字节到缓冲器,然后由缓冲器一次性写到EEPROM。页写操作初始化与字节写操作相同,只是主机不会在写完第一个数据后就发送停止信号,而是在24C02应答后,接着发送7个数据。

需要注意的是,24C02接收到每个数据后,其字节地址的低3位会自动加1,高位地址不变,维持在当前页内。当内部产生的字节地址到达该页边界时,随后的数据将写入该页的页首,先前的写入的数据将会被覆盖。
【6】当前地址读操作

24C02内部的地址寄存器会保存着上次读/写操作最后一个地址加1的值。只要芯片有电,该地址就一直保存着。如果上次读/写操作的地址为N,那么当前地址读操作就从N+1开始。当读到最后一个字节(即255处),地址会回转到0。

【7】字节读操作

主机首先发送起始信号,接着发送设备地址和它想要读取的数据内存字节地址,执行一个伪写操作。在24C02应答主机之后,主机重新发送起始信号和从设备地址,进行读操作。24C02响应并发送应答信号,然后输出所要求的一个8位字节数据。主机接收完这个8位数据后,产生一个“非应答”信号,最后发送停止条件,字节读操作结束。

【8】连续读操作

在24C02发送完一个8位字节数据之后,主机产生一个应答信号来响应,告知24C02要求读取更多的数据,直到读完最后一个数据,主机向24C02发送一个“非应答”信号,然后发送一个停止信号,结束此操作。

【9】基本读写操作流程

24C02的字节写操作及其参考代码:

在这里插入图片描述

void Write_24C02(unsigned char addr, unsigned char dat)
{
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa0); 	//24C02的写设备地址
	IIC_WaitAck();		//等待从机应答	
	IIC_SendByte(addr); 	//内存字节字节
	IIC_WaitAck(); 		//等待从机应答	
	IIC_SendByte(dat); 	//写入目标数据
	IIC_WaitAck();		//等待从机应答	
	IIC_Stop();		//IIC总线停止信号		
}

24C02的字节读操作,及其参考代码:

在这里插入图片描述

unsigned char Read_24C02(unsigned char addr)
{
	unsigned char tmp;
	//进行一个伪写操作
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa0); 	//24C02写设备地址
	IIC_WaitAck();		//等待从机应答	
	IIC_SendByte(addr); 	//内存自己地址
	IIC_WaitAck(); 		//等待从机应答	
	//进行字节读操作
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa1); 	//24C02读设备地址
	IIC_WaitAck();		//等待从机应答	
	tmp = IIC_RecByte();	//读取目标数据
	IIC_Ack(0); 		//产生非应答信号		
	IIC_Stop();		//IIC总线停止信号			
	return tmp;
}
主要是这两段代码很简洁,对得上AT24C02手册中对读写的要求,对照着手册看能很容易看明白。
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F103可以通过硬件I2C接口24C02芯片。 步骤如下: 1. 配置I2C接口:设置I2C时钟频率、I2C地址、I2C模式等参数。 2. 发送起始信号:向I2C总线发送起始信号。 3. 发送设备地址:向24C02芯片发送设备地址,包括位。 4. 发送数据地址:向24C02芯片发送要的数据地址。 5. 发送数据:向24C02芯片发送要入的数据,或者从24C02芯片取数据。 6. 发送停止信号:向I2C总线发送停止信号。 具体实现可以参考STM32F103的I2C库函数,例如HAL库中的HAL_I2C_Mem_Read()和HAL_I2C_Mem_Write()函数。 ### 回答2: STM32F103是一种非常流行的32位单片机系列,它具有强大的硬件性能和广泛的应用领域。而24C02则是I2C系列串行EEPROM,可以供我们存储大量的数据。在这里,我们主要介绍如何使用STM32F103的硬件I2C接口来24C02。 首先,我们需要对STM32F103的硬件I2C接口进行初始化。其中,我们需要配置I2C的时钟、GPIO口、I2C的工作模式等参数。具体的代码如下: RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);//使能I2C1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PB6--I2C1_SCL,PB7--I2C1_SDA GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//开漏输出 GPIO_Init(GPIOB,&GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//I2C模式 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//占空比为2 I2C_InitStructure.I2C_OwnAddress1 = 0x00;//自己的地址,一般为0 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//地址长度 I2C_InitStructure.I2C_ClockSpeed = 400000;//400kHZ时钟频率 I2C_Init(I2C1,&I2C_InitStructure); I2C_Cmd(I2C1,ENABLE);//使能I2C1 接着,我们编取21C02的程序。取时,由于24C02是以字节为单位进行数据的取,所以我们可以使用IIC的硬件取指令,在取时起始地址+1的下一个字节为第一个地址,直至取结束地址。具体的代码如下: I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);//发送器件地址,命令0xA0 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待发送器件地址成功 I2C_SendData(I2C1,0x00);//发送内部地址0x00 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Receiver);//发送器件地址,命令0xA1 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//等待接收器件地址成功 for(i=0;i<length;i++) { if(i==(length-1))I2C_AcknowledgeConfig(I2C1,DISABLE);//如果是最后一个字节,后面不再发送AK信号,即不再接收数据 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); RxBuffer[i]=I2C_ReceiveData(I2C1); } I2C_GenerateSTOP(I2C1,ENABLE);//发送一个停止信号 再来看一下24C02的入操作。通过IIC硬件入指令,我们可以将数据依次入到指定的地址中,假如入了n个字节,则下一次操作的地址将会到达第n+1个地址。具体的代码如下: I2C_GenerateSTART(I2C1,ENABLE); while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);//发送器件地址,命令0xA0 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待发送器件地址成功 I2C_SendData(I2C1,Addr);//发送入的地址 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 for(i=0;i<length;i++) { I2C_SendData(I2C1,buf[i]);//发送数据 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 } I2C_GenerateSTOP(I2C1,ENABLE);//发送一个停止信号 综上所述,我们可以通过STM32F103的硬件I2C接口来取或入24C02。不过,在实际操作中,还需要注意一些注意事项,如使用IIC取有ACK和无ACK状态,需要注意IIC的时序等问题。 ### 回答3: STM32F103是一款基于ARM Cortex-M3内核的微控制器,支持多种通信接口,包括I2C总线接口。24C02是一种I2C EEPROM芯片,可用于存储小型数据和程序。 在STM32F103中,可以通过GPIO配置I2C总线接口来进行24C02的操作。以下是实现I2C的基本步骤: 1. 配置GPIO引脚 使用CubeMX或者直接编代码,将STM32F103的GPIO引脚配置成I2C总线引脚。通常I2C总线由两个引脚组成,即数据线(SDA)和时钟线(SCL),其中SDA引脚为双向输出,SCL引脚为输出。 2. 配置I2C总线 使用CubeMX或者直接编代码,将STM32F103的I2C总线配置成所需的速率和从设备地址。24C02只有一个地址(0x50),因此将其配置为从设备地址即可。 3. 发送I2C起始信号 在进行I2C通信之前,需要先发送起始信号。发送起始信号的代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, NULL, 0, 100); 其中hi2c1为I2C总线句柄,0xA0为24C02的从设备地址。 4. 发送I2C入地址 在向24C02入数据之前,需要先向其入地址。该地址为数据的存储地址,可以根据具体要求进行设置。例如,向地址0x00入数据,代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, &addr, 1, 100); 其中addr为入的地址。 5. 发送数据 在向24C02入数据之前,需要先向其发送要入的数据。代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, &data, 1, 100); 其中data为要入的数据。 6. 发送I2C停止信号 在完成I2C通信后,需要发送停止信号。发送停止信号的代码如下: HAL_I2C_Stop(&hi2c1); 以上是向24C02入数据的基本步骤,取数据的方法类似,只需将入操作替换为取操作即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值