当前位置: 首页 > news >正文

HAL_CAN

文章目录

  • 一、CAN 简介
    • 1、CAN 总线
    • 2、CAN 核心硬件特点
    • 3、CAN 物理信号线详解
    • 4、CAN 两大协议标准
    • 5、典型应用场景
  • 二、CAN 模块详解
    • 1、CAN功能框图
      • 该芯片内置两路 CAN2.0B 控制器:
      • ① 控制 / 状态配置寄存器组(CAN1 主 + CAN2 从两套独立)
      • ② 发送邮箱模块(主 CAN1 + 从 CAN2 各 3 个发送邮箱)
      • ③ 主接收 FIFO0 / FIFO1(仅 CAN1 拥有双 FIFO)
      • ④ 验收筛选器组(CAN1 独占,共 28 组:主 0~27、从 0~27)
      • ⑤ 共享 512Byte SRAM & 存储器访问控制器
    • 2、CAN基本结构
      • 1.基本功能框图
      • 2. 接收流程
      • 3. 发送流程
      • 4.发送和接收配置位
    • 3、标识符过滤器
      • 1.过滤器能功框图
      • 2.过滤顺配置示例
    • 4、测试模式
      • 1.静默模式
      • 2.环回模式
      • 3.环回静默模式
    • 5、工作模式
    • 6、位时间特性
      • 1.时钟来源
      • 2.单时间TQ时长
      • 3.1位总TQ个数
      • 4.波特率计算
      • 5.常用波特率配置
      • 6.位时序图
    • 7、中断
    • 8、时间触发通信
    • 9、错主处理和离线恢复
    • 10、CAN 与 UART/SPI/IIC 核心区别
  • 三、CubeMX 标准 CAN 配置
    • 1、基础配置
      • Bit Timings Parameters
      • Basic Parameters(工程推荐全开容错)
      • Advanced Parameters
    • 2、关键模式说明
    • 3、配置注意事项
  • 四、CAN编程模块
    • 1、CAN结构
      • 1.CAN_HandleTypeDef 外设句柄(顶层总控)
      • 2.CAN_InitTypeDef 初始化时序结构体
      • 3.CAN_FilterTypeDef 过滤器结构体(框图过滤器核心)
      • 4.CAN_TxHeaderTypeDef 发送报文头(对应 3 个发送邮箱)
      • 5.CAN_RxHeaderTypeDef 接收报文头(对应 FIFO 缓存)
    • 2、HAL_CAN_API
      • 1.初始化 / 反初始化类
      • 2.过滤器配置专用
      • 3.外设启停控制
      • 4.报文发送操作
      • 5.报文接收操作
      • 6.中断管理
      • 7.状态 / 错误查询
      • 8.低功耗睡眠模式
  • 五、CAN 应用实例
    • 1、CubeMX配置
      • 1.Bit Timings Parameters(工业标准 500kbps,PCLK1=36M)
      • 2.Basic Parameters(工程推荐全开容错)
      • 3.Advanced Parameters
      • 4.NVIC 中断配置(中断接收必备)
      • 5.配置完成在代码生成后使能CAN
    • 2、发送代码参考
    • 3、过滤器配置代码参考
    • 4、接收代码参考
    • 5、实验结果
  • 六、CAN 核心要点与避坑大全
    • 1、核心知识点
    • 2、高频坑点
    • 3、工程最佳实践
    • 4、一句话总结
  • 七、全篇总结

一、CAN 简介

1、CAN 总线

CAN(Controller Area Network,控制器局域网),是一种串行、异步、差分、多主、高可靠现场总线,专为复杂电磁环境、多设备组网通信设计,是车载电子、工业控制、机器人、智能家居的核心通信总线。
不同于UART/SPI/IIC板内短距离通信,CAN支持远距离、抗干扰强、多设备无主组网、自动仲裁容错,是唯一可用于工业和车载恶劣环境的低速总线。

2、CAN 核心硬件特点

