在Atmega的I2C接口中没有得到正确的值

时间:2015-07-23 14:32:43

标签: c embedded avr i2c atmega

我对I2C的概念很新,我在2个Atmega32之间连接I2C时遇到了一些问题。

我有一个Atmega32作为Master连接LCD屏幕,另一个I2C作为从属设备连接LM35,这两个Atmega都连接了SDA和SCL线。

所以,虽然我在连接到主设备的LCD屏幕上获取数据,但我没有得到正确的值。就像这里的温度是28摄氏度,但连接到主机的LCD由于某种原因不断重复65280。谁能告诉我哪里出错了?主设备和从设备的代码已发布在下面。

主码:

GET /api/person?q={"filters":[{"name":"age","op":"ge","val":10}]} HTTP/1.1
Host: example.com

奴隶代码:

奴隶代码只是一次又一次地重复一个功能,所以我不会发布整个代码,只是它们之间的片段。

int main(void)
{
    unsigned int xx=0x00;
    unsigned char yy;
    DDRA=0xff;
    I2C_init(); //I2C initialization
    lcd_init(); //LCD initialization
    while(1)
    {
        for (int i=0;i<3;i++) //Getting unsigned int data from slave, so
        {                     //broke data into 4 parts and receiving 
            if (i==0)         //one byte at a time. 
            {
                I2C_start(0x01);  //I2C start along with the address of the slave
                yy=I2C_read_ack(); //Read slave data along with an acknowledgment 
                xx |= (yy << 8);    
                I2C_stop(); //I2C stop function.
            }
            else if (i>0)
            {
                I2C_start(0x01+1); //don't know any particular reason
                yy=I2C_read_ack(); //behind this, but if i don't do 0x01+1
                xx |= (yy << 8);   //then the master ends up reading the
                I2C_stop();        //address as a data packet.
            }
        }
     lcd_num(xx);   //lcd function to display unsigned int data.
    }
}

1 个答案:

答案 0 :(得分:0)

在主代码中,xx永远不会被设置,除非声明它,它只会被修改。因此,我建议您在其中一个循环中初始化xx,不确定哪个循环,因为lcdnum()位于for循环中。

编辑:接收器循环有几个问题。

  • 没有初始化累加器
  • 错误的循环控制(3而不是4)
  • 转错不正确
  • 字节顺序不正确(首先发送l.s.字节)

我建议将代码块重写为

for (int i=0; i<4; i++)
{
    if (i==0)                   // if first byte
    {
        I2C_start(0x01);
        xx = I2C_read_ack();    // initialise accumulator with first byte
        I2C_stop();
    }
    else                        // no need to test i again
    {
        I2C_start(0x01+1);
        yy = I2C_read_ack();
        xx |= (yy << (i*8));    // update accumulator
        I2C_stop();
    }
}