一、应用场景?

有些单片机没有内部的EEPROM,或者说内部的EEPROM空间不够大,这时候,我们就想到了外挂一个EEPROM芯片,而AT24C32就是一种常用的串行EEPROM存储器,它适用于许多需要在系统掉电后保留数据的嵌入式应用场景。


二、AT24C32是什么?

AT24C32是一种常见的串行 EEPROM 存储器芯片,通常用于存储系统配置、用户数据、校准参数等。它具有以下特点,一般会在以下情况下被使用:

1.小容量数据存储:AT24C32的存储容量一般为32Kb,适合存储少量的配置信息、校准参数、设备标识等数据。
2.串行接口:AT24C32采用串行接口进行数据通信,这使得它在占用较少引脚的同时能够进行高效的数据读写操作,因此适合于资源受限的嵌入式系统或小型设备中使用。
3.数据保存与恢复:AT24C32通常被用于存储需要持久保存的数据,例如设备配置、校准参数等。它的非易失性存储特性意味着即使断电也能保持数据完整,可在下次上电时恢复。
4.嵌入式系统:由于其小巧的封装、低功耗和易于集成的特点,AT24C32常被嵌入式系统设计中用于管理系统配置、日志记录、用户个性化设置等数据。

三、使用步骤

1.引脚说明

在这里插入图片描述

1-3.A0~A2:地址输入引脚,共3个,用于设定芯片的I2C地址。
4.GND:地引脚,与VCC联合供电。
5.SDA:串行数据输入/输出引脚,用于与I2C总线进行通信。
6.SCL:串行时钟输入引脚,用于与I2C总线进行同步。
7.WP:写保护引脚,当WP引脚为高电平时,AT24C32将无法写入数据,起到了对AT24C32数据的保护作用。
8.VCC:供电引脚,连接正极电源。

其中,WP引脚是AT24C32的写保护引脚,用于控制AT24C32是否可以写入数据。当WP引脚处于高电平时,AT24C32将进入写保护模式,此时将无法写入数据。当WP引脚处于低电平时,AT24C32将退出写保护模式,此时可以向其写入数据。通常情况下,WP引脚需要连接到系统中的GPIO引脚上,以便在需要时能够动态控制AT24C32的写保护模式

2.示例代码

EEPROM设备都需要一个8位设备地址字,包含一个启动条件,以使芯片能够进行读或写操作。设备地址字前4位最高有效位为1010。这对所有串行EEPROM设备都是通用的。接下来的3位是EEPROM的A2、A1和A0设备地址位。设备地址的第8位是读写操作选择位。如果该位高,则进行读操作;如果该位低,则进行写操作。

综上,如果对AT24C32进行读操作,则设备地址为10100001B=A1H;如果对AT24C32进行写操作,则设备地址为10100000B=A0H.

2.1 读取一个字节数据代码如下(示例):

/*******************************************************************************
 * 函数名:AT24CXX_ReadOneByte
 * 描述  :从串行EEPROM指定地址处开始读取一个字节数据
 * 输入  :_usAddress地址
 * 输出  :读取的数据dat
 * 调用  :
 * 备注  :
 *******************************************************************************/
uint8_t AT24CXX_ReadOneByte(uint16_t _usAddress)
{
	uint8_t dat = 0;		  	    																 
	EE_IIC_Start();  
	if(EE_SIZE > ((128*16)))//>AT24C16
	{
		EE_IIC_Send_Byte(EE_DEV_ADDR);//发送写命令
		EE_IIC_Wait_Ack();
		EE_IIC_Send_Byte(_usAddress>>8);//发送高地址 
		EE_IIC_Wait_Ack(); 
	}		
    else
	{
		EE_IIC_Send_Byte(EE_DEV_ADDR + ((_usAddress/256)<<1));//发送器件地址0xA0,写数据		  
	}			
	EE_IIC_Send_Byte(_usAddress%256);//发送低地址
	EE_IIC_Wait_Ack();	    
	EE_IIC_Start();  	 	   
	EE_IIC_Send_Byte(EE_DEV_ADDR | I2C_RD);//进入接收模式0xA1			   
	EE_IIC_Wait_Ack();	 
	dat = EE_IIC_Read_Byte(0);		   
	EE_IIC_Stop();//产生一个停止条件	    
	return dat;
}

