CAN应答错误怎么解决,CAN标识符应该怎么设置

2019-03-24 13:33发布

CAN应答错误,请问如何解决?是不是CAN标识符设置不对,应该如何配置标识符,或其他,发送文件参数。

[ 本帖最后由 benbending 于 2012-8-28 08:59 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
benbending
2019-03-25 06:10
#include  "config.h"

#include  "serial_com.h"

#include  "can_deal.h"





volatile unsigned long g_ulIntCount = 0;



//*****************************************************************************

//

// Counters that are used to count the number of messages on each of the

// three message objects that are used in this example.

//

//*****************************************************************************

volatile unsigned long g_ulMsg1Count = 0;

volatile unsigned long g_ulMsg2Count = 0;

volatile unsigned long g_ulMsg3Count = 0;



//*****************************************************************************

//

// A flag to indicate that CAN controller message object 3 has sent a message.

//

//*****************************************************************************

volatile unsigned long g_bMsgObj3Sent = 0;



//*****************************************************************************

//

// A flag to indicate that some transmission error occurred.

//

//*****************************************************************************

volatile unsigned long g_bErrFlag = 0;



//*****************************************************************************

//

// CAN message objects that will hold the separate CAN messages.  These could

// also be allocated on the stack but be careful because these structures

// each take about 20 bytes.

//

//*****************************************************************************

tCANMsgObject g_sCANMsgObject1;

tCANMsgObject g_sCANMsgObject2;

tCANMsgObject g_sCANMsgObject3;



//*****************************************************************************

//

// Message buffers that hold the contents of the 4 different messages that

// are being transmitted.  Each one is a different length.

//

//*****************************************************************************

unsigned char g_ucMsg1[4] = { 0, 0, 0, 0 };

unsigned char g_ucMsg2[5] = { 2, 2, 2, 2, 2 };

unsigned char g_ucMsg3[6] = { 3, 3, 3, 3, 3, 3 };

unsigned char g_ucMsg4[8] = { 4, 4, 4, 4, 5, 5, 5, 5 };



tCANBitClkParms CANBitClkSettings[] =

{

    {7, 2, 1, 1},                                                       /* CANBAUD_1M   */

    {14, 5, 2, 1},                                                      /* CANBAUD_500K */

    {14, 5, 2, 2},                                                      /* CANBAUD_250K */

    { 7, 2, 1, 8}, //{14, 5, 2, 4},    {29,10,1,2},                   /* CANBAUD_125K */

    {14, 5, 2, 5},                                                      /* CANBAUD_100k */

    {14, 5, 2, 10},                                                     /* CANBAUD_50k  */

    {13, 6, 2, 20},                                                     /* CANBAUD_25k  */

    {13, 6, 2, 25},                                                     /* CANBAUD_20k  */

    {13, 6, 2, 50},                                                     /* CANBAUD_10k  */

    {13, 6, 2, 100},                                                    /* CANBAUD_5k   */

    {13, 6, 2, 200},                                                    /* CANBAUD_2k5  */

};



//*****************************************************************************

//

// 函数配置UART0 显示例程运行信息

// 波特率:115200;数据位:8位;校验位:无;停止位:1位

//

//*****************************************************************************

void

InitConsole(void)

{

    //

    // Enable GPIO port A which is used for UART0 pins

    //

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);



    //

    // Configure the pin muxing for UART0 functions on port A0 and A1.

    // This step is not necessary if your part does not support pin muxing.

    //

    GPIOPinConfigure(GPIO_PA0_U0RX);

    GPIOPinConfigure(GPIO_PA1_U0TX);



    //

    // Select the alternate (UART) function for these pins.

    //

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);



    //

    // Initialize the UART for console I/O.

    //

    UARTStdioInit(0);

}



//*****************************************************************************

//

// This function prints some information about the CAN message to the

// serial port for information purposes only.(ulMsgObj即报文对象的编号)

//

//*****************************************************************************

void

PrintCANMessageInfo(tCANMsgObject *pCANMsg, unsigned long ulMsgObj)

