目录

  • TC397_CAN简介
  • CAN Loop-Back
  • CAN Transceiver
  • CAN00 标准帧和扩展帧
  • 微信公众号

TC397_CAN简介

不同于TC297的MultiCAN+, TC397的CAN模块唤作MCMCAN:

  • 实现了Bosch的M_CAN, 遵循ISO 11898-1(Classical CAN, CAN FD)和ISO 11898-4(Time-triggered CAN, TTCAN)
  • TTCAN协议级别1和级别2完全硬件实现
  • 支持事件同步时间触发通讯
  • CAN错误记录
  • AUTOSAR优化, SAE J1939优化
  • 改进的验收过滤
  • 接收高优先级消息时的单独信令
  • MCMCAN 0/1/2模块由M_CAN作为CAN节点组成, 每个模块4个节点, 共计12路CANFD
  • 主CPU直接消息RAM访问
  • 一个可配置的消息RAM(configurable Message RAM)用于储存发送或者接收的消息, 多个M_CAN共享相同的消息RAM
  • 可编程回环测试模式
  • 可屏蔽的模块中断
  • 8/16/32位通用从接口,用于连接客户特定的主机CPU
  • 每个CAN节点有两个可配置的接收FIFO, 接收高优先级消息时的单独信令(signaling), 多达64个专用接收缓冲, 多达32个专用发送缓冲, 可配置的发送FIFO/Queue/Event FIFO

TC397的MCMCAN取代之前TC297的MultiCAN+有下面值得注意的改变:

  • 消息对象被可配置的消息RAM取代
  • 支持CAN上的调试

其它可参考 TC297 MultiCAN+

综述如下:

资源如下:

Parameter CAN0 CAN1 CAN2
Node size in byte 1024 1024 1024
Number of CAN Nodes 4 4 4
Number of TTCAN Nodes 1
RAM size in byte 32768 16384 16384
Maximum Number of Standard ID Filter Messages per node 128 128 128
Maximum Number of Extended ID Filter Messages per node 64 64 64
Maximum Number of RxFIFO structures per node 2 2 2
Maximum Number of Messages in a Rx buffer per node 64 64 64
Maximum Number of Tx Event Messages per node 32 32 32
Maximum Number of Tx Messages in a Tx Buffer per node 32 32 32
Maximum number of trigger messages per TTCAN node 64

官方的评估板, 默认仅仅引出了CAN00:

  • P20.7, CAN00 Receive Input B
  • P20.8, CAN00 Transmit Output

CAN的IO可以在 Infineon-AURIX_TC39x-UserManual-v01_00-EN.pdf 第40.4节 MCMCAN的Connectivity查看, 以CAN00为例, 有下面引脚复用:

官方评估板选了P20.7和P20.8来用

CAN Loop-Back

参考 MCMCAN_1 for KIT_AURIX_TC397_TFT

本例MCMCAN用于在两个节点之间交换数据,实现在使用环回模式的同一设备中. 环回模式下, 无需外部引脚.

CAN0发消息给CAN1, 发送中断点亮LED表示发送成功, 一旦CAN消息被CAN1接收, 接收中断中比较接收和发送的消息内容, 一致就点亮另一颗LED表示接收成功:

  • 初始化MODULE_CAN0模块
  • 初始化发送CAN00节点, 回环模式, 发送中断
  • 初始化接收CAN01节点, 回环模式, 接收中断
  • 初始化滤波器
  • 发送消息
  • 发送中断点灯, 接收中断比较消息, 成功点灯

