打印

问题解决!谢谢各位大虾!感谢自己的**!

[复制链接]
5933|33
手机看帖
扫描二维码
随时随地手机跟帖
楼主
hotpower| | 2008-3-16 18:03 | 显示全部楼层 回帖奖励 |倒序浏览

只要读回ACK一切都会解决~~~

使用特权

评论回复
沙发
hotpower| | 2008-3-17 00:23 | 显示全部楼层

模拟I2C一般都是MCU为主器件,反之几乎没有模拟从器件的~~~

使用特权

评论回复
板凳
hotpower| | 2008-3-22 10:01 | 显示全部楼层

应该还是时序的问题,应该先测试读出1个字节

我给的例程虽然不完整,但意思已经够了~~~
相关链接:https://bbs.21ic.com/club/bbs/showEssence.asp?id=8532&page=2

使用特权

评论回复
地板
hotpower| | 2008-3-22 17:59 | 显示全部楼层

估计楼主真没搞清楚I2C协议及串行通讯主从机的关系

实际我给的例程是PC的并口模拟I2C协议,用什么语言并不重要.

楼主的类似以下的程序全部有问题~~~
while(i--)

   I2CStart();
   I2CSendByte(ControlByte&0xfe);//指定芯片,此次必定为写
   if(!WaitAck())              //涵数返回一个1为成功
     continue;                      //结束写操作,并i-1后,再来一次
//...
     if(errorflag==error) //经过写完后,如果最后errorflag标志为1,则表示有错误
           continue;                  //结束写操作,并i-1后,再来一次

等等都有问题.
I2C的通讯状态很规矩,每个状态都有详细的定义.
gccavr中的定义很规范(atmel称I2C为TWI)
enum enum_TWIState
{
/* Master */
    TW_START =                0x08,
    TW_REP_START=        0x10,
/* Master Transmitter */
    TW_MT_SLA_ACK=        0x18,
    TW_MT_SLA_NACK=        0x20,
    TW_MT_DATA_ACK=        0x28,
    TW_MT_DATA_NACK=        0x30,
    TW_MT_ARB_LOST=        0x38,
/* Master Receiver */
    TW_MR_ARB_LOST=        0x38,
    TW_MR_SLA_ACK=        0x40,
    TW_MR_SLA_NACK=        0x48,
    TW_MR_DATA_ACK=        0x50,
    TW_MR_DATA_NACK=        0x58,
/* Slave Transmitter */
    TW_ST_SLA_ACK=        0xA8,
    TW_ST_ARB_LOST_SLA_ACK=    0xB0,
    TW_ST_DATA_ACK=        0xB8,
    TW_ST_DATA_NACK=        0xC0,
    TW_ST_LAST_DATA=        0xC8,
/* Slave Receiver */
    TW_SR_SLA_ACK=        0x60,
    TW_SR_ARB_LOST_SLA_ACK=    0x68,
    TW_SR_GCALL_ACK=        0x70,
    TW_SR_ARB_LOST_GCALL_ACK=   0x78,
    TW_SR_DATA_ACK=        0x80,
    TW_SR_DATA_NACK=        0x88,
    TW_SR_GCALL_DATA_ACK=    0x90,
    TW_SR_GCALL_DATA_NACK=    0x98,
    TW_SR_STOP=                0xA0,
/* Misc */
    TW_NO_INFO=                0xF8,
    TW_BUS_ERROR=        0x00,
    TW_READ=                1,
    TW_WRITE=                    0
};

不管I2C出现的任何错误,主机都应该发送I2CStop(),而不应该像楼主用continue重试.

因为从机是根据主机的节拍即时钟进行工作即状态转移的,主机发现的错误从机并不知晓.

所以正确地容错应该是主机发送I2CStop()停止从机的工作后,使从机的状态归零.
然后再I2CStart()重新通讯.


再者I2C的调试实际很简单,应该在发送I2CStart()和从地址后,在接收应答处
设置个断点.
若裸奔应该在此处加个LedOn()或LedOff()看看到底收到从机的应答信号ACK否.

若收不到就应该检查时序,否则一切都白搭~~~

建议I2C用状态机,虽然在模拟I2C上很少使用,但它能使通讯更可靠~~~
相关链接:https://bbs.21ic.com/club/bbs/showEssence.asp?id=9000&page=1

使用特权

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

本版积分规则