OpenEdv-开源电子网

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

请教一个24C08 Eeprom页读写问题?

[复制链接]

13

主题

175

帖子

0

精华

初级会员

Rank: 2

积分
182
金钱
182
注册时间
2016-4-30
在线时间
141 小时
发表于 2017-7-20 18:47:03 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 执迷 于 2017-7-20 18:54 编辑

    24C08有4个存储区,每个区256个字节,合成1K。。我读写的数据长度超过256.参考原子哥的程序,字节写入可以了。。。但是,速度比较慢。想用页写入不知道怎么办。。(因为我是分多次写入数据,每次数据长度不定。。)用页写入的时候跨区域时要怎么处理。。请各位有经验的前辈分享一些思路。。   

最佳答案

查看完整内容[请看2#楼]

有页读写指令,去看数据手册。一次最多写入256字节。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-7-20 18:47:04 | 显示全部楼层
有页读写指令,去看数据手册。一次最多写入256字节。
回复

使用道具 举报

13

主题

175

帖子

0

精华

初级会员

Rank: 2

积分
182
金钱
182
注册时间
2016-4-30
在线时间
141 小时
 楼主| 发表于 2017-7-21 08:15:15 | 显示全部楼层
正点原子 发表于 2017-7-20 18:47
有页读写指令,去看数据手册。一次最多写入256字节。

24C08页写一次不是16字节吗?  这16字节如果一部分在A0区一部分在A2区怎么办?
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-7-21 09:06:08 | 显示全部楼层
//写多字节,需确保当前写地址+写入数据长度不能超过EEPROM的一页
static void i2c_24clxx_write( u16 write_addr, char* pbuffer,u16 write_size)
{
                struct st_i2c_msg ee24_msg[2];
                u8        buf[2];
                u8  slave_addr;

                //if(WriteAddr+NumByteToWrite > EE24CLXX_PageSize)
                //                return;
                if(EEPROM_MODEL > 16)
                {//大于2k字节时,地址为16位:24c16及以上
                                slave_addr = EE24CLXX_SLAVE_ADDR;
                                buf[0] = (write_addr >>8)& 0xff;
                                buf[1] = write_addr & 0xff;
                                ee24_msg[0].size  = 2;
                }
                else
                {//24c01——24c16
                                slave_addr = EE24CLXX_SLAVE_ADDR | (write_addr>>8);
                                buf[0] = write_addr & 0xff;
                                ee24_msg[0].size  = 1;
                }
                ee24_msg[0].addr = slave_addr;
                ee24_msg[0].flags = ST_I2C_WR;
                ee24_msg[0].buff  = buf;
                ee24_msg[1].addr = slave_addr;
                ee24_msg[1].flags = ST_I2C_WR  | ST_I2C_NO_START;       
                ee24_msg[1].buff  = (u8*)pbuffer;
                ee24_msg[1].size  = write_size;
                i2c_bitops_bus_xfer(&i2c1_dev,ee24_msg,2);
}

//写多字节,页写,自动翻页
char ee_24clxx_writebytes(u16 write_addr, char* pwrite_buff, u16 writebytes)
{
                u8   write_len,page_offset;

                while(writebytes > 0)
                {
                                page_offset = EE24CLXX_PAGESIZE - (write_addr & (EE24CLXX_PAGESIZE-1));
                                write_len   = writebytes > page_offset ? page_offset : writebytes;
                                i2c_24clxx_write(write_addr,pwrite_buff, write_len);
                                writebytes   = writebytes - write_len;
                                if(writebytes > 0)
                                {
                                                pwrite_buff = pwrite_buff + write_len;
                                                write_addr  = write_addr + write_len;
                                                I2C_24CLXXWaitStandby(0);
                                }
                }
             return 0;
}
忽略i2c总线,主要看页写逻辑。
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-6 09:11:39 | 显示全部楼层
大家好,我现在是要用一条IIC总线,连接AT24C32和AT24C08,
1. 两个芯片的A2引脚都是接低,这样可行不?
2. 关于AT24C08的使用,写入时,器件地址写0XA0,要写入的地址直接设为第300个存储字节,这样可行不?
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-6 10:31:41 | 显示全部楼层
ljmf5 发表于 2018-1-6 09:11
大家好,我现在是要用一条IIC总线,连接AT24C32和AT24C08,
1. 两个芯片的A2引脚都是接低,这样可行不?
...

http://blog.csdn.net/qq_20553613/article/details/78878211
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-8 10:03:24 | 显示全部楼层
本帖最后由 ljmf5 于 2018-1-8 10:14 编辑

谢谢!
1.  AT24C16的随机字节写操作,必须先给块地址(000-111),然后再给目标地址在其所属块的相对地址。这可以理解为,每一块的存储地址编号都是00-ff。随机写和页写的区别只在于写完第一个数据后是否给停止信号。
2.  AT24C08的页写必须要先给块地址(00-11),再给目标地址,这里的目标地址也需要做类似于AT24C16那样的处理吗?我个人感觉是需要那样的处理。
3.  AT24C08直接采用随机字节写,能先给第一块的地址00,然后写第二块的某个地址,比如第300个字节地址吗?这里是我还不太确定的地方?

由看到两种说法
一种类似于AT24C16的方式如下所示:

1K地址空间,由外部A2和内部存储阵列A9A8决定地址,例如你的A2固定接地,那么1K的存储空间分成4块,器件写地址分别是#0A0H,#0A2H,#0A4H,#0A6H,器件读地址是#0A1H,#0A3H,#0A5H,#0A7H,每个地址都对应256个字节。正好是8位地址00H--FFH。所以你的400个地址往后写,就要选定一个地址空间如#0A2H,再写入字节地址#091H,然后按字节写或按页写方式,写到#0FFH后,器件地址要变成#0A4H了,字节地址从00H开始。

另一种字节写的操作如下
[mw_shl_code=c,true]//////向24c02的address地址中写入一字节数据info/////
void x24c08_write(unsigned char address,unsigned char info)
{
    EA=0;
    start();
    writex(0xa0);
     clock();
     writex(address);
    clock();
    writex(info);
    clock();
    stop();
    EA=1;
    delay1(50);
} [/mw_shl_code]



回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-8 11:54:49 | 显示全部楼层
ljmf5 发表于 2018-1-8 10:03
谢谢!
1.  AT24C16的随机字节写操作,必须先给块地址(000-111),然后再给目标地址在其所属块的相对地 ...

1/2、理解正确,24c04——24c16比较特殊,寻址都是单字节(估计是前期芯片设计遗留的问题吧),超过1字节容量后,也就有你所说的块,或者有些人称为一大页。块地址放在了i2c设备地址上,占用了地址线(A0A1A2)。
3、单字节寻址,255地址内是第一块,300地址当然是第二块了。
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-8 13:30:46 | 显示全部楼层
Acuity 发表于 2018-1-8 11:54
1/2、理解正确,24c04——24c16比较特殊,寻址都是单字节(估计是前期芯片设计遗留的问题吧),超过1字节 ...

非常感谢!
      关于第3点AT24C08随即字节写操作,是我没有表述清楚,我的意思是能直接那样写不。
      例如,先给器件地址0XA0,再给目标地址300(十六进制为0X12C),我的理解是不能直接这样写,0XA0表示AT24C08第一个区的地址,300超过了该区的存储范围;同时,也因为AT24C08属于单字节地址,实际上是选择了第一个区的0X44存储字节。
      这里应该是先给器件地址0XA1(AT24C08第二个区的地址),再给目标地址(0X12C & 0XFF),才是选择了AT24C08的第300个存储字节。
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-8 15:21:57 | 显示全部楼层
ljmf5 发表于 2018-1-8 13:30
非常感谢!
      关于第3点AT24C08随即字节写操作,是我没有表述清楚,我的意思是能直接那样写不。
   ...

这里应该是先给器件地址0XA1(AT24C08第二个区的地址),再给目标地址(0X12C & 0XFF),才是选择了AT24C08的第300个存储字节。
这是正确的理解。
参考代码:
http://blog.csdn.net/qq_20553613/article/details/78878211
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-8 15:24:45 | 显示全部楼层
Acuity 发表于 2018-1-8 15:21
这里应该是先给器件地址0XA1(AT24C08第二个区的地址),再给目标地址(0X12C & 0XFF),才是选择了AT24C ...

谢谢!
基本上明白了,总是不确定自己想的是否正确,还有很多深入的细节没有仔细研究,且得学习着。
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-1-9 10:21:08 | 显示全部楼层
执迷 发表于 2017-7-21 08:15
24C08页写一次不是16字节吗?  这16字节如果一部分在A0区一部分在A2区怎么办?

在写之前做一个是否会到另一个区的判断。是的话,写入一个换区域符(自己定义一个),然后从下一页开始写。不是的话就直接写。换区域符是为了在读的时候,做判断的。读到换区域符,就转区域读。
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-11 08:23:17 | 显示全部楼层
Acuity 发表于 2018-1-8 15:21
这里应该是先给器件地址0XA1(AT24C08第二个区的地址),再给目标地址(0X12C & 0XFF),才是选择了AT24C ...

你好,有个地方给你反馈一下。
我这两天在写AT24C08的代码,已经做好了。但是在设置器件地址时,直接使用你给的那个参考网页,读写是有问题的。主要是在从机器件地址这一段代码
else  
14.     {  
15.          slave_addr =EE24CLXX_SLAVE_ADDR | (read_ddr>>8);  
16.          buf[0] = read_ddr & 0xff;  
17.          ee24_msg[0].size  = 1;  
18.     }  

我的代码里用的是slave_addr =0xA0  | ((read_ddr>>8)<<1) +1; 这样才是选择了正确的器件地址,并设为读操作。

直接使用参考网页的设置方法有问题,我不知道是不是因为其后续还有一个语句ee24_msg[0].flags = I2C_BUS_WR;来设置读或者写。
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-11 08:47:17 | 显示全部楼层
ljmf5 发表于 2018-1-11 08:23
你好,有个地方给你反馈一下。
我这两天在写AT24C08的代码,已经做好了。但是在设置器件地址时,直接使 ...

1、里面的从机地址都是实际地址(7bit),不包含读写位。Linux设备上的驱动这样。比如我们平常操作24xx EEPROM都是用0xA0,实际7bit地址是0x50,这个要注意。记得我第一次用Linux的i2c驱动就是被这个坑过。
2、标识位要设置,如读/写、或者其他
3、代码已经用在产品上,目前没发现问题,有发现bug欢迎指出。十分谢谢
回复

使用道具 举报

4

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2016-1-25
在线时间
75 小时
发表于 2018-1-12 10:38:44 | 显示全部楼层
Acuity 发表于 2018-1-11 08:47
1、里面的从机地址都是实际地址(7bit),不包含读写位。Linux设备上的驱动这样。比如我们平常操作24xx E ...

这个地方可以看一下,我估计是我们设置地址的方式不一样,我是直接使用0xA0  | ((read_ddr>>8)<<1) +1的形式,你那个是另外再有那个加上读写标志的处理
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-22 12:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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