打印

请教关于I2C总线的问题

[复制链接]
2108|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我是个刚学单片机的,现在学到用89C52模拟一条I2C总线,在写开始时序时,我的写法就用不了,回头参考书本上的写法就能用了,我想请教一下,这两种写法有什么说法吗?或是我错在哪了?谢谢!
file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-14744.png
我自已的写法:        
Void start()
{
Scl=1;
delay();
Sda=1;
delay();
Sda=0;
delay();
}
参考书本上的写法:
void start()
{
Sda=1;
delay();
Scl=1;
delay();
Sda=0;
delay();
}

相关帖子

沙发
ZG11211| | 2012-12-7 15:33 | 只看该作者
时序都不对,肯定用不了啊

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
板凳
readdai| | 2012-12-7 15:45 | 只看该作者
本帖最后由 readdai 于 2012-12-7 15:47 编辑

仔细看自己的时序是否和IIC协议定义的一致……

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
地板
2389676302| | 2012-12-7 16:20 | 只看该作者
好像是有点小错误

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
5
东北小辉辉| | 2012-12-7 16:29 | 只看该作者
本帖最后由 东北小辉辉 于 2012-12-7 16:31 编辑

楼主 我也跟你犯过同样的错误 有人告诉我说好像是这要取决于原来sda总线的状态 如果sda原来就是1是没问题的 但是如果原来sda是0的话时序就有问题了 应该是相当于先给上升沿再给下降沿 而I2C总线的开始信号要求的是在scl是高电平的期间给sda一个下降沿 所以第2种写法是严谨的 顺便看看楼下怎么说?

使用特权

评论回复
评分
参与人数 3威望 +6 收起 理由
zhexuan + 2 很给力!
GXLAOYANG + 2 很给力!
原野之狼 + 2 赞一个!
6
GXLAOYANG|  楼主 | 2012-12-7 16:46 | 只看该作者
void start()
{
        SDA=1;
        delay();
       
        SCL=1;
        delay();
        SDA=1;
        delay();
        SDA=0;
        delay();
}
非常感谢各位的回复。现在我按楼上朋友的意思改了一下,是可以的,证明楼上朋友说的是对的,不过这样写有点浪费了。

使用特权

评论回复
7
chenyu988| | 2012-12-7 21:04 | 只看该作者
void Start_I2c()
{
  S_SDA;     /*发送起始条件的数据信号*/
  Delay1us(1);
  S_SCL;
  Delay1us(5);      /*起始条件建立时间*/

  C_SDA;     /*发送起始信号*/
  Delay1us(5);      /* 起始条件锁定时间*/
      
  C_SCL;     /*钳住I2C总线,准备发送或接收数据 */
  Delay1us(2);
}

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
8
dqyubsh| | 2012-12-7 21:16 | 只看该作者
个人不建议新手去模拟IIC协议,没什么意义。

使用特权

评论回复
9
NE5532| | 2012-12-7 21:25 | 只看该作者
不赞成楼上,只有模拟了才能真正理解到I2C时序,否则是囫囵吞枣。楼主明显发现跟例程不一样,为什么不找区别?程序不是想怎么写就怎么写的。

使用特权

评论回复
评论
江枫渔火 2012-12-8 15:41 回复TA
赞成新手模拟,没用过模拟的,未必理解时序。新手学习就应该这样,不能囫囵吞枣。 
东北小辉辉 2012-12-8 11:53 回复TA
顶一个 
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
10
lzqxs89| | 2012-12-7 23:23 | 只看该作者
NE5532 发表于 2012-12-7 21:25
不赞成楼上,只有模拟了才能真正理解到I2C时序,否则是囫囵吞枣。楼主明显发现跟例程不一样,为什么不找区 ...

时序这种东西要是有个示波器或者逻辑分析仪看看就更好了。版主能不能指点下WIFI开发怎么入门?

使用特权

评论回复
评论
江枫渔火 2012-12-8 15:43 回复TA
用仪器测时序一般只是出问题时才去做,实际上是什么时序是可以预知的。特别是模拟方式的操作,什么时序都你定的。 
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
11
P0.0| | 2012-12-7 23:52 | 只看该作者
其实两种写法都可以,你的“写法”用不了是因为你在某个地方没有释放总线SDA  造成的。并不是上面的写法有错误。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
12
~Beyond~| | 2012-12-8 00:03 | 只看该作者
本帖最后由 ~Beyond~ 于 2012-12-8 00:06 编辑

5楼正确 比如24c02随机读:开始+写器件地址+响应 +写器件页内的地址+响应+开始信号+读数据+NOACK不响应 。
        第2个开始信号会和ACK衔接,响应后SDA=0,此时若sclk=1,本来该是开始信号,你那样写 却成了停止信号

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2 赞一个!
13
NE5532| | 2012-12-8 08:28 | 只看该作者
lzqxs89 发表于 2012-12-7 23:23
时序这种东西要是有个示波器或者逻辑分析仪看看就更好了。版主能不能指点下WIFI开发怎么入门? ...

这个一般都用模块了。

使用特权

评论回复
14
lzqxs89| | 2012-12-8 09:18 | 只看该作者
NE5532 发表于 2012-12-8 08:28
这个一般都用模块了。

你意思是理解了wifi通信的协议就行了,然后根据协议与模块的数据手册来操作模块实现wifi通信?

使用特权

评论回复
评论
江枫渔火 2012-12-8 15:46 回复TA
没了解WIFI协议也可以,WIFI模块提供接口,可能是串行UART,可能SPI,可能是SDIO,跟读写FLASH一个道理,关于FIWI的其他东西不需要深入了解~ 
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
15
NE5532| | 2012-12-8 10:17 | 只看该作者
模块已经给你封装好了,你有一点点基础知识就足够了。请找个模块的说明书来看下你就清楚了。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2
16
hdl551890| | 2012-12-8 10:19 | 只看该作者

使用特权

评论回复
17
zwz7219| | 2012-12-8 11:34 | 只看该作者
两种写法都没有错,你自己写的不能用是错在了其它函数,参考书上的发起始位隐含了一个结束位
1 先拉高时钟线
2 在时钟线为高电平下拉高数据线,发出一个停止位
3 在时钟线为高电平下拉低数据线,发出一个起始位
这在某些情况下是有用的,如在随机读的情况下,先有一个“假写”的动作,用于设置 IIC 器件内的数据指针,然后发出一个停止位,接着发出一个起始位,然后开始发出“芯片选择+读”命令。

而你的程序没有发出停止位,在这种情况下可能工作不正常,当然,有些器件是允许“重复起始位”,那么你的程序就是可以用的。

还有参考程序想要既要发停止位,又可以发起始位,有一个条件,即在进入函数前数据线必须是低电平,如果已经是高电平,那么它就只有发起始位功能了。

同样对于你的程序,如果能保证在进入该函数前你的数据线是低电平,时钟线为高电平,也可以起到与参考程序相同的效果。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
GXLAOYANG + 2 赞一个!
18
GXLAOYANG|  楼主 | 2012-12-8 19:00 | 只看该作者
非常感谢各位的回复和指导,我相信我能弄明白问题出在哪了。谢谢!

使用特权

评论回复
19
1638574407| | 2012-12-8 19:53 | 只看该作者

使用特权

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

本版积分规则

3

主题

95

帖子

0

粉丝