深入解析 CAN 通信:接收、发送与中断处理
1. CAN 通信原理
CAN(Controller Area Network)是一种在汽车电子和工业自动化领域中广泛使用的高可靠性通信协议。本文将探讨 CAN 协议的接收与发送过程,包括中断处理和滤波设计的关键技术点。
1.1 CAN 通信的特点
- 多主通信:多个主节点可以在同一个网络上发送数据。
- 优先级:基于标识符的消息优先级机制确保紧急信息优先传输。
- 非破坏仲裁:网络上如果有多个节点同时发送消息,通过仲裁机制决定哪个节点控制总线。
1.2 CAN 通信的硬件基础
硬件上,CAN 通信需要 CAN 控制器和 CAN 收发器,它们共同实现了 CAN 协议的物理层和数据链路层功能。为了减少信号反射,网络通常会使用双绞线,并通过匹配电阻来终止网络。
1.3 CAN 通信的工作机制
在工作机制上,CAN 采用非破坏性的位仲裁技术,确保数据传输的稳定性和实时性。数据帧在传输过程中,若发生错误,节点将自动重发该帧。这种自我纠错的能力赋予了 CAN 通信在复杂环境下良好的性能表现。
1.4 CAN 通信的应用范围
由于 CAN 的高可靠性、实时性和灵活性,它已经成为工业控制、医疗设备、航空航天等多个领域不可或缺的通信标准。特别是在汽车领域,CAN 总线已经成为现代汽车电子系统的标准通信方式,广泛应用于引擎管理、刹车控制、车载娱乐系统等多个方面。
2. CAN 数据帧结构与解析
2.1 CAN 帧的基本结构
2.1.1 帧格式与类型
CAN 总线协议中定义了两种主要的帧格式:标准帧和扩展帧。标准帧使用 11 位标识符,而扩展帧使用 29 位标识符。这种设计允许开发者根据项目需求选择合适的帧类型,以优化网络通信的灵活性和效率。
- 标准帧:主要用于简单的网络系统,适用于节点数量较少的网络。
- 扩展帧:允许更多的节点通信,适用于复杂的系统设计。
2.1.2 帧起始位、控制位和数据位
一个 CAN 数据帧的开始由帧起始位(SOF)标志,这是帧的第一个位,并确保网络上的所有设备同步开始接收数据帧。接下来是控制位,其中包含标识符(ID),这个标识符定义了消息的优先级以及目的地。控制位之后是数据字段,数据长度可以变化,最短为 0 个字节,最长为 8 个字节。
数据字段之后是 CRC 序列,用于错误检测。循环冗余校验(CRC)确保了数据在传输过程中没有被损坏。CRC 后是 CRC 界定符,它由一个固定的位模式构成,用于标示 CRC 序列的结束。最后是帧结束位,标志着数据帧的结束。
2.1.3 帧结束位和帧间空间
帧结束位(EOF)是数据帧的最后一个字段,由 7 个连续的 1 位组成,确保了所有接收器能够识别数据帧的结束。帧间空间(IFS)是数据帧和随后帧之间的间隔。它允许网络上的设备有一个短暂的准备时间,用于处理当前接收到的数据帧,并准备接收下一个数据帧。
2.1.4 标准帧与扩展帧的比较
| 特征 | 标准帧 | 扩展帧 |
|---|---|---|
| 标识符位数 | 11 位 | 29 位 |
| 应用场景 | 小型系统、节点数量少 | 大型系统、节点数量多 |
| 优先级 | 较低 | 较高 |
| 数据长度 | 最多 8 字节 | 最多 8 字节 |
| 网络复杂性 | 较简单 | 较复杂 |
| 资源冲突处理 | 较困难 | 较容易 |
graph LR
A[开始] --> B[帧起始位]
B --> C[控制位]
C --> D[数据字段]
D --> E[CRC 序列]
E --> F[CRC 界定符]
F --> G[帧结束位]
G --> H[帧间空间]
3. 接收 CAN 消息的流程与实践
3.1 接收 CAN 消息的硬件配置
3.1.1 CAN 控制器与 CAN 收发器的选择
在任何 CAN 网络中,CAN 控制器和 CAN 收发器是两个关键组件。控制器负责帧的格式化、错误检测与处理以及帧的发送与接收,而收发器则负责信号的电气特性转换。
- CAN 控制器选择:取决于其性能规格,例如处理速度、支持的帧类型、波特率及错误处理能力。
- CAN 收发器选择:需考虑输出驱动能力、共模电压范围、保护特性等,直接影响网络可靠性。
3.1.2 网络拓扑结构设计
典型的 CAN 网络拓扑采用'线 + 终端电阻'的形式,最大限度减少反射和信号失真。
- 物理层设计:考虑网络物理长度、分支数量和节点数量对信号质量的影响。
- 电气特性:关注终端电阻的位置、阻值以及电缆类型。
3.2 接收 CAN 消息的软件实现
3.2.1 消息过滤和缓冲策略
- 消息过滤:通常在接收时立即执行,避免处理无关数据。例如设置过滤器掩码只接收特定 ID 的帧。
- 缓冲策略:管理内存中的消息队列,可使用 FIFO 或按优先级排序。
3.2.2 错误检测与异常处理机制
CAN 总线支持强大的错误检测机制,包括 CRC、帧检查、消息确认等。软件层面需实现相应的错误处理逻辑,如处理帧冲突、总线错误、节点故障等。
3.2.3 消息接收的中断驱动和轮询方式
- 中断驱动方式:通过中断信号告知 CPU 有新数据到达,适合高实时性应用。
- 轮询方式:CPU 周期性检查输入缓冲区状态,CPU 利用率较高但可能增加延迟。
示例代码展示
以下是一个简化的 CAN 消息接收示例,使用中断驱动方式:
// CAN 接收中断服务程序示例
void CAN_RX_Interrupt() {
CAN_Message_t rxMessage;
// 检查是否为接收中断
if (CANInterruptReason == RX_INTERRUPT) {
// 清除中断标志
CANClearInterruptFlag();
// 读取接收缓冲区中的消息
rxMessage = CANReadMessageFromBuffer();
// 根据消息 ID 进行过滤
if (FilterMessage(rxMessage)) {
// 处理消息
ProcessMessage(rxMessage);
}
}
}
// 消息过滤函数
bool FilterMessage(CAN_Message_t message) {
return (message.id == FILTER_ID);
}
// 消息处理函数
void ProcessMessage(CAN_Message_t message) {
// 根据实际需求进行消息处理逻辑
}
4. 发送 CAN 消息的步骤与应用
4.1 发送 CAN 消息的软件设计
4.1.1 消息帧格式的构建
在构建 CAN 消息帧格式时,需遵循 ISO 11898 标准。主要涉及标识符的设置、数据长度码(DLC)的指定、数据域的填充以及校验部分的计算。
// CAN 消息帧结构体定义
typedef struct {
uint32_t id; // 11/29 bits ID
uint8_t length; // 0-8 bytes
uint8_t data[8]; // data bytes
uint8_t rtr; // remote transmission request
} CAN_MessageFrame;
// 构建标准 CAN 帧的函数
void buildStandardCANFrame(CAN_MessageFrame *frame, uint32_t id, uint8_t length, uint8_t *data, uint8_t rtr) {
frame->id = id;
frame->length = length;
memcpy(frame->data, data, length);
frame->rtr = rtr;
}
4.1.2 发送缓冲区和消息优先级的管理
发送缓冲区是确保消息按照既定顺序和优先级发送的重要组成部分。在 CAN 网络中,消息优先级是由标识符的数值决定的,数值越小,优先级越高。
// 使用优先队列管理发送缓冲区
#include <queue>
#include <functional>
// CAN 消息帧优先级比较函数
bool compareCANMessage(CAN_MessageFrame a, CAN_MessageFrame b) {
return a.id > b.id; // 标识符越小优先级越高
}
int main() {
std::priority_queue<CAN_MessageFrame, std::vector<CAN_MessageFrame>, decltype(&compareCANMessage)> sendQueue(compareCANMessage);
CAN_MessageFrame frame;
buildStandardCANFrame(&frame, 0x200, 8, (uint8_t *)"Data", 0);
sendQueue.push(frame);
while (!sendQueue.empty()) {
CAN_MessageFrame topMessage = sendQueue.top();
sendQueue.pop();
// 发送消息到 CAN 总线的代码
}
return 0;
}
4.2 发送 CAN 消息的硬件实现
4.2.1 CAN 总线驱动电平与匹配电阻
物理层面上,CAN 总线使用差分信号。推荐使用 120 欧姆的匹配电阻,连接在 CAN_High 和 CAN_Low 之间,位于物理网络的两端。
// 示例代码,设置 CAN 控制器为发送模式
#define CAN_TX_ENABLE 0x01
void enableCANTransmission(CAN_Controller *controller) {
uint8_t controlRegister = readCANControlRegister(controller);
controlRegister |= CAN_TX_ENABLE;
writeCANControlRegister(controller, controlRegister);
}
4.3 发送与接收同步策略
4.3.1 时间同步机制
时间同步机制可以通过硬件或软件来实现,例如使用时间戳或事件触发。
void enableCANTimeStamps(CAN_Controller *controller, bool enable) {
uint8_t controlRegister = readCANControlRegister(controller);
if (enable) {
controlRegister |= TIMESTAMP_ENABLE;
} else {
controlRegister &= ~TIMESTAMP_ENABLE;
}
writeCANControlRegister(controller, controlRegister);
}
4.3.2 低延迟消息处理
低延迟消息处理要求优化流程、减少中断响应时间。在中断服务程序中仅处理必要的逻辑,将工作委托给后台任务。
void CAN_InterruptHandler() {
CAN_MessageFrame frame;
if (isMessageReceived()) {
readMessage(&frame);
if (isHighPriority(frame)) {
handleHighPriorityMessage(&frame);
} else {
signalSEM();
}
}
}
5. 中断处理与滤波设计策略
5.1 中断处理机制
5.1.1 CAN 中断源分析
中断源通常包括数据帧接收完成、错误帧接收、状态改变等。数据接收完成通常具有最高优先级。
5.1.2 中断优先级配置与管理
大多数现代 CAN 控制器允许用户通过软件编程设置中断优先级。需权衡不同中断源的重要性及其对系统性能的影响。
5.1.3 中断服务程序的设计要点
- 最小化执行时间:ISR 应尽可能简短。
- 使用标志位:在 ISR 中设置标志位,在主循环中处理。
- 处理嵌套中断:考虑当前正在处理的中断与其他高优先级中断之间的策略。
void CAN_InterruptHandler() {
if (CAN_RX_INTERRUPT_FLAG) {
CANReceiveData();
CAN_RX_INTERRUPT_FLAG = 0;
}
if (CAN_ERROR_INTERRUPT_FLAG) {
CANHandleError();
CAN_ERROR_INTERRUPT_FLAG = 0;
}
}
5.2 滤波设计策略
5.2.1 滤波器的类型与作用
滤波器主要有两种类型:标识符过滤和内容过滤。高优先级的消息可以被赋予较低的滤波器掩码。
5.2.2 滤波器的配置与优化
- 动态与静态配置:静态配置简单,动态配置灵活。
- 优先级映射:将不同的消息优先级映射到不同的滤波器。
- 资源管理:合理规划滤波器的使用。
CAN_FilterConfigTypeDef canFilterConfig;
canFilterConfig.FilterBank = 0;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterIdHigh = 0x0000;
canFilterConfig.FilterIdLow = 0x0000;
canFilterConfig.FilterMaskIdHigh = 0x0000;
canFilterConfig.FilterMaskIdLow = 0x0000;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(&hcan, &canFilterConfig);
5.2.3 滤波性能评估方法
评估方法应包括漏检率与误检率、实时性测试、资源占用等。
6. CAN 通信在嵌入式系统中的应用分析
6.1 CAN 通信在汽车电子中的应用
6.1.1 车辆动力系统中的 CAN 网络
- 发动机控制单元 (ECU):接收传感器数据,调整喷油量和点火时机。
- 传动系统控制:自动变速箱换挡逻辑等。
- 动态稳定控制:利用传感器数据实时计算车辆动态状态。
6.1.2 安全与舒适系统的集成
- 防抱死制动系统 (ABS):调节制动压力。
- 乘员保护系统:气囊触发逻辑。
- 多媒体娱乐系统:音频、视频设备的控制。
6.2 CAN 通信在工业自动化中的应用
6.2.1 工业控制网络的构建
- 生产线控制:机器人臂、传感器互联。
- 能源管理系统:监控和控制工业能源消耗。
- 远程监测与维护:现场数据发送至中央控制系统。
6.2.2 实时数据采集与处理
- 过程控制:温度、压力等参数采集。
- 故障预测:结合分析技术进行预测性维护。
- 数据整合:提供完整的生产信息。
6.3 嵌入式系统中 CAN 通信的挑战与展望
6.3.1 网络安全性与隐私保护
- 安全协议:开发加密和认证协议。
- 入侵检测:实时监控网络流量。
- 隐私保护:敏感数据匿名化处理。
6.3.2 CAN FD 技术与未来趋势
CAN FD(Flexible Data-rate)提供了更高的数据传输速率,支持高达 5Mbps,兼容现有设备,将在智能交通和自动驾驶领域发挥重要作用。
