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.

280049Can通讯例程,166行如何禁止lookback,程序正常与上位机通讯,直接将166行屏蔽吗?



  • 你好,禁用测试模式有专门的函数:CAN_disableTestMode(uint32_t base)
    另外,如果要与上位机通信,除了更改测试模式,硬件上还需要有CAN转换芯片进行驱动。
  • 屏蔽66行,使能发送,进入中断status为229,为什么不是发送地址1?
    //#############################################################################
    //
    // FILE: can_ex2_loopback_interrupts.c
    //
    // TITLE: CAN External Loopback with Interrupts Example
    //
    //! \addtogroup driver_example_list
    //! <h1> CAN External Loopback with Interrupts </h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit and receive
    //! messages on the CAN bus. The CAN peripheral is configured to transmit
    //! messages with a specific CAN ID. A message is then transmitted once per
    //! second, using a simple delay loop for timing. The message that is sent is
    //! a 4 byte message that contains an incrementing pattern. A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example sets up the CAN controller in External Loopback test mode.
    //! Data transmitted is visible on the CANTXA/CANATX pin and is received internally
    //! back to the CAN Core.
    //!
    //! \b External \b Connections \n
    //! - None.
    //!
    //! \b Watch \b Variables \n
    //! - txMsgCount - A counter for the number of messages sent
    //! - rxMsgCount - A counter for the number of messages received
    //! - txMsgData - An array with the data being sent
    //! - rxMsgData - An array with the data that was received
    //! - errorFlag - A flag that indicates an error has occurred
    //!
    //
    //#############################################################################
    // $TI Release: F28004x Support Library v1.11.00.00 $
    // $Release Date: Sun Oct 4 15:49:15 IST 2020 $
    // $Copyright:
    // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions
    // are met:
    //
    // Redistributions of source code must retain the above copyright
    // notice, this list of conditions and the following disclaimer.
    //
    // Redistributions in binary form must reproduce the above copyright
    // notice, this list of conditions and the following disclaimer in the
    // documentation and/or other materials provided with the
    // distribution.
    //
    // Neither the name of Texas Instruments Incorporated nor the names of
    // its contributors may be used to endorse or promote products derived
    // from this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"

    //
    // Defines
    //
    #define MSG_DATA_LENGTH 4
    #define TX_MSG_OBJ_ID 1
    #define RX_MSG_OBJ_ID 2

    //
    // Globals
    //
    volatile uint32_t txMsgCount = 0;
    volatile uint32_t rxMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t txMsgData[4];
    uint16_t rxMsgData[4];

    //
    // Function Prototypes
    //
    __interrupt void canISR(void);

    //
    // Main
    //
    void main(void)
    {
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Initialize GPIO and configure GPIO pins for CANTX/CANRX
    //
    Device_initGPIO();
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);

    //
    // Initialize the CAN controller
    //
    CAN_initModule(CANA_BASE);

    //
    // Set up the CAN bus bit rate to 500kHz
    // Refer to the Driver Library User Guide for information on how to set
    // tighter timing control. Additionally, consult the device data sheet
    // for more information about the CAN module clocking.
    //
    CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);

    //
    // Enable interrupts on the CAN peripheral.
    //
    CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
    CAN_INT_STATUS);

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    // This registers the interrupt handler in PIE vector table.
    //
    Interrupt_register(INT_CANA0, &canISR);

    //
    // Enable the CAN interrupt signal
    //
    Interrupt_enable(INT_CANA0);
    CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);

    //
    // Enable CAN test mode with external loopback
    //
    CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);

    //
    // Initialize the transmit message object used for sending CAN messages.
    // Message Object Parameters:
    // Message Object ID Number: 1
    // Message Identifier: 0x1
    // Message Frame: Standard
    // Message Type: Transmit
    // Message ID Mask: 0x0
    // Message Object Flags: Transmit Interrupt
    // Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
    CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
    MSG_DATA_LENGTH);

    //
    // Initialize the receive message object used for receiving CAN messages.
    // Message Object Parameters:
    // Message Object ID Number: 2
    // Message Identifier: 0x1
    // Message Frame: Standard
    // Message Type: Receive
    // Message ID Mask: 0x0
    // Message Object Flags: Receive Interrupt
    // Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
    CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
    MSG_DATA_LENGTH);

    //
    // Initialize the transmit message object data buffer to be sent
    //
    txMsgData[0] = 0x12;
    txMsgData[1] = 0x34;
    txMsgData[2] = 0x56;
    txMsgData[3] = 0x78;

    //
    // Start CAN module operations
    //
    CAN_startModule(CANA_BASE);

    //
    // Loop Forever - A new message will be sent once per second.
    //
    for(;;)
    {
    //
    // Check the error flag to see if errors occurred
    //
    if(errorFlag)
    {
    Example_Fail = 1;
    asm(" ESTOP0");
    }

    //
    // Verify that the number of transmitted messages equal the number of
    // messages received before sending a new message
    //
    if(txMsgCount == rxMsgCount)
    {
    CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
    txMsgData);

    Example_PassCount++;
    }
    else
    {
    errorFlag = 1;
    }

    //
    // Delay 1 second before continuing
    //
    DEVICE_DELAY_US(1000000);

    //
    // Increment the value in the transmitted message data.
    //
    txMsgData[0] += 0x01;
    txMsgData[1] += 0x01;
    txMsgData[2] += 0x01;
    txMsgData[3] += 0x01;

    //
    // Reset data if exceeds a byte
    //
    if(txMsgData[0] > 0xFF)
    {
    txMsgData[0] = 0;
    }
    if(txMsgData[1] > 0xFF)
    {
    txMsgData[1] = 0;
    }
    if(txMsgData[2] > 0xFF)
    {
    txMsgData[2] = 0;
    }
    if(txMsgData[3] > 0xFF)
    {
    txMsgData[3] = 0;
    }
    }
    }

    //
    // CAN ISR - The interrupt service routine called when a CAN interrupt is
    // triggered. It checks for the cause of the interrupt, and
    // maintains a count of all messages that have been transmitted.
    //
    __interrupt void
    canISR(void)
    {
    uint32_t status;

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

    //
    // If the cause is a controller status interrupt, then get the status
    //
    if(status == CAN_INT_INT0ID_STATUS)
    {
    //
    // Read the controller status. This will return a field of status
    // error bits that can indicate various errors. Error processing
    // is not done in this example for simplicity. Refer to the
    // API documentation for details about the error status bits.
    // The act of reading this status will clear the interrupt.
    //
    status = CAN_getStatus(CANA_BASE);

    //
    // Check to see if an error occurred.
    //
    if(((status & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) &&
    ((status & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0))
    {
    //
    // Set a flag to indicate some errors may have occurred.
    //
    errorFlag = 1;
    }
    }

    //
    // 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;
    }

    //
    // Check if the cause is the receive message object 2
    //
    else if(status == RX_MSG_OBJ_ID)
    {
    //
    // Get the received message
    //
    CAN_readMessage(CANA_BASE, RX_MSG_OBJ_ID, rxMsgData);

    //
    // Getting to this point means that the RX interrupt occurred on
    // message object 2, and the message RX is complete. Clear the
    // message object interrupt.
    //
    CAN_clearInterruptStatus(CANA_BASE, RX_MSG_OBJ_ID);

    //
    // Increment a counter to keep track of how many messages have been
    // received. In a real application this could be used to set flags to
    // indicate when a message is received.
    //
    rxMsgCount++;

    //
    // Since the message was received, clear any error flags.
    //
    errorFlag = 0;
    }

    //
    // If something unexpected caused the interrupt, this would handle it.
    //
    else
    {
    //
    // Spurious interrupt handling can go here.
    //
    }

    //
    // 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);
    }

    //
    // End of File
    //
  • 那如果单纯的屏蔽166行,进行测试,进入中断status为229,为什么不是发送地址1?这个产生的中断为什么不是发送中断