OpenEdv-开源电子网

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

求问模拟IIC函数里面每次设置数据IO口输入还是输出是否有必要

[复制链接]

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
发表于 2015-2-1 12:46:19 | 显示全部楼层 |阅读模式
5金钱
求问模拟IIC函数里面每次设置数据IO口输入还是输出是否有必要?
原子哥的例程里面每次都有 SDA_out,或者SDA_IN
但是我看了网上有的其他人写的模拟IIC,从头到尾在这些函数里面都没有管SDA是否是输入和输出,只是在初始化的时候设置了一下。所以想问一下这个有么有必要?

最佳答案

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

IIC协议,主机写的时候,时序最简单;即便简单,仍然要读取从机的反应,即 ACK 位。这时 SDA 必须从输出状态变化为输入。 如果不读 ACK,实际上也行得通,但绝不允许。(你举的例子,应当就是这种情况。) 主机读的时候,先要输出命令和地址,然后再转为读,又转为写,反复多次,变化是必须的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 12:46:20 | 显示全部楼层
IIC协议,主机写的时候,时序最简单;即便简单,仍然要读取从机的反应,即 ACK 位。这时 SDA 必须从输出状态变化为输入。
如果不读 ACK,实际上也行得通,但绝不允许。(你举的例子,应当就是这种情况。)

主机读的时候,先要输出命令和地址,然后再转为读,又转为写,反复多次,变化是必须的。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-2-1 12:46:20 | 显示全部楼层
楼主如果用51,那就看不到这个过程了.
用STM32就必须有了.
51的IO貌似不具有设置方向的功能.所以也就不存在方向设置了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 14:59:54 | 显示全部楼层
回复【2楼】xuande:
---------------------------------
不是的,我看到的是,在读函数中,依然没有管输入和输出,从一开始定义SDA输出之后就没有管了,读数据的时候还是可以读出来,用的这个程序已经成功读取了MPU6050,所以不知道为什么
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 16:35:11 | 显示全部楼层
什么高级技术,有具体资料吗?

估计你误判的可能性大。
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 17:46:57 | 显示全部楼层
回复【4楼】xuande:
---------------------------------
你去搜一下网上模拟IIC的程序,很多在读写函数里面都是直接让SDA高或者低,没有设置是输入还是输出
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 18:38:03 | 显示全部楼层

下图,百度文库,文件名在图里。看红圈。




回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 18:44:02 | 显示全部楼层

另一个,
http://wenku.baidu.com/link?url=RZerdO51UVy8XkDa_f5OcXreMIoLY9D5P_kytUopOv814Aovz4uRAk151DFbLiGZRpYb3y0tsqqdkOrhjNED1DSB-f6O6ySN-gzGUgqA13W

截图是一段主机程序,还真没有看到转换输入的语句。
但绝对要有,要么作者不觉得这是重点,所以没写出来;要么,转换输入的语句就包含在宏定义里面。




回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 18:45:10 | 显示全部楼层
无论如何,必须有。不用怀疑。
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:23:23 | 显示全部楼层
[mw_shl_code=c,true] #define SCL_H GPIOB->BSRR = SCL_PIN /* GPIO_SetBits(GPIOB , GPIO_Pin_6) */ #define SCL_L GPIOB->BRR = SCL_PIN /* GPIO_ResetBits(GPIOB , GPIO_Pin_6) */ #define SDA_H GPIOB->BSRR = SDA_PIN /* GPIO_SetBits(GPIOB , GPIO_Pin_7) */ #define SDA_L GPIOB->BRR = SDA_PIN /* GPIO_ResetBits(GPIOB , GPIO_Pin_7) */ #define SCL_read GPIOB->IDR & SCL_PIN /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_6) */ #define SDA_read GPIOB->IDR & SDA_PIN /* GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_7) */ [/mw_shl_code]
以上是宏定义

[mw_shl_code=c,true]u8 IIC_ReadByte(void) //数据从高位到低位// { u8 i=8; u8 ReceiveByte=0; SDA_H; while(i--) { ReceiveByte<<=1; SCL_L; delay_us(1); SCL_H; delay_us(1); if(SDA_read) { ReceiveByte|=0x01; } } SCL_L; return ReceiveByte; } [/mw_shl_code]
这个是期中的一个函数
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:24:13 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
原子哥看看上面的一个IIC的程序,就是这么写的,没有设置输入输出转换,但是,我用这个IIC读取到了mpu6050,数据都很对!
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:25:00 | 显示全部楼层
回复【8楼】xuande:
---------------------------------
可是,我确实用到的程序里面没有改变,可是成功读取了
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 19:27:13 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
对,51是双向的,提前写次 1 就可以输入了。
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:27:45 | 显示全部楼层
回复【13楼】xuande:
---------------------------------
不是51,我用的stm32
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 19:29:57 | 显示全部楼层
哪里有完整工程文件?
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:30:58 | 显示全部楼层
回复【15楼】xuande:
---------------------------------
你有mpu6050吗,可以拿过去自己试验
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 19:33:12 | 显示全部楼层
不用实验,给我完整工程文件就行。
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:33:26 | 显示全部楼层
这个是读取mpu的文件

