CAN通信

基本介绍:

CAN,是ISO国际标准化的串行通信协议。

低速CAN  10~125K  长度达1000M

高速CAN 125K~1M  总线<=40M

CAN总线拓扑图:

多主控制,每一个设备都可以主动发送数据;没有地址的信息,添加设备不改变原来总线的状态;速度块,距离远;错误检测&错误通知&错误恢复功能;判断故障类型,并进行隔离;

使用差分信号进行数据传输,根据CANH、CANL电位差判断总线电平。

   CAN(Controller Area Network)通信 是一种广泛应用于汽车、工业控制等领域的高可靠性串行通信协议,具备抗干扰、多主节点、实时性强等特点。以下是CAN通信的全面解析:

一、CAN核心特性

  1. 多主架构

    • 任一节点均可主动发送数据,总线仲裁机制避免冲突。
  2. 高可靠性

    • 差分信号(CAN_H/CAN_L)抗电磁干扰。
    • CRC校验 + ACK确认保证数据完整性。
  3. 实时性

    • 非破坏性仲裁(基于标识符ID优先级),高优先级数据优先传输。
  4. 灵活拓扑

    • 支持总线型、星型等多种拓扑,最大节点数可达110个(理论值)。

二、CAN协议帧结构

1. 数据帧

| SOF | ID(11/29位) | RTR | IDE | DLC | Data(0-8字节) | CRC | ACK | EOF |

  • SOF:帧起始(1 bit)。
  • ID:标识符(标准帧11位,扩展帧29位)。
  • DLC:数据长度码(0~8字节)。
  • Data:有效载荷。
2. 远程帧

用于请求其他节点发送数据(无数据字段)。

3. 错误帧与过载帧

用于错误通知和流量控制。

三、CAN通信实现步骤(以STM32为例)

1. 硬件连接
  • CAN收发器(如TJA1050)连接MCU与总线:
    STM32 CAN_TX → 收发器TXD  
    STM32 CAN_RX ← 收发器RXD  
    收发器CAN_H → 总线CAN_H  
    收发器CAN_L → 总线CAN_L  

  • 终端电阻:总线两端需接120Ω电阻(抑制信号反射)。
2. 初始化CAN控制器
// 启用CAN时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

// 配置GPIO(CAN_TX: PA12, CAN_RX: PA11)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  // 复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// 配置CAN工作模式与波特率
CAN_InitTypeDef CAN_InitStruct;
CAN_InitStruct.CAN_TTCM = DISABLE;       // 关闭时间触发模式
CAN_InitStruct.CAN_ABOM = ENABLE;        // 自动离线恢复
CAN_InitStruct.CAN_Prescaler = 4;        // 分频系数
CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;    // 同步跳转宽度
CAN_InitStruct.CAN_BS1 = CAN_BS1_9tq;    // 时间段1长度
CAN_InitStruct.CAN_BS2 = CAN_BS2_4tq;    // 时间段2长度
CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; // 正常模式
CAN_Init(CAN1, &CAN_InitStruct);
3. 配置过滤器(接收特定ID数据)
CAN_FilterInitTypeDef CAN_FilterInitStruct;
CAN_FilterInitStruct.CAN_FilterNumber = 0;         // 过滤器编号
CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;  // 标识符掩码模式
CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit; // 32位过滤
CAN_FilterInitStruct.CAN_FilterIdHigh = 0x123 << 5; // 标准ID高16位(左对齐)
CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000;     
CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0xFFF << 5; // 掩码匹配所有扩展ID
CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_FIFO0; // 数据存入FIFO0
CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStruct);
4. 发送数据
CanTxMsg TxMessage;
TxMessage.StdId = 0x123;               // 标准ID
TxMessage.ExtId = 0x00;                // 扩展ID(标准帧时为0)
TxMessage.IDE = CAN_Id_Standard;       // 标准帧
TxMessage.RTR = CAN_RTR_Data;          // 数据帧
TxMessage.DLC = 8;                     // 数据长度8字节
TxMessage.Data = 0xAA;              // 数据内容
// ...填充Data~Data

// 发送数据
uint8_t mailbox;
mailbox = CAN_Transmit(CAN1, &TxMessage);
while (CAN_TransmitStatus(CAN1, mailbox) != CANTXOK); // 等待发送完成
5. 接收数据(中断方式)
// 启用CAN接收中断
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

// 中断处理函数
void CAN1_RX0_IRQHandler(void) {
    if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET) {
        CanRxMsg RxMessage;
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
        // 处理接收到的数据(例如解析ID和Data)
        CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    }
}

四、CAN波特率计算

  • 公式
    波特率 = APB1时钟 / (Prescaler × (BS1 + BS2 + 1))
  • 示例(APB1=36MHz,目标波特率=500kbps):

    Prescaler = 36MHz / (500k × (9 + 4 + 1)) = 36,000,000 / (500,000 × 14) ≈ 5.14 → 取Prescaler=5 实际波特率 = 36MHz / (5 × 14) = 514,285 bps(误差可接受)

五、常见问题与调试

1. 无法发送或接收数据
  • 检查硬件:确认收发器供电、CAN_H/CAN_L接线、终端电阻。
  • 验证波特率:确保所有节点波特率一致。
  • 逻辑分析仪:抓取总线信号,观察波形是否正常。
2. 总线错误频繁
  • 终端电阻:总线两端必须接120Ω电阻。
  • 电磁干扰:使用屏蔽双绞线,避免与强电线路平行走线。
3. 数据丢失或冲突
  • ID分配:确保高优先级数据使用更小的ID值。
  • 总线负载:控制发送频率(建议负载率<70%)。

六、CAN高层协议

  1. CANopen

    • 工业自动化标准协议,定义对象字典、PDO/SDO通信方式。
  2. J1939

    • 汽车领域协议,用于商用车(如卡车、工程机械)的参数传输。
  3. DeviceNet

    • 基于CAN的设备级网络,适用于工业控制。

七、典型应用场景

领域应用
汽车电子发动机控制、车身网络(ECU间通信)
工业自动化PLC控制、传感器网络
医疗设备监护仪、手术机器人内部通信
航空航天飞行控制系统、机载设备通信

通过掌握CAN通信的核心原理与实现方法,开发者能够构建高可靠、实时的分布式嵌入式系统,满足复杂环境下的通信需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值