差分信号传输:CAN_H、CAN_L 差分电压传输,抗电磁干扰能力极强。
多主架构:无固定主机从机,任意节点均可主动发送数据。
总线仲裁机制:多节点同时发数据时,ID优先级自动仲裁,无数据冲突。
自带错误容错:硬件自动重发、错误计数、离线保护。
远距离通信:125Kbps下可通信1000米,远超其他串口。
总线广播机制:一发多收,全网节点均可监听数据。

3、CAN 物理信号线详解

闭环总线网络

开环总线网络:

CAN_H:总线高位差分线。
CAN_L:总线低位差分线。
120Ω、2.2kΩ终端电阻:总线首尾节点必须并联,用于阻抗匹配、防止信号反射。
正常工作电平:显性电平(CAN_H高、CAN_L低,差分压差)、隐性电平(双线电平近似相等,压差为0)。

4、CAN 两大协议标准

CAN 2.0A(标准帧):11位ID,设备少、简单组网使用。
CAN 2.0B(扩展帧):29位ID,海量设备组网、车载设备标配。

5、典型应用场景

车载电子:汽车仪表、电机控制、车身组网、自动驾驶外设。
工业控制:PLC通信、工业传感器、伺服电机组网。
机器人:多舵机、多控制器协同通信。
楼宇智能、无人设备、恶劣电磁环境数据传输。

二、CAN 模块详解

1、CAN功能框图

该芯片内置两路 CAN2.0B 控制器:

CAN1(主):拥有完整硬件资源(发送邮箱、接收 FIFO、28 组验收筛选器),具备筛选器主控权;
CAN2(从):无独立筛选器,复用 CAN1 的验收筛选器,仅自带控制状态寄存器、收发缓存;
两者共用一片 512Byte 片内 SRAM 作为报文存储区,由存储器访问控制器统一调度。

① 控制 / 状态配置寄存器组(CAN1 主 + CAN2 从两套独立)

每套 CAN 都拥有独立寄存器,功能完全一致:
主控制:使能 CAN、睡眠模式、软件复位、自动重发、时间触发模式开关。
主状态:总线空闲 / 发送忙 / 接收忙、总线错误、离线状态标记。
发送状态:3 个发送邮箱空满、发送完成、发送失败标记。
接收 FIFO 0/1 状态:FIFO 满、FIFO 溢出、新报文到达标志。
中断使能:发送完成、接收报文、错误、总线离线中断开关。
错误状态:发送错误计数 TEC、接收错误计数 REC、错误类型位。
位定时:配置波特率、采样点、同步跳转宽度 BS1/BS2。
筛选器专属寄存器(仅 CAN1 有效):筛选器主模式、单 / 双 32 位模式、FIFO 分配、筛选器激活开关。
主从差异:
CAN2 无筛选器配置寄存器,所有报文过滤规则全部由 CAN1 统一配置。

② 发送邮箱模块(主 CAN1 + 从 CAN2 各 3 个发送邮箱)

CAN1:主发送邮箱 0/1/2;CAN2:从发送邮箱 0/1/2;
每个邮箱存储一帧完整 CAN 报文(ID + 数据长度 + 8 字节数据);
内置传输调度程序:硬件自动仲裁 3 个邮箱优先级,按 ID 优先级顺序发送;
发送流程:CPU 填充邮箱 → 置位发送请求 → 调度器竞争总线 → 总线发送完成置中断标志。

③ 主接收 FIFO0 / FIFO1(仅 CAN1 拥有双 FIFO)

两路独立先进先出接收缓冲区,硬件自动分流匹配报文:
FIFO0:分配低序号筛选器报文;FIFO1:分配高序号筛选器报文;
每个 FIFO 内置 3 级缓存,支持连续接收多帧不丢失;
报文匹配筛选器后,硬件自动存入对应 FIFO,产生接收中断;
读取报文后 CPU 释放缓存空间,FIFO 自动移位。

④ 验收筛选器组(CAN1 独占,共 28 组:主 0~27、从 0~27)

核心报文过滤硬件,CAN2 完全复用此模块,是双 CAN 架构核心:
总计 28 个筛选器单元,支持两种模式:
32 位模式:单个筛选器匹配标准 ID + 扩展 ID + 掩码;
16 位双筛选:一个单元拆为两组短 ID 筛选;
每个筛选器可绑定分配到 FIFO0 或 FIFO1;
报文流程:总线接收报文 → 筛选器匹配校验 → 匹配成功送入对应 FIFO,匹配丢弃;
CAN1 为主控,可开启 / 关闭、配置所有筛选器;CAN2 无配置权限,仅共享过滤规则。

