查看: 2846|回复: 9

[已解决] LPC824与LPC1765通讯的问题

[复制链接]
  • TA的每日心情
    郁闷
    2018-7-24 10:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    20
    最后登录
    2018-7-24
    发表于 2018-7-20 08:14:23 | 显示全部楼层 |阅读模式
    本帖最后由 zzkkll22 于 2018-7-20 08:26 编辑

       进行8片LPC824M201JHI33与LPC1765进行i2c通讯时,在1765做主机地址为0x70先向LPC824M201JHI33发送写地址(地址为0x01-0x08),发送四个字节后,不停止,直接再发送读地址,若此时LPC824M201JHI33回答一个字节,若此字节小于0x80如0x55,则数据线一直不释放,如图所示

    数据不释放

    数据不释放
    若回答字节大于0x80如0xAA,则此包数据正常结束如图所示:
    TIM图片20180720082001.jpg
    请问为什么不能回答小于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
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20067
    最后登录
    2024-4-28
    发表于 2018-7-20 09:13:36 | 显示全部楼层
    一对一交互是可行的吗?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-7-24 10:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    20
    最后登录
    2018-7-24
     楼主| 发表于 2018-7-20 09:45:00 | 显示全部楼层
    小恩GG 发表于 2018-7-20 09:13
    一对一交互是可行的吗?

    现在就是一对一,一片1765,和一片824,只要回0x80以上的数据那就能正常结束
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20067
    最后登录
    2024-4-28
    发表于 2018-7-20 13:54:46 | 显示全部楼层
    zzkkll22 发表于 2018-7-20 09:45
    现在就是一对一,一片1765,和一片824,只要回0x80以上的数据那就能正常结束 ...

    okay,你现在的问题是LPC824 回复给LPC1765 (master)小于0x80, LPC1765就会一直不释放,而不释放的意思就是总线上电平保持不变,我这样理解对吗?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-7-24 10:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    20
    最后登录
    2018-7-24
     楼主| 发表于 2018-7-20 14:46:18 | 显示全部楼层
    本帖最后由 zzkkll22 于 2018-7-20 16:54 编辑
    小恩GG 发表于 2018-7-20 13:54
    okay,你现在的问题是LPC824 回复给LPC1765 (master)小于0x80, LPC1765就会一直不释放,而不释放的意思 ...

    总线数据线在发送结束位后应该拉高,就像我发的第二张图片。但实际上是第一张图片,绿色数据一直是低的,不拉高。实际上时钟线上已经给出结束位的时钟,但是数据线就是没有拉高。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20067
    最后登录
    2024-4-28
    发表于 2018-7-23 09:49:48 | 显示全部楼层
    zzkkll22 发表于 2018-7-20 14:46
    总线数据线在发送结束位后应该拉高,就像我发的第二张图片。但实际上是第一张图片,绿色数据一直是低的, ...

    Okay,那调试代码过程中有没有出现代码卡在哪一行或有其他什么异常情况出现呢?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-7-24 10:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    20
    最后登录
    2018-7-24
     楼主| 发表于 2018-7-23 15:54:09 | 显示全部楼层
    小恩GG 发表于 2018-7-23 09:49
    Okay,那调试代码过程中有没有出现代码卡在哪一行或有其他什么异常情况出现呢? ...

    没有异常出现,同样的代码,回0x55就不行,回0xAA就可以,就是回的数据不一样,测试过程也没有出现其他异常.
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20067
    最后登录
    2024-4-28
    发表于 2018-7-23 17:35:27 | 显示全部楼层
    zzkkll22 发表于 2018-7-23 15:54
    没有异常出现,同样的代码,回0x55就不行,回0xAA就可以,就是回的数据不一样,测试过程也没有出现其他异 ...

    Okay,我建议使用LPC1765和LPC824对应的LPCOpen libary中的I2C 测试代码重新测试一下
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-7-24 10:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    20
    最后登录
    2018-7-24
     楼主| 发表于 2018-7-24 09:00:46 | 显示全部楼层
    小恩GG 发表于 2018-7-23 17:35
    Okay,我建议使用LPC1765和LPC824对应的LPCOpen libary中的I2C 测试代码重新测试一下  ...

    您能给个LPC1765和LPC824对应的LPCOpen libary么?我测试一下。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20067
    最后登录
    2024-4-28
    发表于 2018-7-24 17:16:38 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-29 05:46 , Processed in 0.154799 second(s), 33 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表