AURIX TC397 CAN MCMCAN
目录
- 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相关推荐
- AURIX TC397 SCU 之 Watchdog 看门狗
目录 看门狗基础 TC397 Watchdog 微信公众号 看门狗基础 文档参阅 TC3XX User Manual 的9.4节, 看门狗Watchdog Timers (WDT)是System Co ...
- TriCore AURIX TC397一览
目录 选型 命名规则 资源 框图 Datasheet & Usermanual 封装 IDE与例程 开发板 中文论坛 参考 微信公众号 选型 命名规则 资源 框图 Datasheet & ...
- AURIX TC397 Timer PWM 基础知识
目录 Timer/PWM资源 STM GTM GPT12 CCU6 参考 微信公众号 Timer/PWM资源 TC397有下列Timer/PWM资源: 6x STM GTM 1x GPT12 1x C ...
- AURIX TC397 SCU 之 ERU 外部中断
目录 ERU基础知识 ERU引脚 ERU Example 微信公众号 ERU基础知识 参考 AURIX™ TC3xx User Manual Part-1 ERU, Event Request Uni ...
- Infineon Aurix TC397启动过程学习
一.概览 TC397整个启动过程如下图所示: 首先由某个复位事件开始,必要情况下经历上电过程,然后执行芯片的引导固件进而跳转到用户启动代码,最后执行用户程序,因此整个过程可总结为"复位.上电 ...
- AURIX TC397 ADC EVADC EDSADC
目录 EVADC EDSADC Example_ADC_Queued_Scan Example_ADC_Filtering 微信公众号 EVADC EVADC, Enhanced Versatile ...
- Aurix TC397多核开发建议
一.多核开发建议
- ST NXP Infineon 常用MCU的汇总说明
文章目录 ST NXP Infineon 主要是 ST, NXP, Infineon 的芯片: 基本都有免费的IDE 图形化的配置, 生成初始化代码 便宜的调试工具(RMB几十 ~几百) 都有移植好的 ...
- 英飞凌TC397芯片ASCLIN和MCMCAN模块讲解
英飞凌TC397芯片ASCLIN和CAN模块讲解 一.车用总线概述 1.车用LIN总线 2.车用CAN总线 3.车用FlexRay总线 4. 车用MOST总线 二.TC397-ASCLIN模块 1. ...
最新文章
- HPU第三次积分赛-D:Longest Increasing Subsequence(DP)
- HALCON识别数字ID
- 【深度学习】生动分析半监督学习与负相关学习算法
- 我为什么更喜欢 Mac OS X
- 【Anychat音视频开发】相对路径与绝对路径详解
- 【采用】无监督核心聚类算法
- 思科路由器怎么安装?
- erlang lists模块函数使用大全
- PHP AJAXFORM提交图片上传并显示图片源代码
- mysql 区间/替换/自增/where与having/字段运算/关键词/修改字段
- linux 命令-全称
- np.dot和np.matmul的区别与联系
- python——语音信号读取、分帧、加窗
- dsp 链接命令文件的写法
- Unity独立游戏大集合
- Win10电脑 安装 逍遥模拟器【安装步骤、使用指南、逍遥多开器、卸载“逍遥模拟器”、安装手机软件示例“学习国防”】
- JavaScript编程精解(笔记1)
- 用python3制作视频字幕,生成双英文双语字幕txt和srt文件使用百度和有道翻译自封装翻译接口,可以秒杀付费工具,字幕脚本为qiweb3远程 2022年5月29日
- IE浏览器无法添加进信任站点和受限站点,添加后被还原
- 计算机网络的速率怎么计算,宽带速率对照表和计算方法
热门文章
- [Swift]求最大公约数和最小公倍数【用微信查看本文链接可查看到引用图片】
- 定时器 java qua,(翻译)Quartz官方教程——第八课:SchedulerListeners
- YOLO如何训练分类网络???
- Python语法错误和异常
- 自动驾驶(十一)---------泰勒展开式、雅克比矩阵、主成分分析
- Maven 高级玩法
- JavaScript中的常用浏览器对象
- jupyter能debug了,使用vscode的jupyter插件进行debug
- dp在约会上是什么意思_饭圈用语dp是什么意思什么梗? 饭圈为什么喜欢用缩写?...
- 【VHDL语言学习笔记(二)】 4位向量加法器