⑤ 共享 512Byte SRAM & 存储器访问控制器

存储资源:整片 512 字节 SRAM 由 CAN1、CAN2 共同占用,存放所有发送邮箱、接收 FIFO、筛选器掩码 / ID 表;
存储器访问控制器:硬件仲裁 CPU/CAN1/CAN2 的读写请求,避免 SRAM 访问冲突;
资源分配规则:
CAN1 占用大部分缓存;CAN2 仅占用自身 3 个发送邮箱缓存;
筛选器表、CAN1 接收 FIFO 固定占用 SRAM 前段空间。

2、CAN基本结构

1.基本功能框图

2. 接收流程

CAN 总线差分信号 → CAN 内核位同步 → 报文帧接收 → 筛选器匹配校验 → 匹配成功存入CAN1 FIFO0/FIFO1 → CPU 读取 FIFO 数据。

3. 发送流程

CPU 填充 CAN1/CAN2 发送邮箱(主 / 从邮箱)→ 传输调度程序仲裁发送顺序 → 存储器控制器读取 SRAM 报文 → CAN 内核编码输出到 CAN 总线。

4.发送和接收配置位

NART:
置1,关闭自动重传,CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失);置0,自动重传,CAN硬件在发送报文失败时会一直自动重传直到发送成功。
TXFP:
置1,优先级由发送请求的顺序来决定,先请求的先发送;置0,优先级由报文标识符来决定,标识符值小的先发送(标识符值相等时,邮箱号小的报文先发送)。
RFLM:
置1,接收FIFO锁定,FIFO溢出时,新收到的报文会被丢弃;置0,禁用FIFO锁定,FIFO溢出时,FIFO中最后收到的报文被新报文覆盖

3、标识符过滤器

1.过滤器能功框图

每个过滤器的核心由两个32位寄存器组成:R1[31:0]和R2[31:0]。
FSCx:位宽设置
置0,16位;置1,32位。
FBMx:模式设置
置0,屏蔽模式;置1,列表模式。
FFAx:关联设置
置0,FIFO 0;置1,FIFO 1。
FACTx:激活设置
置0,禁用;置1,启用。

2.过滤顺配置示例

4、测试模式

1.静默模式

用于分析CAN总线的活动,不会对总线造成影响。

2.环回模式

用于自测试,同时发送的报文可以在CAN_TX引脚上检测到。

3.环回静默模式

用于热自测试,自测的同时不会影响CAN总线。

5、工作模式

初始化模式:用于配置CAN外设,禁止报文的接收和发送。
正常模式:配置CAN外设后进入正常模式,以便正常接收和发送报文。
睡眠模式:低功耗,CAN外设时钟停止,可使用软件唤醒或者硬件自动唤醒。
AWUM:置1,自动唤醒,一旦检测到CAN总线活动,硬件就自动清零SLEEP,唤醒CAN外设;置0,手动唤醒,软件清零SLEEP,唤醒CAN外设。

6、位时间特性

1.时钟来源

STM32F103 的 CAN 外设挂载 APB1 总线。
系统时钟 SYSCLK=72MHz,APB1 预分频器 = 2 → PCLK1 = 36MHz(工程最常用)。
APB1 预分频 = 1 时,PCLK1=72MHz。

2.单时间TQ时长

TQ = Prescaler/PCLK1。Prescaler:CAN 分频器(CubeMX 参数 Prescaler for Time Quantum)

3.1位总TQ个数

CAN 一位分为 4 段:SYNC_SEG (固定 1TQ) + BS1 + BS2
(TotalTQ = 1 + BS1 + BS2)

4.波特率计算

BaudRate = PCLK1/Prescaler/(1+BS1+BS2)

5.常用波特率配置

目标波特率PrescalerBS1BS2TotalTQ采样点
1000 kbps21321687.5%
750 kbps31321687.5%
500 kbps41321687.5%
250 kbps81321687.5%
125 kbps161321687.5%
50 kbps401321687.5%
20 kbps1001321687.5%

