在论坛里看到有人想用单片机模拟I2C从机。
原帖:http://bbs.ednchina.com/ShowTopic.aspx?id=68892
贴子发表于:2008-8-25 18:06:20
我最近用单片机模拟I2C做slave,现在做出来了,但是误码率很高,检查了一下原因,是地址经常读错,还有的是地址读到之后没有给主机应答。我检测时钟信号是用while语句写的,下面是我写的接收一个字节数据的程序:
uchar RcvB()
{
。。。。。。
}
首先很少人有这个想法,但模拟主机很普遍。
模拟I2C主机是可行的,因为时钟SCL由主机提供,MCU很容易掌控。
但是模拟I2C从机的难度要大很多。
首先SCL由主机提供,有效地捕捉和跟随它要看主机的速率而定。
所以选择模拟从机应该是个错误,但又带来了可行性的讨论。
一般IO模拟有2种方法:中断或查询。
由于中断有着固定的响应时间,再加上到中断的有效处理处的时间,可能信号早已翻转,此时有不如简单的IO查询了。
所以要根据主机速率来选择IO模拟的方式。
真正满足I2C协议的主机有个很重要的特性:
允许从机拉低时钟降速。
这就告诉我们模拟从机是可行的,虽然并不合理。
考虑到中断嵌套和中断响应时间等问题,我认为查询比中断会好些。(当主机速率低是中断是很好的选择)
但这又带来了CPU占有率的问题。
因为while(SCL)或while(!SCL)会使其他任务阻塞,故裸奔时其他程序
应该由定时中断及其他中断激活,OS时由高优先级任务激活。
这样做问题又来了---其他任务打断了I2C协议的次序。
所以程序应该采用协作式,即在主机SCL=0时:
首先从机拉低SCL=0!!!
若需从机发送数据,此时从机可以发送SDA.
然后开中断在其他任务中断时把控制权让出。
当从机程序重新获取控制权后,再关中断后释放SCL=1.
再用while(!SCL)捕捉SCL的上升沿后来读取SDA数据。
总之模拟从机很困难,成功的前提时:
必须捕捉到SCL=0而不丢失一次。
要做到这个可以选择外部中断为最高级中断。但中断响应时间
必须小于SCL=0的脉宽,否则只能采用查询方法。
用户461316 2008-9-4 18:54
ilove314_323192455 2008-8-31 17:46