{

    unsigned int uIdx;



    UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ulMsgObj,

               pCANMsg->ulMsgID);

    for(uIdx = 0; uIdx < pCANMsg->ulMsgLen; uIdx++)

    {

        UARTprintf("%02X ", pCANMsg->pucMsgData[uIdx]);

    }

    UARTprintf(" ");

}



//*****************************************************************************

//

// 软件延时函数

//

//*****************************************************************************

void

SimpleDelay(void)

{

    //

    // Delay cycles for 1 second

    //

    SysCtlDelay(16000000 / 3);

}



//*****************************************************************************

//

// This function is the interrupt handler for the CAN peripheral.  It checks

// for the cause of the interrupt, and maintains a count of all messages that

// have been transmitted.

//

//*****************************************************************************

void

CANIntHandler(void)

{

    unsigned long ulStatus;

    unsigned long ulNewData,ulTxReQuest,ulMsgVal;

           unsigned long temp;

    //

    // Read the CAN interrupt status to find the cause of the interrupt

    //

    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);



    //

    // If the cause is a controller status interrupt, then get the status

    //

    if(ulStatus == CAN_INT_INTID_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.  If the

        // CAN peripheral is not connected to a CAN bus with other CAN devices

        // present, then errors will occur and will be indicated in the

        // controller status.

        //

        ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

        temp = HWREG(CAN0_BASE + CAN_O_ERR);

        ulTxReQuest = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST);                     

                              ulNewData   = CANStatusGet(CAN0_BASE ,CAN_STS_NEWDAT);

                              ulMsgVal    = CANStatusGet(CAN0_BASE ,CAN_STS_MSGVAL);

        //

        // Set a flag to indicate some errors may have occurred.

        //

        g_bErrFlag = 1;

    }



    //

    // Check if the cause is message object 1, which is used for sending

    // message 1.

    //

    else if(ulStatus == 1)

    {

        //

        // 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.

        //

        CANIntClear(CAN0_BASE, 1);



        //

        // 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.

        //

        g_ulMsg1Count++;



        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }



    //

    // Check if the cause is message object 2, which is used for sending

    // message 2.

    //

    else if(ulStatus == 2)

    {

        //

        // Getting to this point means that the TX interrupt occurred on

        // message object 2, and the message TX is complete.  Clear the

        // message object interrupt.

        //

        CANIntClear(CAN0_BASE, 2);



        //

        // 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.

        //

        g_ulMsg2Count++;



        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }



    //

    // Check if the cause is message object 3, which is used for sending

    // messages 3 and 4.

    //

    else if(ulStatus == 3)

    {

        //

        // Getting to this point means that the TX interrupt occurred on

        // message object 3, and a message TX is complete.  Clear the

        // message object interrupt.

        //

        CANIntClear(CAN0_BASE, 3);



        //

        // 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.

        //

        g_ulMsg3Count++;



        //

        // 报文对象3的报文发送完毕标志设置,

        // 这个标志能使主程序知道何时能用报文对象3发送另外一个报文

        //

        g_bMsgObj3Sent = 1;



        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }



    //

    // Otherwise, something unexpected caused the interrupt.  This should

    // never happen.

    //

    else

    {

        //

        // Spurious interrupt handling can go here.

        //

    }

}



//*****************************************************************************

//

// Configure the CAN and enter a loop to transmit periodic CAN messages.

//

//*****************************************************************************

int

main(void)

