OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7240|回复: 6

用了战舰的例程读写24C04发现一个BUG

[复制链接]

4

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2012-2-28
在线时间
12 小时
发表于 2014-1-17 16:27:48 | 显示全部楼层 |阅读模式

            在文件24Cxx里面,会发现读写24C04上超过256的地址的时候出问题, 经过验证,是代码读指令有个bug,写是没有问题的。不知道是不是我发现的比较晚,还是有人发现了。


 

u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{     
 u8 temp=0;                         
    IIC_Start(); 
 if(EE_TYPE>AT24C16)
 {
  IIC_Send_Byte(0XA0);    //发送写命令
  IIC_Wait_Ack();
  IIC_Send_Byte(ReadAddr>>8);//发送高地址
  IIC_Wait_Ack();  
 }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据  

 IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr%256);   //发送低地址
 IIC_Wait_Ack();    
 IIC_Start();        
 //IIC_Send_Byte(0XA1);           //进入接收模式      ,这里错了, 正确的应该是下面
IIC_Send_Byte(0XA1+((ReadAddr/256)<<1)); 
 IIC_Wait_Ack(); 
    temp=IIC_Read_Byte(0);    
    IIC_Stop();//产生一个停止条件    
 return temp;
}


 

 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
金钱
243
注册时间
2013-8-23
在线时间
24 小时
发表于 2014-1-18 10:52:09 | 显示全部楼层
    后期的例程这个函数都改进了,正确的函数为:

u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{      
  u8 temp=0;
  //                          
  IIC_Start();  
  if(EE_TYPE>AT24C02)
  {
    IIC_Send_Byte(0XA0);         //发送写命令
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr>>8);  //发送高地址
    //IIC_Wait_Ack();   
  }
  else
    IIC_Send_Byte(0XA0);         //发送写命令   

  IIC_Wait_Ack(); 
  IIC_Send_Byte(ReadAddr%256);   //发送低地址
  IIC_Wait_Ack();     
  IIC_Start();        
  IIC_Send_Byte(0XA1);           //发送读命令 
  IIC_Wait_Ack();  
  temp=IIC_Read_Byte(0);     
  IIC_Stop();                   //产生一个停止条件     
  return temp;
}


回复 支持 1 反对 0

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-1-17 17:02:23 | 显示全部楼层
回复【楼主位】xuzhenglim:
---------------------------------
楼主注意一下,24C04的设备地址格式,相对于24C02来说,A0位在24C04中对应的是存储阵列地址字地址,所以你在超过256个数据进行存储的时候发送这个器件设备地址的时候就要注意了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2018-3-8
在线时间
25 小时
发表于 2018-5-31 10:45:55 | 显示全部楼层
dzkmr 发表于 2014-1-18 10:52
&nbsp; &nbsp; 后期的例程这个函数都改进了,正确的函数为:

u8 AT24CXX_ReadOneByte(u16 ReadAddr)

新手有不明白处:24c04手册上器件地址最后一位P0相当于是ReadAddr/256,内存地址ReadAddr实际上应该是高位为P0拼接上低8位ReadAddr%256,我想问的就是发送一个器件地址和一个低8位地址一共2个字节就可以找到芯片和其内存地址,如果按照改进后的程序,实际上是发送了3个字节的数据才找到芯片和其内存地址
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2018-10-9
在线时间
8 小时
发表于 2018-10-9 21:02:37 | 显示全部楼层
sea1216 发表于 2018-5-31 10:45
新手有不明白处:24c04手册上器件地址最后一位P0相当于是ReadAddr/256,内存地址ReadAddr实际上应该是高 ...

24C04如果使用256以上的空间,是不是需要将现在硬件上的24C02换成24C04并且将它的P0连接到一个IO口上。
回复 支持 反对

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-10-9 23:39:19 | 显示全部楼层
张招 发表于 2018-10-9 21:02
24C04如果使用256以上的空间,是不是需要将现在硬件上的24C02换成24C04并且将它的P0连接到一个IO口上。

24系列EEPROM通用驱动:
https://blog.csdn.net/qq_20553613/article/details/82733817
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2019-5-9
在线时间
0 小时
发表于 2019-5-9 17:52:17 | 显示全部楼层
存储数据地址位数”:(数据存储地址和器件地址不是一个概念),24CXX器件内部存储的每个字节(Byte)都可以进行单独的读写操作(单字节读写),“存储数据地址位数”就代表了其用于寻址的地址位长度。根据容量不同,24C01/02使用8位数据地址位,24C04/08/16虽然也使用了8位的数据地址位,但8位数据地址最大0xff,表示最高可寻址256位(0~255),而24C04/08/16的存储容量有512/1024/2048Byte,明显不够,的A2、A1和A0的其他功能;在程序中要访问高地址,需把占用下面说到的A2、A1和A0,位相对应的置高,如,24C04访问256地址时,就需要把器件地址A0位置高(如器件地址0xA0,则对应的是0xA2(bit1位),不要搞错了,很多人刚开始理解要用硬件IO,去搞,是理解错了,实际是软件发送的器件地址)

                /* Send EEPROM address for write */
                I2C_Send7bitAddress(I2C1, EEPROM_I2C_SLAVE_ADDRESS7|((addrs>>7)&0x02), I2C_Direction_Transmitter);
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 01:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表