打印

89s52 iic 程序,等不到ACK咋回事?

[复制链接]
4036|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
isbit|  楼主 | 2007-10-26 14:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AC, ck, iic, s52, TE
  7bit 器件地址和write 位 (0),波形正确,
等不到 ACK?
相关程序如下:
    uint8 SystemError;
    sbit SCL= P1^0; //定义串行时钟线所在口 使用时根据自己的需要来定义
    sbit SDA= P1^1; //定义串行数据线所在口 使用时根据自己的需要来定义
    sbit test_LED0=P0^0;
    sbit test_LED1=P0^1;


   void I2CStart(void)
{
    EA=0;
    SDA=1; 
    _nop_();    
    _nop_();    
    SCL=1; 
    SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
    SDA=0; 
    SomeNOP(); 
    SCL=0;
}

void I2CSendByte(uint8 Data)
{
    uint8 BitCounter=8;//位数控制
     uint8 temp;//中间变量控制
    do{ 
     temp=Data;
     SCL=0;
     SomeNOP();
     if((temp&0x0080)==0x0080)//如果最高位是1
        SDA=1;
     else
        SDA=0;
     SCL=1;
     temp=Data<<1;//左移
     Data=temp;
     BitCounter--;
     }while(BitCounter);
     SCL=0;
}

WaitAck(void)
{
    int16 errtime=200;//因故障接收方无ACK,超时值为255。
    SDA=1;
    _nop_();    
    _nop_();    
    SCL=1;
    SystemError=0; 
    while(SDA)
    { errtime--;
        if(!errtime)
        { 
            I2CStop();
            SystemError=1; //出错后给全局变量赋值
            Prints("        无ACK应答信号 ",1);
            return;
        }
        
    }
    _nop_();    
    _nop_();    
    SCL=0; 
}

void    I2C_Write(uint8 address, uint8 data_size,uint8 *s_data)
{
    uint8    i;
    //do{
        //do{
            //Prints("            W1:开始写数据 ",1);
            I2CStart();
            I2CSendByte(ATA2508_AddrW);
            //Prints("        W2:写ATA2508器件地址等ACK信号 ",1);
            WaitAck();
            //}while(SystemError);
        I2CSendByte(address);
        //Prints("        W3:写ATA2508寄存器地址等ACK信号 ",1);
        WaitAck();
        //}while(SystemError);
    for(i=0;i<data_size;i++)    
        {
            I2CSendByte(s_data);
            WaitAck();
        }
    //Prints("        W4:写完ATA2508寄存器数据结束 ",1);
    I2CStop();
}
MAIN()
{
    data1[0]=0x04;        //aps-2 MODE
    I2C_Write(0,1,data1);
}

相关帖子

沙发
isbit|  楼主 | 2007-10-26 14:13 | 只看该作者

以前写过读写 eeprom的按时序要求写程序很顺利啊

  那种芯片和51稍微不同,他们的io口可以设置input mode
和output mode,写完8bit 后只要设置输入模式等ACK就行了!
  现在51 在等ACK的时候 还要把sda=1,是不是器件返回的0,
sda检测不到啊?
  

使用特权

评论回复
板凳
5_0_5| | 2007-10-26 21:09 | 只看该作者

个人认为如下的时序起始信号会更可靠

 void I2CStart(void)
{
    SCL=0;
    SomeNOP(); 
    SDA=1; 
    _nop_();    
    _nop_();    
    SCL=1; 
    SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
    SDA=0; 
    SomeNOP(); 
    SCL=0;
}
楼主写的程序中,有可能因为SCL的起始状态不定,而误产生结束信号
说的不一定对,试一试了
另外,要是用的P0口就要注意上拉

使用特权

评论回复
地板
isbit|  楼主 | 2007-10-27 13:45 | 只看该作者

谢谢ls,原因是硬件的原因

使用特权

评论回复
5
lin415804| | 2011-4-12 22:11 | 只看该作者
楼主你好,硬件什么导致ack丢失?我的ack会经常丢失

使用特权

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

本版积分规则

193

主题

956

帖子

1

粉丝