6.位时序图


SS = 1Tq。
BS1 = 1~16Tq。
BS2 = 1~8Tq。
SJW=1~4Tq。
波特率 = APB1时钟频率 / 分频系数 / 一位的Tq数量
= 36MHz / (BRP[9:0]+1) / (1 + (TS1[3:0]+1) + (TS2[2:0]+1))

7、中断

CAN外设占用4个专用的中断向量:
发送中断:发送邮箱空时产生。
FIFO 0中断:收到一个报文/FIFO 0满/FIFO 0溢出时产生。
FIFO 1中断:收到一个报文/FIFO 1满/FIFO 1溢出时产生。
状态改变错误中断:出错/唤醒/进入睡眠时产生。

8、时间触发通信

TTCM:置1,开启时间触发通信功能;置0,关闭时间触发通信功能。
CAN外设内置一个16位的计数器,用于记录时间戳。
TTCM置1后,该计数器在每个CAN位的时间自增一次,溢出后归零。
每个发送邮箱和接收FIFO都有一个TIME[15:0]寄存器,发送帧SOF时,硬件捕获计数器值到发送邮箱的TIME寄存器,接收帧SOF时,硬件捕获计数器值到接收FIFO的TIME寄存器。
发送邮箱可配置TGT位,捕获计数器值的同时,也把此值写入到数据帧数据段的最后两个字节,为了使用此功能,DLC必须设置为8。

9、错主处理和离线恢复

TEC和REC根据错误的情况增加或减少。
ABOM:
置1,开启离线自动恢复,进入离线状态后,就自动开启恢复过程;
置0,关闭离线自动恢复,软件必须先请求进入然后再退出初始化模式,随后恢复过程才被开启。

10、CAN 与 UART/SPI/IIC 核心区别

通信总线CANUARTSPIIIC
传输方式差分异步单端异步单端同步单端同步
组网方式多主多从、无冲突仲裁一对一一主多从(片选)一主多从(地址)
抗干扰极强(差分传输)
传输距离最远1000米几十米板内短距离板内短距离
容错能力硬件自动容错重发无硬件容错无硬件容错无硬件容错

三、CubeMX 标准 CAN 配置

1、基础配置

Parameter Settings 位时序 & 基础参数(工业标准 500kbps,PCLK1=36M)

Bit Timings Parameters

参数标准配置说明
Prescaler (for Time Quantum)4时钟分频
Time Quanta in Bit Segment 113BS1,保证高采样点
Time Quanta in Bit Segment 22BS2
ReSynchronization Jump Width(SJW)1同步宽度

Basic Parameters(工程推荐全开容错)

Time Triggered Communication Mode:Disable。
Automatic Bus-Off Management:Enable(总线短路自动恢复)。
Automatic Wake-Up Mode:Disable。
Automatic Retransmission:Enable(发送失败自动重发)。
Receive Fifo Locked Mode:Disable。
Transmit Fifo Priority:Disable(硬件按 ID 仲裁优先级)。

Advanced Parameters

Test Mode:
Normal(正常总线模式)
Loopback:内部自测;
Silent:仅监听不发送

2、关键模式说明

Normal 正常模式:真实总线收发,工程正式使用。
Loopback 回环模式:内部自收自发,无需外接设备,纯代码调试。
Silent 静默模式:只接收不发送,总线监听专用。

3、配置注意事项

总线两端必须焊接120Ω终端电阻,否则通信乱码、丢包。
所有CAN节点波特率、时序参数必须完全一致。
未配置过滤器或过滤器屏蔽错误,会接收不到数据。
调试优先使用回环模式,无需外接硬件即可验证代码。

四、CAN编程模块

1、CAN结构

1.CAN_HandleTypeDef 外设句柄(顶层总控)

