4. CAN驱动开发环境搭建
在AURIX TC3xx平台上开发CAN通信,最省力的路径是使用英飞凌官方提供的AURIX Development Studio(ADS)配合iLLD(Infineon Low Level Driver)库。ADS基于Eclipse,内置TriCore GCC编译器、调试器和iLLD源码,无需额外购买编译器授权。本节以TC375为例,围绕“建工程—配CAN—写中断—调试验证”这条主线展开,所有参数均为教学示例,实际项目需按硬件与总线需求调整。
一、工程创建与iLLD库引入
启动ADS后选择 File → New → AURIX Project,在器件列表中选中 TC375TP,工具链保持默认的 TriCore GCC。工程模板建议选择 iLLD Application,这样ADS会自动把 iLLD/TC37A 下的 IfxCpu、IfxCan、IfxPort、IfxStm 等驱动源码以链接方式加入工程,避免手工拷贝导致的版本错配。若使用已有工程,则需在 Project → Properties → C/C++ Build → Settings → Include paths 中确认已包含 iLLD 与 iLLD/TC37A 两级目录,否则 IfxCan_Can.h 会报找不到头文件。
工程建立后先做一次空编译,确认 LSL 链接脚本与启动文件(IfxCpu_CStart0.c、CStart1.c)能正常通过。这一步很关键:很多“CAN初始化失败”的根因其实是时钟或启动配置没跑通,而不是CAN模块本身的问题。
二、CAN模块与引脚配置
TC375的CAN模块称为 MCMCAN(Modular CAN),包含 CAN0~CAN3 四个节点,每个节点有独立的 Node 与 Message RAM。配置分三步:模块时钟、引脚复用、节点参数。
模块时钟通过 IfxCan_Can_initModuleConfig 设置,示例中 moduleConfig.clockSource = IfxCan_ClockSource_both,波特率计算依赖 fCAN,TC375默认 fCAN = 100 MHz(来自 PLL 分频,需在 IfxScuCcu 中确认)。引脚方面,以 CAN00 为例,P20.7 为 RX、P20.8 为 TX,需将这两个引脚配置为 IfxPort_OutputAlt1 与 IfxPort_InputMode_pullUp,并设置 padDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1。
节点参数是核心,示例配置如下:
IfxCan_Can_NodeConfig nodeConfig;
IfxCan_Can_initNodeConfig(&nodeConfig, &canModule);
nodeConfig.nodeId = IfxCan_NodeId_0;
nodeConfig.frame.type = IfxCan_FrameType_transmitAndReceive;
nodeConfig.frame.mode = IfxCan_FrameMode_fdLongAndFast;
nodeConfig.baudRate.baudrate = 500000; /* 仲裁段 500 kbps */
nodeConfig.baudRate.samplePoint = 8000; /* 80% 采样点 */
nodeConfig.baudRate.syncJumpWidth = 2000;
nodeConfig.fastBaudRate.baudrate = 2000000; /* 数据段 2 Mbps */
nodeConfig.fastBaudRate.samplePoint = 7500;
nodeConfig.txConfig.txMode = IfxCan_TxMode_dedicatedBuffers;
nodeConfig.rxConfig.rxMode = IfxCan_RxMode_fifo0;
nodeConfig.rxConfig.rxBufferDataFieldSize = IfxCan_DataFieldSize_8;
这里 baudrate 与 samplePoint 的单位分别是 bps 和“万分比”,8000 即 80%。若采样点设置不当,总线在长线缆或强干扰下会出现偶发错误帧,调试时可用示波器观察 CAN_H/CAN_L 差分波形确认位时间。
三、发送与接收中断服务程序
iLLD的CAN发送有两种方式:轮询 IfxCan_Can_sendMessage 与中断/发送完成回调。接收则强烈建议用中断,否则容易丢帧。接收中断挂在 CAN0 的 SRN(Service Request Node)上,需在 IfxCan_Can_initNode 之后注册 ISR:
IFX_INTERRUPT(can0_rxIsr, 0, CAN0_RX_PRIO);
void can0_rxIsr(void)
{
IfxCan_Message msg;
IfxCan_Can_MessageContent content;
if (IfxCan_Can_readMessage(&g_canNode, &msg, &content) == TRUE) {
/* content.data[0..7] 为接收数据,msg.messageId 为标识符 */
g_rxFlag = 1;
}
IfxCan_Node_clearInterruptFlag(g_canNode.node, IfxCan_Interrupt_rxFifo0NewMessage);
}
发送中断用于确认帧已进入总线,典型写法是在 IfxCan_Can_sendMessage 后使能 IfxCan_Interrupt_transmissionCompleted,在 ISR 中清除标志并置位 g_txDone。注意:IFX_INTERRUPT 的第二个参数是 ISR 优先级,TC3xx中CAN中断优先级应低于系统定时器但高于普通任务,示例取 CAN0_RX_PRIO = 20。
四、调试与测试方法
调试CAN驱动建议按“由内到外”的顺序:先回环自测,再单节点发送,最后双节点通信。
回环自测:将 nodeConfig.frame.mode 设为 IfxCan_FrameMode_fdLongAndFast 的同时,把 nodeConfig.loopBack = IfxCan_LoopBack_internal,此时发送的帧不经过物理总线,直接进入接收FIFO。若 can0_rxIsr 能命中且 content.data 与发送一致,说明初始化、中断注册、Message RAM 配置全部正确。这一步能排除90%的软件配置错误。
单节点发送:关闭回环,用CAN分析仪(如PCAN-USB或周立功USBCAN)以500 kbps接入总线。若分析仪收不到帧,先查 P20.8 是否有波形;有波形但收不到,多半是波特率或采样点不匹配;无波形则检查 IfxCan_Can_sendMessage 的返回值是否为 IfxCan_Status_ok,以及Tx Buffer是否被正确分配。
双节点通信:两块TC375板分别配置为500 kbps,一块周期发送ID 0x123、DLC 8、数据 0x11~0x18,另一块在 can0_rxIsr 中判断 msg.messageId == 0x123 后翻转LED。若LED闪烁周期与发送周期一致,说明收发链路闭环。此时可进一步用 IfxCan_Node_getErrorCounters 读取 TEC/REC,正常应长期为0;若持续增长,需检查终端电阻(120 Ω)与地线。
g_rxFlag、g_txDone、msg.messageId、content.data[0] 加入ADS的Expressions视图,配合断点即可在不接分析仪的情况下快速定位问题。