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