Cpu0_Main.c代码如下:

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"#include <stdio.h>
#include <string.h>
#include "Ifx_Types.h"
#include "IfxCan_Can.h"
#include "IfxCan.h"
#include "IfxCpu_Irq.h"
#include "IfxPort.h"IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;#define LED0                     &MODULE_P13,0
#define LED1                     &MODULE_P13,1#define CAN_MESSAGE_ID              (uint32)0x777           /* Message ID that will be used in arbitration phase    */
#define INVALID_RX_DATA_VALUE       0xA5                    /* Used to invalidate RX message data content           */
#define INVALID_ID_VALUE            (uint32)0xFFFFFFFF      /* Used to invalidate RX message ID value               */
#define ISR_PRIORITY_CAN_TX         2                       /* Define the CAN TX interrupt priority                 */
#define ISR_PRIORITY_CAN_RX         1                       /* Define the CAN RX interrupt priority                 */
#define TX_DATA_LOW_WORD            (uint32)0xC0CAC01A      /* Define CAN data lower word to be transmitted         */
#define TX_DATA_HIGH_WORD           (uint32)0xBA5EBA11      /* Define CAN data higher word to be transmitted        */
#define MAXIMUM_CAN_DATA_PAYLOAD    2                       /* Define maximum classical CAN payload in 4-byte words *//*********************************************************************************************************************/
/*--------------------------------------------------Data Structures--------------------------------------------------*/
/*********************************************************************************************************************/
typedef struct
{IfxCan_Can_Config canConfig;                            /* CAN module configuration structure                   */IfxCan_Can canModule;                                   /* CAN module handle                                    */IfxCan_Can_Node canSrcNode;                             /* CAN source node handle data structure                */IfxCan_Can_Node canDstNode;                             /* CAN destination node handle data structure           */IfxCan_Can_NodeConfig canNodeConfig;                    /* CAN node configuration structure                     */IfxCan_Filter canFilter;                                /* CAN filter configuration structure                   */IfxCan_Message txMsg;                                   /* Transmitted CAN message structure                    */IfxCan_Message rxMsg;                                   /* Received CAN message structure                       */uint32 txData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Transmitted CAN data array                           */uint32 rxData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Received CAN data array                              */
} McmcanType;McmcanType                  g_mcmcan;IFX_INTERRUPT(canIsrTxHandler, 0, ISR_PRIORITY_CAN_TX);
void canIsrTxHandler(void)
{/* Clear the "Transmission Completed" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.canSrcNode.node, IfxCan_Interrupt_transmissionCompleted);/* Just to indicate that the CAN message has been transmitted by turning on LED0 */IfxPort_setPinState(LED0, IfxPort_State_low);
}IFX_INTERRUPT(canIsrRxHandler, 0, ISR_PRIORITY_CAN_RX);
void canIsrRxHandler(void)
{/* Clear the "Message stored to Dedicated RX Buffer" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.canDstNode.node, IfxCan_Interrupt_messageStoredToDedicatedRxBuffer);/* Clear the "New Data" flag; as long as the "New Data" flag is set, the respective Rx buffer is* locked against updates from received matching frames.*/IfxCan_Node_clearRxBufferNewDataFlag(g_mcmcan.canDstNode.node, g_mcmcan.canFilter.rxBufferOffset);/* Read the received CAN message */IfxCan_Can_readMessage(&g_mcmcan.canDstNode, &g_mcmcan.rxMsg, g_mcmcan.rxData);/* Check if the received data matches with the transmitted one */if( ( g_mcmcan.rxData[0] == g_mcmcan.txData[0] ) &&( g_mcmcan.rxData[1] == g_mcmcan.txData[1] ) &&( g_mcmcan.rxMsg.messageId == g_mcmcan.txMsg.messageId ) ){/* Turn on the LED1 to indicate correctness of the received message */IfxPort_setPinState(LED1, IfxPort_State_low);}
}void core0_main(void)
{IfxCpu_enableInterrupts();/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!* Enable the watchdogs and service them periodically if it is required*/IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());/* Wait for CPU sync event */IfxCpu_emitEvent(&g_cpuSyncEvent);IfxCpu_waitEvent(&g_cpuSyncEvent, 1);//initLEDIfxPort_setPinMode(LED0, IfxPort_Mode_outputPushPullGeneral);    /* Initialize LED port pin                      */IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinState(LED0, IfxPort_State_high);                   /* Turn off LED (LED is low-level active)       */IfxPort_setPinState(LED1, IfxPort_State_high);//initMcmcan/*******CAN module configuration and initialization*******///load default CAN module configuration into configuration structureIfxCan_Can_initModuleConfig(&g_mcmcan.canConfig, &MODULE_CAN0);//initialize CAN module with the default configurationIfxCan_Can_initModule(&g_mcmcan.canModule, &g_mcmcan.canConfig);/*******Source CAN node configuration and initialization*******/IfxCan_Can_initNodeConfig(&g_mcmcan.canNodeConfig, &g_mcmcan.canModule);g_mcmcan.canNodeConfig.busLoopbackEnabled = TRUE;g_mcmcan.canNodeConfig.nodeId = IfxCan_NodeId_0;g_mcmcan.canNodeConfig.frame.type = IfxCan_FrameType_transmit;g_mcmcan.canNodeConfig.interruptConfig.transmissionCompletedEnabled = TRUE;g_mcmcan.canNodeConfig.interruptConfig.traco.priority = ISR_PRIORITY_CAN_TX;g_mcmcan.canNodeConfig.interruptConfig.traco.interruptLine = IfxCan_InterruptLine_0;g_mcmcan.canNodeConfig.interruptConfig.traco.typeOfService = IfxSrc_Tos_cpu0;IfxCan_Can_initNode(&g_mcmcan.canSrcNode, &g_mcmcan.canNodeConfig);/*******Destination CAN node configuration and initialization*******///load default CAN node configuration into configuration structureIfxCan_Can_initNodeConfig(&g_mcmcan.canNodeConfig, &g_mcmcan.canModule);//set destination CAN node in the "Loop-Back" mode (no external pins are used)g_mcmcan.canNodeConfig.busLoopbackEnabled = TRUE;//assign destination CAN node to CAN node 1g_mcmcan.canNodeConfig.nodeId = IfxCan_NodeId_1;//define the frame to be the receiving oneg_mcmcan.canNodeConfig.frame.type = IfxCan_FrameType_receive;//once the message is stored in the dedicated RX buffer, raise the interruptg_mcmcan.canNodeConfig.interruptConfig.messageStoredToDedicatedRxBufferEnabled = TRUE;//define the receive interrupt priorityg_mcmcan.canNodeConfig.interruptConfig.reint.priority = ISR_PRIORITY_CAN_RX;//assign the interrupt line 1 to the receive interruptg_mcmcan.canNodeConfig.interruptConfig.reint.interruptLine = IfxCan_InterruptLine_1;//receive interrupt service routine should be serviced by the CPU0g_mcmcan.canNodeConfig.interruptConfig.reint.typeOfService = IfxSrc_Tos_cpu0;//initialize the destination CAN node with the modified configurationIfxCan_Can_initNode(&g_mcmcan.canDstNode, &g_mcmcan.canNodeConfig);/*******CAN filter configuration and initialization*******///filter configuration is stored under the filter element number 0g_mcmcan.canFilter.number = 0;//store received frame in a dedicated RX Bufferg_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;//define the same message ID as defined for the TX messageg_mcmcan.canFilter.id1 = CAN_MESSAGE_ID;//assign the filter to the dedicated RX Buffer (RxBuffer0 in this case)g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_0;//initialize the standard filter with the modified configurationIfxCan_Can_setStandardFilter(&g_mcmcan.canDstNode, &g_mcmcan.canFilter);//transmitCanMessage//Initialization of the RX message with the default configurationIfxCan_Can_initMessage(&g_mcmcan.rxMsg);//Invalidation of the RX message data contentmemset((void *)(&g_mcmcan.rxData[0]), INVALID_RX_DATA_VALUE, MAXIMUM_CAN_DATA_PAYLOAD * sizeof(uint32));//Initialization of the TX message with the default configurationIfxCan_Can_initMessage(&g_mcmcan.txMsg);//Define the content of the data to be transmittedg_mcmcan.txData[0] = TX_DATA_LOW_WORD;g_mcmcan.txData[1] = TX_DATA_HIGH_WORD;//Set the message ID that is used during the receive acceptance phaseg_mcmcan.txMsg.messageId = CAN_MESSAGE_ID;//Send the CAN message with the previously defined TX message contentwhile( IfxCan_Status_notSentBusy ==IfxCan_Can_sendMessage(&g_mcmcan.canSrcNode, &g_mcmcan.txMsg, &g_mcmcan.txData[0]) ){}while(1){}
}

