STM32-CAN

一、CAN总线简介

1.1 CAN简介

CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信
协议。异步半双工。
ISO11898:123kbps~1Mbps。

ISO11519:125kbps

特点:

  • 多主控制
  • 没有地址信息
  • 速度快,距离远
  • 具有错误检测、错误通知、错误恢复功能
  • 故障封闭功能
  • 多节点连接

1.1.1 ISO11898、ISO11519

帮助记忆:显“0”。多点线与机制,一个是0全是0,所有1才为1。类似于上拉。

差分信号:抗干扰,双绞线(相互抵消电磁干扰),电压差值不变。

1.2 CAN协议帧

  • 数据帧:发送单元向接收单元传送数据。
  • 遥控帧:接收单元向具有相同ID的发送单元请求数据的帧。
  • 错误帧:检测出错误,向其他单元通知错误。
  • 过载帧:接收单元通知为做好准备。
  • 间隔帧:将数据帧及遥控帧与前面的帧分隔开。

1.2.1 数据帧

1.2.1.1 帧起始(1bit)

1bit,显性电平。

1.2.1.2 仲裁段(12bit)
  • 显性电平获取优先。
  • 禁止高7位都为隐性电平(1111111XXXX)。标准:ID10~ID0。扩展:基本ID28~ID18,扩展ID17~ID0。
  • RTR:0数据帧,1远程帧
  • IDE:0标准,1扩展
  • SRR:代替RTR,隐性电平。

1.2.1.3 控制段(6bit)
  • r0,r1:保留,显性电平。
  • DLC:4bit,数据长度,MSB,0~8。

1.2.1.4 数据段(0~8bytes)
  • MSB

1.2.1.5 CRC段(16bit)
  • 计算:帧起始、仲裁段、控制段、数据段。

1.2.1.6 ACK段(2bit)
  • 发送单元:隐性,隐性。
  • 接收单元:显性,隐性。

1.2.1.7 帧结束(7bit隐性)

1.2.2 位时序

1位,分为4个段,每个段分为若干个Tq。

  • 同步段(SS):1Tq,
  • 传播时间段(PTS):1~8Tq,
  • 相位缓冲段1(PBS1):1~8Tq,
  • 相位缓冲段2(PBS2):2~8Tq,
  • 再同步补偿宽度(SJW):1~4T

1.2.3 位填充

当同样的电平持续 5 位时则添加一个位的反型数据。

发送单元的工作

在发送数据帧和遥控帧时,SOF~CRC 段间的数据,相同电平如果持续 5 位,在下一个位(第 6 个位)则要插入 1 位与前 5 位反型的电平。

接收单元的工作

在接收数据帧和遥控帧时,SOF~CRC 段间的数据,相同电平如果持续 5 位,需要删除下一个位(第 6 个位)再接收。如果这个第 6 个位的电平与前 5 位相同,将被视为错误并发送错误帧。

1.2.4 同步

硬件同步(帧起始同步);

再同步(发慢收快,延长相位缓冲段1;发快收慢,缩短相缓2)。

同步规则

  • 每位只同步一次。
  • 任何一个隐性到显性的跳变都可以用于同步。
  • 硬同步发生在SOF,其他接受节点调整各自的同步段。
  • 重同步发生在帧除SOF之外的位置,当跳变沿落在了同步段之外的情况下。

1.2.5 总线优先级

  • 在总线空闲态,最先开始发送消息的单元获得发送权。
  • 多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。
  • 具有相同 ID 的数据帧和遥控帧在总线上竞争时,仲裁段的最后一位(RTR)为显性位的数据帧具有优先权,可继续发送。(数据大于遥控)
  • 标准格式 ID 与具有相同 ID 的遥控帧或者扩展格式的数据帧在总线上竞争时,标准格式的 RTR 位为显性位的具有优先权,可继续发送。(标准大于扩展)

扩展知识:

STM32F1 自带的是 bxCAN,即基本扩展 CAN。它支持 CAN 协议 2.0A 和 2.0B。 CAN2.0A
只能处理标准数据帧,扩展帧的内容会识别错误; CAN2.0B Active 可以处理标准数据帧和扩展
数据帧;而 CAN2.0B passive 只能处理标准数据帧,扩展帧的内容会忽略。 它的设计目标是,
以最小的 CPU 负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性
可软件配置)。

STM32F1 的 bxCAN 的主要特点有:
  • 支持 CAN 协议 2.0A 和 2.0B 主动模式
  • 波特率最高达 1Mbps
  • 支持时间触发通信
  • 具有 3 个发送邮箱
  • 具有 3 级深度的 2 个接收 FIFO
  • 可变的过滤器组(最多 28 个)

