打印

EEPROM 24Cxx操作碰到的问题

[复制链接]
2016|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
haolaishi|  楼主 | 2015-10-26 13:24 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
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);//发送高地址     
}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_Wait_Ack();  
    temp=IIC_Read_Byte(0);     
    IIC_Stop();//产生一个停止条件     
return temp;
else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据  
上面这句是什么意思啊,如果我用24C08(最大容量1K)这个芯片现在我要向304这个单元写数据,难道发送的地址就应该是10100010嘛?
我查了一下芯片手册,手册上列出如下:               1K/2K: 1010A2A1A0R/W    4K:1010A2A1P0R/W   8K:1010A2P1P0R/W  16K:1010P2P1P0.其中A2A1A0对应的管脚应该是和实际电路连接有关,P2\P1\P0的值应该是任意,R/W表示读还是写,用1/0区分。

相关帖子

沙发
STM32初学者| | 2015-10-26 14:10 | 只看该作者
P0,P1不是任意呢.是地址的高位.
后面还有一句 IIC_Send_Byte(ReadAddr%256);   //发送低地址
发送低位地址.

使用特权

评论回复
板凳
王大熊| | 2015-10-26 18:06 | 只看该作者
我的程序跟这个差不多, 可能看的更清楚一些

分解开来就这个意思:

addr 是要访问的地址 , 而 IC_Address是硬件地址(P2\P1\P0的值) , rw是读写选择
<PageNum 是后面处理要用到的>
^^^^^^^^
……………………………………
                case AT24C01:
                case AT24C02:
                        StartByte = (0xA0|(IC_Address<<1)|rw);
                        PageNum = 8;
                        break;
                case AT24C04:
                        StartByte = (0xA0|(IC_Address<<2)|((addr>>8)<<1)|rw);
                        PageNum = 16;
                        break ;

                case AT24C08:
                        StartByte = (0xA0|(IC_Address<<3)|((addr>>8)<<2)|rw);
                        PageNum = 16;
                        break ;

                case AT24C16:
                        StartByte = (0xA0|((addr>>8)<<3)|rw);
                        PageNum = 16;
                        break ;

                case AT24C32:
                case AT24C64:
                        PageNum = 32;
                        break ;
                case AT24C128:
                case AT24C256:
                case AT24C512:
                        PageNum = 64;
                        break;
……
后面的 处理 如果 芯片型号是 24C16一下,则 数据为一个字节, &0xff就行 了
如果容量更大的 则 外部地址没用了, 两个字节的数据

使用特权

评论回复
地板
haolaishi|  楼主 | 2015-10-26 18:07 | 只看该作者
王大熊 发表于 2015-10-26 18:06
我的程序跟这个差不多, 可能看的更清楚一些

分解开来就这个意思:

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);//发送高地址     


}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据    ,这句话改为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;
}

else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据 ,这句话改为else IIC_Send_Byte(0xA0);可以吗?

使用特权

评论回复
5
白丁野老| | 2015-10-26 18:08 | 只看该作者
把 else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); 改成 else IIC_Send_Byte(0XA0);后,测试了一下读写也没问题
另外从24C04开始地址就要16位了,需要先给高八位,后给低八位,程序中为什么要从24C16开始判断呢?不解

使用特权

评论回复
6
王大熊| | 2015-10-26 18:08 | 只看该作者
白丁野老 发表于 2015-10-26 18:08
把 else IIC_Send_Byte(0XA0+((ReadAddr/256)

8个字节,能表示多宽的地址?
是不是只有256个?256个地址,容量是多少?是不是2K,也就是24C02
24C16是多大?2K字节.
AX是24Cxx的地址.
1楼也列出了,AX=1010    A2   A1   A0   R/W
也就是这个地址可以有3个位(A2,A1,A0)来表示字节地址,8+3=11.最大表示的范围是多少?是不是2的11次方?是不是2048,2K字节?
那么大于2K的时候,还能用AX+1个字节表示所有的地址么?明显不能了.
不能怎么办?
那就用2个字节表示地址!
2个字节可以表示多大?2的16次方,65536,最大可以表示到24C512.
也就是全系列了.  
所以2个字节就可以记录所有地址了.

使用特权

评论回复
7
haolaishi|  楼主 | 2015-10-26 18:09 | 只看该作者
王大熊 发表于 2015-10-26 18:08
8个字节,能表示多宽的地址?
是不是只有256个?256个地址,容量是多少?是不是2K,也就是24C02
24C16是多大? ...

1楼也列出了,AX=1010    A2   A1   A0   R/W
也就是这个地址可以有3个位(A2,A1,A0)来表示字节地址

A2 A1 A0 应该是表示器件地址吧,从000到111,IIC总线可以接8个IIC器件

如果只接一个,而且器件地址是000,那不管是什么型号的EEPROM,最先发送的都是0XA0,然后是发送要读写的地址,只有24C02发一个地址,其他的都要先发个高地址,然后再发低地址

使用特权

评论回复
8
haolaishi|  楼主 | 2015-10-26 18:11 | 只看该作者
看了datasheet才明白

使用特权

评论回复
9
fengmailx| | 2016-3-10 16:14 | 只看该作者
王大熊 发表于 2015-10-26 18:06
我的程序跟这个差不多, 可能看的更清楚一些

分解开来就这个意思:

AT24CXX这里的XX是怎么判断的?

使用特权

评论回复
10
wangjiahao88| | 2016-3-21 21:49 | 只看该作者
24C08 的地址不分高地位的吧!

这一点要注意一下!

只有一个直接的地址传送就可以了!

使用特权

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

本版积分规则

个人签名:不忘初心,积极乐观,勤且道义!

243

主题

1996

帖子

12

粉丝