ARM:由于在接收到ACK后未设置I2C标志,因此I2C地址写操作会自动等待

时间:2016-08-07 17:28:12

标签: c arm embedded i2c

我正在使用LPC2138开发一个裸机ARM项目。 I2C配置为主发送器模式。我使用以下代码将数据写入从站。我选择了I2C轮询方法。

#define AA  (0x04)
#define SI  (0x08)
#define STO (0x10)
#define STA (0x20)
#define I2EN    (0x40)

/* I2C0CONCLR bits  */
#define AAC     AA
#define SIC     SI
#define STAC    STA 
#define I2ENC   I2EN

void I2C0_init(unsigned char mode)
{
    PINSEL0     = 0x50;
    IO0DIR      = 0x0C;
    IO0SET      = 0x0C;

    I2C0CONCLR  = AAC | SIC | STAC | I2ENC;
    I2C0SCLL    = 0x4B;
    I2C0SCLH    = 0x4B;
    I2C0CONSET  = I2EN;
    __i2c0_mode = mode;
    __i2c0_initialised = TRUE;
}

static bool I2C0_start()
{
    I2C0CONSET  = STA;
    while(!(I2C0CONSET & SI));
    if(I2C0STAT != 0x08)
    {
        return FALSE;
    }
    return TRUE;
}

static inline bool I2C0_slave_addr(unsigned char addr, bool rw)
{
    addr = rw ? addr | BIT_MASK_RD : addr & BIT_MASK_WR;
    I2C0DAT = addr;
    I2C0CONCLR = SIC | STAC;
    while(!(I2C0CONSET & SI));  // infinite loop here
    I2C0CONCLR = SIC;
    if(rw == I2C_WR && I2C0STAT != 0x18)
        return FALSE;
    else if(rw == I2C_RD && I2C0STAT != 0x40)
        return FALSE;
    return TRUE;
}

long I2C0_write(unsigned char addr, const char *buff, unsigned long buff_len)
{
    unsigned long count = 0;
    if(!__i2c0_initialised)
            return I2C_ERROR_UNINITIALISED;
    if(!buff_len)
        return 0;
    if(__i2c0_mode == I2C_MODE_MASTER)
    {
        I2C0_start();
        I2C0_slave_addr(addr, I2C_WR);
        ..............................
        ..............................
    }
}

我实际上是使用Proteus模拟代码。正确发送I2C启动条件和从机地址,从机成功确认地址。

从机确认后,应根据LPC2138参考手册自动重新设置SI标志。这没有发生,因此,代码进入无限循环。 我不明白我哪里出错了。有人可以帮忙吗?

0 个答案:

没有答案