{

    //

    // Set the clocking to run directly from the external crystal/oscillator.

    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the

    // crystal on your board.

    //

    jtagWait();                                             // 防止JTAG失效,重要!

    clockInit();                                            // 时钟初始化:晶振,6MHz

    board_initialize();                                     // 初始化



    //

    // Set up the serial console to use for displaying messages.  This is

    // just for this example program and is not needed for CAN operation.

    //

    InitConsole();



    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);                               // 使能GPIOD系统外设

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);                                // 使能CAN控制器系统外设

    GPIOPinConfigure(GPIO_PA6_CAN0RX);

    GPIOPinConfigure(GPIO_PB5_CAN0TX);

    GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_6 );

    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_5 );

        

    CANInit(CAN0_BASE);                                                        // 初始化CAN节点

    CANBitTimingSet(CAN0_BASE,

                  (tCANBitClkParms *)&CANBitClkSettings[CANBAUD_125K]);      // 对 CAN控制器位时序进行配置

    CANEnable(CAN0_BASE);                                                      // 使能CAN控制器        



    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_STATUS | CAN_INT_ERROR ); // 使能CAN控制器中断源

    IntEnable(INT_CAN0);                                                       // 使能CAN控制器中断(to CPU)

    IntMasterEnable();                                                         // 使能中断总开关



    // 初始化报文对象1,使其能发送CAN报文1

    // 这个报文对象没有被多个报文共用,因此只需初始化1次

    // 且能用相同的标识符重复多次发送报文

    //

    g_sCANMsgObject1.ulMsgID = 0x0001;

    g_sCANMsgObject1.ulMsgIDMask = 0;

    g_sCANMsgObject1.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    g_sCANMsgObject1.ulMsgLen = sizeof(g_ucMsg1);

    g_sCANMsgObject1.pucMsgData = g_ucMsg1;



    //

    // 初始化报文对象2,使其能发送CAN报文2

    // 这个报文对象没有被多个报文共用,因此只需初始化1次

    // 且能用相同的标识符重复多次发送报文

    //

    g_sCANMsgObject2.ulMsgID = 0x2001;

    g_sCANMsgObject2.ulMsgIDMask = 0;

    g_sCANMsgObject2.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    g_sCANMsgObject2.ulMsgLen = sizeof(g_ucMsg2);

    g_sCANMsgObject2.pucMsgData = g_ucMsg2;



    //

    // 进入循环发送报文,四个报文发送的时间间隔是1秒

    // 这四个报文的内容每当在下一次循环前更改一次

    //

    for(;;)

    {

        PrintCANMessageInfo(&g_sCANMsgObject1, 1);          //显示报文对象1的信息

        CANMessageSet(CAN0_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);





        PrintCANMessageInfo(&g_sCANMsgObject2, 2);

        CANMessageSet(CAN0_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);



        //

        // 调用报文对象3发送报文3,这时它每次用前都需初始化1次,

        // 因为报文对象3由2个不同的报文所共享

        //

        g_sCANMsgObject3.ulMsgID = 0x3001;

        g_sCANMsgObject3.ulMsgIDMask = 0;

        g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;

        g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg3);

        g_sCANMsgObject3.pucMsgData = g_ucMsg3;



        //

        // 清除报文发送完毕标志,

        // 这个标志用来指示报文对象3报文发送完毕,

        // 它将在报文发送完毕后置位

        g_bMsgObj3Sent = 0;



        //

        // Now send message 3 using CAN controller message object 3.  This is

        // the first message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject3, 3);

        CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);



        //

        // 等待报文3发送完毕,也即等待报文对象3的中断,因为这是需要再次用它来发送另外一个报文

        //

        while(!g_bMsgObj3Sent)

        {

        }



        //

        // 再次用报文对象3发送报文4,这时有需要初始化一次

        //

        g_sCANMsgObject3.ulMsgID = 0x3002;

        g_sCANMsgObject3.ulMsgIDMask = 0;

        g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;

        g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg4);

        g_sCANMsgObject3.pucMsgData = g_ucMsg4;



        //

        // Now send message 4 using CAN controller message object 3.  This is

        // the second message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject3, 3);

        CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);



        //

        // Wait 1 second before continuing

        //

        SimpleDelay();



        //

        // Check the error flag to see if errors occurred

        //

        if(g_bErrFlag)

        {

            UARTprintf(" error - cable connected? ");

        }

        else

        {

            //

            // If no errors then print the count of message sent

            //

            UARTprintf(" total count = %u ",

                       g_ulMsg1Count + g_ulMsg2Count + g_ulMsg3Count);

        }



        //

        //  更改上次发给报文的数据

        //

        (*(unsigned long *)g_ucMsg1)++;

        (*(unsigned long *)g_ucMsg2)++;

        (*(unsigned long *)g_ucMsg3)++;

        (*(unsigned long *)&g_ucMsg4[0])++;

        (*(unsigned long *)&g_ucMsg4[4])--;

    }



    //

    // Return no errors

    //

//    return(0);                 //若删去它则程序不能正常运行

}

这是例程,运行后结果还是应答错误。

一周热门 更多>

相关问题

    相关文章