typedef struct { CAN_TypeDef *Instance; // CAN寄存器基地址(CAN1/CAN2) CAN_InitTypeDef Init; // 时序、工作模式配置 CAN_FilterTypeDef FilterConfig; // 过滤器配置缓存 HAL_LockTypeDef Lock; // 互斥锁,多任务防冲突 __IO HAL_StateTypeDef State; // 外设运行状态 __IO uint32_t ErrorCode; // 硬件错误标志 } CAN_HandleTypeDef;

2.CAN_InitTypeDef 初始化时序结构体

对应框图位定时、总线基础功能开关 typedef struct { uint32_t Prescaler; // 波特率分频TQ uint32_t Mode; // 工作模式:正常/自测/监听 uint32_t SyncJumpWidth; // SJW同步跳转宽度 uint32_t TimeSeg1; // BS1时间段 uint32_t TimeSeg2; // BS2时间段 FunctionalState TimeTriggeredMode; // TTCAN时间触发关闭/开启 FunctionalState AutoBusOff; // 总线离线自动恢复 FunctionalState AutoWakeUp; // 总线唤醒睡眠 FunctionalState AutoRetransmission; // 发送失败自动重发 FunctionalState ReceiveFifoLocked; // FIFO满锁定不覆盖旧数据 FunctionalState TransmitFifoPriority; // 邮箱ID优先级发送 } CAN_InitTypeDef;

3.CAN_FilterTypeDef 过滤器结构体(框图过滤器核心)

HAL_CAN_ConfigFilter() 入参,对应硬件 0~27 组 Filter Bank typedef struct { uint32_t FilterBank; // 过滤器编号0~27 uint32_t FilterMode; // 模式:掩码匹配/列表匹配 uint32_t FilterScale; // 位宽:32位(单ID)/16位(双ID) uint32_t FilterIdHigh; // ID寄存器高16位 uint32_t FilterIdLow; // ID寄存器低16位 uint32_t FilterMaskHigh; // 掩码寄存器高16位 uint32_t FilterMaskLow; // 掩码寄存器低16位 uint32_t FilterFIFOAssignment; // 匹配报文送入FIFO0/FIFO1 uint32_t FilterActivation; // 过滤器使能/关闭 uint32_t SlaveFilterBank; // 双CAN时分配给CAN2的过滤器段 } CAN_FilterTypeDef;

4.CAN_TxHeaderTypeDef 发送报文头(对应 3 个发送邮箱)

填充后调用HAL_CAN_AddTxMessage()写入发送邮箱 typedef struct { uint32_t StdId; // 标准ID 0~0x7FF uint32_t ExtId; // 扩展ID 0~0x1FFFFFFF uint32_t IDE; // 帧类型:标准帧CAN_ID_STD / 扩展帧CAN_ID_EXT uint32_t RTR; // 远程帧CAN_RTR_REMOTE / 数据帧CAN_RTR_DATA uint32_t DLC; // 数据长度0~8字节 FunctionalState TransmitGlobalTime; // 时间触发时间戳 } CAN_TxHeaderTypeDef;

5.CAN_RxHeaderTypeDef 接收报文头(对应 FIFO 缓存)

HAL_CAN_GetRxMessage() 读取 FIFO 报文输出参数 typedef struct { uint32_t StdId; // 接收报文标准ID uint32_t ExtId; // 接收报文扩展ID uint32_t IDE; // 标准/扩展帧标识 uint32_t RTR; // 数据帧/远程帧标识 uint32_t DLC; // 接收数据长度 uint32_t FilterMatchIndex; // 匹配的过滤器编号 } CAN_RxHeaderTypeDef;

2、HAL_CAN_API

1.初始化 / 反初始化类

HAL_CAN_Init(CAN_HandleTypeDef *hcan):根据句柄 Init 配置初始化 CAN 外设时序与模式。 HAL_CAN_DeInit(CAN_HandleTypeDef *hcan):复位 CAN 外设,清空运行状态。 HAL_CAN_MspInit(CAN_HandleTypeDef *hcan):底层 MSP 初始化,开启时钟、配置 TX/RX 引脚复用。 HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan):释放 CAN 底层资源,关闭外设时钟、恢复 GPIO。

2.过滤器配置专用

HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig):配置 ID 过滤器,设置匹配规则与绑定 FIFO。

3.外设启停控制

HAL_CAN_Start(CAN_HandleTypeDef *hcan):使能 CAN 内核,退出睡眠,进入正常收发状态。 HAL_CAN_Stop(CAN_HandleTypeDef *hcan):关闭 CAN 内核,进入睡眠,停止总线收发。

4.报文发送操作

HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pTxHeader, const uint8_t *pData, uint32_t *pTxMailbox):填充空闲发送邮箱,载入待发报文,返回使用的邮箱号。 HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailbox):取消指定邮箱未发送报文,释放邮箱缓存。 HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan):查询当前空闲发送邮箱数量(0~3)。 HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailbox):查询指定邮箱是否存在待发送报文。