过滤器组的位宽和工作模式

为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。
为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。应用程序不用的过滤器组,应该保持在禁用状态。

优先级:32位>16位,标识符列表>屏蔽位,过滤号小的优先级高。

举例说明:过滤器组0工作在:1个32位过滤器-标识符屏蔽模式,CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00,

1.2.6 CAN收发流程

CAN发送

程序选择 1 个空置的邮箱(TME=1) →设置标识符(ID),数据长度和发送数据→设置 CAN_TIxR 的 TXRQ 位为 1,请求发送→邮箱挂号(等待成为最高优先级) →预定发送(等待总线空闲) →发送→邮箱空置。

CAN接收

FIFO 空→收到有效报文→挂号_1(存入 FIFO 的一个邮箱,这个由硬件控制,我们不需要理会) →收到有效报文→挂号_2→收到有效报文→挂号_3→收到有效报文溢出。

通过查询 CAN_RFxR 的 FMP 寄存器来得到,只要 FMP不为 0,我们就可以从 FIFO 读出收到的报文。

STM32的CAN位时间特性:

1.3 CAN寄存器

  • CAN_MCR:INRQ位,先设置为1,初始化,设置为0,正常工作。
  • CAN_BTR:设置分频,Tbs1,Tbs2及Tsjw等参数,进而设置波特率。可以设置环回模式。
  • CAN_TIxR:设置标识符,帧类型。TXRQ请求邮箱发送。x=0~3。
  • CAN_TDTxR:设置数据长度。
  • CAN_TDLxR、CAN_TDHxR:数据。
  • CAN_RIxR:设置接收标识符。
  • CAN_FM1R:设置28个过滤器的模式。
  • CAN_FS1R:设置各过滤器组的位宽。
  • CAN_FFA1R:设置报文存放的FIFO。
  • CAN_FA1R:过滤器激活寄存器。
  • CAN_FiRx:过滤器位。i=0~13,x=1或2。

二、程序设计

2.1 CAN的HAL驱动

HAL_CAN_Init函数

HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan);typedef struct __CAN_HandleTypeDef
{CAN_TypeDef *Instance; /* CAN 控制寄存器基地址 */CAN_InitTypeDef Init; /* 初始化参数结构体 */__IO HAL_CAN_StateTypeDef State; /* CAN 通讯状态 */__IO uint32_t ErrorCode; /* CAN 通讯结果编码 */
} CAN_HandleTypeDef;typedef struct
{uint32_t Prescaler; /* 分频值, 可以配置为 1~1024 间的任意整数 */uint32_t Mode; /* can 操作模式,有效值参考 CAN_operating_mode 的描述 */uint32_t SyncJumpWidth; /* CAN 硬件的最大超时时间 */uint32_t TimeSeg1; /* CAN_time_quantum_in_bit_segment_1 */uint32_t TimeSeg2; /* CAN_time_quantum_in_bit_segment_2 */FunctionalState TimeTriggeredMode; /* 启用或禁用时间触发模式 */FunctionalState AutoBusOff; /* 禁止/使能软件自动断开总线的功能 */FunctionalState AutoWakeUp; /* 禁止/使能 CAN 的自动唤醒功能 */FunctionalState AutoRetransmission; /* 禁止/使能 CAN 的自动传输模式 */FunctionalState ReceiveFifoLocked; /* 禁止/使能 CAN 的接收 FIFO */FunctionalState TransmitFifoPriority; /* 禁止/使能 CAN 的发送 FIFO */
} CAN_InitTypeDef;

HAL_CAN_ConfigFilter 函数

HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan,CAN_FilterTypeDef *sFilterConfig)typedef struct
{uint32_t FilterIdHigh; /* 过滤器标识符高位 */uint32_t FilterIdLow; /* 过滤器标识符低位 */uint32_t FilterMaskIdHigh; /* 过滤器掩码号高位(列表模式下,也是属于标识符) */uint32_t FilterMaskIdLow; /* 过滤器掩码号低位(列表模式下,也是属于标识符) */uint32_t FilterFIFOAssignment; /* 与过滤器组管理的 FIFO */uint32_t FilterBank; /* 指定过滤器组, 单 CAN 为 0~13, 双 CAN 可为 0~27 */uint32_t FilterMode; /* 过滤器的模式 标识符屏蔽位模式/标识符列表模式 */uint32_t FilterScale; /* 过滤器的位宽 32 位/16 位 */uint32_t FilterActivation; /* 禁用或者使能过滤器 */uint32_t SlaveStartFilterBank; /* 双 CAN 模式下,规定 CAN 的主从模式的过滤器分配 */
} CAN_FilterTypeDef;

