[其他ST产品] stm32下的IIC实现EEPROM代码-stm32G431RBT6

[复制链接]
737|27
 楼主| 工程师犹饿死 发表于 2022-12-29 23:24 | 显示全部楼层 |阅读模式
手册中总共有五种EEPROM的读和写的方式
4412163adb12b57ef2.png
74963adb131cdb5b.png

评论

版权声明:本文为博主原创文章,遵循 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/de  发表于 2022-12-29 23:56
 楼主| 工程师犹饿死 发表于 2022-12-29 23:27 | 显示全部楼层
在开始写程序前,需要知道它的设备地址:

2995763adb1dc7fb5b.png
 楼主| 工程师犹饿死 发表于 2022-12-29 23:30 | 显示全部楼层
可以看到设备地址是:1010xxxx即0xa?.

 楼主| 工程师犹饿死 发表于 2022-12-29 23:32 | 显示全部楼层
5365363adb2846dbc5.png
在原理图中可以看见:E123都接gnd了,所以A012都是0,所以设备地址就是1010000x(二进制),最后一位x是在读和写的时候配置的。
 楼主| 工程师犹饿死 发表于 2022-12-29 23:33 | 显示全部楼层
   1.当前地址读取:
9515063adb32ae7798.png
从这个图上看到:读的时候READ是高电平,所以设备地址是:0xa1。
 楼主| 工程师犹饿死 发表于 2022-12-29 23:36 | 显示全部楼层
按照图片写代码:
  1. void eeprom_current_read(unsigned char data) //当前地址读,读的是上次访问的地址加1
  2. {

  3.         I2CStart();
  4.         I2CSendByte(0xa1);
  5.         I2CWaitAck();
  6.        
  7.         data=I2CReceiveByte();
  8.         I2CSendNotAck();
  9.         I2CStop();
  10. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:37 | 显示全部楼层
根据图片我们就可以发现DATA是八位的数据,所以最大就是256,所以用unsigned char。

当前地址读:
内部地址计数器保存着上次访问时最后一个地址加1的值。只要芯片有电,该地址就一直保存。
当读到最后页的最后字节,地址会回转到0。但是在实际操作中,这个没有实现,读出来的是混乱的数字。这个还不清楚为什么?
 楼主| 工程师犹饿死 发表于 2022-12-29 23:38 | 显示全部楼层
.随机地址读取:
2382263adb442c4caf.png
 楼主| 工程师犹饿死 发表于 2022-12-29 23:39 | 显示全部楼层
同样根据图片写代码:
  1. unsigned char eeprom_random_read(unsigned char adress)
  2. {
  3.    unsigned char data;
  4.         I2CStart();
  5.         I2CSendByte(0xa0);
  6.         I2CWaitAck();
  7.        
  8.         I2CSendByte(adress);
  9.         I2CWaitAck();
  10.         I2CStart();
  11.         I2CSendByte(0xa1);
  12.         I2CWaitAck();
  13.         data=I2CReceiveByte();
  14.         I2CSendNotAck();
  15.         I2CStop();
  16.         return data;
  17. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:39 | 显示全部楼层
程序验证是正确的。可以自己选一个地址读取该处的数据。
 楼主| 工程师犹饿死 发表于 2022-12-29 23:40 | 显示全部楼层
.顺序读取:
1488363adb4c8ac6b2.png
 楼主| 工程师犹饿死 发表于 2022-12-29 23:40 | 显示全部楼层
可以通过当前地址读或顺序读开启,然后读就行了
 楼主| 工程师犹饿死 发表于 2022-12-29 23:45 | 显示全部楼层
  1. void eeprom_sequential_read(unsigned char adress,unsigned char *data,unsigned char num)  //写一个数据给这个地址
  2. {
  3.         I2CStart();
  4.         I2CSendByte(0xa0);
  5.         I2CWaitAck();
  6.        
  7.         I2CSendByte(adress);
  8.         I2CWaitAck();
  9.         I2CStart();
  10.         I2CSendByte(0xa1);
  11.         I2CWaitAck();
  12.         while(num--)
  13.         {
  14.                 *data++=I2CReceiveByte();
  15.                 if(num)
  16.                                 I2CSendAck();       
  17.                 else
  18.                                 I2CSendNotAck();
  19.        
  20.         }
  21.         I2CStop();
  22. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:46 | 显示全部楼层
测试可以运行,可以读取任意个数数据
 楼主| 工程师犹饿死 发表于 2022-12-29 23:46 | 显示全部楼层
字节写入:
2209363adb64a69f6f.png
 楼主| 工程师犹饿死 发表于 2022-12-29 23:47 | 显示全部楼层
  1. void eeprom_byte_write(unsigned char adress,unsigned char data)  //写一个数据给这个地址
  2. {
  3.         I2CStart();
  4.         I2CSendByte(0xa0);
  5.         I2CWaitAck();
  6.        
  7.   I2CSendByte(adress);
  8.         I2CWaitAck();
  9.         I2CSendByte(data);
  10.         I2CWaitAck();
  11.         I2CStop();
  12. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:47 | 显示全部楼层
经检验是可以实现的
 楼主| 工程师犹饿死 发表于 2022-12-29 23:49 | 显示全部楼层
.页写入:
4578163adb6b7948fc.png
* 表示数据量不要超过1kbit
 楼主| 工程师犹饿死 发表于 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,字地址将回转到该页的首字节,先前的字节将会被覆盖。
 楼主| 工程师犹饿死 发表于 2022-12-29 23:51 | 显示全部楼层
上面时网上的解释,但是我实际测试发现,超过8个数据的话后面的就不会写入了,也不会覆盖先前字节。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

967

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部