5.报文接收操作

HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pRxHeader, uint8_t *pData):从指定 FIFO 读取一帧完整接收报文。 HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo):查询 FIFO 内缓存的未读报文数量(0~3)。 HAL_CAN_ClearRxFifoOverrunFlag(CAN_HandleTypeDef *hcan, uint32_t RxFifo):清除 FIFO 报文溢出标志,代表存在丢帧。

6.中断管理

中断开关: HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs):开启指定 CAN 中断(接收 / 发送 / 故障)。 HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs):关闭指定 CAN 中断 中断底层入口: HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan):CAN 中断服务总入口,解析中断标志并分发对应回调 发送完成回调(用户重写): void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan):邮箱 0 报文发送完成回调。 void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan):邮箱 1 报文发送完成回调。 void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan):邮箱 2 报文发送完成回调。 FIFO 接收回调(用户重写): void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan):FIFO0 收到新报文中断回调。 void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan):FIFO1 收到新报文中断回调。 FIFO 状态异常回调(用户重写): void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan):FIFO0 缓存已满中断回调。 void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan):FIFO1 缓存已满中断回调。 void HAL_CAN_RxFifo0OverrunCallback(CAN_HandleTypeDef *hcan):FIFO0 报文溢出丢帧回调。 void HAL_CAN_RxFifo1OverrunCallback(CAN_HandleTypeDef *hcan):FIFO1 报文溢出丢帧回调。 总线故障回调(用户重写): void HAL_CAN_BusOffCallback(CAN_HandleTypeDef *hcan):总线离线 BusOff 严重故障回调。 void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan):通用硬件错误中断回调(位错 / 仲裁丢失等)。

7.状态 / 错误查询

HAL_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan):获取 CAN 外设当前运行状态(就绪 / 忙 / 错误)。 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan):读取 CAN 硬件错误标志位。 HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan):清除硬件错误计数 TEC/REC 与错误标志。

8.低功耗睡眠模式

HAL_CAN_EnterSleepMode(CAN_HandleTypeDef *hcan):控制 CAN 进入低功耗睡眠模式。 HAL_CAN_WakeUpFromSleepMode(CAN_HandleTypeDef *hcan):软件唤醒睡眠中的 CAN 外设,恢复通信。

五、CAN 应用实例

1、CubeMX配置

1.Bit Timings Parameters(工业标准 500kbps,PCLK1=36M)

参数标准配置说明
Prescaler (for Time Quantum)4时钟分频
Time Quanta in Bit Segment 113BS1,保证高采样点
Time Quanta in Bit Segment 22BS2
ReSynchronization Jump Width(SJW)1同步宽度

2.Basic Parameters(工程推荐全开容错)

Time Triggered Communication Mode:Disable(TTCAN 时间触发模式)
Automatic Bus-Off Management:Enable(总线短路自动恢复)
Automatic Wake-Up Mode:Disable(总线自动唤醒)
Automatic Retransmission:Enable(发送失败自动重发)
Receive Fifo Locked Mode:Disable(FIFO 满锁定)
Transmit Fifo Priority:Disable(硬件按 ID 仲裁优先级)

3.Advanced Parameters

Test Mode:
Normal(正常总线模式)
Loopback(内部自测)
Silent(仅监听不发送)

4.NVIC 中断配置(中断接收必备)

5.配置完成在代码生成后使能CAN

//使能CAN HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);

2、发送代码参考