HAL_CAN_Start 函数

HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);

HAL_CAN_ActivateNotification 函数

HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan,uint32_t ActiveITs);

HAL_CAN_AddTxMessage 函数

HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan,CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)typedef struct
{
uint32_t StdId; /* 标准标识符 11 位 范围:0~0x7FF */
uint32_t ExtId; /* 扩展标识符 29 位 范围:0~0x1FFFFFFF */
uint32_t IDE; /* 标识符类型 CAN_ID_STD / CAN_ID_EXT */
uint32_t RTR; /* 帧类型 CAN_RTR_DATA / CAN_RTR_REMOTE */
uint32_t DLC; /* 帧长度 范围:0~8byte */
FunctionalState TransmitGlobalTime; /* 时间戳是否在开始时捕获 */
} CAN_TxHeaderTypeDef;

HAL_CAN_GetRxMessage 函数

HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, 
uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])typedef struct
{uint32_t StdId; /* 标准标识符 11 位 范围:0~0x7FF */uint32_t ExtId; /* 扩展标识符 29 位 范围:0~0x1FFFFFFF */uint32_t IDE; /* 标识符类型 CAN_ID_STD / CAN_ID_EXT */uint32_t RTR; /* 帧类型 CAN_RTR_DATA / CAN_RTR_REMOTE */uint32_t DLC; /* 帧长度 范围:0~8byte */uint32_t Timestamp; /* 在帧接收开始时开始捕获的时间戳 */uint32_t FilterMatchIndex; /* 过滤器匹配序号 */
} CAN_RxHeaderTypeDef;

2.2 CAN初始化配置步骤

1.CAN参数初始化

can_init(CAN_SJW_1TQ, CAN_BS2_8TQ, CAN_BS1_9TQ, 4, CAN_MODE_LOOPBACK);//500Kbps

2.开启CAN和对应管脚时钟,配置CAN_TX和CAN_RX的复用功能输出

3.设置过滤器

4.CAN数据接收和发送

/**
* @brief CAN 发送一组数据
* @note 发送格式固定为: 标准 ID, 数据帧
* @param id : 标准 ID(11 位)
* @retval 发送状态 0, 成功; 1, 失败;
*/
uint8_t can_send_msg(uint32_t id, uint8_t *msg, uint8_t len)
{uint32_t TxMailbox = CAN_TX_MAILBOX0;g_canx_txheader.StdId = id; /* 标准标识符 */g_canx_txheader.ExtId = id; /* 扩展标识符(29 位) */g_canx_txheader.IDE = CAN_ID_STD; /* 使用标准帧 */g_canx_txheader.RTR = CAN_RTR_DATA; /* 数据帧 */g_canx_txheader.DLC = len;if (HAL_CAN_AddTxMessage(&g_canx_handler, &g_canx_txheader,msg, &TxMailbox) != HAL_OK) /* 发送消息 */{return 1;}/* 等待发送完成,所有邮箱为空(3 个邮箱) */while (HAL_CAN_GetTxMailboxesFreeLevel(&g_canx_handler) != 3);return 0;
}/**
* @brief CAN 接收数据查询
* @note 接收数据格式固定为: 标准 ID, 数据帧
* @param id : 要查询的 标准 ID(11 位)
* @param buf : 数据缓存区
* @retval 接收结果
* @arg 0 , 无数据被接收到;
* @arg 其他, 接收的数据长度
*/
uint8_t can_receive_msg(uint32_t id, uint8_t *buf)
{if (HAL_CAN_GetRxFifoFillLevel(&g_canx_handler, CAN_RX_FIFO0) != 1){return 0;}if (HAL_CAN_GetRxMessage(&g_canx_handler, CAN_RX_FIFO0, &g_canx_rxheader,buf) != HAL_OK){return 0;}/* 接收到的 ID 不对 / 不是标准帧 / 不是数据帧 */if (g_canx_rxheader.StdId!= id || g_canx_rxheader.IDE != CAN_ID_STD ||g_canx_rxheader.RTR != CAN_RTR_DATA){return 0;}return g_canx_rxheader.DLC;
}

三、常见问题

1、为什么用CAN?

汽车的电子控制单元逐渐增多。各电控单元之间的信号交换导致汽车线束的级数增加。大大减少了汽车的线束。可靠性下降。增加了重量。

2、如何减少波特率的误差带来的通信错误?

