STM32之I2C向EEPROM读写数据基于HAl库代码

1 篇文章 0 订阅
1 篇文章 0 订阅

STM32之I2C向EEPROM读写数据基于HAl库代码


/**
  * @brief   将缓冲区中的数据写到I2C EEPROM中
  * @param   
  *		@arg pBuffer:缓冲区指针
  *		@arg WriteAddr:写地址
  *     @arg NumByteToWrite:写的字节数
  * @retval  无
  */
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
{
  uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

  Addr = WriteAddr % EEPROM_PAGESIZE;															//第一页从哪开始
  count = EEPROM_PAGESIZE - Addr;																	//第一页写几个位
  NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;									//写几页
  NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;									//最后还剩几个数据需要写
 
  /* If WriteAddr is I2C_PageSize aligned  */
  if(Addr == 0) 																									//如果首地址是0
  {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage == 0) 																						//如果页数是0 ,不满一页 直接写到底
    {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);					//直接写一页
    }	
    /* If NumByteToWrite > I2C_PageSize */
    else  																												//大于1页
    {
      while(NumOfPage--)																					//写一页 减减
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE); 		//按页写
        WriteAddr +=  EEPROM_PAGESIZE;														//写完地址+8 换页
        pBuffer += EEPROM_PAGESIZE;																//数组内容+8  
      }

      if(NumOfSingle!=0)																					//如果最有一页不为0
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);				//全写上
      }
    }
  }
  /* If WriteAddr is not I2C_PageSize aligned  */
  else 																														//否则(首地址不为0)
  {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage== 0) 																						//但是页数为0,不满一页
    {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);					//直接写
    }
    /* If NumByteToWrite > I2C_PageSize */
    else																													//大于一页
    {
      NumByteToWrite -= count;																		//要写的数据减去第一页的数据
      NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;							//剩下的页数
      NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;							//剩下不满一页的数据
				
      if(count != 0)																							//如果不为0,即第一页有不满8个数据
      {  
        I2C_EE_PageWrite(pBuffer, WriteAddr, count);							//写数据
        WriteAddr += count;																				//第一页写完,首地址换第二页
        pBuffer += count;																					//缓冲区数量+
      } 
      
      while(NumOfPage--)																					//开始写第二页一直到最后一页
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE);	
        WriteAddr +=  EEPROM_PAGESIZE;
        pBuffer += EEPROM_PAGESIZE;  
      }
      if(NumOfSingle != 0)																				//如果最后一页有单独的数据
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); 				//写最后一页
      }
    }
  }  
}

/**
  * @brief   写一个字节到I2C EEPROM中
  * @param   
  *		@arg pBuffer:缓冲区指针
  *		@arg WriteAddr:写地址 
  * @retval  无
  */
uint32_t I2C_EE_ByteWrite(uint8_t* pBuffer, uint8_t WriteAddr)  					//按字节写
{
	HAL_StatusTypeDef status = HAL_OK	;																			//状态先给正常

//调用库函数 写数据   需要传入 I2C句柄	EEPROM地址		写地址			地址大小			数据缓存地址		发送数据大小	超时时间
	status = HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS, (uint16_t)WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, 1, 100); 
	//调用库函数成功返回OK

	/* Check the communication status */
	if(status != HAL_OK)																										//如果返回的状态不正常就调用出错函数
	{
	/* Execute user timeout callback */
	//I2Cx_Error(Addr);
	}
	while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)						//死循环直到状态READY
	{
		
	}

	/* Check if the EEPROM is ready for a new operation */
	while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);  //死循环直到硬件设备准备好

	/* Wait for the end of the transfer */
	while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)   					//死循环直到状态READY
	{
		
	}
	return status;																													//返回值
}

/**
  * @brief   在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数
  *          不能超过EEPROM页的大小,AT24C02每页有8个字节
  * @param   
  *		@arg pBuffer:缓冲区指针
  *		@arg WriteAddr:写地址
  *     @arg NumByteToWrite:写的字节数
  * @retval  无
  */
uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
{
	HAL_StatusTypeDef status = HAL_OK;
	/* Write EEPROM_PAGESIZE */
	
	//传入数据    I2C句柄		EEPROM地址  写地址  数据大小 缓冲区指针  每次写的大小		超时时间
	status=HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS,WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);

	while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)					//等待状态就绪
	{
		
	}

	/* Check if the EEPROM is ready for a new operation */
	while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);	//等待硬件设备就绪

	/* Wait for the end of the transfer */
	while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)					//传输后返回值正确
	{
		
	}
	return status;
}

/**
  * @brief   从EEPROM里面读取一块数据 
  * @param   
  *		@arg pBuffer:存放从EEPROM读取的数据的缓冲区指针
  *		@arg WriteAddr:接收数据的EEPROM的地址
  *     @arg NumByteToWrite:要从EEPROM读取的字节数
  * @retval  无
  */
uint32_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
{
	HAL_StatusTypeDef status = HAL_OK;
	
	status=HAL_I2C_Mem_Read(&I2C_Handle,EEPROM_ADDRESS,ReadAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)pBuffer, NumByteToRead,1000);

	return status;
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用STM32HAL库来实现I2C读写EEPROM。首先,确保已经正确配置了I2C外设和相关引脚。然后,按照以下步骤进行操作: 1. 初始化I2C外设:使用`HAL_I2C_Init()`函数初始化I2C外设。 2. 配置EEPROM地址:在发送I2C读写请求之前,需要设置EEPROM的地址。这可以通过向I2C外设发送一个写入EEPROM地址的I2C Start信号,然后发送EEPROM地址字节来实现。 3. 发送数据:如果要向EEPROM写入数据,可以使用`HAL_I2C_Master_Transmit()`函数发送数据。如果要从EEPROM读取数据,可以使用`HAL_I2C_Master_Receive()`函数接收数据。 下面是一个示例代码,演示如何使用HAL库进行I2C读写EEPROM: ```c #include "stm32xxxx.h" // 根据具体的芯片型号选择头文件 #define EEPROM_ADDRESS 0xA0 // EEPROM的I2C地址 // 初始化I2C外设 void I2C_Init(void) { // I2C外设初始化代码 // ... } // 向EEPROM写入数据 void EEPROM_Write(uint16_t address, uint8_t* data, uint16_t size) { // 发送I2C Start信号和EEPROM地址 HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, (uint8_t*)&address, 2, HAL_MAX_DELAY); // 发送数据EEPROM HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, data, size, HAL_MAX_DELAY); } // 从EEPROM读取数据 void EEPROM_Read(uint16_t address, uint8_t* data, uint16_t size) { // 发送I2C Start信号和EEPROM地址 HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, (uint8_t*)&address, 2, HAL_MAX_DELAY); // 从EEPROM接收数据 HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, data, size, HAL_MAX_DELAY); } ``` 请注意,上述代码中的`hi2c1`是I2C外设的句柄,具体根据你的芯片型号和使用的外设进行修改。此外,还需要根据EEPROM的具体规格和通信协议进行相应的配置。 希望以上信息对你有所帮助!如有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值