在线时间3 小时
UID1130800
注册时间2014-12-1
NXP金币0
TA的每日心情 | 郁闷 2018-7-24 10:39 |
---|
签到天数: 2 天 [LV.1]初来乍到
新手上路
- 积分
- 20
- 最后登录
- 2018-7-24
|
本帖最后由 zzkkll22 于 2018-7-20 08:26 编辑
进行8片LPC824M201JHI33与LPC1765进行i2c通讯时,在1765做主机地址为0x70先向LPC824M201JHI33发送写地址(地址为0x01-0x08),发送四个字节后,不停止,直接再发送读地址,若此时LPC824M201JHI33回答一个字节,若此字节小于0x80如0x55,则数据线一直不释放,如图所示
数据不释放
若回答字节大于0x80如0xAA,则此包数据正常结束如图所示:
请问为什么不能回答小于0x80的数据。其中824和1765i2c的数据发送和数据接收都在i2c中断服务程序中进行的,我们的协议要求,主机发送一串数据之后,从机必须回答一个数据,来确定从机收到的数据是否正确,因为有多个I2C,所以在主机发送一串数据之后不停止I2C,直接转为主收方式,避免I2C停止后被别的主机抢占总线,回答不能第一时间收到,等主机收到回答后再发送停止,释放总线,此次通讯正常结束。
824的中断服务程序代码:
void I2C_IRQHandler(void)
{
uint32_t INTStatValue,StatValue;
StatValue =LPC_I2C->STAT;
INTStatValue =LPC_I2C->INTSTAT;
if(INTStatValue & MSTPENDINGEN)
{
if(StatValue&1)//主机挂起
{
switch((StatValue>>1) &0x07)
{
case 0://主机空闲可以启动下次发码
{
if(I2CSIG==I2C_SENDDATA)
{
LPC_I2C->MSTDAT = I2C_SLV_WRITE;
}
LPC_I2C->MSTCTL = (1 << 1) ; /* 发送起始位 */
I2State = I2C_STARTED;
break;
}
case 1://主接模式:地址和读已得到应答,接受准备就绪,开始接收数据
{
if(I2State != I2C_STOPED)
{
*MasterR = LPC_I2C->MSTDAT;//主模式只接受一个字节就可以
EvtPostQue(MASTER_STO, I2C_TASK);//本次通讯结束,去大循环更改为从模式并处理收到的数据
I2State = I2C_STOPED; LPC_I2C->MSTCTL = (1 <<2);
LPC_I2C->INTENCLR=INTStatValue;
}
break;
}
case 2://主发模式:地址和读已得到应答,可以发送数据
{
if (WrIndex != I2CWriteLength)
{
LPC_I2C->MSTDAT = *(I2CMaster + WrIndex);
WrIndex++;
LPC_I2C->MSTCTL = (1 << 0);
}
else
{
LPC_I2C->MSTCTL = (1 << 1) ;
LPC_I2C->MSTDAT = I2C_SLV_READ; I2CSIG=I2C_REDATA;//转为主收
}
break;
}
case 3:
{
// break;
}
case 4:
{
// break;
}
default:
{
LPC_I2C->INTENCLR=INTStatValue;
I2CStop();
break;
}
}
}
}
else if(INTStatValue & SLVPENDINGEN)//从机挂起
{
switch((StatValue>>9) &0x03)
{
case 0:// ADDR + R/W 检测成功
{ if((LPC_I2C->SLVDAT&0x01)==0)
{
I2CReadLength = I2C_BUFSIZE + 2; //从接收开始
CHECK_SUM = 0;
RdIndex = 0;
I2State = I2C_STARTED;
}
LPC_I2C->SLVCTL = (1 << 0);
break;
}
case 1://接收数据可用
{
if(RdIndex != I2CReadLength)//最多接收
{
*(I2CSlave + RdIndex) = LPC_I2C->SLVDAT;
if(RdIndex>=2 && RdIndex<I2CReadLength-1)
{
CHECK_SUM += *(I2CSlave + RdIndex);
}
RdIndex++;
if(RdIndex == 3)//收下了主机地址和数据长度
{
I2CReadLength = *(I2CSlave + 1) + 2;
}
if(RdIndex == I2CReadLength)
{
EvtPostQue(SLAVE_STO, I2C_TASK);//接收结束 从模式
}
LPC_I2C->SLVCTL = (1 << 0);
}
else
LPC_I2C->SLVCTL = (1 << 1);
break;
}
case 2://数据可以发送:发送数据
{
if(I2State != I2C_STOPED)
{
if(CHECK_SUM == *(I2CSlave + RdIndex - 1))
{
LPC_I2C0->SLVDAT = 0xAA;
I2Cdata_Add();//本次接收结束,将收到的数据放入缓冲区
}
else
{
LPC_I2C0->SLVDAT = 0x55;
}
I2State = I2C_STOPED;
LPC_I2C->SLVCTL = 1<<0;
}
else
{
LPC_I2C->SLVCTL = 1<<1;
}
break;
}
}
}
else if( (LPC_I2C->STAT & (1 << 15)) )
{
LPC_I2C->STAT |= (1 << 15); /* 清除取消选择标志位 */
}
}
最佳答案
LPC17xx LPCOpen:
http://www.nxp.com/support/devel ... rm-lpc17xx
|
|