CAN总线规定信号的跳变沿时刻进行同步,将误差累计限制在两个跳变沿。 当发送数据出现都为0或者1的时候,同样不跳变造成误差累计怎么办? 采用填充位在连续5个相同位后插入一个相反位,产生跳变沿,用于同步。

3、终端电阻的作用

  • 提高抗干扰能力,让高频低能量信号快速走掉。
  • 确保总线快速进入隐性状态,让寄生电容的能量快速走掉。
  • 提高信号质量,放置在总线两端,让反射能量降低。

4、需要在接收数据的时候用一个标志来判断当前发送的数据是真正的命令还是干扰,用一个特殊的值来做为接收指令的开始,这里选用0XA5做为数据的开始,为什么选0xA5呢?

因为0xA5的 二进制数位 1010 0101 刚好是一个1一个0,间隔开,用这个数字做为开始可以很大程度上的避免干扰信号,因为干扰信号一般不会是这种高低高低很有规律的信号。于是协议就改为 0xA5 为第一个数据,做为上位机发送命令的标志。

5、CAN物理层常见故障(CAN示波器)

(1)CAN节点供电正常,CAN工具上就是接收不到CAN报文数据或者报错,可能是什么原因?

首先确定CAN器件程序有bug;终端电阻不匹配;CAN收发器的影响。

(2)测试CAN物理波形,发现报文出现严重的振铃和反射现象?

缩短引线长度;加粗到线、印制铜箔的宽度;减小信号的传输距离;采用引线电感小的元器件;阻抗匹配

(3)通信错误会不会是CAN收发器故障引脚,如何判断收发器的好坏?

可以在ECU上电的CAN总线空闲情况下,测量CANH和CANL对地的电压是否在2.5V左右,如果出现0V或5V之类的,可考虑收发器故障问题。

(4)来自想用厂家的两个CAN节点又可以正常通信,为什么两个不同厂家的CAN节点连接通信时好时坏,甚至不能正常通信?

不同的厂家使用不用的采样点,也有可能造成通信不良。

(5)所有在测ECU节点CAN功能单独测试正常,装车后CAN功能失常,CAN错误频发,特别是新能源车上?

电磁干扰:选择性能好的隔离收发器;增加CAN双绞程度;布线尽量远离;感性防护器件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶仿真:Carsim转向传动比设置

文章目录 一、转向传动比概念二、如何设置转向传动比1、C factor概念2、Steer Kinematics概念3、传动比计算公式 三、转向传动比验证 一、转向传动比概念 转向传动比(Steering Ratio)表示方向盘转动角度与车轮转动角度之间的关系。公式如下:…

数字化校园:打造未来教育新风尚

在21世纪的教育蓝图中,"数字化校园"正逐渐从愿景走向现实,它不仅是科技进步与教育创新深度融合的产物,更是重塑教育生态、引领未来学习风尚的关键力量。随着云计算、大数据、人工智能等前沿技术的蓬勃发展,传统的教育模…

【SpringBoot】SpringBoot:简化数据库操作与API开发

文章目录 引言SpringBoot概述数据库操作简化传统数据库操作的挑战使用Spring Data JPA示例:定义Repository接口实现服务层 使用MyBatis示例:配置MyBatis定义Mapper接口 API开发简化RESTful API概述创建RESTful API示例:定义控制器 高级特性与…

【Better Lighting V2】Blender商城10周年免费送插件灯光预设和图案轮库场景打光和模拟光透过图案水滴波纹效果

Blender商城10周年免费送插件:https://blendermarket.com/birthday Better Lighting V2 灯光预设和图案轮库 模拟各种环境下光线透过物体效果 各种预设快速调整 非常简单和快速打光调色 更多详细介绍:https://blendermarket.com/products/bette…

element-ui input输入框和多行文字输入框字体不一样

页面中未作样式修改,但是在项目中使用element-ui input输入框和多行文字输入框字体不一样,如下图所示: 这是因为字体不一致引起的,如果想要为Element UI的输入框设置特定的字体,你可以在你的样式表中添加以下CSS代码…

WWDC 2024 回顾:Apple Intelligence 的发布与解析

一年一度的苹果全球开发者大会(WWDC)如期而至,2024 年的 WWDC 再次成为科技界的焦点。本次发布会中,苹果正式推出了他们在 AI 领域的全新战略——Apple Intelligence。这一全新概念旨在为用户打造“强大、易用、全面、个性化、注重…

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证

原文链接:EFDC建模方法及在地表水环境评价、水源地划分、排污口论证 近年,随着水环境问题的凸显,地表水水环境状况不仅是公众关注的焦点,也是环保、水务等部门兼管的重点,已成为项目审批、规划制定,甚至领…

