CAN总线学习整理

CAN 总线架构详细介绍

物理层

物理层决定了 CAN 总线的电气特性、信号传输方式以及节点和总线的连接方式。常见的 CAN 物理层标准有 ISO 11898 - 2(高速 CAN)和 ISO 11898 - 3(低速容错 CAN)。

电气特性
  • 高速 CAN(ISO 11898 - 2)
    • 显性位(逻辑 0):CAN_H 与 CAN_L 之间的电压差大约是 2V,典型值为 CAN_H = 3.5V,CAN_L = 1.5V。
    • 隐性位(逻辑 1):CAN_H 和 CAN_L 之间的电压差约为 0V,通常 CAN_H = CAN_L = 2.5V。
    • 位速率:高速 CAN 的位速率最高可达 1Mbps,一般汽车应用中常用 500kbps 或 250kbps。
  • 低速容错 CAN(ISO 11898 - 3)
    • 显性位(逻辑 0):CAN_H 与 CAN_L 之间的电压差约为 1.5V,例如 CAN_H = 3V,CAN_L = 1.5V。
    • 隐性位(逻辑 1):CAN_H 和 CAN_L 之间的电压差约为 0V,通常 CAN_H = CAN_L = 2.25V。
    • 位速率:低速容错 CAN 的位速率通常在 125kbps 以下。
拓扑结构

CAN 总线一般采用总线型拓扑,所有节点都连接到同一条总线上。为减少信号反射,需要在总线两端连接终端电阻,高速 CAN 中终端电阻值通常为 120Ω。

节点连接

每个 CAN 节点由 CAN 控制器和 CAN 收发器构成。CAN 控制器负责处理 CAN 协议的高层功能,像数据帧的生成、接收和错误处理;CAN 收发器则把 CAN 控制器输出的数字信号转化为适合在总线上传输的差分信号,同时将总线上的差分信号转换为数字信号输入给 CAN 控制器。

数据链路层

数据链路层是 CAN 总线的核心,负责数据的封装、传输、仲裁和错误检测,主要包含介质访问控制(MAC)子层和逻辑链路控制(LLC)子层。

介质访问控制(MAC)子层
  • 帧格式
    • 数据帧:由帧起始、仲裁场、控制场、数据场、CRC 场、ACK 场和帧结束七个部分组成。
      • 帧起始:一个显性位,用于表示数据帧的开始。
      • 仲裁场:包含标识符(ID)和远程传输请求(RTR)位。ID 用于确定数据帧的优先级,ID 越小,优先级越高。RTR 位用于区分数据帧和远程帧,RTR = 0 表示数据帧,RTR = 1 表示远程帧。
      • 控制场:包含数据长度码(DLC)和一些保留位。DLC 用于指示数据场的字节数,取值范围为 0 - 8。
      • 数据场:最多可包含 8 个字节的数据。
      • CRC 场:包含 15 位的循环冗余校验码,用于检测数据传输过程中的错误。
      • ACK 场:包含一个 ACK 槽和一个 ACK 界定符。发送节点在 ACK 槽发送隐性位,若总线上有节点正确接收到数据,则会在 ACK 槽发送显性位进行应答。
      • 帧结束:由 7 个隐性位组成,用于表示数据帧的结束。
    • 远程帧:用于请求其他节点发送数据。其格式与数据帧类似,但没有数据场,且 RTR 位为 1。
    • 错误帧:当节点检测到错误时,会发送错误帧通知其他节点。错误帧由错误标志和错误界定符组成。
    • 过载帧:用于在节点处理数据时需要额外时间的情况下,通知其他节点暂停发送数据。过载帧由过载标志和过载界定符组成。
  • 仲裁机制:CAN 总线采用非破坏性逐位仲裁机制解决多个节点同时发送数据时的冲突问题。每个数据帧的仲裁场包含一个唯一的标识符(ID),ID 越小,优先级越高。当多个节点同时发送数据时,它们会逐位比较仲裁场的 ID,发送隐性位(逻辑 1)的节点如果检测到总线上出现显性位(逻辑 0),则认为自己的优先级较低,立即停止发送,让出总线使用权,而优先级高的节点则可以继续发送数据。
  • 位填充:为保证数据的同步和避免长串的连续相同位导致的同步丢失,CAN 总线采用位填充技术。在发送数据时,如果连续出现 5 个相同的位,发送器会自动插入一个相反的位;在接收数据时,接收器会自动删除这些插入的位。
