STM32 的 CAN 通讯全攻略

news/2024/11/14 11:52:58/

目录

一、CAN 通讯概述

二、 CAN 通讯原理

1.ISO11898 标准下的物理层特征

2.CAN 协议的帧类型 

3. 总线仲裁介绍

 4.位时序

5.STM32 CAN 控制器简介

6.标识符筛选器 

三、软件设计

1.发送流程

1.1初始化 CAN 控制器

1.2准备发送数据

1.3 将数据填充到发送缓冲区

1.4启动发送 

1.5等待发送完成

2.接收流程 

2.1初始化 CAN 控制器

2.2开启接收中断(可选)

2.3等待数据接收

2.4读取数据 

2.5处理接收的数据


一、CAN 通讯概述

STM32 的 CAN 通讯是一种常用于嵌入式系统的串行通信协议,具有高可靠性和多主控制等特点,广泛应用于汽车电子、工业自动化等领域。

CAN 协议经过 ISO 标准化后有两个标准:ISO11898 标准和 ISO11519 - 2 标准。其中 ISO11898 是针对通信速率为 125Kbps - 1Mbps 的高速通信标准,而 ISO11519 - 2 是针对通信速率为 125Kbps 以下的低速通信标准。STM32 的 CAN 控制器支持 CAN 2.0A 和 CAN 2.0B Active 版本协议。CAN 2.0A 只能处理标准数据帧,扩展帧的内容会识别为错误;CAN 2.0B Active 可以处理标准数据帧和扩展数据帧。

CAN 总线物理层主要有两种形式,一种是遵循 ISO11898 标准的高速、短距离 “闭环网络”,总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个 “120 欧” 的电阻。另一种是遵循 ISO11519 - 2 标准的低速、远距离 “开环网络”,最大传输距离为 1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个 “2.2 千欧” 的电阻。

CAN 通讯节点由一个 CAN 控制器及 CAN 收发器组成,控制器与收发器之间通过 CAN_Tx 及 CAN_Rx 信号线相连,收发器与 CAN 总线之间使用 CAN_High 及 CAN_Low 信号线相连。差分信号传输方式具有抗干扰能力强、能有效抑制电磁干扰、时序定位精确等优点。

STM32 的 CAN 通讯具有多主控制、系统的柔软性、通信速度较快且通信距离远、具有错误检测和恢复功能、故障封闭功能以及连接节点多等特点。这些特点使得 CAN 特别适合工业过程监控设备的互连,越来越受到工业界的重视。

二、 CAN 通讯原理

1.ISO11898 标准下的物理层特征

CAN 控制器根据 CAN_L 和 CAN_H 上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。显性电平对应逻辑 “0”,此时 CAN_High和 CAN_Low 之差为 2.5V 左右;隐性电平对应逻辑 “1”,此时 CAN_High和 CAN_Low 电压都为 2.5V 左右,电位差为 0V。显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平。另外,在 CAN 总线的起止端都有一个 120Ω 的终端电阻,用于匹配总线阻抗,减少回波反射,提高数据通信的抗干扰能力以及可靠性。

2.CAN 协议的帧类型 

CAN 协议有数据帧、遥控帧、错误帧、超载帧和间隔帧五种类型帧。

其中,数据帧最常用且复杂,一般由 7 个段构成,包括帧起始、仲裁段、控制段、数据段、CRC 段、应答段和帧结束

帧起始由 1 个显性位构成,标志着报文的开始。

仲裁段表示该帧优先级,标准格式包含 11 位标识符和远程发送请求位 RTR,扩展格式包含 29 位标识符、SRR 位、IDE 位和 RTR 位。

控制段包含数据长度等信息。

数据段包含要发送的 0 - 8 个字节的数据。

CRC 段用于校验数据是否正确发送。

应答段用于确认是否正常接收。

帧结束由连续的 7 个隐性位组成。

 

3. 总线仲裁介绍

