单片机STM32F103如何实现CAN总线?
在STM32F103微控制器上实现CAN(Controller Area Network)总线通信是嵌入式开发中的常见需求。STM32F103系列(如STM32F103C8T6或STM32F103ZET6)内置了CAN控制器(bxCAN),支持CAN 2.0A和2.0B协议,适合工业控制、汽车电子等场景。以下是详细的实现步骤,涵盖硬件连接、开发环境配置、代码编写、调试及注意事项。
1. 硬件准备
要实现CAN总线通信,需准备以下硬件:
- STM32F103开发板:如STM32F103C8T6(“蓝板”)或正点原子/野火开发板。
- CAN收发器:STM32F103的CAN控制器需要外部收发器将逻辑电平转换为差分信号。常用芯片包括:
- TJA1050(高性价比,最大1Mbps)。
- SN65HVD230(支持3.3V,低功耗)。
- CAN总线设备:至少需要两节点(一个发送,一个接收)进行测试。可以用另一块STM32开发板或CAN分析仪(如PCAN、CANoe)。
- 连接线:杜邦线、USB线等。
- 调试器:ST-Link V2或J-Link,用于程序下载和调试。
- 电源:确保开发板供电稳定(通常USB供电,5V或3.3V)。
- 终端电阻:在CAN总线两端各接一个120Ω终端电阻,防止信号反射(若总线较短,单节点测试可省略一个)。
硬件连接
以TJA1050为例,典型连接方式如下:
- STM32F103与TJA1050:
- STM32的CAN_TX(PB9)连接TJA1050的TXD。
- STM32的CAN_RX(PB8)连接TJA1050的RXD。
- TJA1050的VCC接3.3V,GND接地。
- TJA1050与CAN总线:
- TJA1050的CANH和CANL引脚连接到CAN总线。
- CAN总线两端各接120Ω电阻。
- 两节点连接:
- 节点1的CANH接节点2的CANH,CANL接CANL。
- 确保所有节点GND共地,避免电位差。
注意:STM32F103的CAN引脚需要重映射(默认PA11/PA12,需改为PB8/PB9),通过软件配置实现。
2. 开发环境搭建
参考前文(STM32F103开发环境搭建),确保以下工具已准备好:
- STM32CubeIDE:用于代码编写和调试。
- STM32CubeMX:用于外设配置和初始化代码生成。
- ST-Link驱动:确保调试器正常工作。
- STM32CubeProgrammer:用于程序烧录。
- 固件库:推荐使用HAL库(通过CubeMX自动获取STM32F1固件包)。
3. CAN总线配置与代码实现
以下以STM32CubeMX和STM32CubeIDE为基础,详细说明如何实现CAN通信。假设实现一个简单的两节点通信:节点1发送数据,节点2接收并打印。
3.1 使用STM32CubeMX配置CAN
- 创建新项目:
- 打开STM32CubeMX,选择MCU(如STM32F103C8T6)。
- 进入“Pinout & Configuration”界面。
- 配置CAN引脚:
- 在“Connectivity”中选择“CAN”。
- 设置引脚重映射:
- 选择PB8(CAN_RX)和PB9(CAN_TX)。
- 在“GPIO Settings”中,启用引脚重映射(将CAN设置为“CAN_REMAP[1:0]=10”)。
- 启用CAN外设,模式选择“Normal”或“Loopback”(用于单节点测试)。
- 配置CAN参数:
- 在“Parameter Settings”中:
- Prescaler:设置时钟分频,计算公式为:
例如,APB1时钟为36MHz,波特率设为500kbps:波特率 = APB1时钟频率 / (Prescaler × (Tseg1 + Tseg2 + 1))
- Prescaler = 4
- Time Segment 1 (Tseg1) = 15
- Time Segment 2 (Tseg2) = 2
- 结果:36MHz / (4 × (15 + 2 + 1)) = 500kbps
- Prescaler:设置时钟分频,计算公式为:
- Mode:选择“Normal Mode”用于实际通信,或“Loopback Mode”用于调试。
- 启用中断(可选):勾选“RX interrupt”以接收数据。
- 在“Parameter Settings”中:
- 配置时钟:
- 在“Clock Configuration”中,设置HSE(外部8MHz晶振),PLL倍频到72MHz,APB1时钟为36MHz。
- 生成代码:
- 在“Project Manager”中,设置项目名称、路径,选择“STM32CubeIDE”工具链。
- 点击“Generate Code”生成初始化代码。
3.2 编写CAN发送代码(节点1)
在STM32CubeIDE中打开生成的项目,修改main.c
实现CAN数据发送。
#include "main.h"
#include "can.h"