看了几天的datasheet,准备完成硬件I2C操作。现在先实现查询方式读取与写入。
硬件上面EEPROM使用AT24C02国产兼容芯片,地址为0xA0(8bit),I2C外设为I2C2,引脚为PF6,PF7。
我实现的示例是在地址0x00处写入'hello"字符串,并回读预期应为"hello"。实验测试通过
/**
* @brief: I2C2,
* PF6 AF0 SCK,
* PF7 AF0 SDA,
*
* @param:
* @return:
* @note:
*/
void i2c_init(void)
{
GPIO_Config_T gpioConfigStruct;
I2C_Config_T i2cConfigStruct;
/* Enable I2C related Clock */
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOF);
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_I2C2);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
/* Free I2C_SCL and I2C_SDA */
gpioConfigStruct.mode = GPIO_MODE_OUT;
gpioConfigStruct.speed = GPIO_SPEED_2MHz;
gpioConfigStruct.outtype = GPIO_OUT_TYPE_PP;
gpioConfigStruct.pupd = GPIO_PUPD_NO;
gpioConfigStruct.pin = GPIO_PIN_6;
GPIO_Config(GPIOF, &gpioConfigStruct);
gpioConfigStruct.pin = GPIO_PIN_7;
GPIO_Config(GPIOF, &gpioConfigStruct);
GPIO_SetBit(GPIOF, GPIO_PIN_6);
GPIO_SetBit(GPIOF, GPIO_PIN_7);
/* Connect I2C to SCL */
GPIO_ConfigPinAF(GPIOF, GPIO_PIN_SOURCE_6, GPIO_AF_PIN0);
/* Connect I2C to SDA */
GPIO_ConfigPinAF(GPIOF, GPIO_PIN_SOURCE_7, GPIO_AF_PIN0);
/* Config I2C1 GPIO */
gpioConfigStruct.mode = GPIO_MODE_AF;
gpioConfigStruct.speed = GPIO_SPEED_2MHz;
gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;
gpioConfigStruct.pupd = GPIO_PUPD_NO;
gpioConfigStruct.pin = GPIO_PIN_6;
GPIO_Config(GPIOF, &gpioConfigStruct);
gpioConfigStruct.pin = GPIO_PIN_7;
GPIO_Config(GPIOF, &gpioConfigStruct);
/* Config I2C2 */
I2C_Reset(I2C2);
i2cConfigStruct.ack = I2C_ACK_ENABLE;
i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;
i2cConfigStruct.address1 = 0x52;
i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;
i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;
i2cConfigStruct.mode = I2C_MODE_I2C;
i2cConfigStruct.timing = 0xB0420F13;
I2C_Config(I2C2, &i2cConfigStruct);
/* Enable I2Cx */
I2C_Enable(I2C2);
}
int i2c_send(uint8_t dev_addr, uint8_t *buf, uint16_t len)
{
int ret = 0;
uint16_t i;
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_BUSY) == SET)
{
;
}
I2C_HandlingTransfer(I2C2, dev_addr, len, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_WRITE);
for (i = 0; i < len; i++)
{
I2C_TxData(I2C2, buf[i]);
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
;
}
}
I2C_EnableGenerateStop(I2C2);
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_STOP) == RESET)
{
;
}
return (ret);
}
int i2c_receive(uint8_t dev_addr, uint8_t *buf, uint16_t len)
{
int ret = 0;
uint16_t i;
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_BUSY) == SET)
{
;
}
I2C_HandlingTransfer(I2C2, dev_addr, len, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_READ);
for (i = 0; i < len; i++)
{
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_RXBNE) == RESET)
{
;
}
buf[i] = (uint8_t)I2C_RxData(I2C2);
}
I2C_EnableGenerateStop(I2C2);
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_STOP) == RESET)
{
;
}
return (ret);
}
int i2c_xfer(uint8_t dev_addr, uint16_t reg_addr, uint8_t reg_len, uint8_t *buf, uint16_t len)
{
int ret = 0;
uint16_t i;
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_BUSY) == SET)
{
;
}
I2C_HandlingTransfer(I2C2, dev_addr, reg_len, I2C_RELOAD_MODE_SOFTEND, I2C_GENERATE_START_WRITE);
if (reg_len == 1)
{
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
;
}
}
else if (reg_len == 2)
{
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
;
}
I2C_TxData(I2C2, (uint8_t)(reg_addr & 0x00FF));
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_TXBE) == RESET)
{
;
}
}
else
{
/* something wrong */
}
I2C_HandlingTransfer(I2C2, dev_addr, len, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_READ);
for (i = 0; i < len; i++)
{
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_RXBNE) == RESET)
{
;
}
buf[i] = (uint8_t)I2C_RxData(I2C2);
}
I2C_EnableGenerateStop(I2C2);
while (I2C_ReadStatusFlag(I2C2, I2C_FLAG_STOP) == RESET)
{
;
}
return (ret);
}
我要赚赏金
