我正在使用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标志。这没有发生,因此,代码进入无限循环。 我不明白我哪里出错了。有人可以帮忙吗?