打印
[其他ST产品]

stm32下的IIC实现EEPROM代码-stm32G431RBT6

[复制链接]
417|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
手册中总共有五种EEPROM的读和写的方式



使用特权

评论回复
评论
工程师犹饿死 2022-12-29 23:56 回复TA
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/zerokingwang/article/details/123784843 ———————————————— 版权声明:本文为CSDN博主「贾saisai」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/zerokingwang/article/details/123784843 
沙发
工程师犹饿死|  楼主 | 2022-12-29 23:27 | 只看该作者
在开始写程序前,需要知道它的设备地址:

使用特权

评论回复
板凳
工程师犹饿死|  楼主 | 2022-12-29 23:30 | 只看该作者
可以看到设备地址是:1010xxxx即0xa?.

使用特权

评论回复
地板
工程师犹饿死|  楼主 | 2022-12-29 23:32 | 只看该作者

在原理图中可以看见:E123都接gnd了,所以A012都是0,所以设备地址就是1010000x(二进制),最后一位x是在读和写的时候配置的。

使用特权

评论回复
5
工程师犹饿死|  楼主 | 2022-12-29 23:33 | 只看该作者
   1.当前地址读取:

从这个图上看到:读的时候READ是高电平,所以设备地址是:0xa1。

使用特权

评论回复
6
工程师犹饿死|  楼主 | 2022-12-29 23:36 | 只看该作者
按照图片写代码:
void eeprom_current_read(unsigned char data) //当前地址读,读的是上次访问的地址加1
{

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

使用特权

评论回复
7
工程师犹饿死|  楼主 | 2022-12-29 23:37 | 只看该作者
根据图片我们就可以发现DATA是八位的数据,所以最大就是256,所以用unsigned char。

当前地址读:
内部地址计数器保存着上次访问时最后一个地址加1的值。只要芯片有电,该地址就一直保存。
当读到最后页的最后字节,地址会回转到0。但是在实际操作中,这个没有实现,读出来的是混乱的数字。这个还不清楚为什么?

使用特权

评论回复
8
工程师犹饿死|  楼主 | 2022-12-29 23:38 | 只看该作者
.随机地址读取:

使用特权

评论回复
9
工程师犹饿死|  楼主 | 2022-12-29 23:39 | 只看该作者
同样根据图片写代码:
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;
}

使用特权

评论回复
10
工程师犹饿死|  楼主 | 2022-12-29 23:39 | 只看该作者
程序验证是正确的。可以自己选一个地址读取该处的数据。

使用特权

评论回复
11
工程师犹饿死|  楼主 | 2022-12-29 23:40 | 只看该作者
.顺序读取:

使用特权

评论回复
12
工程师犹饿死|  楼主 | 2022-12-29 23:40 | 只看该作者
可以通过当前地址读或顺序读开启,然后读就行了

使用特权

评论回复
13
工程师犹饿死|  楼主 | 2022-12-29 23:45 | 只看该作者
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();
}

使用特权

评论回复
14
工程师犹饿死|  楼主 | 2022-12-29 23:46 | 只看该作者
测试可以运行,可以读取任意个数数据

使用特权

评论回复
15
工程师犹饿死|  楼主 | 2022-12-29 23:46 | 只看该作者
字节写入:

使用特权

评论回复
16
工程师犹饿死|  楼主 | 2022-12-29 23:47 | 只看该作者
void eeprom_byte_write(unsigned char adress,unsigned char data)  //写一个数据给这个地址
{
        I2CStart();
        I2CSendByte(0xa0);
        I2CWaitAck();
       
  I2CSendByte(adress);
        I2CWaitAck();
        I2CSendByte(data);
        I2CWaitAck();
        I2CStop();
}

使用特权

评论回复
17
工程师犹饿死|  楼主 | 2022-12-29 23:47 | 只看该作者
经检验是可以实现的

使用特权

评论回复
18
工程师犹饿死|  楼主 | 2022-12-29 23:49 | 只看该作者
.页写入:

* 表示数据量不要超过1kbit

使用特权

评论回复
19
工程师犹饿死|  楼主 | 2022-12-29 23:50 | 只看该作者
24C02器件按8字节/页执行页写,24C04/08/16器 件按16字节/页执行页写,24C32/64器 件
按32字节/页执行页写。
每次写完内部自动加1,高位地址位不变,维持在当前页内。当内部产生的字地址达到该页边界地址时,随后的数据将写入该页的页首。如果超过8个(24C02) 或16个(24C04/08/16) 或32个
(24C32/64)数据传送给了EEPROM,字地址将回转到该页的首字节,先前的字节将会被覆盖。

使用特权

评论回复
20
工程师犹饿死|  楼主 | 2022-12-29 23:51 | 只看该作者
上面时网上的解释,但是我实际测试发现,超过8个数据的话后面的就不会写入了,也不会覆盖先前字节。

使用特权

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

本版积分规则

75

主题

886

帖子

0

粉丝