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.

[参考译文] TMS320F28065:eCAN 邮箱接收到错误消息

Guru**** 2500435 points
Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1265579/tms320f28065-ecan-mailbox-receives-the-wrong-message

器件型号:TMS320F28065
主题中讨论的其他器件:C2000WARE

尊敬的专家:

我有一个关于邮箱数据接收的问题。

为了测试验收掩码、我修改了一个 back2bak 演示代码(C:\software\c2000ware\C2000Ware_4_03_00_00\device_support\f2806x\examples\c28\eCAN-back2back)。 我将邮箱30和邮箱31设置为接收邮箱、邮箱13和邮箱15设置为 发送邮箱。 邮箱30从邮箱13接收邮件。  邮箱31从邮箱15接收邮件。 我没有修改 InitECana()和 InitECanGpio() 。

这是代码  

#define REC_MBOX31_MSGID_ID        0x784UL
#define REC_MBOX31_LOCAL_FILTER    0x0003FFFF
#define REC_MBOX30_MSGID_ID        0x785UL
#define REC_MBOX30_LOCAL_FILTER    0x0003FFFF

#define REC_MBOX_LAM_LAMI         0x80000000UL
#define REC_MBOX_MSGIN_AME        0x40000000UL

#define REC_MBOX30_LAM_REG        ((REC_MBOX30_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_LAM_LAMI)
#define REC_MBOX30_MSGID_REG      ((REC_MBOX30_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_MSGIN_AME)

#define REC_MBOX31_LAM_REG        ((REC_MBOX31_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_LAM_LAMI)
#define REC_MBOX31_MSGID_REG      ((REC_MBOX31_MSGID_ID<<18)&0x1FFFFFFF | REC_MBOX_MSGIN_AME)

void main(void)
{
    Uint16  j;

    Uint16 i;

    struct ECAN_REGS ECanaShadow;

    InitSysCtrl();

    InitECanGpio();

    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();

    MessageReceivedCount = 0;
    ErrorCount = 0;
    PassCount = 0;

    InitECana();            // Initialize eCAN-A module


    //transmit setting
    ECanaMboxes.MBOX13.MSGID.all = REC_MBOX30_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX15.MSGID.all = REC_MBOX31_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX30.MSGID.all = REC_MBOX30_MSGID_REG;// 0x9555AAAF;//
    ECanaMboxes.MBOX31.MSGID.all = REC_MBOX31_MSGID_REG;//0x9555AAAF;//

    ECanaRegs.CANMD.all = 0xC0000000;//CHANGE

    ECanaMboxes.MBOX13.MSGCTRL.bit.DLC = 8;

    ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;

    ECanaMboxes.MBOX13.MDL.all = 0x22222222;
     ECanaMboxes.MBOX13.MDH.all = 0x22334455;


     ECanaMboxes.MBOX15.MDL.all = 0x11111111;
     ECanaMboxes.MBOX15.MDH.all = 0x11223344;

    ECanaRegs.CANTA.all = 0xFFFFFFFF;    // Clear all TAn bits
    ECanaRegs.CANRMP.all = 0xFFFFFFFF;   // Clear all RMPn bits

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

    ECanaLAMRegs.LAM30.all = REC_MBOX30_LAM_REG;
    ECanaLAMRegs.LAM31.all = REC_MBOX31_LAM_REG;

    ECanaRegs.CANOPC.all  = 0xC0000000;  //change

    //
    EALLOW;

    ECanaRegs.CANGIM.all = 0x00000000;

    ECanaRegs.CANMIM.all = 0xFFFFFFFF;



    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.STM = 1;    // Configure CAN for self-test mode
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;


    ECanaRegs.CANMD.all = 0xC0000000;
    ECanaRegs.CANME.all = 0xC000A000;

    //
    // Begin transmitting
    //
    for(;;)
    {
        //
        // Set TRS for all transmit mailboxes
        //
        ECanaRegs.CANTRS.all = 0x0000A000;
        
        while(ECanaRegs.CANTA.all != 0x0000A000 )
        {


        }
        ECanaRegs.CANTA.all = 0x0000A000;

        j=30;

            mailbox_read(j);         

    }
}

void
InitECanaGpio(void)
{
    EALLOW;

    //
    // Enable internal pull-up for the selected CAN pins
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;   // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;   // Enable pull-up for GPIO31 (CANTXA)

    //
    // Set qualification for selected CAN pins to asynch only
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    //
    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)

    //
    // Configure eCAN-A pins using GPIO regs
    // This specifies which of the possible GPIO pins will be eCAN functional 
    // pins.
    //
    
    //
    // Configure GPIO30 for CANRXA operation
    //
    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    
    
    //
    // Configure GPIO31 for CANTXA operation
    //
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;

    EDIS;
}
#endif