同时多个单元发送数据时,总线仲裁过程如下:多个单元同时开始向总线发送数据,开始部分数据格式一样,无法区分优先级。直到某个时刻,一个单元输出隐性电平,而另一个单元输出显性电平,此时输出隐性电平的单元仲裁失利,立刻转入接收状态工作,不再与其他单元竞争,而输出显性电平的单元则顺利获得总线使用权,继续发送自己的数据。规律为:总线空闲时,最先发送的单元获得发送优先权,一旦发送,其他单元无法抢占;如果有多个单元同时发送,则连续输出显性电平多的单元,具有较高优先级

 4.位时序

位速率是由发送单元在非同步的情况下发送的每秒钟的位数。一个位一般可以分为同步段(SS)、传播时间段(PTS)、相位缓冲段 1(PBS1)和相位缓冲段 2(PBS2)

这些段又由可称为 Time Quantum(Tq)的最小时间单位构成,1 位分为 4 个段,每个段又由若干个 Tq 构成,这称为位时序。位时间 = 1 / 波特率,知道位时间,我们就可以知道波特率以及 1 位由多少个 Tq 构成、每个段又由多少个 Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。

5.STM32 CAN 控制器简介

STM32F4 的 bxCAN 支持 CAN 协议 2.0A 和 2.0B 主动模式,波特率最高达 1Mbps,支持时间触发通信,具有 3 个发送邮箱,具有 3 级深度的 2 个接收 FIFO,可变的过滤器组(28 个,CAN1 和 CAN2 共享)。它的设计目标是以最小的 CPU 负荷来高效处理大量收到的报文,对于安全紧要的应用,提供所有支持时间触发通信模式所需的硬件功能。

6.标识符筛选器 

CAN 的标识符不表示目的地址而是表示发送优先级。接收节点根据标识符的值,来决定是否接收对应消息。STM32 CAN 控制器提供了 28 个可配置的筛选器组,可降低 CPU 处理 CAN 通信的开销。STM32 CAN 控制器每个筛选器组由 2 个 32 位寄存器组成。根据位宽不同,每个筛选器组可提供

  • 1 个 32 位筛选器,包括 STDID [10:0]、EXTID [17:0]、IDE 和 RTR 位;
  • 或者2 个 16 位筛选器,包括 STDID [10:0]、IDE、RTR 和 EXTID [17:15] 位。

筛选器可配置为屏蔽位模式和标识符列表模式。在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照 “必须匹配” 或 “不用关心” 处理。

 

三、软件设计

1.发送流程

1.1初始化 CAN 控制器
  • 配置时钟:使能 CAN 控制器对应的时钟源。
  • 设置工作模式:如正常模式、环回模式等。
  • 配置波特率:通过设置位时序参数(同步段、传播段、相位缓冲段等)来确定合适的波特率。
  • 初始化过滤器:设置过滤器的模式、位宽、标识符等,以确定哪些报文可以被接收。
1.2准备发送数据

定义一个CAN_TxHeaderTypeDef结构体变量,设置报文的标识符、数据长度、发送类型等信息。例如:

CAN_TxHeaderTypeDef txHeader;
txHeader.StdId = 0x123; // 标准标识符
txHeader.ExtId = 0; // 不使用扩展标识符
txHeader.DLC = 8; // 数据长度为 8 字节
txHeader.TransmitGlobalTime = DISABLE;
1.3 将数据填充到发送缓冲区

定义一个数组用于存储要发送的数据。例如:

uint8_t data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1.4启动发送 

使用HAL_CAN_AddTxMessage函数将数据发送到 CAN 总线。例如:

HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &txMailbox);
if (status!= HAL_OK) {// 处理发送错误
}

该函数会返回发送状态,可根据返回值判断发送是否成功。如果发送失败,可以根据具体情况进行错误处理。

1.5等待发送完成

