4. CAN通信控制器硬件适配
在MICROSAR的CAN驱动(CanDrv)之下,真正与总线电气信号打交道的是MCU内部的CAN通信控制器(CAN Controller,也称CAN外设)。AUTOSAR CanDrv通过一组寄存器访问宏与中断服务例程,把上层CanIf的报文请求翻译成对CAN控制器的位定时、邮箱、滤波器和收发引脚的配置。本节聚焦这一层“硬件适配”工作:寄存器如何配置、中断与轮询如何取舍、收发引脚如何映射、硬件滤波器如何设置。
一、CAN控制器寄存器配置的基本顺序
以常见的Bosch M_CAN(如TC3xx、S32K3等芯片内置)或经典CAN(如S32K1的FlexCAN)为例,控制器上电后处于初始化或冻结状态,必须按固定顺序配置,否则位定时参数不会生效。典型顺序如下:
- 进入初始化/冻结模式(M_CAN写CCCR.INIT=1,FlexCAN写MCR.FRZ=1并等待FRZACK)。
- 配置位定时:设置波特率预分频、时间段1(TSEG1/PropSeg+PhaseSeg1)、时间段2(TSEG2/PhaseSeg2)和同步跳转宽度SJW。
- 配置收发引脚:通过端口控制寄存器(PORTx.PCRn)把CAN_TX、CAN_RX复用为CAN功能,并设置上拉/开漏等电气属性。
- 配置硬件滤波器:写入验收滤波器(Acceptance Filter)的ID、掩码和FIFO分配。
- 配置中断使能:按需打开RX、TX、错误、总线关闭等中断源。
- 退出初始化模式,等待控制器进入正常模式(M_CAN写CCCR.INIT=0并等待CCCR.INIT读回0)。
位定时参数不是随意填的。以500 kbit/s、采样点75%、SJW=1为例,若CAN时钟为40 MHz,则位时间=80个时钟周期,预分频=1,TSEG1=59,TSEG2=20,SJW=1,采样点=(1+59)/(1+59+20)=75%。这些值必须与总线上其他节点一致,否则会出现采样点偏差导致的偶发错误帧。
二、中断模式与轮询模式的选择
CanDrv对CAN控制器的访问有两种典型模式:中断驱动和轮询驱动。中断模式下,控制器在RX FIFO非空、TX完成、错误状态变化时触发ISR,CanDrv在ISR中读取邮箱并回调CanIf;轮询模式下,CanDrv在周期任务(如1 ms)中读取状态寄存器,判断是否有新报文。
选择依据主要是实时性、CPU负载和总线负载。对于高优先级安全报文(如E2E保护的扭矩信号),中断模式能保证毫秒级甚至微秒级响应;对于低速车身报文(如车门状态),轮询模式可以显著降低中断抖动和CPU占用。MICROSAR的CanDrv通常通过CanIf的CanIfRxPduReadNotify和CanIfTxConfirmation回调与上层衔接,中断或轮询只是触发方式不同,回调接口保持一致。
三、收发引脚映射
CAN控制器的TX/RX信号需要经过MCU的端口复用器(Port Mux)连接到外部CAN收发器(如TJA1043、TJA1051)。以TC3xx为例,CAN0的TX可映射到P20.8,RX映射到P20.7,配置时需写P20_IOCR8和P20_IOCR7,选择ALT1或ALT2功能,并设置RX为输入、TX为推挽输出。若使用CAN FD,还需确认收发器支持5 Mbit/s数据段速率,并检查TX/RX走线是否等长、是否靠近收发器放置。
引脚映射错误是硬件适配中最常见的故障之一:TX/RX接反、复用功能选错、RX未使能上拉,都会导致控制器无法进入正常模式或持续报总线错误。调试时可以先读PSR.BO(Bus Off)和ECR.TEC/REC,若TEC快速上升到255,通常说明TX引脚没有真正输出或总线没有终端电阻。
四、硬件滤波设置
硬件滤波器决定哪些CAN ID能进入RX FIFO,从而减少CPU中断和软件过滤开销。M_CAN提供标准ID滤波(SIDFC)和扩展ID滤波(XIDFC),每个滤波器元素包含ID、掩码和FIFO/缓冲区目标。FlexCAN则使用RXFGMASK和RXFIR。配置原则是:只放行本ECU需要的ID,其余全部屏蔽。
例如,某ECU需要接收0x100、0x101、0x200三个标准帧,可以配置两个滤波器元素:元素0的ID=0x100,掩码=0x7FE(只比较bit1~bit10,忽略bit0),可同时匹配0x100和0x101;元素1的ID=0x200,掩码=0x7FF,精确匹配0x200。这样三个ID进入FIFO 0,其余ID被硬件丢弃,软件无需再遍历判断。
五、一个可参考的配置片段
下面以M_CAN为例,给出位定时与滤波器的配置片段(参数为示例,需按实际时钟和总线速率调整):
/* 进入初始化模式 */
M_CAN->CCCR |= CCCR_INIT;
while (!(M_CAN->CCCR & CCCR_INIT));
/* 位定时:40 MHz 时钟,500 kbit/s,采样点 75% */
M_CAN->NBTP = (0 << NBTP_NBRP_Pos) /* 预分频 = 1 */
| (58 << NBTP_NTSEG1_Pos) /* TSEG1 = 59 */
| (19 << NBTP_NTSEG2_Pos) /* TSEG2 = 20 */
| (0 << NBTP_NSJW_Pos); /* SJW = 1 */
/* 标准 ID 滤波器:0x100/0x101 进 FIFO0,0x200 进 FIFO0 */
M_CAN->SIDFC = (uint32_t)&sidfilt[0];
sidfilt[0].S0 = 0x100 << 18; /* ID */
sidfilt[0].S1 = 0x7FE << 18; /* 掩码,忽略 bit0 */
sidfilt[1].S0 = 0x200 << 18;
sidfilt[1].S1 = 0x7FF << 18; /* 精确匹配 */
/* 使能 RX FIFO0 新报文中断 */
M_CAN->IE |= IE_RF0NE;
/* 退出初始化,进入正常模式 */
M_CAN->CCCR &= ~CCCR_INIT;
while (M_CAN->CCCR & CCCR_INIT);
配置完成后,可以通过读取PSR寄存器确认控制器是否进入正常模式(PSR.LEC为0、PSR.BO为0),再通过发送一帧已知ID的报文,观察ECR.TEC是否保持为0,来验证引脚映射和位定时是否正确。若TEC持续增长,应优先检查TX引脚复用、收发器供电和总线终端电阻。
总结来看,CAN控制器硬件适配的核心是“让控制器与总线电气层正确对话”:寄存器配置决定位定时和采样点,中断/轮询决定软件响应方式,引脚映射决定物理连接,硬件滤波决定哪些报文进入软件。四者缺一不可,且任何一项配置错误都会在ECR、PSR或总线错误计数器中留下可观察的痕迹,调试时应优先从这些寄存器入手定位问题。