void
InitECana(void)
{
    //
    // Create a shadow register structure for the CAN control registers. 
    // This is needed, since only 32-bit access is allowed to these registers. 
    // 16-bit access to these registers could potentially corrupt the register 
    // contents or return false data.
    //
    struct ECAN_REGS ECanaShadow;
    
    //
    // Setup variables to initialize mailboxes to zero
    //
    int16 mboxCount;
    volatile struct MBOX *Mailbox = (void *) 0x6100;

    EALLOW;     // EALLOW enables access to protected bits

    //
    // Configure eCAN RX and TX pins for CAN operation using eCAN regs
    //
    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

    //
    // Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
    // HECC mode also enables time-stamping feature
    //
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    //
    // Initialize all registers of the mailboxes to zero
    // Some bits of MSGCTRL register come up in an unknown state. 
    // For proper operation, all bits (including reserved bits) of MSGCTRL must
    // be initialized to zero
    //
    for(mboxCount=0; mboxCount<32; mboxCount++)
    {
        Mailbox->MSGID.all = 0;
        Mailbox->MSGCTRL.all = 0;
        Mailbox->MDH.all = 0;
        Mailbox->MDL.all = 0;
        Mailbox = Mailbox + 1;
    }

    //
    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    //  as a matter of precaution.
    //
    ECanaRegs.CANTA.all = 0xFFFFFFFF;    // Clear all TAn bits

    ECanaRegs.CANRMP.all = 0xFFFFFFFF;   // Clear all RMPn bits

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

    //
    // Configure bit timing parameters for eCANA
    //
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
    //
    // Wait until the CPU has been granted permission to change the 
    // configuration registers
    //
    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );   // Wait for CCE bit to be set

    ECanaShadow.CANBTC.all = 0;
    
    //
    // The following block is for 90 MHz SYSCLKOUT. 
    // (45 MHz CAN module clock Bit rate = 1 Mbps)
    // See Note at end of file.
    //
    ECanaShadow.CANBTC.bit.BRPREG = 2;
    ECanaShadow.CANBTC.bit.TSEG1REG = 10;
    ECanaShadow.CANBTC.bit.TSEG2REG = 2;

    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    //
    // Wait until the CPU no longer has permission to change the 
    // configuration registers
    //
    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );// Wait for CCE bit to be  cleared

    //
    //  Disable all Mailboxes
    //
    ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs

    EDIS;
}
#endif // endif DSP28_ECANA

如果设置正确、邮箱30应该接收到 0x22222222和 0x2233455。  邮箱30应接收0x11111111 和0x11223344

但当我调试时、mailbox30有时会收到 0x22222222和0x2233455 、有时会收到 0x11111111 和0x11223344 。 似乎邮箱30接收到两个发送邮箱的消息。

但是、如果我注释代码 ECanaRegs.CANOC.all = 0xC0000000;、问题就不会再发生了。

您能帮我找出哪里出了问题吗?

除了我想要一个关于接受屏蔽的演示、因为我认为这个代码中的设置可能是错误的。 我在 SPRA876B 中提到的 c2000ware_1_00_01_00  中进行了下载、但在 C:\ti\c2000\C2000Ware_1_00_01_00\device_support\F2833x\examples 中找不到 CAN_LAM 示例。 您能举个例子吗?

代码位于附件中。

感谢您的帮助!!

此致

奇田市

e2e.ti.com/.../ecan_5F00_test.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kita,

                   SPRA876中有一个示例显示了接受过滤的工作原理。 示例不是 C2000ware 的一部分。 需要从 http://www.ti.com/lit/zip/spra876下载它们。此外、验收屏蔽滤波等功能可使用两个单独的节点进行更好的测试、而不是使用自检模式在同一节点内进行测试。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Hareesh。

    感谢您的建议。

    我对代码进行了修改、当前代码没有  接受屏蔽滤波、但 问题是  静止的 量。

    我确信 邮箱13的标识符等于  邮箱 30的标识符、   邮箱15的 标识符等于邮箱 的标识符  31.

    有时、邮箱30接收邮箱15的数据。

    有时、邮箱30接收邮箱13的数据、正确的数据。

    然后,在 CANTRS 被清除之前,我尝试清除 mailbox30和 mailbox31的 CANRMP。 问题不再出现。 邮箱30接收邮箱13的数据、正确的数据。

    但是、如果我添加"ECanaRegs.CANRMP.All = 0xC0000000"的注释、问题仍然存在。

    我对这感到困惑。

    1. 根据 TRM、接收邮箱只接收对应标识符的数据信息。 如果 CANOPC 被启用、 未读消息就不会被写覆盖。

     在消息从邮箱复制后、邮箱的 CANRMP 位必须被清除。 否则、邮箱不能接收下一条消息(假定使用了 OPC 特性)。  Clear 命令可直接在原始寄存器中执行、无需使用影子。

    在这个代码中、邮箱30和邮箱31的 CANOPC 都被启用。  为什么邮箱30有时会收到错误的值???  

    2. 如果 邮箱的 CANRMP 位没有 被清除、邮箱将无法接收下一条消息(假定使用了 OPC 功能)。   

    但在原始代码中,邮箱30仍然可以接收消息(有时是错误的),即使 CANRMP 未被清除。

    您能告诉我原因吗?

    3.为什么 CANRMP 被清除,问题不再发生?

    e2e.ti.com/.../ecan_5F00_test_5F00_new.zip

    代码位于附件中。

    感谢您的帮助!

    此致

    奇田市

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kita,

                 读取数据后必须立即将 CANRMP 位清零。 这是使用该模块的正确方法。

    1.  根据 TRM、接收邮箱将只接收标识符对应的数据信息。 如果启用了 CANOPC, 将防止未读消息被覆盖。

    是的。

     邮箱的 CANRMP-bit 必须在从邮箱复制消息后清除。 否则、邮箱不能接收下一条消息(假定使用了 OPC 特性)。  清除命令可以直接执行到原始寄存器中、无需影子。

    如果所有32位都未写入、则必须使用影子寄存器。

    在该代码中,邮箱30和邮箱31的 CANOPC 均已启用。  为什么邮箱30有时会收到错误的值???  [/报价]

    如前所述、请尝试在两个节点之间进行通信、而不是在自检模式下进行通信。

    但在原始代码中,邮箱30仍然可以接收消息(有时是错误的),即使 CANRMP 未被清除。

    您能告诉我原因吗?

    [/报价]

    这可能是在自检模式中没有明确定义该行为。

    代码位于附件中。
    [/quote]

    调试代码不是我们可以在 e2e 中支持的代码。 SPRA876中的所有示例均为经过测试的示例。 请尝试一下。  

    [/quote][/quote]