请熟悉IIC协议的和AVR单片机的高手进来~~~~~

[复制链接]
3395|18
 楼主| Nevea 发表于 2007-10-9 17:52 | 显示全部楼层 |阅读模式
最近在调试时钟芯片&nbsp;PCF8563&nbsp;与&nbsp;ATMEGA128的IIC通讯。<br />使用的是模拟IIC.<br />附上&nbsp;几个程序&nbsp;并告知我的问题所在,希望有高手可以指点迷津:<br />void&nbsp;Start()<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;SET_SDA;<br />&nbsp;&nbsp;&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;CLR_SDA;<br />&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br />void&nbsp;Stop()<br />{<br />&nbsp;<br />&nbsp;&nbsp;CLR_SDA;<br />&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;SET_SDA;<br />&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br />void&nbsp;WaitACK()<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;UCHAR&nbsp;errtime=20;<br />&nbsp;&nbsp;&nbsp;&nbsp;UCHAR&nbsp;&nbsp;tp=0;<br />&nbsp;&nbsp;&nbsp;//&nbsp;SDA_IN;<br />&nbsp;&nbsp;&nbsp;DDRD=DDRD&0xfd;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;PORTD=PORTD|0x02;&nbsp;///0:禁止上拉;1:使能上拉<br />&nbsp;&nbsp;&nbsp;PIND=PIND&0xfd;<br />&nbsp;&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;//&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;tp=PIND;<br />&nbsp;&nbsp;&nbsp;while(tp&0x02)<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(errtime)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errtime--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stop();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tp=PIND;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;<br />&nbsp;}<br /><br />void&nbsp;writebyte(UCHAR&nbsp;wdata)<br />{<br />&nbsp;&nbsp;&nbsp;UCHAR&nbsp;i;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;SDA_OUT;<br /><br />&nbsp;&nbsp;&nbsp;for(i=0;i&lt8;i++)<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(wdata&0x80)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET_SDA;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLR_SDA;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wdata&lt&lt=1;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;WaitACK();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//I2C器件或通讯出错,将会退出I2C通讯<br />}<br /><br />void&nbsp;writeData(UCHAR&nbsp;address,UCHAR&nbsp;mdata)<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;cli();<br />&nbsp;&nbsp;&nbsp;Start();<br />&nbsp;&nbsp;&nbsp;writebyte(0xa2);&nbsp;//*写命令<br />&nbsp;&nbsp;&nbsp;writebyte(address);&nbsp;//*写地址<br />&nbsp;&nbsp;&nbsp;writebyte(mdata);&nbsp;//*写数据<br />&nbsp;&nbsp;&nbsp;Stop();<br />}<br /><br />这是几个子函数。时序方面我都对过了,不应该有什么错误。现在的问题&nbsp;就是<br />WaitACK()函数里面的循环&nbsp;&nbsp;<br />&nbsp;while(tp&0x02)<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(errtime)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errtime--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stop();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tp=PIND;<br />&nbsp;&nbsp;&nbsp;}始终也跳不出来。<br />我这个函数是在写完一个字节给从机之后,检测从机是否返回一个低电平信号的。按照IIC协议上说,如果返回的是个低电平,则说明写成功;否则,则说明写失败。<br />我现在&nbsp;无法跳出循环,就说明检测到的这个信号,始终为高电平。这是我一直困惑的。<br />想请同时&nbsp;熟悉AVR的&nbsp;朋友给看看,我的寄存器使用是否有错误,但是感觉上好像也应该就是这样的。谢谢大家~~~~~
 楼主| Nevea 发表于 2007-10-10 08:14 | 显示全部楼层

对,就是对方没释放总线~~~~~

不知何因,还请高手指教~~~
computer00 发表于 2007-10-10 09:14 | 显示全部楼层

可能还是时序不对...地址没写对,导致设备无应答。

  
 楼主| Nevea 发表于 2007-10-10 09:23 | 显示全部楼层

地址肯定是对了,

时序??要是还有人说不对,我也是真的不知道如何做了?<br />时序&nbsp;我都确认过好几次了,如果,还不对,实在不知道该从何入手了~~~~~~~~~~~~~
啊啊哈 发表于 2007-10-10 09:27 | 显示全部楼层

可能是延时时间太短

时钟频率不要超过100k
 楼主| Nevea 发表于 2007-10-10 10:20 | 显示全部楼层

100KHz??时钟芯片上说最大可以达到400KHz呢

  
ayb_ice 发表于 2007-10-10 10:55 | 显示全部楼层

随便说说

void&nbsp;WaitACK()<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;UCHAR&nbsp;errtime=20;<br />&nbsp;&nbsp;&nbsp;&nbsp;UCHAR&nbsp;&nbsp;tp=0;<br />&nbsp;&nbsp;&nbsp;//&nbsp;SDA_IN;<br />&nbsp;&nbsp;&nbsp;DDRD=DDRD&0xfd;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;PORTD=PORTD|0x02;&nbsp;///0:禁止上拉;1:使能上拉<br />&nbsp;&nbsp;&nbsp;PIND=PIND&0xfd;<br />&nbsp;&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;//&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;tp=PIND;<br />&nbsp;&nbsp;&nbsp;while(tp&0x02)<br />&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(errtime)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errtime--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stop();&nbsp;&nbsp;//&nbsp;停止后没有返回,仍在继续操作,函数应该返回一个值更好<br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tp=PIND;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;<br />}<br />
 楼主| Nevea 发表于 2007-10-10 12:28 | 显示全部楼层

回楼上,我知道你意思,我也可以在这里加个返回值

但是,我真正的问题,不在这里呀~~
ayb_ice 发表于 2007-10-10 15:12 | 显示全部楼层

你的程序写法本来就退不出来(失败时)...

好象你发数据时IO没有设为输出吧...
 楼主| Nevea 发表于 2007-10-10 15:49 | 显示全部楼层

回复楼上

发数据时,我io方向设置为输出了。<br />失败时间超过&nbsp;errtime=20,程序进入<br />void&nbsp;Stop()<br />{<br /><br />&nbsp;&nbsp;CLR_SDA;<br />&nbsp;&nbsp;SET_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;SET_SDA;<br />&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__&nbsp;volatile(&quot;nop&quot;);<br />&nbsp;&nbsp;CLR_SCL;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />}函数,也就是退出iic协议了。<br /><br />现在是程序无论如何都没有“成功”的时候,永远“失败”。<br />
ayb_ice 发表于 2007-10-10 16:47 | 显示全部楼层

网上下个看一下...

也许是你的从机操作不对...<br />A210接地时读写操作分别是0xA1,0xA0...
 楼主| Nevea 发表于 2007-10-11 08:11 | 显示全部楼层

re:

什么叫&nbsp;从机操作不对呢??<br />我的PCF8563的写&nbsp;读&nbsp;地址&nbsp;分别是0xa2,0xa3.<br />您指的&nbsp;是什么呢&nbsp;?
zusen 发表于 2007-10-11 11:13 | 显示全部楼层

到老周的网站上下载I2C的资料看看吧

那里也有C51的I2C程序,,按照思路,很容易更改到mega上
 楼主| Nevea 发表于 2007-10-12 08:15 | 显示全部楼层

谢谢了。

主管说这部分可以先不调了
dadodo 发表于 2007-10-12 16:08 | 显示全部楼层

楼主没用AVR的TWI?

模拟I2C对于AVR来说,在时序正确的前提下,2个NOP是不够的。
 楼主| Nevea 发表于 2007-10-13 08:48 | 显示全部楼层

re:

2个NOP是不够的。那要多少个可以合适吗?
maychang 发表于 2007-10-13 10:40 | 显示全部楼层

直接用AVR单片机的IIC接口算了

何必这样麻烦?<br />51单片机没有IIC接口,只能用软件模拟,AVR多数有这个接口,为什么不用?
zusen 发表于 2007-10-14 09:28 | 显示全部楼层

谁说51单片机没有IIC接口

楼上没用过菲利普的吧???
hotpower 发表于 2007-10-14 09:46 | 显示全部楼层

彻底倒塌了~~~Stop()让俺发晕~~~看看给白沙的例程

  <br /> 相关链接:<a href='https://bbs.21ic.com/club/bbs/showEssence.asp?id=8532'>https://bbs.21ic.com/club/bbs/showEssence.asp?id=8532</a>
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

306

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部