test.rar

4.26 MB, 下载次数: 415

回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 19:33:41 | 显示全部楼层
回复【17楼】xuande:
---------------------------------
在下面
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 20:11:32 | 显示全部楼层
看完了,确实没有。

奇怪了。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 20:17:25 | 显示全部楼层

看了下 IO 口的结构,也许这是一个 "好bug"。
如果在输出状态下,输入信号没有关断,就会一路畅通过来;而后面的路也是畅通的,最终就会进入输入寄存器。
导致输出状态下,输入功能保持正常。这在数字信号的情况下,是完全可以做到的。但手册却是按另一回事说话。







回复

使用道具 举报

0

主题

133

帖子

0

精华

初级会员

Rank: 2

积分
169
金钱
169
注册时间
2014-12-21
在线时间
1 小时
发表于 2015-2-1 20:22:36 | 显示全部楼层
不用等回复ACK,是默认数据已经被对方接收,并且对方是完整接收,这在没有干扰的环境下是可行的,但工业复杂环境下极不可取。

快递员可以把你快递放门口(数据给你了,但你回ACK他不接收)。一般情况下没问题,但很可能出问题。
流过汗水才能代表自己真的学会了如何不流汗。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 20:53:15 | 显示全部楼层
回复【22楼】花戒:
---------------------------------

LZ 现在遇到情况是这样:
在 SDA 的 IO 口保持输出状态不变的情况下,可以正确读到输入的数据。

看过例程了,确实没有改变为输入状态。
奇怪不?
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-1-12
在线时间
4 小时
 楼主| 发表于 2015-2-1 20:58:22 | 显示全部楼层
回复【23楼】xuande:
---------------------------------
诶,那如果是这样的话,我还是加上改变输入输出吧,免得以后出问题
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 21:01:37 | 显示全部楼层
回复【24楼】StarFlying:
---------------------------------
这就对了。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11556
金钱
11556
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-2-1 21:06:38 | 显示全部楼层
应当就是 20L 那种可能性。原因如下:

例程中,每次判断 “SDA_READ” 时,之前都有条语句 “SDA_H”,即输出 1 电平。

而 IO 口已经初始化为 OD,输出 1 ,其实真正意思是: “ 不要输出0 ”。

由于总线结构是“线与",只要主机这边没有把 SDA 拉低,这条线就只有子机在控制,不受影响。

这样, 20L 的可能性就起作用了,导致结果正确。

只是,必须要知道 20L 的规则。
回复

使用道具 举报

3

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2014-12-5
在线时间
1 小时
发表于 2015-4-25 11:32:19 | 显示全部楼层
回复【26楼】xuande:
---------------------------------
借楼主的帖子问下, if (SDA_read)  byte |= 0x01; 怎么理解啊??
回复

使用道具 举报

0

主题

13

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-4-14
在线时间
0 小时
发表于 2015-4-25 11:39:30 | 显示全部楼层
回复【27楼】Lemon:
---------------------------------
是高电平,就读出1,
回复

使用道具 举报

3

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2014-12-5
在线时间
1 小时
发表于 2015-4-25 12:00:08 | 显示全部楼层
回复【28楼】wenting920:
---------------------------------
读出1有什么用?不是很理解
回复

使用道具 举报

0

主题

13

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-4-14
在线时间
0 小时
发表于 2015-4-25 12:11:37 | 显示全部楼层
回复【29楼】Lemon:
---------------------------------
就是SDA为高电平(1),就把该位置1,然后再进行下一位判断,直到8位判断完成就跳出那个for()
回复

使用道具 举报

3

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2014-12-5
在线时间
1 小时
发表于 2015-4-25 12:26:07 | 显示全部楼层
回复【30楼】wenting920:
---------------------------------
那如果SDA为低电平会怎样?,如果SDA一直是高电平的话那byte接收到的不就是全1了吗?
回复

使用道具 举报

0

主题

13

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-4-14
在线时间
0 小时
发表于 2015-4-25 17:52:39 | 显示全部楼层
回复【31楼】Lemon:
---------------------------------
……
为低就不置高,你有没有发现那个For语句会让你的寄存器左移?不给1的情况下,经过左移,就是0,告诉你编译器此位为0。8次后得到一个byte的数据。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-23 07:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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