1.使用硬件i2c,polling模式
2.从任意地址写任意长度数据暂未实现
3.FM24C16D的地址说明
#define I2C_READY_STATUS_TIMEOUT 400000 ///< I2C timeout value
#define I2C_POLLING_SW (TRUE)
#define I2C_SLAVE_ADDR (0xA0)//从机地址
#define I2C_STAND_MODE (FALSE)//设置为TRUE时,标准模式,否则是快速模式.
#define I2C_DATA_TTL_LEN (8)//数据长度为8.
#define I2C_SDA_PIN (GPIO_PB8)
#define I2C_SCL_PIN (GPIO_PD10)
#define I2C_READ 0x01 ///< I2C read
#define I2C_WRITE 0x0 ///< I2C write
void I2C_Init(void)
{
I2C_ConfigType i2cConfig = {0};
/*初始化I2C引脚.*/
GPIO_SetFunc(I2C_SDA_PIN, GPIO_FUNC_2);
GPIO_SetFunc(I2C_SCL_PIN, GPIO_FUNC_2);
/*初始化I2C模块.*/
i2cConfig.setting.master = ENABLE;
#if (I2C_POLLING_SW)
i2cConfig.setting.intEn = DISABLE;
#else
i2cConfig.setting.intEn = ENABLE;
#endif
i2cConfig.setting.i2cEn = ENABLE;
i2cConfig.setting.syncEn = ENABLE;
i2cConfig.setting.gcaEn = ENABLE;
i2cConfig.setting.addressExt = DISABLE;
i2cConfig.addr1 = I2C_SLAVE_ADDR;
#if (I2C_STAND_MODE)//100K波特率
i2cConfig.sampleCNT = 11;//speed = APBclk/((sampleCnt+1)*(stepCNT+1)*2)
i2cConfig.stepCNT = 19;
#else //400K波特率
i2cConfig.sampleCNT = 11;//speed = APBclk/((sampleCnt+1)*(stepCNT+1)*2)
i2cConfig.stepCNT = 4;
#endif
I2C_Initialize(I2C2, &i2cConfig);
}
void WRITE(uint16_t addr, uint8_t data)
{
uint8_t tempWrBuf[2];
uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
tempWrBuf[0] = (uint8_t)addr;
tempWrBuf[1] = data;
I2C_MasterWrite(I2C2, slaveAddr, &tempWrBuf[0], 2);
udelay(1500);
}
uint8_t READ(uint16_t addr)
{
uint8_t wdata;
uint8_t rdata;
uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
wdata = (uint8_t)addr;
I2C_MasterWrite(I2C2, slaveAddr, &wdata, 1);//此函数最多只能读当前页数据
I2C_MasterRead(I2C2, (I2C_SLAVE_ADDR>>1), &rdata,1);
return rdata;
}
uint16_t READWORD(uint16_t addr)
{
uint8_t wdata;
uint8_t rdata[2];
uint16_t data;
uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
wdata = (uint8_t)addr;
I2C_MasterWrite(I2C2, slaveAddr, &wdata, 1);
I2C_MasterRead(I2C2, (I2C_SLAVE_ADDR>>1), &rdata[0],2);
data = (rdata[0]<<8 | rdata[1]);
return data;
}
void ERASE(void)
{
uint8_t tempWrBuf[600];
memset(tempWrBuf,0x0,600);
WriteBytes(0x0, tempWrBuf, 600);
}
/**
* @prototype WriteBytes(uint8_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
*
* @param[in] startAddr:写数据起始地址
* @param[in] pDataBuf: 写数据缓存区
* @param[in] dataLen: 写数据长度
* @return void
*
* @brief 向EEPROM写入数据.**此函数地址只能是页的整数倍**
*/
void WriteBytes(uint16_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
{
uint8_t ii,restLen,wrTimes;
uint8_t tempWrBuf[16 + 1];
if ((startAddr + (dataLen - 1)) > 2047){return;}//地址超出范围退出
restLen = (dataLen % 16);
wrTimes = (dataLen / 16);
for (ii = 0; ii < wrTimes; ii++)
{
tempWrBuf[0] = (uint8_t)startAddr;
memcpy(&tempWrBuf[1], &pDataBuf[ii * 16], 16);//单次写页16字节
uint32_t slaveAddr =(uint32_t) (((startAddr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
I2C_MasterWrite(I2C2, slaveAddr, tempWrBuf, 16+1);//此函数只能写入当前页的数据
startAddr += 16;
mdelay(5);//需要等待5ms发送下一条写入命令
}
if (restLen > 0)//非满页,需要单字节方式写入
{
tempWrBuf[0] = (uint8_t)startAddr;
memcpy(&tempWrBuf[1], &pDataBuf[ii * 16], restLen);//单次写页16字节
uint32_t slaveAddr =(uint32_t) (((startAddr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
I2C_MasterWrite(I2C2, slaveAddr, tempWrBuf, restLen+1);
mdelay(5);//需要等待5ms发送下一条写入命令
}
}