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.

[参考译文] TMS320F28379D:CAN TX ISR 示例

Guru**** 2482225 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1449125/tms320f28379d-can-tx-isr-example

器件型号:TMS320F28379D

工具与软件:

有没有介绍如何配置 CAN TX ISR 的示例?

我已成功创建 CAN RX ISR、但我要对其进行修改、以便处理传入和传出消息(mbox 1 = TX、mbox 2 = RX)。

/**
 * This interrupt is triggered whenever a msg is received on CANA mailbox 2
 * or transmitted on CANA mailbox 1
 */
interrupt void CANAISR(void) {

    Uint8 rxCANhead;
    Uint16 rxMsgData[8];
    bool dataAvail;
    Uint32 msgID;
    CAN_MsgFrameType frameType = CAN_MSG_FRAME_EXT;
    Uint32 status;

    tx_struct tx;
    Uint16 txMsgData[8];
    Uint8 msgCtr;

    //
    // Read the CAN interrupt status to find the cause of the interrupt
    //
    status = CAN_getInterruptCause(CANA_BASE);

    //
    // If the cause of the interrupt is the receive mbox 2
    //
    if (status == 2)
    {

        //
        // Get the received message
        //
        dataAvail = CAN_readMessageWithID(CANA_BASE,
                                          2,
                                          &frameType,
                                          &msgID,
                                          rxMsgData);
                                          
...

        //
        // Clear the mbox 2 interrupt.
        //
        CAN_clearInterruptStatus(CANA_BASE, 2);

    // else the cause of the interrupt is the transmit mbox 1
    } else if (status == 1) {

        // if a msg is available on the circular buffer and the mbox isn't
        // busy sending the previous msg
        if ((get_tx0_head() != get_tx0_tail()) &&
           (((HWREGH(CANA_BASE + CAN_O_ES) & CAN_ES_TXOK)) == CAN_ES_TXOK)) {

            get_tx0Entry(get_tx0_tail(), &tx);
            inc_tx0_tail();

            if (tx.id != prevMsgId) {

                // setup the TX mbox with the specified msgid
                CAN_setupMessageObject(CANA_BASE, 1, tx.id, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE, 8);

                prevMsgId = tx.id;
            }

            for (msgCtr=0; msgCtr<8; msgCtr++) {
                txMsgData[msgCtr] = tx.data[msgCtr];
            }

            CAN_sendMessage(CANA_BASE, 1, 8, txMsgData);
        }

        //
        // Clear the mbox 1 interrupt.
        //
        CAN_clearInterruptStatus(CANA_BASE, 1);
    }
    
    //
    // Clear the global interrupt flag for the CAN interrupt line
    //
    CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);

    //
    // Acknowledge this interrupt located in group 9
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

但是、当我尝试触发 CAN TX ISR 时、绝不会触发:

    union CAN_IF1MCTL_REG CAN_IF1MCTL_SHADOW;

    // insert the given tx_struct into the circular buffer
    set_tx0Entry(get_tx0_head(), &tx);
    inc_tx0_head();

    //
    // Wait for busy bit to clear
    //
    while (CanaRegs.CAN_IF1CMD.bit.Busy == 1)
    {
    }

    // Set a flag indicating a msg is available to transmit in order to trigger
    // the TX ISR
    CAN_IF1MCTL_SHADOW.all = CanaRegs.CAN_IF1MCTL.all;
    CAN_IF1MCTL_SHADOW.bit.TxIE = 1;
    CanaRegs.CAN_IF1MCTL.all = CAN_IF1MCTL_SHADOW.all;

如果我只调用 can_sendMessage()而不使用 TX ISR、则运行起来很好:

    CAN_sendMessage(CANA_BASE, 1, 8, txMsgData);

谢谢!

Diane

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

    根据 can_ex2_loopback_interrupts、我可以假设这是不可能的吗?  当有待发送的消息时、不能触发 TX ISR。  仅在传输成功后才可触发呢?

        //
        // Check if the cause is the transmit message object 1
        //
        else if(status == TX_MSG_OBJ_ID)
        {
            //
            // Getting to this point means that the TX interrupt occurred on
            // message object 1, and the message TX is complete.  Clear the
            // message object interrupt.
            //
            CAN_clearInterruptStatus(CANA_BASE, TX_MSG_OBJ_ID);
    
            //
            // Increment a counter to keep track of how many messages have been
            // sent.  In a real application this could be used to set flags to
            // indicate when a message is sent.
            //
            txMsgCount++;
    
            //
            // Since the message was sent, clear any error flags.
            //
            errorFlag = 0;
        }