OpenEdv-开源电子网

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

stm32F1x,IIC接口操控EEPROM实验代码中,关于24C02读写时序代码的问题

[复制链接]

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
发表于 2018-12-3 20:41:21 | 显示全部楼层 |阅读模式
3金钱
问:学到IIC接口操控EEPROM一实验,在读写时序代码中,自认为有几行代码不对应24C02读写时序图。看代码:
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_Wait_Ack();         
    temp=IIC_Read_Byte(0);                  
    IIC_Stop();//产生一个停止条件            
        return temp;
}
//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址   
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{                                                                                                                                                                                          
    IIC_Start();  
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0XA0);            //发送写命令
                IIC_Wait_Ack();
                IIC_Send_Byte(WriteAddr>>8);//发送高地址
        }else
        {
                IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据
        }         
        IIC_Wait_Ack();          
    IIC_Send_Byte(WriteAddr%256);   //发送低地址
        IIC_Wait_Ack();                                                                                                              
        IIC_Send_Byte(DataToWrite);     //发送字节                                                          
        IIC_Wait_Ack();                                
    IIC_Stop();//产生一个停止条件
        delay_ms(10);         
}

标红的这三行代码:
IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据          
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);   //发送低地址

对应的读时序:
设备地址(读/写) + ACK应答 + 读的地址的位置
我认为的写法:
IIC_Send_Byte(0xA0);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr/256);
IIC_Send_Byte(ReadAddr%256);
不理解处:  为什么发送的0XA0后边没有ACK应答,(ReadAddr/256)<<1)左移一位是什么原因,而且要读的地址高8位与低8位之间用ACK应答分隔开?还有我的理解有没有问题?24C02写时序代码同理。

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

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-4 00:09:23 | 显示全部楼层
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-4 21:00:37 | 显示全部楼层
biglu 发表于 2018-12-4 00:09
写字节的图如下。。

第一段代码是读时序,而且我有时序图
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-4 23:58:45 | 显示全部楼层
你去看AT24C16和AT24C32的pdf:

1. AT24C16写Byte,步骤是 ①发Start ② 写DeviceAddress ③WaitAck ④写WordAddress ⑤WaitAck ⑥写Data ⑦WaitAck ⑧发Stop

2. AT24C32写Byte,步骤是 ①发Start ②写DeviceAddress ③WaitAck ④写FirstWordAddress ⑤WaitAck ⑥写SecondWordAddress ⑦WaitAck ⑧写Data ⑨WaitAck ⑩发Stop

你对照代码再看一下。
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-5 10:01:55 | 显示全部楼层
biglu 发表于 2018-12-4 23:58
你去看AT24C16和AT24C32的pdf:

1. AT24C16写Byte,步骤是 ①发Start ② 写DeviceAddress ③WaitAck ④ ...

不管是AT24CXX,写DeviceAddress后面不都得跟WaitAck嘛,也就是你写的步骤2后跟步骤3.
我问的是 IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); 发送0XA0后为什么没有等待ACK应答
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 10:07:04 | 显示全部楼层
本帖最后由 秋天 于 2018-12-5 10:16 编辑

看看吧,采集原子iic代码时序图
原子iic7.jpg
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 10:07:33 | 显示全部楼层
本帖最后由 秋天 于 2018-12-5 10:17 编辑

看图你就知道了,实验平台原子nano开发板
后面.png
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-5 11:34:50 | 显示全部楼层
硕果磊磊 发表于 2018-12-5 10:01
不管是AT24CXX,写DeviceAddress后面不都得跟WaitAck嘛,也就是你写的步骤2后跟步骤3.
我问的是 IIC_Sen ...

程序里怎么就没有WaitAck了。。。。else{...}后面不就是WaitAck。。。。

4F660CD8-FD35-48d1-B090-D3886EF6C26F.png
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-5 11:39:08 | 显示全部楼层
DeviceAddress是1个字节,高4位是1010,所以是0xA0,后面3个位是A0A1A2地址位,最后一个位是读写位。
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 13:49:35 | 显示全部楼层
biglu 发表于 2018-12-5 11:34
程序里怎么就没有WaitAck了。。。。else{...}后面不就是WaitAck。。。。

看时序说话   楼上是我采集原子iic时序图
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

6

主题

36

帖子

1

精华

初级会员

Rank: 2

积分
169
金钱
169
注册时间
2018-12-5
在线时间
4 小时
发表于 2018-12-5 14:24:34 | 显示全部楼层
基于STM32L476+64M QSPI接口PSRAM(IPS6404L)开源分享
http://bbs.21ic.com/icview-2597832-1-1.html
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-5 15:00:48 | 显示全部楼层
秋天 发表于 2018-12-5 13:49
看时序说话   楼上是我采集原子iic时序图

