[STM32F3]

stm32下的IIC实现EEPROM代码

[复制链接]
294|18
手机看帖
扫描二维码
随时随地手机跟帖
和下土|  楼主 | 2022-11-30 23:49 | 显示全部楼层 |阅读模式
stm32下的IIC实现EEPROM代码-stm32G431RBT6(蓝桥杯嵌入式)手册中总共有五种EEPROM的读和写的方式
177263877b7a4bacc.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:49 | 显示全部楼层
8265863877b9a63a0a.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:50 | 显示全部楼层
在开始写程序前,需要知道它的设备地址:
1475663877ba82937b.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:50 | 显示全部楼层
可以看到设备地址是:1010xxxx即0xa?.
5394363877bcb5e124.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:51 | 显示全部楼层
在原理图中可以看见:E123都接gnd了,所以A012都是0,所以设备地址就是1010000x(二进制),最后一位x是在读和写的时候配置的。

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:51 | 显示全部楼层
    1.当前地址读取:


2742363877c0bde3da.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:52 | 显示全部楼层
从这个图上看到:读的时候READ是高电平,所以设备地址是:0xa1。

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:53 | 显示全部楼层
按照图片写代码:
void eeprom_current_read(unsigned char data) //当前地址读,读的是上次访问的地址加1
{

        I2CStart();
        I2CSendByte(0xa1);
        I2CWaitAck();
       
        data=I2CReceiveByte();
        I2CSendNotAck();
        I2CStop();
}

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:53 | 显示全部楼层
根据图片我们就可以发现DATA是八位的数据,所以最大就是256,所以用unsigned char。

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:54 | 显示全部楼层
当前地址读:
内部地址计数器保存着上次访问时最后一个地址加1的值。只要芯片有电,该地址就一直保存。
当读到最后页的最后字节,地址会回转到0。但是在实际操作中,这个没有实现,读出来的是混乱的数字。这个还不清楚为什么?

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:55 | 显示全部楼层
    2.随机地址读取:
9328163877cb56d4ef.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:55 | 显示全部楼层
同样根据图片写代码:
unsigned char eeprom_random_read(unsigned char adress) 
{
   unsigned char data;
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
       
        I2CSendByte(adress);
        I2CWaitAck();
        I2CStart();
        I2CSendByte(0xa1);
        I2CWaitAck();
        data=I2CReceiveByte();
        I2CSendNotAck();
        I2CStop();
        return data;
}

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:56 | 显示全部楼层
程序验证是正确的。可以自己选一个地址读取该处的数据。

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:56 | 显示全部楼层
顺序读取:
6448363877d35e0dcc.png

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:57 | 显示全部楼层
可以通过当前地址读或顺序读开启,然后读就行了
void eeprom_sequential_read(unsigned char adress,unsigned char *data,unsigned char num)  //写一个数据给这个地址
{
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
       
        I2CSendByte(adress);
        I2CWaitAck();
        I2CStart();
        I2CSendByte(0xa1);
        I2CWaitAck();
        while(num--)
        {
                *data++=I2CReceiveByte();
                if(num)
                                I2CSendAck();       
                else
                                I2CSendNotAck();
       
        }
        I2CStop();
}

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:57 | 显示全部楼层
测试可以运行,可以读取任意个数数据

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:58 | 显示全部楼层
字节写入: 811563877d92b7fad.png
void eeprom_byte_write(unsigned char adress,unsigned char data)  //写一个数据给这个地址
{
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
       
  I2CSendByte(adress);
        I2CWaitAck();
        I2CSendByte(data);
        I2CWaitAck();
        I2CStop();
}

可以实现

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:59 | 显示全部楼层
页写入:
8640763877dd47d360.png
表示数据量不要超过1kbit

24C02器件按8字节/页执行页写,24C04/08/16器 件按16字节/页执行页写,24C32/64器 件
按32字节/页执行页写。
每次写完内部自动加1,高位地址位不变,维持在当前页内。当内部产生的字地址达到该页边界地址时,随后的数据将写入该页的页首。如果超过8个(24C02) 或16个(24C04/08/16) 或32个
(24C32/64)数据传送给了EEPROM,字地址将回转到该页的首字节,先前的字节将会被覆盖。

上面时网上的解释,但是我实际测试发现,超过8个数据的话后面的就不会写入了,也不会覆盖先前字节。

使用特权

评论回复
和下土|  楼主 | 2022-11-30 23:59 | 显示全部楼层
void eeprom_page_write(unsigned char adress,unsigned char *data,unsigned char num) 
{
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
       
  I2CSendByte(adress);
        I2CWaitAck();
        while(num--)
        {
        I2CSendByte(*data++);
        I2CWaitAck();
        }
        I2CStop();
}

使用特权

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

本版积分规则

73

主题

926

帖子

0

粉丝