逻辑链路控制(LLC)子层

LLC 子层主要负责数据帧的过滤、确认和错误恢复。它可以根据标识符过滤接收到的数据帧,只接收那些符合自己需求的数据帧。同时,LLC 子层还会对接收的数据帧进行确认,并在检测到错误时采取相应的错误恢复措施。

CAN 总线协议详细介绍

通信协议
  • 数据传输模式:CAN 总线支持单播和广播两种数据传输模式。单播是指一个节点向另一个特定节点发送数据;广播是指一个节点向总线上的所有节点发送数据。
  • 通信周期:在实际应用中,CAN 总线通信通常采用周期性通信和事件驱动通信相结合的方式。周期性通信是指节点按照一定的时间间隔周期性地发送数据,适用于需要实时更新的数据;事件驱动通信是指节点在发生特定事件时才发送数据,适用于突发情况的数据传输。
错误处理协议
  • 错误检测:CAN 总线采用多种错误检测机制,包括位错误检测、填充错误检测、CRC 错误检测、格式错误检测和 ACK 错误检测等。这些错误检测机制可以及时发现数据传输过程中出现的错误。
  • 错误处理:当检测到错误时,CAN 节点会根据错误的类型和严重程度采取不同的错误处理措施。如果是轻微错误,节点会发送错误帧通知其他节点,并尝试重新发送数据;如果是严重错误,节点会进入错误被动状态或总线关闭状态,暂时停止参与总线通信。
网络管理协议
  • 节点状态管理:CAN 总线网络管理协议负责管理节点的状态,包括节点的唤醒、休眠、初始化和故障诊断等。节点可以根据自身的工作状态和网络需求进入不同的状态,以节省能源和提高系统的可靠性。
  • 通信调度:网络管理协议还可以对 CAN 总线的通信进行调度,确保各个节点按照预定的时间和优先级进行通信,避免通信冲突和数据丢失。

C 语言示例代码

以下是一个简单的基于 STM32 的 C 语言示例代码,用于初始化 CAN 总线并发送和接收 CAN 消息。

#include "stm32f4xx.h"

// 定义CAN初始化结构体和过滤器初始化结构体以及GPIO初始化结构体
CAN_InitTypeDef        CAN_InitStructure;
CAN_FilterInitTypeDef  CAN_FilterInitStructure;
GPIO_InitTypeDef       GPIO_InitStructure;

// 函数功能:配置CAN总线相关参数
void CAN_Configuration(void)
{
    // 使能CAN1和GPIOA的时钟
    // CAN1挂载在APB1总线上,因此使用RCC_APB1PeriphClockCmd使能其时钟
    // GPIOA挂载在AHB1总线上,使用RCC_AHB1PeriphClockCmd使能其时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // 配置CAN引脚(PA11 - CAN_RX, PA12 - CAN_TX)
    // 设置引脚为复用功能模式,用于连接CAN外设
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    // 设置引脚速度为50MHz,以满足高速通信需求
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // 设置引脚为推挽输出类型
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    // 设置引脚为上拉模式,增强信号稳定性
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    // 将配置应用到GPIOA端口
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 将PA11和PA12连接到CAN1
    // 把PA11引脚复用为CAN1的接收引脚
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1);
    // 把PA12引脚复用为CAN1的发送引脚
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1);

    // 对CAN1寄存器进行复位操作,将其恢复到默认状态
    CAN_DeInit(CAN1);
    // 用默认值初始化CAN_InitStructure结构体
    CAN_StructInit(&CAN_InitStructure);

    // CAN工作模式配置
    // 关闭时间触发通信模式
    CAN_InitStructure.CAN_TTCM = DISABLE;
    // 关闭自动离线管理模式
    CAN_InitStructure.CAN_ABOM = DISABLE;
    // 关闭自动唤醒模式
    CAN_InitStructure.CAN_AWUM = DISABLE;
    // 禁用非自动重传模式,即允许自动重传
    CAN_InitStructure.CAN_NART = DISABLE;
    // 关闭接收FIFO锁定模式
    CAN_InitStructure.CAN_RFLM = DISABLE;
    // 关闭发送FIFO优先级模式
    CAN_InitStructure.CAN_TXFP = DISABLE;
    // 设置CAN工作在正常模式
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    // 设置同步跳转宽度为1个时间量子
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    // 设置位段1的时间长度为6个时间量子
    CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    // 设置位段2的时间长度为8个时间量子
    CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    // 设置CAN总线的预分频系数为5
    CAN_InitStructure.CAN_Prescaler = 5;
    // 根据上述配置初始化CAN1
    CAN_Init(CAN1, &CAN_InitStructure);

    // 配置CAN过滤器
    // 设置过滤器编号为0
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    // 设置过滤器工作在标识符掩码模式
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    // 设置过滤器为32位宽
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    // 设置过滤器标识符高16位为0
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    // 设置过滤器标识符低16位为0
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    // 设置过滤器掩码高16位为0
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    // 设置过滤器掩码低16位为0
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    // 将过滤后的消息放入FIFO0
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    // 使能该过滤器
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    // 根据上述配置初始化CAN过滤器
    CAN_FilterInit(&CAN_FilterInitStructure);
}