可以通过查询发送邮箱的状态标志或者使用中断方式来判断发送是否完成。例如,使用轮询方式:

while (HAL_CAN_IsTxMessagePending(&hcan, txMailbox)) {// 等待发送完成
}

2.接收流程 

2.1初始化 CAN 控制器
  • 配置时钟:使能 CAN 控制器对应的时钟源。
  • 设置工作模式:如正常模式、环回模式等。
  • 配置波特率:通过设置位时序参数(同步段、传播段、相位缓冲段等)来确定合适的波特率。
  • 初始化过滤器:设置过滤器的模式、位宽、标识符等,以确定哪些报文可以被接收。
2.2开启接收中断(可选)

如果希望使用中断方式接收数据,可以配置相应的中断并开启中断。例如:

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef *hcan) {// 接收中断处理函数
}
2.3等待数据接收

可以通过查询接收邮箱的状态标志来判断是否有新的数据到达。例如:

if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) > 0) {// 有数据到达
}
2.4读取数据 

当检测到有数据接收后,使用HAL_CAN_GetRxMessage函数从接收邮箱中读取数据。例如:

CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];
HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxData);

该函数会将接收到的报文信息填充到传入的结构体和数据缓冲区中。

2.5处理接收的数据

根据实际应用需求对接收的数据进行处理。例如,可以根据标识符判断数据的来源和类型,然后进行相应的操作。


http://www.ppmy.cn/news/1523900.html

相关文章

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期] 第二期介绍:频道模块之频道管理 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]第二期介绍:频道模块之频道管理获取用户详情获取用户频道列表获取频道详情获取子频道列表获…

个人随想-一道简单的AI面试题

大模型的兴起,很多公司现在都开始进入AI开发的新篇章,那么或多或少​也需要招聘一些AI的开发人员。 其实很多公司需要的,说白了就是一个AI开发工程师或者架构师,但是在招聘过程中,或多或少对要求写的太过夸张&#xf…

膨胀腐蚀操作opencv dilate膨胀白膨胀,erode腐蚀是黑吃白。主要针对二值图

效果: 代码: import cv2 import numpy as np from matplotlib import pyplot as pltif __name__ "__main__":h 10w 10data np.random.normal(0, 1, [h, w]) # sigma, 2*sigma, 3*sigma之间的数的比例分别为0.68, 0.96&#…

什么是设计模式,要掌握那些知识

设计模式就像是软件开发中的“秘籍”,它们是经过无数开发者反复实践验证的“套路”,帮助我们解决常见的代码设计问题。如果把编程比作武功,那设计模式就像是“武功秘籍”,能让你在应对复杂开发问题时,招式更灵活、思路…

Ubuntu 24.04 配置 nginx + php-fpm

nginx 是一个流行的 web 服务器,以其速度和可靠性而闻名,被许多顶级网站使用。要用 PHP 运行网站,您需要设置 php-fpm,nginx 与 php-fpm 一起处理 PHP 文件并将其显示给用户,帮助网站更快地加载并处理更多流量。 本教…

每日一题——第八十五题

题目&#xff1a;写一个函数&#xff0c;输入一个十六进制/八进制数/二进制数,输出对应的十进制数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> long stringToDecimal(const char* str, int base);int main() {char …

ML 系列:机器学习和深度学习的深层次总结(02)线性回归

ML 系列&#xff1a; — 简单线性回归 线性回归、损失函数、假设函数 图 1.线性回归 文章目录 一、说明二、线性回归2.1 简单线性回归2.2 回归中的损失函数 三、线性回归中的评估标准四、线性回归模型训练五、可视化5.1 假设函数5.2 计算训练模型的损失&#xff1a;5.3 绘制 H…

Spring Cloud Gateway学习记录

Spring中文网 https://springdoc.cn/spring-cloud-gateway/ Spring官网 https://spring.io/projects/spring-cloud-gateway 网关简介 大家都都知道在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f; 如果…