CAN_TxHeaderTypeDef can_Tx; uint8_t sendBuf[5] = {"hello"}; uint32_t box; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_CAN_Init(); HAL_CAN_Start(&hcan); can_Tx.StdId = 0x123; can_Tx.ExtId = 0; can_Tx.IDE = CAN_ID_STD; can_Tx.RTR = CAN_RTR_DATA; can_Tx.DLC = 5; can_Tx.TransmitGlobalTime = DISABLE; while (1) { HAL_CAN_AddTxMessage(&hcan, &can_Tx, sendBuf, &box); HAL_Delay(100); } }

3、过滤器配置代码参考

//1.配置为CAN总线上所有的报文都会被接收,并存入FIFO0中。 CAN_FilterTypeDef can_Filter = {0}; can_Filter.FilterIdHigh = 0; can_Filter.FilterIdLow = 0; can_Filter.FilterMaskIdHigh = 0; can_Filter.FilterMaskIdLow = 0; can_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; can_Filter.FilterBank = 0; can_Filter.FilterMode = CAN_FILTERMODE_IDMASK; can_Filter.FilterScale = CAN_FILTERSCALE_32BIT; can_Filter.FilterActivation = CAN_FILTER_ENABLE; HAL_CAN_ConfigFilter(&hcan, &can_Filter); //2.配置仅接收标准ID为0x0的数据帧和遥控帧,并存入FIFO0中。 /* CAN_FilterTypeDef can_Filter = {0}; can_Filter.FilterIdHigh = 0; can_Filter.FilterIdLow = 0; can_Filter.FilterMaskIdHigh = 0; can_Filter.FilterMaskIdLow = 2; can_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; can_Filter.FilterBank = 0; can_Filter.FilterMode = CAN_FILTERMODE_IDLIST; can_Filter.FilterScale = CAN_FILTERSCALE_32BIT; can_Filter.FilterActivation = CAN_FILTER_ENABLE; HAL_CAN_ConfigFilter(&hcan, &can_Filter); */

4、接收代码参考

使能CAN外设中断函数:
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
实例代码:

#include <stdio.h> CAN_RxHeaderTypeDef can_Rx; uint8_t recvBuf[8]; uint8_t uartBuf[64]; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_CAN_Init(); MX_USART1_UART_Init() CAN_FilterTypeDef can_Filter = {0}; can_Filter.FilterIdHigh = 0; can_Filter.FilterIdLow = 0; can_Filter.FilterMaskIdHigh = 0; can_Filter.FilterMaskIdLow = 0; can_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; can_Filter.FilterBank = 0; can_Filter.FilterMode = CAN_FILTERMODE_IDMASK; can_Filter.FilterScale = CAN_FILTERSCALE_32BIT; can_Filter.FilterActivation = CAN_FILTER_ENABLE; HAL_CAN_ConfigFilter(&hcan1, &can_Filter); HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); HAL_CAN_Start(&hcan); while (1) { } } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { uint16_t len = 0; HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &can_Rx, recvBuf); if(can_Rx.IDE == CAN_ID_STD) { len += sprintf((char *)&uartBuf[len], "标准ID:%#X; ", can_Rx.StdId); } else if(can_Rx.IDE == CAN_ID_EXT) { len += sprintf((char *)&uartBuf[len], "扩展ID:%#X; ", can_Rx.ExtId); } if(can_Rx.RTR == CAN_RTR_DATA) { len += sprintf((char *)&uartBuf[len], "数据帧; 数据为:"); for(int i = 0; i < can_Rx.DLC; i ++) { len += sprintf((char *)&uartBuf[len], "%X ", recvBuf[i]); } len += sprintf((char *)&uartBuf[len], "\r\n"); HAL_UART_Transmit(&huart, uartBuf, len, 100); } else if(can_Rx.RTR == CAN_RTR_REMOTE) { len += sprintf((char *)&uartBuf[len], "遥控帧\r\n"); HAL_UART_Transmit(&huart, uartBuf, len, 100); } }

5、实验结果

六、CAN 核心要点与避坑大全

1、核心知识点

CAN为差分异步多主总线,抗干扰强、支持远距离组网。
ID越小优先级越高,硬件自动仲裁,无总线冲突。
总线首尾必须120Ω终端电阻,是通信成功的前提。
单帧最大8字节数据,超长数据需分包传输。
必须配置过滤器,否则无法正常接收总线数据。
支持自动重发、错误计数、总线离线保护。

