官方例程是8位EEPROM地址,实际使用16位地址的EEPROM,改写官方例程,实现16位地址读写
/**
******************************************************************************
** \brief 主机接收函数
**
** \param u8Addr从机内存地址,pu8Data读数据存放缓存,u32Len读数据长度
**
** \retval 读数据是否成功
**
******************************************************************************/
en_result_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint16_t u16Addr,uint8_t *pu8Data,uint32_t u32Len)
{
en_result_t enRet = Error;
uint8_t u8i=0,u8State;
uint8_t i=0;
I2C_SetFunc(I2CX,I2cStart_En);
while(1)
{
while(0 == I2C_GetIrq(I2CX))
{}
u8State = I2C_GetState(I2CX);
switch(u8State)
{
case 0x08: ///< 已发送起始条件,将发送SLA+W
I2C_ClearFunc(I2CX,I2cStart_En);
I2C_WriteByte(I2CX,I2C_SLAVEADDR);
break;
case 0x18: ///< 已发送SLA+W,并接收到ACK
I2C_WriteByte(I2CX,u16Addr<<8); ///<高8位地址,发送从机内存地址
break;
case 0x28: ///< 已发送数据,接收到ACK, 此处是已发送从机内存地址u8Addr并接收到ACK
i++;
I2C_WriteByte(I2CX,u16Addr&0xff); ///<低8位地址 发送从机内存地址
if(i>1)
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送重复起始条件
break;
case 0x10: ///< 已发送重复起始条件
I2C_ClearFunc(I2CX,I2cStart_En);
I2C_WriteByte(I2CX,I2C_SLAVEADDR|0x01);///< 发送SLA+R,开始从从机读取数据
break;
case 0x40: ///< 已发送SLA+R,并接收到ACK
if(u32Len>1)
{
I2C_SetFunc(I2CX,I2cAck_En); ///< 使能主机应答功能
}
break;
case 0x50: ///< 已接收数据字节,并已返回ACK信号
pu8Data[u8i++] = I2C_ReadByte(I2CX);
if(u8i==u32Len-1)
{
I2C_ClearFunc(I2CX,I2cAck_En); ///< 已接收到倒数第二个字节,关闭ACK应答功能
}
break;
case 0x58: ///< 已接收到最后一个数据,NACK已返回
pu8Data[u8i++] = I2C_ReadByte(I2CX);
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
break;
case 0x38: ///< 在发送地址或数据时,仲裁丢失
I2C_SetFunc(I2CX,I2cStart_En); ///< 当总线空闲时发起起始条件
break;
case 0x48: ///< 发送SLA+R后,收到一个NACK
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送起始条件
break;
default:
I2C_SetFunc(I2CX,I2cStart_En); ///< 其他错误状态,重新发送起始条件
break;
}
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
if(u8i==u32Len) ///< 数据全部读取完成,跳出while循环
{
break;
}
}
enRet = Ok;
return enRet;
}
/**
******************************************************************************
** \brief 主机发送函数
**
** \param u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
**
** \retval 写数据是否成功
**
******************************************************************************/
en_result_t I2C_MasterWriteData(M0P_I2C_TypeDef* I2CX,uint16_t u16Addr,uint8_t *pu8Data,uint32_t u32Len)
{
en_result_t enRet = Error;
uint8_t u8i=0,u8State;uint8_t i=0;
I2C_SetFunc(I2CX,I2cStart_En);
while(1)
{
while(0 == I2C_GetIrq(I2CX))
{;}
u8State = I2C_GetState(I2CX);
switch(u8State)
{
case 0x08: ///< 已发送起始条件
I2C_ClearFunc(I2CX,I2cStart_En);
I2C_WriteByte(I2CX,I2C_SLAVEADDR); ///< 从设备地址发送
break;
case 0x18: ///< 已发送SLA+W,并接收到ACK
I2C_WriteByte(I2CX,u16Addr<<8); ///< 高8位地址从设备内存地址发送
break;
case 0x28: ///< 上一次发送数据后接收到ACK
i++;
I2C_WriteByte(I2CX,u16Addr&0xff); ///<低8位地址 从设备内存地址发送
if(i>1)
I2C_WriteByte(I2CX,pu8Data[u8i++]); ///< 继续发送数据
break;
case 0x20: ///< 上一次发送SLA+W后,收到NACK
case 0x38: ///< 上一次在SLA+读或写时丢失仲裁
I2C_SetFunc(I2CX,I2cStart_En); ///< 当I2C总线空闲时发送起始条件
break;
case 0x30: ///< 已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
break;
default:
break;
}
if(u8i>u32Len)
{
I2C_SetFunc(I2CX,I2cStop_En); ///< 此顺序不能调换,出停止条件
I2C_ClearIrq(I2CX);
break;
}
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
}
enRet = Ok;
return enRet;
}
/******************************************************************************
* EOF (not truncated)
******************************************************************************/