LVS工作模式详解,NAT全方位剖析

请求到达: 当用户请求到达Director Server(负载均衡服务器)时,数据包会先到达内核空间的PREROUTING链。此时,数据包的源IP为CIP(Client IP),目标IP为VIP(Virtual IP&…

MySQL学习笔记-进阶篇-SQL优化

SQL优化 插入数据 insert优化 1)批量插入 insert into tb_user values(1,Tom),(2,Cat),(3,Jerry); 2)手动提交事务 mysql 默认是自动提交事务,这样会导致频繁的开启和提交事务,影响性能 start transaction insert into tb_us…

实拆一个风扇

fr:徐海涛(hunkxu)

Qwen2——阿里巴巴最新的多语言模型挑战 Llama 3 等 SOTA

引言 经过几个月的期待, 阿里巴巴 Qwen 团队终于发布了 Qwen2 – 他们强大的语言模型系列的下一代发展。 Qwen2 代表了一次重大飞跃,拥有尖端的进步,有可能将其定位为 Meta 著名的最佳替代品 骆驼3 模型。在本次技术深入探讨中,我…

神经网络学习2

张量(Tensor)是深度学习和科学计算中的基本数据结构,用于表示多维数组。张量可以看作是一个更广义的概念,涵盖了标量、向量、矩阵以及更高维度的数据结构。具体来说,张量的维度可以是以下几种形式: 标量&am…

LogicFlow 学习笔记——2. LogicFlow 基础 实例

LogicFlow 实例 创建实例 每一个流程设计界面&#xff0c;就是一个 LogicFlow 的实例。 <template><div id"container"></div><!-- 用于显示 LogicFlow 图表的容器 --> </template> <script>// 创建 LogicFlow 实例const lf …

Day03 链表概念与单向不循环链表的实现

目录 1、顺序表的优缺点 2、链式存储的线性表 3、单向不循环链表实现 1、顺序表的优缺点 顺序表的优点是: 由于顺序表数据元素的内存地址都是连续的,所以可以实现随机访问,而且不需要多余的信息来描述相关的数据,所以存储密度高。 顺序表的缺点是: 顺序表的数据在进行…

常用的JDK调优监控工具整理

JVM 调优首先要做的就是监控 JVM 的运行状态&#xff0c;这就需要用到各种官方和第三方的工具包了 一、 JDK 工具包 JDK 自带的 JVM 工具可以分为命令行工具和可视化工具 命令行工具 jps: JVM Process status tool&#xff1a;JVM进程状态工具&#xff0c;查看进程基本信息j…

Spring Aop及事务管理

5 Spring AOP AOP概述 AOP&#xff1a;全称是 Aspect Oriented Programming 即&#xff1a;面向切面编程。简单的说它就是把我们程序重复的代码抽取出来&#xff0c;在需要执行的时候&#xff0c;使用动态代理的技术&#xff0c;在不修改源码的基础上&#xff0c;对我们的已有…

SpringMVC框架学习笔记(七):处理 json 和 HttpMessageConverter 以及文件的下载和上传

1 处理 JSON-ResponseBody 说明: 项目开发中&#xff0c;我们往往需要服务器返回的数据格式是按照 json 来返回的 下面通过一个案例来演示SpringMVC 是如何处理的 &#xff08;1&#xff09; 在web/WEB-INF/lib 目录下引入处理 json 需要的 jar 包&#xff0c;注意 spring5.x…

OpenCV练习(1)签名修复

1.目的 在学校的学习过程中&#xff0c;需要递交许多材料&#xff0c;且每份材料上都需要对应负责人签名&#xff0c;有时候找别人要签名&#xff0c;然后自己粘贴的话&#xff0c;会出现签名模糊&#xff0c;背景不是纯白透明。为此以word中的“颜色校正”功能为参照&#xf…

基于iBeacon蓝牙定位技术的反向寻车系统

随着城市化进程的加速和汽车保有量的不断增加&#xff0c;大型停车场成为了人们日常生活中不可或缺的一部分。然而&#xff0c;在繁忙的停车场中快速找到自己的车辆&#xff0c;成为了许多车主的难题。为了解决这一问题&#xff0c;维小帮基于iBeacon蓝牙技术打造的反向寻车系统…

Android开发AndroidStudio安装教程

本文图示展示AndroidStudio安装教程。 目录 一、下载安装包 二、安装 一、下载安装包 https://developer.android.google.cn/studio?hlzh-cn 二、安装 双击exe Next Next Next 默认点击Install Next 点击finish进入设置文件界面。 如果本地有设置文件&#xff0c;选择C…