2、高频坑点

未接120Ω终端电阻,导致信号反射、乱码、丢包严重。
多设备波特率、时序参数不统一,总线通信失败。
忘记配置过滤器或过滤器屏蔽全部ID,接收不到数据。
单帧发送数据超过8字节,触发传输错误。
总线干扰严重导致报错、离线,未开启自动恢复。
混淆标准帧与扩展帧ID,数据收发不匹配。

3、工程最佳实践

调试阶段使用回环模式,快速验证代码逻辑。
正式工程开启自动重发、自动总线离线恢复。
统一使用500Kbps标准波特率,设备兼容性最强。
采用中断方式接收,实时响应总线数据。
超长数据自定义分包协议,规避8字节单帧限制。
增加总线错误检测与重连机制,提升工业稳定性。

4、一句话总结

CAN是差分异步多主现场总线,依靠CAN_H/CAN_L差分传输实现强抗干扰,通过ID优先级硬件仲裁避免总线冲突,自带错误容错与自动重发机制,支持多设备远距离组网,是车载与工业控制的核心通信总线。

七、全篇总结

CAN 是嵌入式工业与车载领域的核心总线,区别于普通板级通信总线,具备高抗干扰、多主组网、硬件容错、远距离传输的核心优势。
掌握 CAN 时序原理、仲裁机制、过滤器配置、CubeMX工程配置、中断收发实战代码,即可独立完成工业组网、车载设备、机器人多机通信项目开发,是嵌入式高薪进阶的必备核心技能。

http://www.gsyq.cn/news/1624652.html

相关文章:

  • 边缘计算中DNN模型保护的ConvShatter技术解析
  • 终极B站视频下载指南:解锁大会员4K和充电专属内容
  • Oracle EBS配置器未授权访问漏洞(CVE-2025-61884)深度剖析与防护实践
  • 本地部署AI Agent,6G显存跑Qwen3.6-35B-A3B 从入门到实战全流程
  • OpenClaw与QQ Bot集成开发指南
  • 我为能准时下班而做的准备,以及由此的收获,同时总结下不足
  • 2026不花百万到纳米级:国产轮廓仪精度实测
  • 做好谷歌网站内容营销:5 类高转化文章模板,直接复制落地
  • 一人公司OPC——AI实战培训怎么让一个人具备完整战斗力
  • Node.js跨平台路径处理与path.normalize实战指南
  • 【239期】斩获一万星标!GitHub免费开源Win系统优化工具。
  • 漫话JavaScript与异步·第三话——Generator:化异步为同步一、Promise并非完美
  • Three.js 高斯sparkjs教程
  • 从M4Markets客服回应来看,该怎么看?
  • 05-服务端渲染与元框架——10. 字体优化 - next/font
  • 专知智库 · 定义者时代的思想架构师——将企业关键资产转化为市场思想领导力
  • SpringBoot+MySQL实战:从零搭建企业级后台管理系统
  • 多模态安全审核:图像/音频内容合规检测与Agent对齐护栏
  • 【从0到1构建一个ClaudeAgent】工具与执行-Agent循环
  • 强力解锁浏览器画中画功能:告别视频观看的割裂体验
  • CI/CD 回滚演练:能发布,也要能撤回来
  • 贝叶斯优化:用高斯过程与采集函数实现智能超参数调优
  • 统一多模态Agent编排:用单一模型驱动多感官任务的可行性与边界
  • 基于HuggingFace生态的Zero_NLP项目实战指南:从Transformer模型微调到中文文本分类与NER任务的深度解析
  • Claude Code 国内安装与实战指南:AI 编程助手从零到项目集成
  • FanControl终极指南:3步搞定Windows风扇控制,告别噪音与高温
  • 企业级AI集成实战:Agent、RAG与MCP架构深度解析
  • Three.js 本地模型加载教程
  • 离线运行的 3D 模型处理工具,保密项目的稳妥选择
  • openEuler Compiler-docs技术白皮书解读:LLVM构建openEuler的完整技术方案