CAN Transceiver

下面的例子用到了CAN00, 加收发器, 评估板有, 连到CAN卡, 以便在电脑上收发:

  • 板子上默认有120Ω终端电阻了, 可以把USB-CAN卡的120Ω也用上
  • Classic CAN波特率500K
  • 对应的引脚是P20.7(CAN00_RX)和P20.8(CAN00_TX)
  • CAN发送ID为 0x1234567, 中断中翻转LED0
  • CAN接收 0x1234561 扩展帧, 数据为0x 01 23 45 67 89 AB CD EF 时, 点亮LED1
  • CAN接收 0x1234562 扩展帧, 数据为0x 02 23 45 67 89 AB CD EF 时, 点亮LED2
  • CAN接收 0x1234563 扩展帧, 数据为0x 03 23 45 67 89 AB CD EF 时, 点亮LED3

Cpu0_Main.c代码:

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;#include "Ifx_Types.h"
#include "IfxCan_Can.h"
#include "IfxCan.h"
#include "IfxCpu_Irq.h"
#include "IfxPort.h"
#include "Bsp.h"#define LED0                     &MODULE_P13,0
#define LED1                     &MODULE_P13,1
#define LED2                     &MODULE_P13,2
#define LED3                     &MODULE_P13,3#define MODULE_CAN0_RAM    0xF0200000
#define NODE0_RAM_OFFSET   0x0
//#define NODE1_RAM_OFFSET   0x1000#define CAN_MESSAGE_TX_ID0             (uint32)0x1234567
#define CAN_MESSAGE_RX_ID1             (uint32)0x1234561
#define CAN_MESSAGE_RX_ID2             (uint32)0x1234562
#define CAN_MESSAGE_RX_ID3             (uint32)0x1234563#define ISR_PRIORITY_CAN_TX         2                       /* Define the CAN TX interrupt priority                 */
#define ISR_PRIORITY_CAN_RX         1                       /* Define the CAN RX interrupt priority                 */
#define MAXIMUM_CAN_DATA_PAYLOAD    2                       /* Define maximum classical CAN payload in 4-byte words */IFX_CONST IfxCan_Can_Pins Can00_pins = {&IfxCan_TXD00_P20_8_OUT,   IfxPort_OutputMode_pushPull, // CAN00_TX&IfxCan_RXD00B_P20_7_IN,   IfxPort_InputMode_pullUp,    // CAN00_RXIfxPort_PadDriver_cmosAutomotiveSpeed4
};typedef struct
{IfxCan_Can_Config canConfig;                            /* CAN module configuration structure                   */IfxCan_Can canModule;                                   /* CAN module handle                                    */IfxCan_Can_Node can00Node;                             /* CAN source node handle data structure                */IfxCan_Can_NodeConfig canNodeConfig;                    /* CAN node configuration structure                     */IfxCan_Filter canFilter;                                /* CAN filter configuration structure                   */IfxCan_Message txMsg;                                   /* Transmitted CAN message structure                    */IfxCan_Message rxMsg;                                   /* Received CAN message structure                       */uint32 txData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Transmitted CAN data array                           */uint32 rxData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Received CAN data array                              */
} McmcanType;McmcanType                  g_mcmcan;IFX_INTERRUPT(canIsrTxHandler, 0, ISR_PRIORITY_CAN_TX);
void canIsrTxHandler(void)
{/* Clear the "Transmission Completed" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.can00Node.node, IfxCan_Interrupt_transmissionCompleted);IfxPort_togglePin(LED0);    //transmit indicator
}IFX_INTERRUPT(canIsrRxHandler, 0, ISR_PRIORITY_CAN_RX);
void canIsrRxHandler(void)
{/* Clear the "Message stored to Dedicated RX Buffer" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.can00Node.node, IfxCan_Interrupt_messageStoredToDedicatedRxBuffer);/* Clear the "New Data" flag; as long as the "New Data" flag is set, the respective Rx buffer is* locked against updates from received matching frames.*/IfxCan_Node_clearRxBufferNewDataFlag(g_mcmcan.can00Node.node, g_mcmcan.canFilter.rxBufferOffset);/* Read the received CAN message */IfxCan_Can_readMessage(&g_mcmcan.can00Node, &g_mcmcan.rxMsg, g_mcmcan.rxData);/* Check if the received data matches with the transmitted one */if((g_mcmcan.rxMsg.messageId == CAN_MESSAGE_RX_ID1)&& (g_mcmcan.rxData[1] == 0xEFCDAB89)){if(g_mcmcan.rxData[0] == 0x67452301) {  //send 0xIfxPort_setPinState(LED1, IfxPort_State_low);   //LED ON} else {IfxPort_setPinState(LED1, IfxPort_State_high);  //LED OFF}}if((g_mcmcan.rxMsg.messageId == CAN_MESSAGE_RX_ID2)&& (g_mcmcan.rxData[1] == 0xEFCDAB89)){if(g_mcmcan.rxData[0] == 0x67452302) {IfxPort_setPinState(LED2, IfxPort_State_low);} else {IfxPort_setPinState(LED2, IfxPort_State_high);}}if((g_mcmcan.rxMsg.messageId == CAN_MESSAGE_RX_ID3)&& (g_mcmcan.rxData[1] == 0xEFCDAB89)){if(g_mcmcan.rxData[0] == 0x67452303) {IfxPort_setPinState(LED3, IfxPort_State_low);} else {IfxPort_setPinState(LED3, IfxPort_State_high);}}}void initCAN0(void)
{/*******CAN module configuration and initialization*******/IfxCan_Can_initModuleConfig(&g_mcmcan.canConfig, &MODULE_CAN0);IfxCan_Can_initModule(&g_mcmcan.canModule, &g_mcmcan.canConfig);/*******CAN00 node configuration and initialization*******/IfxCan_Can_initNodeConfig(&g_mcmcan.canNodeConfig, &g_mcmcan.canModule);g_mcmcan.canNodeConfig.nodeId = IfxCan_NodeId_0;g_mcmcan.canNodeConfig.clockSource = IfxCan_ClockSource_both;g_mcmcan.canNodeConfig.frame.type = IfxCan_FrameType_transmitAndReceive;g_mcmcan.canNodeConfig.frame.mode = IfxCan_FrameMode_standard;  //Classic CANg_mcmcan.canNodeConfig.txConfig.txMode = IfxCan_TxMode_dedicatedBuffers;g_mcmcan.canNodeConfig.txConfig.dedicatedTxBuffersNumber = 255;g_mcmcan.canNodeConfig.txConfig.txBufferDataFieldSize = IfxCan_DataFieldSize_8;g_mcmcan.canNodeConfig.rxConfig.rxMode = IfxCan_RxMode_dedicatedBuffers;g_mcmcan.canNodeConfig.rxConfig.rxBufferDataFieldSize = IfxCan_DataFieldSize_8;g_mcmcan.canNodeConfig.filterConfig.extendedListSize = 255; //Extended Frameg_mcmcan.canNodeConfig.filterConfig.messageIdLength = IfxCan_MessageIdLength_extended;g_mcmcan.canNodeConfig.messageRAM.extendedFilterListStartAddress = 0x100;   //Extended Frameg_mcmcan.canNodeConfig.messageRAM.rxBuffersStartAddress = 0x200;g_mcmcan.canNodeConfig.messageRAM.txBuffersStartAddress = 0x400;g_mcmcan.canNodeConfig.messageRAM.baseAddress = MODULE_CAN0_RAM + NODE0_RAM_OFFSET;g_mcmcan.canNodeConfig.baudRate.baudrate = 500000;   //500KBaud//transmit interruptg_mcmcan.canNodeConfig.interruptConfig.transmissionCompletedEnabled = TRUE;g_mcmcan.canNodeConfig.interruptConfig.traco.priority = ISR_PRIORITY_CAN_TX;g_mcmcan.canNodeConfig.interruptConfig.traco.interruptLine = IfxCan_InterruptLine_0;g_mcmcan.canNodeConfig.interruptConfig.traco.typeOfService = IfxSrc_Tos_cpu0;//receive interruptg_mcmcan.canNodeConfig.interruptConfig.messageStoredToDedicatedRxBufferEnabled = TRUE;g_mcmcan.canNodeConfig.interruptConfig.reint.priority = ISR_PRIORITY_CAN_RX;g_mcmcan.canNodeConfig.interruptConfig.reint.interruptLine = IfxCan_InterruptLine_1;g_mcmcan.canNodeConfig.interruptConfig.reint.typeOfService = IfxSrc_Tos_cpu0;//binding ping_mcmcan.canNodeConfig.pins = &Can00_pins;IfxCan_Can_initNode(&g_mcmcan.can00Node, &g_mcmcan.canNodeConfig);/*******CAN filter configuration and initialization*******/g_mcmcan.canFilter.number = 0;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID1;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_0;//IfxCan_Can_setStandardFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);IfxCan_Can_setExtendedFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);g_mcmcan.canFilter.number = 1;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID2;//g_mcmcan.canFilter.id2 = CAN_MESSAGE_RX_ID2;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_0;//IfxCan_Can_setStandardFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);IfxCan_Can_setExtendedFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);g_mcmcan.canFilter.number = 2;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID3;//g_mcmcan.canFilter.id2 = CAN_MESSAGE_RX_ID3;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_0;//IfxCan_Can_setStandardFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);IfxCan_Can_setExtendedFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);}void initLED(void)
{IfxPort_setPinMode(LED0, IfxPort_Mode_outputPushPullGeneral);    /* Initialize LED port pin                      */IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinMode(LED3, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinState(LED0, IfxPort_State_high);                   /* Turn off LED (LED is low-level active)       */IfxPort_setPinState(LED1, IfxPort_State_high);IfxPort_setPinState(LED2, IfxPort_State_high);IfxPort_setPinState(LED3, IfxPort_State_high);
}void core0_main(void)
{IfxCpu_enableInterrupts();/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!* Enable the watchdogs and service them periodically if it is required*/IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());/* Wait for CPU sync event */IfxCpu_emitEvent(&g_cpuSyncEvent);IfxCpu_waitEvent(&g_cpuSyncEvent, 1);initLED();initTime();initCAN0();IfxCan_Can_initMessage(&g_mcmcan.txMsg);g_mcmcan.txMsg.messageId = CAN_MESSAGE_TX_ID0;g_mcmcan.txMsg.bufferNumber = 0;g_mcmcan.txMsg.dataLengthCode = IfxCan_DataLengthCode_8;//8 bytesg_mcmcan.txMsg.frameMode = IfxCan_FrameMode_standard;   //Classic CANg_mcmcan.txMsg.messageIdLength=IfxCan_MessageIdLength_extended;  //Extended Frameg_mcmcan.txData[0] = 0x98BADCFE;g_mcmcan.txData[1] = 0x10325476;//you will receive: FE DC BA 98 76 54 32 10while(1){while(IfxCan_Status_notSentBusy ==IfxCan_Can_sendMessage(&g_mcmcan.can00Node, &g_mcmcan.txMsg, &g_mcmcan.txData[0]) );waitTime(TimeConst_1s);}
}

编译运行, LED0每秒翻转一次状态, 查看CAN00发送出来的数据:

点亮LED1:

CAN00 标准帧和扩展帧

在另一块板子测试了标准帧和扩展帧同时收发, 注意如果同时发送或者接收偶数帧, 发送/接收中断的LED不会亮. 奇数帧才会. 另外, 因为没有配置, 所以如果CAN总线断开, 再连上, 不会自动重传, 不会再往总线发CAN帧.

Cpu0_Main.c代码:

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;#include "Bsp.h"
#include "IfxPort.h"
#include "IfxStm.h"
#include "Ifx_Types.h"
#include "IfxCan_Can.h"
#include "IfxCan.h"#define     LED0                &MODULE_P33,4   //STM
#define     LED1                &MODULE_P33,5   //CAN00TX
#define     LED2                &MODULE_P33,6   //CAN00RX#define     STM                 &MODULE_STM0
#define     ISR_PRIORITY_STM    10
#define     TIMER_INT_TIME      (uint32)(TimeConst_1ms * 1)
IfxStm_CompareConfig g_STMConf;     //STM configuration structure#define MODULE_CAN0_RAM    0xF0200000
#define NODE0_RAM_OFFSET   0x0
//#define NODE1_RAM_OFFSET   0x1000//Standard Frame(11-bit): 0x000~0x7FF
//Extended Frame(29-bit): 0x0000 0000 ~ 0x1FFF FFFF
#define CAN_MESSAGE_TX_ID0             (uint32)0x123
#define CAN_MESSAGE_TX_ID1             (uint32)0x1234567
#define CAN_MESSAGE_TX_ID2             (uint32)0xABCDEF#define CAN_MESSAGE_RX_ID0             (uint32)0x321
#define CAN_MESSAGE_RX_ID1             (uint32)0x7654321
#define CAN_MESSAGE_RX_ID2             (uint32)0xFEDCBA#define ISR_PRIORITY_CAN00_TX         1
#define ISR_PRIORITY_CAN00_RX         2#define MAXIMUM_CAN_DATA_PAYLOAD    2IFX_CONST IfxCan_Can_Pins Can00_pins = {&IfxCan_TXD00_P20_8_OUT,   IfxPort_OutputMode_pushPull, // CAN00_TX&IfxCan_RXD00B_P20_7_IN,   IfxPort_InputMode_pullUp,    // CAN00_RXIfxPort_PadDriver_cmosAutomotiveSpeed4
};typedef struct
{IfxCan_Can_Config canConfig;                            /* CAN module configuration structure                   */IfxCan_Can canModule;                                   /* CAN module handle                                    */IfxCan_Can_Node can00Node;                             /* CAN source node handle data structure                */IfxCan_Can_NodeConfig canNodeConfig;                    /* CAN node configuration structure                     */IfxCan_Filter canFilter;                                /* CAN filter configuration structure                   */IfxCan_Message txMsg;                                   /* Transmitted CAN message structure                    */IfxCan_Message rxMsg;                                   /* Received CAN message structure                       */uint32 txData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Transmitted CAN data array                           */uint32 rxData[MAXIMUM_CAN_DATA_PAYLOAD];                /* Received CAN data array                              */
} McmcanType;
McmcanType                  g_mcmcan;void initLED(void)
{IfxPort_setPinMode(LED0, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);IfxPort_setPinState(LED0, IfxPort_State_high);   //Turn Off LEDIfxPort_setPinState(LED1, IfxPort_State_high);   //Turn Off LEDIfxPort_setPinState(LED2, IfxPort_State_high);   //Turn Off LED
}void initSTM(void)
{IfxStm_initCompareConfig(&g_STMConf);           /* Initialize the configuration structure with default values   */g_STMConf.triggerPriority = ISR_PRIORITY_STM;   /* Set the priority of the interrupt                            */g_STMConf.typeOfService = IfxSrc_Tos_cpu0;      /* Set the service provider for the interrupts                  */g_STMConf.ticks = TIMER_INT_TIME;               /* Set the number of ticks after which the timer triggers an* interrupt for the first time                                 */IfxStm_initCompare(STM, &g_STMConf);            /* Initialize the STM with the user configuration               */
}void initCAN(void)
{/*******CAN module configuration and initialization*******/IfxCan_Can_initModuleConfig(&g_mcmcan.canConfig, &MODULE_CAN0);IfxCan_Can_initModule(&g_mcmcan.canModule, &g_mcmcan.canConfig);IfxCan_Can_initNodeConfig(&g_mcmcan.canNodeConfig, &g_mcmcan.canModule);//nodeg_mcmcan.canNodeConfig.nodeId = IfxCan_NodeId_0;    //CAN00g_mcmcan.canNodeConfig.clockSource = IfxCan_ClockSource_both;g_mcmcan.canNodeConfig.frame.type = IfxCan_FrameType_transmitAndReceive;g_mcmcan.canNodeConfig.frame.mode = IfxCan_FrameMode_standard;  //Classic CANg_mcmcan.canNodeConfig.txConfig.txMode = IfxCan_TxMode_dedicatedBuffers;g_mcmcan.canNodeConfig.txConfig.dedicatedTxBuffersNumber = 16;g_mcmcan.canNodeConfig.txConfig.txBufferDataFieldSize = IfxCan_DataFieldSize_8;g_mcmcan.canNodeConfig.rxConfig.rxMode = IfxCan_RxMode_dedicatedBuffers;g_mcmcan.canNodeConfig.rxConfig.rxBufferDataFieldSize = IfxCan_DataFieldSize_8;g_mcmcan.canNodeConfig.filterConfig.extendedListSize = 16;  //Extended Frameg_mcmcan.canNodeConfig.filterConfig.standardListSize = 16;  //Standard Frameg_mcmcan.canNodeConfig.filterConfig.messageIdLength = IfxCan_MessageIdLength_both;g_mcmcan.canNodeConfig.messageRAM.extendedFilterListStartAddress = 0x100;   //Extended Frameg_mcmcan.canNodeConfig.messageRAM.standardFilterListStartAddress = 0x100;   //Standard Frameg_mcmcan.canNodeConfig.messageRAM.rxBuffersStartAddress = 0x200;g_mcmcan.canNodeConfig.messageRAM.txBuffersStartAddress = 0x400;g_mcmcan.canNodeConfig.messageRAM.baseAddress = MODULE_CAN0_RAM + NODE0_RAM_OFFSET;//transmit interruptg_mcmcan.canNodeConfig.interruptConfig.transmissionCompletedEnabled = TRUE;g_mcmcan.canNodeConfig.interruptConfig.traco.priority = ISR_PRIORITY_CAN00_TX;g_mcmcan.canNodeConfig.interruptConfig.traco.interruptLine = IfxCan_InterruptLine_0;g_mcmcan.canNodeConfig.interruptConfig.traco.typeOfService = IfxSrc_Tos_cpu0;//receive interruptg_mcmcan.canNodeConfig.interruptConfig.messageStoredToDedicatedRxBufferEnabled = TRUE;g_mcmcan.canNodeConfig.interruptConfig.reint.priority = ISR_PRIORITY_CAN00_RX;g_mcmcan.canNodeConfig.interruptConfig.reint.interruptLine = IfxCan_InterruptLine_1;g_mcmcan.canNodeConfig.interruptConfig.reint.typeOfService = IfxSrc_Tos_cpu0;g_mcmcan.canNodeConfig.baudRate.baudrate = 500000;   //500KBaudg_mcmcan.canNodeConfig.pins = &Can00_pins;IfxCan_Can_initNode(&g_mcmcan.can00Node, &g_mcmcan.canNodeConfig);g_mcmcan.canFilter.number = 0;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID0;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_0;IfxCan_Can_setStandardFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);g_mcmcan.canFilter.number = 1;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID1;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_1;IfxCan_Can_setExtendedFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);g_mcmcan.canFilter.number = 2;g_mcmcan.canFilter.elementConfiguration = IfxCan_FilterElementConfiguration_storeInRxBuffer;g_mcmcan.canFilter.id1 = CAN_MESSAGE_RX_ID2;g_mcmcan.canFilter.rxBufferOffset = IfxCan_RxBufferId_1;IfxCan_Can_setExtendedFilter(&g_mcmcan.can00Node, &g_mcmcan.canFilter);
}void can00Send(void)
{IfxCan_Can_initMessage(&g_mcmcan.txMsg);g_mcmcan.txMsg.dataLengthCode = IfxCan_DataLengthCode_8;//8 bytesg_mcmcan.txMsg.frameMode = IfxCan_FrameMode_standard;   //Classic CANg_mcmcan.txMsg.bufferNumber = 0;g_mcmcan.txMsg.messageId = CAN_MESSAGE_TX_ID0;g_mcmcan.txData[0] = 0x98BADCFE;g_mcmcan.txData[1] = 0x10325476;g_mcmcan.txMsg.messageIdLength=IfxCan_MessageIdLength_standard;  //Extended Framewhile(IfxCan_Status_notSentBusy ==IfxCan_Can_sendMessage(&g_mcmcan.can00Node, &g_mcmcan.txMsg, &g_mcmcan.txData[0]) );g_mcmcan.txMsg.bufferNumber = 1;g_mcmcan.txMsg.messageId = CAN_MESSAGE_TX_ID1;g_mcmcan.txData[0] = 0x22222222;g_mcmcan.txData[1] = 0x33333333;g_mcmcan.txMsg.messageIdLength=IfxCan_MessageIdLength_extended;  //Extended Framewhile(IfxCan_Status_notSentBusy ==IfxCan_Can_sendMessage(&g_mcmcan.can00Node, &g_mcmcan.txMsg, &g_mcmcan.txData[0]) );g_mcmcan.txMsg.bufferNumber = 2;g_mcmcan.txMsg.messageId = CAN_MESSAGE_TX_ID2;g_mcmcan.txData[0] = 0xAAAAAAAA;g_mcmcan.txData[1] = 0xBBBBBBBB;g_mcmcan.txMsg.messageIdLength=IfxCan_MessageIdLength_extended;  //Extended Framewhile(IfxCan_Status_notSentBusy ==IfxCan_Can_sendMessage(&g_mcmcan.can00Node, &g_mcmcan.txMsg, &g_mcmcan.txData[0]) );}//isrCan00Tx
IFX_INTERRUPT(can00IsrTxHandler, 0, ISR_PRIORITY_CAN00_TX);
void can00IsrTxHandler(void)
{/* Clear the "Transmission Completed" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.can00Node.node, IfxCan_Interrupt_transmissionCompleted);IfxPort_togglePin(LED1);    //transmit indicator, %2=1 ON, else OFF
}//isrCan00Rx
IFX_INTERRUPT(can00IsrRxHandler, 0, ISR_PRIORITY_CAN00_RX);
void can00IsrRxHandler(void)
{/* Clear the "Message stored to Dedicated RX Buffer" interrupt flag */IfxCan_Node_clearInterruptFlag(g_mcmcan.can00Node.node, IfxCan_Interrupt_messageStoredToDedicatedRxBuffer);/* Clear the "New Data" flag; as long as the "New Data" flag is set, the respective Rx buffer is* locked against updates from received matching frames.*/IfxCan_Node_clearRxBufferNewDataFlag(g_mcmcan.can00Node.node, g_mcmcan.canFilter.rxBufferOffset);/* Read the received CAN message */IfxCan_Can_readMessage(&g_mcmcan.can00Node, &g_mcmcan.rxMsg, g_mcmcan.rxData);IfxPort_togglePin(LED2);    //%2=1 ON, else OFF
}void core0_main(void)
{IfxCpu_enableInterrupts();/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!* Enable the watchdogs and service them periodically if it is required*/IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());/* Wait for CPU sync event */IfxCpu_emitEvent(&g_cpuSyncEvent);IfxCpu_waitEvent(&g_cpuSyncEvent, 1);initTime();initLED();initCAN();initSTM();while(1){}
}IFX_INTERRUPT(isrSTM, 0, ISR_PRIORITY_STM);
void isrSTM(void)
{/* Update the compare register value that will trigger the next interrupt and toggle the LED */IfxStm_increaseCompare(STM, g_STMConf.comparator, TIMER_INT_TIME);can00Send();IfxPort_setPinState(LED0, IfxPort_State_toggled);
}

微信公众号

欢迎扫描关注我的微信公众号, 及时获取最新文章:

AURIX TC397 CAN MCMCAN相关推荐

  1. AURIX TC397 SCU 之 Watchdog 看门狗

    目录 看门狗基础 TC397 Watchdog 微信公众号 看门狗基础 文档参阅 TC3XX User Manual 的9.4节, 看门狗Watchdog Timers (WDT)是System Co ...

  2. TriCore AURIX TC397一览

    目录 选型 命名规则 资源 框图 Datasheet & Usermanual 封装 IDE与例程 开发板 中文论坛 参考 微信公众号 选型 命名规则 资源 框图 Datasheet & ...

  3. AURIX TC397 Timer PWM 基础知识

    目录 Timer/PWM资源 STM GTM GPT12 CCU6 参考 微信公众号 Timer/PWM资源 TC397有下列Timer/PWM资源: 6x STM GTM 1x GPT12 1x C ...

  4. AURIX TC397 SCU 之 ERU 外部中断

    目录 ERU基础知识 ERU引脚 ERU Example 微信公众号 ERU基础知识 参考 AURIX™ TC3xx User Manual Part-1 ERU, Event Request Uni ...

  5. Infineon Aurix TC397启动过程学习

    一.概览 TC397整个启动过程如下图所示: 首先由某个复位事件开始,必要情况下经历上电过程,然后执行芯片的引导固件进而跳转到用户启动代码,最后执行用户程序,因此整个过程可总结为"复位.上电 ...

  6. AURIX TC397 ADC EVADC EDSADC

    目录 EVADC EDSADC Example_ADC_Queued_Scan Example_ADC_Filtering 微信公众号 EVADC EVADC, Enhanced Versatile ...

  7. Aurix TC397多核开发建议

    一.多核开发建议

  8. ST NXP Infineon 常用MCU的汇总说明

    文章目录 ST NXP Infineon 主要是 ST, NXP, Infineon 的芯片: 基本都有免费的IDE 图形化的配置, 生成初始化代码 便宜的调试工具(RMB几十 ~几百) 都有移植好的 ...

  9. 英飞凌TC397芯片ASCLIN和MCMCAN模块讲解

    英飞凌TC397芯片ASCLIN和CAN模块讲解 一.车用总线概述 1.车用LIN总线 2.车用CAN总线 3.车用FlexRay总线 4. 车用MOST总线 二.TC397-ASCLIN模块 1. ...

最新文章

  1. HPU第三次积分赛-D:Longest Increasing Subsequence(DP)
  2. HALCON识别数字ID
  3. 【深度学习】生动分析半监督学习与负相关学习算法
  4. 我为什么更喜欢 Mac OS X
  5. 【Anychat音视频开发】相对路径与绝对路径详解
  6. 【采用】无监督核心聚类算法
  7. 思科路由器怎么安装?
  8. erlang lists模块函数使用大全
  9. PHP AJAXFORM提交图片上传并显示图片源代码
  10. mysql 区间/替换/自增/where与having/字段运算/关键词/修改字段
  11. linux 命令-全称
  12. np.dot和np.matmul的区别与联系
  13. python——语音信号读取、分帧、加窗
  14. dsp 链接命令文件的写法
  15. Unity独立游戏大集合
  16. Win10电脑 安装 逍遥模拟器【安装步骤、使用指南、逍遥多开器、卸载“逍遥模拟器”、安装手机软件示例“学习国防”】
  17. JavaScript编程精解(笔记1)
  18. 用python3制作视频字幕,生成双英文双语字幕txt和srt文件使用百度和有道翻译自封装翻译接口,可以秒杀付费工具,字幕脚本为qiweb3远程 2022年5月29日
  19. IE浏览器无法添加进信任站点和受限站点,添加后被还原
  20. 计算机网络的速率怎么计算,宽带速率对照表和计算方法

热门文章

  1. [Swift]求最大公约数和最小公倍数【用微信查看本文链接可查看到引用图片】
  2. 定时器 java qua,(翻译)Quartz官方教程——第八课:SchedulerListeners
  3. YOLO如何训练分类网络???
  4. Python语法错误和异常
  5. 自动驾驶(十一)---------泰勒展开式、雅克比矩阵、主成分分析
  6. Maven 高级玩法
  7. JavaScript中的常用浏览器对象
  8. jupyter能debug了,使用vscode的jupyter插件进行debug
  9. dp在约会上是什么意思_饭圈用语dp是什么意思什么梗? 饭圈为什么喜欢用缩写?...
  10. 【VHDL语言学习笔记(二)】 4位向量加法器