打印

基于GD32F450芯片的IIC读写EEPROM详解

[复制链接]
1582|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
4y1b3|  楼主 | 2023-4-30 23:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

本文采用的是GD32F450芯片,基于此芯片的官网例程来对IIC读写EEPROM进行详解。
对于初学者来说,感觉IIC很复杂,时许逻辑很绕,无从下手。感觉很多概念不理解,但是不要慌,此文给你详解。

上来不多说,直接贴代码!


void eeprom_page_write(uint8_t* p_buffer, uint8_t write_address, uint8_t number_of_byte)
{
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
   
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C0);
   
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
   
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C0, eeprom_address, I2C_TRANSMITTER);
   
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
   
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
   
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2C0, I2C_FLAG_TBE));
   
    /* send the EEPROM's internal address to write to : only one byte address */
    i2c_data_transmit(I2C0, write_address);
   
    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
   
    /* while there is data to be written */
    while(number_of_byte--){  
        i2c_data_transmit(I2C0, *p_buffer);
        
        /* point to the next byte to be written */
        p_buffer++;
        
        /* wait until BTC bit is set */
        while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
    }
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C0);
   
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C0)&0x0200);
}

上面的代码是页写EEPROM的程序。不懂EEPROM页写,字节写概念的童靴,请自行百度一下,比较好理解,这个就不再赘述了。


使用特权

评论回复
评论
4y1b3 2023-4-30 23:11 回复TA
———————————————— 版权声明:本文为CSDN博主「a_happy_ant」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/a_happy_ant/article/details/121670388 
沙发
4y1b3|  楼主 | 2023-4-30 23:10 | 只看该作者
直接讲代码:
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
就是判断I2C总线是否忙,忙的话就等等,开始接下来的操作。

i2c_start_on_bus(I2C0);
发送起始信号,给从机。不懂为什么要发起始信号的童鞋,可以百度一下IIC时序。

while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
为什么等待SBSEND置位呢,因此发送起始信号之后,IIC硬件会将I2C_DATA0寄存器的SBSEND位置1,检测到置1之后,才能说明起始信号发送完成。

使用特权

评论回复
板凳
4y1b3|  楼主 | 2023-4-30 23:11 | 只看该作者
i2c_master_addressing(I2C0, eeprom_address, I2C_TRANSMITTER);
起始信号发送之后,现在要发从机地址,也就是eeprom_address。这是IIC时序规定的!
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
为啥要等待ADDSEND置位呢
因为ADDSEND表示:
在主机模式下:成功发送了地址
在从机模式下:接收到了地址并且和自身的地址匹配
此位由硬件置 1,软件读 I2C_STAT0 寄存器和读 I2C_STAT1 的时候清 0。
0:无地址被发送或接收
1:地址在主机模式下被发送或从机模式下接收到匹配地址
也就是说地址被发送出去了会被置位!因此要判断此位来证明是否发送成功。

i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
读到ADDSEND置位后,要软件清零,要不然下次再发送地址的时候就无法判断是否发送成功!

while( SET != i2c_flag_get(I2C0, I2C_FLAG_TBE));
按道理从机地址也发了,应该要发数据了呀,干嘛要检测TBE位呢?此位叫做发送数据空也就是手册上说的I2C_DATA。
IIC发送数据的过程,有两个寄存器要参与其中,一个是数据寄存器,一个是移位寄存器。

使用特权

评论回复
地板
4y1b3|  楼主 | 2023-4-30 23:12 | 只看该作者
当没有数据要发送,也就是说数据寄存器和移位寄存器为空的时候,TBE为1,就是TBE默认状态为1。

当有第一个数据要发送的时候,数据会先被发送到数据寄存器,但是!注意,此时TBE不会被置为0,因为这个数,立马会被放到移位寄存器里面,一旦移位寄存器非空,IIC就开始发数据到总线,但此时数据寄存器就没数了。这个过程非常快

在第一个字节发送的过程中,软件可以找到第二个字节的数据,放到数据寄存器,此时TBE被置为0。

因此理解为,TBE发送数据空,这一位,针对的是数据寄存器来说的,当数据寄存器为空的时候,TBE为默认高,当数据寄存器有数的时候,TBE被置为0。

也就是说,当TBE为1的时候,就可以将数据放到数据寄存器里面,因此判断TBE为1,就可以发数据了!

i2c_data_transmit(I2C0, write_address);
上面判断可以发送数据,那么就发送EEPROM的内部数据地址,这个是由IIC时序决定的!

使用特权

评论回复
5
4y1b3|  楼主 | 2023-4-30 23:13 | 只看该作者
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
BTC为字节发送结束
接收模式下,如果一个字节已经被移位寄存器接收但是此时 I2C_DATA 寄存器仍然是满的;
或者发送模式下,一个字节已经被移位寄存器发送但是 I2C_DATA 寄存器仍然是空的,硬件就会置起 BTC 标志位。

while(number_of_byte–){
i2c_data_transmit(I2C0, p_buffer);
/ point to the next byte to be written /
p_buffer++;
/ wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
}

使用特权

评论回复
6
4y1b3|  楼主 | 2023-4-30 23:13 | 只看该作者
最后就是发送数据

i2c_stop_on_bus(I2C0);
数据发送完毕之后,发送停止信号

while(I2C_CTL0(I2C0)&0x0200);
等待停止信号发送完成

至此对EEPROM的页写程序就讲解完毕,对于EEPROM的页边界的处理,字节写,读操作这些内容,等有空了再更新文章!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

236

帖子

0

粉丝