老哥应该回复楼主吧。。
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-5 15:21:16 | 显示全部楼层
biglu 发表于 2018-12-5 11:39
DeviceAddress是1个字节,高4位是1010,所以是0xA0,后面3个位是A0A1A2地址位,最后一个位是读写位。

DeviceAddress1个字节,高4位是1010,低四位0000     16进制:0XA0 代表读
                                   高4位是1010,低四位0001     16进制:0XA1 代表写








A0,A1,A2接地,都是0

1.png
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-5 15:24:48 | 显示全部楼层
biglu 发表于 2018-12-5 11:34
程序里怎么就没有WaitAck了。。。。else{...}后面不就是WaitAck。。。。

看到了,我说的是else里边 发送0XA0发完紧接着应该是Ack应答,
而不是紧接着WriteAddr
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 15:28:11 | 显示全部楼层
本帖最后由 秋天 于 2018-12-5 15:29 编辑
硕果磊磊 发表于 2018-12-5 15:24
看到了,我说的是else里边 发送0XA0发完紧接着应该是Ack应答,
而不是紧接着WriteAddr

时序图里面很清楚呢  
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 15:29:49 | 显示全部楼层
硕果磊磊 发表于 2018-12-5 15:21
DeviceAddress1个字节,高4位是1010,低四位0000     16进制:0XA0 代表读
                            ...

我就是采集这两个脚的
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-5 16:27:21 | 显示全部楼层
硕果磊磊 发表于 2018-12-5 15:24
看到了,我说的是else里边 发送0XA0发完紧接着应该是Ack应答,
而不是紧接着WriteAddr

写在else的括号和写在括号内都一样啊,if里和else里都要用到。。。。。
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-5 20:15:09 | 显示全部楼层
秋天 发表于 2018-12-5 15:29
我就是采集这两个脚的

这么问吧:
IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据         
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);   //发送低地址
IIC_Wait_Ack();
这四行代码改为
IIC_Send_Byte(0xA0);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr/256);
IIC_Send_Byte(ReadAddr%256);
IIC_Wait_Ack(); 对不对?为什么
回复

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 20:54:43 | 显示全部楼层
硕果磊磊 发表于 2018-12-5 20:15
这么问吧:
IIC_Send_Byte(0XA0+((ReadAddr/256)

这和容量有关系
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-7 11:43:18 | 显示全部楼层
硕果磊磊 发表于 2018-12-5 20:15
这么问吧:
IIC_Send_Byte(0XA0+((ReadAddr/256)

不对啊,前面发了啊,AT24C16及以下,和AT24C16以上的读写时序有些不同的,具体搜具体型号芯片的PDF就可以了
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-7 15:57:01 | 显示全部楼层
biglu 发表于 2018-12-7 11:43
不对啊,前面发了啊,AT24C16及以下,和AT24C16以上的读写时序有些不同的,具体搜具体型号芯片的PDF就可 ...

我知道他们时序不同,我这不只是拿出else里边的(也就是AT24C16及以下)代码,理解并替换一下,帮我指正具体什么地方替换的不正确
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-7 16:20:09 | 显示全部楼层
硕果磊磊 发表于 2018-12-7 15:57
我知道他们时序不同,我这不只是拿出else里边的(也就是AT24C16及以下)代码,理解并替换一下,帮我指正 ...

IIC_Send_Byte(0xA0);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr/256);
IIC_Send_Byte(ReadAddr%256);
IIC_Wait_Ack();

你这个写法只适合AT24C16及以下的啊,并且每个send_byte后面要加wait_ack
回复

使用道具 举报

27

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
384
金钱
384
注册时间
2018-11-20
在线时间
62 小时
 楼主| 发表于 2018-12-7 16:31:22 | 显示全部楼层
biglu 发表于 2018-12-7 16:20
IIC_Send_Byte(0xA0);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr/256);

每个send_byte后都加ACK应答,不见得吧
我写的
IIC_Send_Byte(ReadAddr/256);
IIC_Send_Byte(ReadAddr%256);
代码就代表Word Address地址,一个高八位,一个低八位
组合成Word Address地址,中间就不能插入Ack
回复

使用道具 举报

6

主题

108

帖子

1

精华

高级会员

Rank: 4

积分
716
金钱
716
注册时间
2017-4-25
在线时间
203 小时
发表于 2018-12-7 18:39:32 | 显示全部楼层
硕果磊磊 发表于 2018-12-7 16:31
每个send_byte后都加ACK应答,不见得吧
我写的
IIC_Send_Byte(ReadAddr/256);

你用的哪个型号的AT24C啊?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 13:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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