// 函数功能:发送CAN消息
void CAN_SendMessage(void)
{
    // 定义CAN发送消息结构体
    CanTxMsg TxMessage;
    // 定义邮箱编号
    uint8_t mailbox;

    // 设置标准标识符为0x123
    TxMessage.StdId = 0x123;
    // 设置扩展标识符为0x00
    TxMessage.ExtId = 0x00;
    // 设置使用标准标识符
    TxMessage.IDE = CAN_ID_STD;
    // 设置为数据帧
    TxMessage.RTR = CAN_RTR_DATA;
    // 设置数据长度为8字节
    TxMessage.DLC = 8;
    // 填充数据
    for (uint8_t i = 0; i < 8; i++)
    {
        TxMessage.Data[i] = i;
    }

    // 将消息放入CAN1的发送邮箱,并返回邮箱编号
    mailbox = CAN_Transmit(CAN1, &TxMessage);
    // 等待消息发送成功
    while (CAN_TransmitStatus(CAN1, mailbox) != CAN_TxStatus_Ok);
}

// 函数功能:接收CAN消息
void CAN_ReceiveMessage(void)
{
    // 定义CAN接收消息结构体
    CanRxMsg RxMessage;
    // 检查FIFO0中是否有消息待接收
    if (CAN_MessagePending(CAN1, CAN_FIFO0) > 0)
    {
        // 从FIFO0中接收消息
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
        // 处理接收到的数据,这里只是占位,实际使用时可根据需求添加处理逻辑
        for (uint8_t i = 0; i < RxMessage.DLC; i++)
        {
            // 处理接收到的数据
        }
    }
}

int main(void)
{
    // 调用CAN配置函数,对CAN总线进行初始化
    CAN_Configuration();

    while (1)
    {
        // 调用发送消息函数,发送CAN消息
        CAN_SendMessage();
        // 调用接收消息函数,接收CAN消息
        CAN_ReceiveMessage();
    }
}

代码说明

  • CAN_Configuration函数:对 CAN 总线进行初始化,包含使能 CAN 和 GPIO 时钟、配置 CAN 引脚、初始化 CAN 寄存器和配置 CAN 过滤器。
  • CAN_SendMessage函数:创建一个 CAN 发送消息并发送,等待消息发送成功。
  • CAN_ReceiveMessage函数:检查是否有 CAN 消息待接收,若有则接收消息并处理数据。
  • main函数:初始化 CAN 总线,在循环中不断发送和接收 CAN 消息。

此代码基于 STM32F4 系列微控制器,使用标准外设库。不同的硬件平台和开发环境可能需要对代码进行相应的调整。

