4. CAN控制器与MCU接口
在CAN通信硬件设计中,控制器与MCU的接口方式决定了系统的复杂度、成本与性能。本章节将深入剖析两种主流方案:独立控制器MCP2515(通过SPI接口)与集成控制器STM32 bxCAN(通过内部寄存器),并对比其适用场景。
▲ 图4-1 独立控制器 vs 集成控制器架构对比
4.1 独立控制器:MCP2515 + SPI接口
MCP2515是Microchip推出的独立CAN控制器,通过SPI接口与MCU通信。它内部集成了CAN协议引擎、验收滤波、FIFO缓冲等模块,适合MCU本身不带CAN外设的场景。
4.1.1 硬件连接要点
| MCP2515引脚 | MCU对应引脚 | 说明 |
|---|---|---|
| CS | GPIO (片选) | 低电平有效,用于SPI通信使能 |
| SCK | SPI_SCK | 时钟线,最高10MHz |
| SI | SPI_MOSI | 主出从入 |
| SO | SPI_MISO | 主入从出 |
| INT | GPIO (中断) | 接收/错误中断输出 |
| TXCAN/RXCAN | CAN收发器 | 差分信号引脚 |
4.1.2 SPI通信协议与寄存器操作
MCP2515的SPI指令包括:复位、读、写、请求发送、读取状态等。每个指令帧格式如下:
// SPI写寄存器示例(C语言伪代码)
uint8_t spi_write_register(uint8_t addr, uint8_t data) {
CS_LOW();
SPI_TransferByte(0x02); // 写指令
SPI_TransferByte(addr); // 寄存器地址
SPI_TransferByte(data); // 写入数据
CS_HIGH();
return 0;
}
// SPI读寄存器示例
uint8_t spi_read_register(uint8_t addr) {
uint8_t rx_data;
CS_LOW();
SPI_TransferByte(0x03); // 读指令
SPI_TransferByte(addr); // 寄存器地址
rx_data = SPI_TransferByte(0x00); // 读取数据
CS_HIGH();
return rx_data;
}
4.1.3 内部寄存器映射(关键部分)
| 地址 | 寄存器名称 | 功能描述 |
|---|---|---|
| 0x0C | CANCTRL | 模式控制(配置/正常/休眠) |
| 0x2E | CNF1 | 波特率配置寄存器1 |
| 0x2F | CNF2 | 波特率配置寄存器2 |
| 0x30 | CNF3 | 波特率配置寄存器3 |
| 0x60~0x6E | TXB0CTRL~TXB0D7 | 发送缓冲器0控制与数据 |
| 0x70~0x7E | RXB0CTRL~RXB0D7 | 接收缓冲器0控制与数据 |
▲ 图4-2 MCP2515 SPI写寄存器时序示意
4.2 集成控制器:STM32 bxCAN
STM32系列MCU内部集成了bxCAN(Basic Extended CAN)控制器,通过APB总线直接访问内部寄存器,无需外部SPI通信,具有更高的实时性和更低的延迟。
4.2.1 bxCAN核心寄存器
- CAN_MCR (主控制寄存器):设置初始化模式、睡眠模式、自动唤醒等。
- CAN_MSR (主状态寄存器):反映当前工作状态。
- CAN_BTR (位时序寄存器):配置波特率、同步跳转宽度、时间段1/2。
- CAN_TIxR / CAN_TDTxR / CAN_TDLxR (发送邮箱寄存器):标识符、数据长度、数据。
- CAN_RIxR / CAN_RDTxR / CAN_RDLxR (接收FIFO寄存器):接收报文信息。
- CAN_FMR / CAN_FMxR / CAN_FAxR (过滤器寄存器):配置验收滤波组。
4.2.2 初始化配置示例(HAL库)
// STM32 bxCAN 初始化代码片段
CAN_HandleTypeDef hcan1;
void MX_CAN1_Init(void) {
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6; // 分频系数
hcan1.Init.Mode = CAN_MODE_NORMAL; // 正常模式
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // 同步跳转宽度
hcan1.Init.TimeSeg1 = CAN_BS1_8TQ; // 时间段1
hcan1.Init.TimeSeg2 = CAN_BS2_3TQ; // 时间段2
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK) {
Error_Handler();
}
}
4.2.3 内部寄存器访问方式对比
| 特性 | MCP2515 (SPI) | STM32 bxCAN (寄存器) |
|---|---|---|
| 接口类型 | SPI 串行 | APB 并行总线 |
| 访问速度 | 受限于SPI时钟 (通常≤10MHz) | 高速 (APB时钟可达几十MHz) |
| CPU负载 | 需软件模拟SPI或使用SPI外设,中断处理 | 直接内存映射,DMA支持 |
| 滤波灵活性 | 2个验收滤波屏蔽寄存器 | 28个滤波组,可配置为列表/掩码模式 |
| 典型应用 | 低端MCU、扩展CAN接口 | 中高端嵌入式系统 |
▲ 图4-3 STM32 bxCAN 内部寄存器访问路径
4.3 接口选型建议
- 选MCP2515:当MCU无CAN外设、需要多路CAN扩展、或对成本敏感且SPI速率足够时。
- 选集成bxCAN:当系统对实时性要求高、需要复杂滤波、或MCU资源充裕时。
- 注意:无论哪种方案,CAN控制器与收发器之间的TX/RX走线应尽量短,避免信号反射。