LPC22XX,LPC213X系统ARM I2C用做从设备问题

controstr 2016-02-25 05:26:22
业务上需要将LPC系列的ARM用作从设备,一般使用的人会比较少,本人在调试时遇到一些问题如下:
1.接收数据时,最高位总是为1;
2.发送数据时,只能发送二个字节的数据,到0xB8状态后就会直接跳到0xC0状态

需解决:
1.如何解决用作从设备时,最高位总为1的问题;
2.如何解决用作从设备发送时,中断状态为0xA8后只来一个0xB8的状态就变成0xC0状态,按理应该可以产生多个0xB8状态。
从端到主端发送的二个字节数据,主端接收到的数据是正确的。
代码如下:
初始化代码

void I2C1SlaveInit(DWORD freq, BYTE addr)
{
PCONP |= (0x1 << 19); // 打开电源
if (freq > 400000) freq = 400000;

PINSEL0 |= 0x30C00000;// 设置I2C控制口有效

I2C1ADR = (addr); // 设置从地址
I2C1SCLH = (Fpclk/freq + 1) / 2; // 设定I2C时钟
I2C1SCLL = (Fpclk/freq)/2;
I2C1CONCLR = 0x2C;
I2C1CONSET = 0x44; // 使能从I2C
I2C1ADR = (addr); // 设置从地址

// 设置I2C中断允许
install_irq(I2C1_INT, (void*)I2C1SlaveIrq);
}

中断处理代码


BYTE wData[32] = {0xa1, 0xa2, 0xa3, 0x00, 0xff, 0x11, 0x22, 0x33, 0x44, 0x88, 0x0};
int wlength = 0x0;
// 从模式
#ifdef WIN32
void I2C1SlaveIrq(void)
#else
void I2C1SlaveIrq(void) __irq
#endif
{
BYTE stat = I2C1STAT;
/* 根据状态码进行相应的处理 */
switch ( stat & 0xF8)
{
case 0x60:
case 0x70: // 已接收到通用调用位和返回ACK。将接收数据和返回ACK
{
length = 0;
I2C1_end = 0;
I2C1CONSET = 0x4;
I2C1CONCLR = 0x8; // 写0x08 到I2CONCLR 来清除SI 标志?
break;
}
case 0x68:
case 0x78: // I2C开始,初始化接收数据
{
I2C1CONSET = 0x24;
I2C1CONCLR = 0x8; // 写0x08 到I2CONCLR 来清除SI 标志?
I2C1_buf = dataBuffer; // 建立从接收模式数据缓冲区。
length = 0;
I2C1_end = 0;
break;
}
case 0x80:
case 0x90:
{
dataBuffer[length++]= (BYTE)I2C1DAT;
//*I2C1_buf++ = I2C1DAT; // 读取I2DAT 的数据字节,存放到从机接收缓冲区?
//++length;
if ( length == 1 )
{
I2C1CONSET = 0x04; // AA=1
I2C1CONCLR = 0x08;
}else if ( length == 11 )
{
I2C1CONCLR = 0x02C;
} else
{
I2C1CONSET = 0x04; // AA=1
I2C1CONCLR = 0x08;
}
break;
}
case 0x88:
case 0x98:
{
I2C1CONCLR = 0x08;
I2C1CONSET = 0x04;
I2C1_end = 1;
break;
}
case 0xA0: // 结束
{
I2C1CONSET = 0x04;
I2C1CONCLR = 0x08;
wlength = 0x0;
I2C1_end = 1;
break;
}
//---- 发送
case 0xA8:
{
wlength = 0x0;
I2C1DAT = wData[wlength++];
I2C1CONSET = 0x04;
I2C1CONCLR = 0x08;
break;
}
case 0xB8: // 此处只会进入一次,后状态就为0xC0,
{
if ( wlength < 9 )
{
I2C1DAT = wData[wlength++];
I2C1CONCLR = 0x28;
}else
{
I2C1DAT = wData[wlength++];
I2C1CONCLR = 0x028;
}
break;
}
case 0xB0:
{
wlength = 0x0;
I2C1DAT = wData[wlength++];
I2C1CONSET = 0x24;
I2C1CONCLR = 0x08;
break;
}
case 0xC0:
{
I2C1CONSET = 0x04;
I2C1CONCLR = 0x28;
break;
}
case 0xC8:
{
wlength = 0x0;
//I2C1CONSET = 0x04;
I2C1CONCLR = 0x28;
break;
}
}

VICVectAddr = 0; // 中断处理结束
}


注:I2C主端是没有问题的,这个不需要再怀疑
N久没来过CSDN了,不知道为什么我最大只能给100分,问题解决后我再开贴给分,谢谢各位师兄们。
...全文
213 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
controstr 2016-03-01
  • 打赏
  • 举报
回复
这个问题有人帮忙解决吗,我试来试去,总是不行
C_Rabbit 2016-03-01
  • 打赏
  • 举报
回复
没有做过这个,爱莫能助
controstr 2016-02-26
  • 打赏
  • 举报
回复
谢谢楼上,这编文章有介绍I2C从模式的数据接收,且配置也有错误,。
woshi_ziyu 2016-02-26
  • 打赏
  • 举报
回复
从设备确实用的比较少呢 可以看一下一下的文章: LPC2200的I2C从模式

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