<think>好的,用户想查找关于CAN总线学习资料知识点总结。我需要根据提供的引用内容整理出一个清晰的回答,同时生成相关问题。首先,我应该回顾用户提供的引用资料,确保信息准确无误。 首先,用户提供的引用资料涵盖了CAN总线的基本原理、错误处理机制、电平判断、故障节点处理以及物理层特性。我需要将这些内容分门别类,组织成结构化的知识点。例如,可以分成基础概念、错误处理机制、电平标准、应用场景等部分。 接下来,我需要检查每个引用内容,确保引用的正确性。比如引用1提到CSMA/CR,但根据上下文,这可能是一个笔误,因为通常CAN总线使用的是CSMA/CA(载波侦听多路访问/冲突避免),或者可能用户混淆了不同的协议。不过查看用户提供的引用,引用1确实写的是CSMA/CR,可能需要确认是否准确。但根据用户提供的引用内容,直接引用即可,不过可能需要注明可能存在的不一致。 然后,关于差分信号的部分,引用3引用5提到了不同的电压标准。引用3提到高速总线的差分电压为逻辑0时2V,而引用5指出显性电平(逻辑0)下CANH为3.5V,CANL为1.5V,压差2V。这些信息需要整合,说明不同标准下的电平差异,比如ISO 11898-2ISO 11898-3的区别。 错误处理机制在引用2、4中有详细说明,包括错误类型的检测故障节点的隔离。这部分需要详细说明五种错误类型以及如何处理永久性故障。 物理层特性方面,引用35提供了电压参数,需要明确区分高速低速总线的不同电平标准。同时,引用5中的显性电平对应逻辑0,而隐性电平对应逻辑1,这可能容易混淆,需要明确说明。 此外,用户提供的引用还提到了TTCAN,即时间触发CAN,这在引用4中简要提到,可以作为应用场景的一部分。可能需要简要说明其特点。 在组织回答时,应按照逻辑顺序,从基础到高级,逐步展开。每个部分引用对应的文献,确保标注正确。同时,生成的相关问题需要覆盖用户可能感兴趣的扩展内容,比如故障处理、电平标准比较、应用场景等。 需要确保回答中的LaTeX格式正确,行内公式用$...$,独立公式用$$...$$。但根据用户的问题,可能数学公式较少,主要关注文本结构。但如果有涉及电压计算或其他数学表达,需要正确应用格式。 最后,生成的问题应具有针对性,帮助用户深入学习相关知识点。例如,询问错误类型、比较电平标准、故障隔离机制等。 现在检查是否有遗漏的信息点,比如总线仲裁机制、帧格式、位定时等,但根据提供的引用,用户没有给出相关内容,可能不需要包含。但根据CAN总线的常见知识点,是否需要补充?不过用户只提供了特定的引用,应严格基于这些引用进行回答,避免引入外部知识。 总结,回答应包含以下几个部分: 1. 基础原理:包括CSMA/CR(引用1)、差分信号(引用3、5) 2. 错误处理机制:错误类型、故障隔离(引用2、4) 3. 电平标准:高速与低速的差异(引用3、5) 4. 应用场景:如TTCAN(引用4) 生成的问题可以围绕这些部分展开,比如询问错误类型的具体内容,电平标准的比较,故障处理的方法等。</think>### CAN总线知识点总结 #### 1. **基础原理** CAN总线采用**CSMA/CR(载波侦听多路访问/冲突避免)**机制,设备通过监听总线状态判断是否可以发送数据,避免冲突[^1]。数据传输基于**差分信号**,分为高速(ISO 11898-2)低速(ISO 11898-3)两种耦合方式: - **高速总线**:逻辑1对应差分电压$0\ \mathrm{V}$,逻辑0对应$2\ \mathrm{V}$(显性电平)[^3]。 - **实际电平**:显性电平(逻辑0)时,CANH为$3.5\ \mathrm{V}$,CANL为$1.5\ \mathrm{V}$,压差$2\ \mathrm{V}$;隐性电平(逻辑1)时,CANH与CANL均为$2.5\ \mathrm{V}$[^5]。 #### 2. **错误检测与处理** CAN总线能区分**暂时性错误**(如外部噪声)**永久性故障**(如断线),并自动隔离故障节点[^2]。控制器会检测以下五类错误: 1. 位错误 2. 填充错误(位填充规则违反) 3. CRC错误 4. 帧格式错误 5. 应答错误[^4]。 #### 3. **故障节点处理** 系统通过错误计数器定位故障节点,若某节点持续发送错误帧,则会被**自动关闭**,避免影响整体通信[^4]。 #### 4. **应用场景** - **实时控制**:如汽车ECU通信。 - **工业自动化**:设备状态监控。 - **扩展协议**:如**TTCAN(时间触发CAN)**,通过时间同步提升确定性[^4]。 --- ### 学习资料推荐 1. **ISO 11898标准文档**:涵盖物理层与数据链路层规范。 2. **《CAN总线设计与应用》**:详解协议栈设计与实例。 3. **厂商手册**:如NXP、TI的CAN控制器芯片手册。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值