2.2 写入一个字节数据代码如下(示例):

/*******************************************************************************
 * 函数名:AT24CXX_WriteOneByte
 * 描述  :从串行EEPROM指定地址处开始写入一个字节数据
 * 输入  :_usAddress地址,_usWrite数据
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void AT24CXX_WriteOneByte(uint16_t _usAddress,uint8_t _usWrite)
{
	EE_IIC_Start();
	if(EE_SIZE > ((128*16)))//>AT24C16
    {  
	    EE_IIC_Send_Byte(EE_DEV_ADDR);//发送写命令
		EE_IIC_Wait_Ack();
		EE_IIC_Send_Byte(_usAddress>>8);//发送高地址
	}
	else
	{
		EE_IIC_Send_Byte(EE_DEV_ADDR + ((_usAddress/256)<<1));//发送器件地址0xA0,写数据		  			
	}
	EE_IIC_Wait_Ack();	   
	EE_IIC_Send_Byte(_usAddress%256);//发送低地址
	EE_IIC_Wait_Ack(); 	 										  		   
	EE_IIC_Send_Byte(_usWrite);//发送字节							   
	EE_IIC_Wait_Ack();  		    	   
	EE_IIC_Stop();//产生一个停止条件 
	delay_syms(10);	 
}

2.3 读取若干数据代码如下(示例):

/*******************************************************************************
 * 函数名:AT24CXX_ReadBytes
 * 描述  :从串行EEPROM指定地址处开始读取若干数据
 * 输入  : usAddress : 起始地址
 *			_pReadBuf : 存放读到的数据的缓冲区指针
 *			 _usSize : 数据长度,单位为字节
 * 输出  :0 表示失败,1表示成功
 * 调用  :
 * 备注  :
 *******************************************************************************/
void AT24CXX_ReadBytes(uint16_t _usAddress, uint8_t *_pReadBuf, uint16_t _usSize)
{
    while(_usSize)
	{
		    *_pReadBuf++ = AT24CXX_ReadOneByte(_usAddress++);
			 _usSize--; 
	}
}

2.4 写入若干数据代码如下(示例):

/*******************************************************************************
 * 函数名:AT24CXX_WriteBytes
 * 描述  :向串行EEPROM指定地址写入若干数据
 * 输入  :_usAddress : 起始地址 
 *			 _pWriteBuf : 存放读到的数据的缓冲区指针
 *			 _usSize : 数据长度,单位为字节
 * 调用  :0 表示失败,1表示成功
 * 备注  :
 *******************************************************************************/
void AT24CXX_WriteBytes(uint16_t _usAddress, uint8_t *_pWriteBuf, uint16_t _usSize)
{
    while(_usSize--)
	{
		AT24CXX_WriteOneByte(_usAddress,*_pWriteBuf);
        _usAddress++;
		_pWriteBuf++;
	}
}

2.5 测试代码如下(示例):

/*******************************************************************************
 * 函数名:DEBUG_test_AT24C32
 * 描述  :测试AT24C32
 * 输入  :void
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void DEBUG_test_AT24C32(void)
{
	uint8_t i,j;
	if(EE_CheckOk() == 1)//检测设备是否存在
	{
		printf("Check OK \r\n");
		 
        for(i = 0; i < 16; i++)
	    {
		    test_buf1[i] = i;
	    }	
	    AT24CXX_WriteBytes(0x20,test_buf1,16);
	 
	    AT24CXX_ReadBytes(0x20,test_buf2,16);
        for(j=0;j<16;j++)
	    {
		    printf("test_buf2 = %d\r\n",test_buf2[j]);
	    }			 
	}
    else
	{
		 printf("Check Fail \r\n");
	}	 
}

3.测试结果

和测试代码写的结果是一样,测试代码首先把0-15写入到test_buf1数组里面,再通过写函数把它写入到EEPROM芯片,最后通过读函数将它读取出来给到test_buf2数组,再打印出来。

在这里插入图片描述


四、总结

今天主要讲了AT24C32的应用驱动,这个驱动我也只是在AT24C32上验证过,是否可以兼容AT24CXX同类型的芯片需要自行验证,有兴趣的可以下载驱动附件参考,感谢你的观看,谢谢!

在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