This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28377D: 使用28377的CAN模块与外界通信,无法接收到数据

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

基于例程C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2837xd\examples\cpu1\can_loopback,使用CANA,只是将使用的GPIO口改为GPIO4和GPIO5,并将数组ucTXMsgData 和 ucRXMsgData长度改为8个元素,每次发送成功后自动+1,再将判断发送数据与接收数据是否一致的代码注释掉:if((ucTXMsgData[0] != ucRXMsgData[0]) ||(ucTXMsgData[1] != ucRXMsgData[1]))

其他部分不变。GPIO4和GPIO5 (分别对应CANA_TX和CANA_RX) 的信号经过电路变换 符合CAN总线:

然后通过一个usb-can适配器与电脑通信:

运行程序,可以看到电脑收到了数据:

接下来,我让电脑通过这个软件发送数据帧,让DSP接收,就是类似这样:

当然这此之前要先修改c程序,我的改动是:注释掉这两行代码:

HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_TEST;
HWREG(CANA_BASE + CAN_O_TEST) = CAN_TEST_EXL;

这样就不是外部环回模式了。我的理解是,如果DSP成功接收到CAN帧了, 观察ucRXMsgData的变化就知道。

结果是 ucRXMsgData一直不变,好像一直没收到数据?为什么会这样,我认为电路是没问题的,能发就能收,应该是c程序哪里不对,要怎么改。

  • 你好,

    1、loopback模式的话有个寄存器控制的,CAN_TEST的LBACK位。

    2、如果你是测试接收的话应该用can_ex5_simple_receive.c例程啊,这个是单独接收的。

  • 我用了例程can_ex5_simple_receive.c,发送数据:

    前面if(((HWREGH(CANA_BASE + CAN_O_ES) & CAN_ES_RXOK)) == CAN_ES_RXOK)判断成功,单步执行到函数 CAN_readMessage内部,在判断语句 if((msgCtrl & CAN_IF1MCTL_NEWDAT) == CAN_IF1MCTL_NEWDAT)时,不成立,导致  CAN_readDataReg等语句都不执行。观察寄存器CAN_IF2MCTL 的NewDat位,一直为0。所以,为什么要判断NewDat位是否变为1?查28377数据手册,寄存器CAN_IF2MCTL 的NewDat位:
    0 No new data has been written into the data portion of this message
    object by the message handler since the last time when this flag was
    cleared by the CPU.
    1 The message handler or the CPU has written new data into the
    data portion of this message object.

    我的理解:接收就是读取message object的值,而不是写message object的值。NewDat自然不会变为1.

    于是我注释掉了 if((msgCtrl & CAN_IF1MCTL_NEWDAT) == CAN_IF1MCTL_NEWDAT)这个判断条件,终于能执行到函数CAN_readDataReg,可是发现寄存器CAN_IF2MCTL 的DLC域为0,

    所以CAN_readDataReg函数即使执行了,rxMsgData的值也没改变。我又观察内存0x49020,即message object 1 所在位置:

    DATA域也没数据,好像都在说明 我的message RAM没有通过CAN总线收到数据。但是,前面执行的时候

    if(((HWREGH(CANA_BASE + CAN_O_ES) & CAN_ES_RXOK)) == CAN_ES_RXOK)已经判断成功了呀,

    RxOK=1 不就说明message RAM通过CAN总线成功收到了一条message吗?到底怎么回事。

  • NewDat 位置位是指示已接收到新数据(尚未被 CPU 看到)。 当 CPU 读取消息对象时,会重置 NewDat 位。 如果在接收时 NewDat 位已被置位,则置位 MsgLst 以指示先前的数据(CPU 未看到)丢失。