小熊派gd32f303学习之旅(9)— 使用硬件I2C读写EEPROM
一、前言
在上一篇中,我们使用软件模拟IIC对AT24C02进行了读写,通过查看GD32F30X的参考手册可以知道,其有2个硬件IIC控制器,现在我们就尝试使用其硬件IIC进行对AT24C02的读写。
查看小熊派的原理图,确定AT24C02其使用的IIC引脚为SCL->PB6、SDA->PB7
查看数据手册可以知道这两个引脚被I2C0控制器复用为I2C引脚了,那么就可以满足我们的使用需求了
二、初始化I2C0控制器
如下所示,将I2C0控制器进行初始化
void i2c0_init(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_I2C0);
gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x78);
i2c_enable(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
三、编写AT24C02控制函数
通过查看AT24C02的数据手册可以看到其读写时序如下
然后编写AT24C02的读取和写入函数
#define AT24C02_Addr 0x50
void at24c02_init(void)
{
i2c0_init();
}
uint8_t AT24C02_Read_Byte(uint16_t ReadAddr, uint8_t *ReadByte)
{
uint8_t err = 1;
i2c_start_on_bus(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
i2c_master_addressing(I2C0, AT24C02_Addr<<1, I2C_TRANSMITTER);
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_data_transmit(I2C0, ReadAddr);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_start_on_bus(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
i2c_master_addressing(I2C0, AT24C02_Addr<<1, I2C_RECEIVER);
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
i2c_stop_on_bus(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
*ReadByte = i2c_data_receive(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
err = 0;
return err;
}
uint8_t AT24C02_Write_Byte(uint16_t WriteAddr,uint16_t WriteByte)
{
uint8_t err = 0;
i2c_start_on_bus(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
i2c_master_addressing(I2C0, AT24C02_Addr<<1, I2C_TRANSMITTER);
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_data_transmit(I2C0, WriteAddr);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_data_transmit(I2C0, WriteByte);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_stop_on_bus(I2C0);
return err;
}
四、编写主函数
int main(void)
{
uint8_t buff;
uint8_t err;
systick_config();
uart0_init(115200);
at24c02_init();
u0_printf("Hello world! ");
u0_printf("I am William. \r\n");
err = AT24C02_Write_Byte(0x0a, 0xa5);
if(err == 0)
printf("Write 0xa5 to addr 0x0a ok \r\n");
else
{
printf("Write 0xa5 to addr 0x0a err \r\n");
printf("err num : 0x%x \r\n",err);
}
if(AT24C02_Read_Byte(0x0a, &buff) == 0)
printf("Read data: 0x%x from addr 0x0a ok \r\n", buff);
else
printf("Read data from addr 0x0a err \r\n");
while(1)
{
if(UART0_RX_STAT > 0)
{
UART0_RX_STAT = 0;
u0_printf("RECEIVE %d data:%s \r\n", UART0_RX_NUM, UART0_RX_BUF);
}
delay_1ms(10);
}
}
五、功能验证
编译链接烧录到小熊派开发板,然后观察串口输出情况,可以看到读取和写入都成功了
六、附录
完整代码我存放在码云,可以查看:https://gitee.com/william_william/BearPi-GD32F303RGT6.git
上一篇:小熊派gd32f303学习之旅(8)— 使用软件模拟I2C读写EEPROM
下一篇:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)