STM32的CAN外设

我们的CAN控制器支持最高的通讯速率为1Mb/s,可以自动地接收和发送CAN报文,支持使用标准ID和扩展ID地报文,外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间,具有两个3级深度的接收FIFO,可使用过滤功能只接受或不接收某些ID号,可配置成自动重发,不支持使用DMA进行数据收发。

10aa738e465e415a8436ff90aa4323af.png

在上图中,我们可以发现STM32是有两组CAN,其中这个CAN1是主设备,我们这个CAN2是从设备,其中这个“存储器访问控制器”是由CAN1控制的,要是我们的CAN2想使用的话,我们就要打开CAN1的外设时钟才可以使用,

第一个是控制内核,第二个是发送邮箱,第三个是接收FIFO,第四个是验收筛选器。

下面我们就对这个几个部分分别介绍一下了

1.CAN控制内核

在CAN的控制内核中,包含着各种控制寄存器和状态寄存器,这次我们主要学习一下其中的主控制寄存器CAN_MCR以及位时序寄存器CAN_BTR。

主控制寄存器CAN_MCR

主控制器寄存器CAN_MCR负责管理CAN的工作模式,它使用以下寄存器位实现控制。

(1)DBF调试冻结功能

使用这个可设置我们CAN处于工作状态或禁止收发的状态,处于程序调试的时候才使用的。

置0的话就表示我们CAN处于工作状态

置1的话就表示我们CAN处于接收/发送冻结状态。接收FIFO仍可正常访问/控制

(2)TTCM时间触发模式

这个是用于配置CAN的时间触发通信模式,在此模式下,CAN使用它内部定时器产生时间戳,并把它保存在CAN_RDTxR , CAN_TDTxR寄存器中。内部定时器在每个CAN位时间累加,在接收和发送的帧起始位被采样,并生成时间戳。利用这个可以实现ISO 11898-4CAN标准的分时同步通信功能。

(3)ABOM自动离线管理

它用于设置是否使用自动离线管理功能,当节点检测到它发送错误或接收错误超过一定值时,会自动进入离线状态,在离线状态中,CAN不能接收或发送报文。处于离线状态的时候,可以软件控制恢复或者直接使用这个自动离线管理功能,它会在适当的时候自动恢复。

84a86354180e44d898ad4fb37bc08415.png

(4)AWUM自动唤醒

CAN外设可以使用软件进入低功耗的睡眠模式,如果使能这个自动唤醒功能,当CAN检测到总线活动的时候会自动唤醒。

d1539839475743f48f490398f378f4c6.png

(5)NART自动重传

设置了这个动能后,当报文发送失败时会自动重传至成功为止。若不使用这个功能,消息只发送一次。

584fced0ca2643298d876a1a1c1cf768.png

(6)RFLM锁定模式

该功能用于锁定接收FIFO,锁定后,当接收FIFO溢出时,会丢弃下一个接收的报文。

如果不锁定,我们下一个接收的报文会覆盖原来报文。

a0210b8207b64e3984415d36b5e047eb.png

(7)TXFP报文发送优先级的判定方法

当CAN外设的发送邮箱中有多个待发送报文时,本功能可以控制它是根据报文的ID优先级还是报文存进邮箱的顺序来发送。

e14100e8df564694b3a63d49d1befbd2.png

位时序寄存器(CAN_BTR)及波特率

CAN_BTR寄存器可用于配置测试模式,波特率以及各种位内的段参数

(1)测试模式

为方便调试,STM32的CAN提供了测试模式,我们配置位时序寄存器CAN_BTR的SILM和LBKM寄存器位可以控制使用正常模式,静默模式,回环模式,及静默回环模式。

022a245bf8704909952e95ee748e4f4c.png

0db0d14fc07741ecb677597a2170fba3.png

 

如上图,各种模式介绍如下:

1.正常模式

正常模式下就是一个正常的CAN节点,可以向总线发送数据和接收数据。

2.静默模式

在静默模式下,它自己的输出端的逻辑0会直接传输到它自己的输入端,逻辑1可以被发送到总线,所以它是不能向总线发送显性位(逻辑0),只能发送隐性位(逻辑1).输入端可以从总线接收内容.;由于它只发送隐性位不会强制影响总线的状态,所以我们称它为静默模式.

这种模式一般用于监测,它可以分析总线上的流量,但又不会因为发送显性位而影响总线.

3.回环模式

回环模式下,它自己的输出端的所有内容都直接传输到自己的输入端,输出端的内容同时也会被传输到总线上,即也可使用总线监测它的发送内容.输入端只接受自己发送端的内容,不接收来自总线上的内容.可以使用回环模式可以进行自检.

4.回环静默模式

这是回环模式和静默模式的结合,自己输出的端的所有内容都直接传输到自己的输入端,并且不会向总线发送显性位影响总线,不能通过总线监测它的发送内容,输入端只接受自己发送端的内容,不接收来自总线上的东西.这种方式一般在"热自检"时使用,即自我检查的时候,不会干扰总线

以上的四种模式都是不用修改硬件接线的.

(2)位时序及波特率

8d28f4fea3f74e779d615354015c7a97.png

STM32外设定义的位时序和我们前面解释的CAN标准时序有一点区别,

STM32的CAN外设位时序中只包含3段,分别是同步段SYNC_SEG,位段BS1及位段BS2,这个BS1段可以理解成前面介绍的PTS段与PBS1段合在一起的.

采样点位于BS1和BS2段的交界处,其中同步段SYNC_SEG固定为1Tq,而这个BS1和BS2段可以在位时序寄存器CAN_BTR设置它们的时间长度,它们可以在重新同步期间增长或缩短,该长度SJW也可在位时序寄存器中配置.

3dd4a4df99374dfabe3ab56b51558ac5.png

了解了位时序以后,我们就可以配置波特率了.通过配置位时序寄存器CAN_BTR的的TS1[3:0]以及TS2[2:0]寄存器位设定BS1及BS2段的长度后,我们就可以确定每个CAN数据位的时间:

BS1段时间:

Ts1 = Tq ✖ (TS1[3:0]+1),

BS2段时间:

Ts2 = Tq ✖ (TS2[3:0]+1),

一个数据位的时间:

T1bit = 1Tq+Ts1+Ts2 = 1+(TS1[3:0]+1)+(TS2[2:0]+1) = NTq

其中这个Tq时间片的长度与CAN外设的所挂载的时钟总线及分频器配置有关,CAN1和CAN2外设都是挂载在APB1总线上,而我们CAN_BTR中的BRP[9:0]寄存器位可以设置CAN外设时钟的分频值,所以:

Tq = (BRP[9:0]+1)✖Tpclk

其中的PCLK指APB1时钟,默认值为45Mhz.

最终可以计算出CAN通讯的波特率:

BaudRate = 1/N Tq;

如下表有一种波特率为1Mbps的方式,说明了一种把波特率配置为1Mbps的方式

efd481ed618946aeac447f1eea935278.png

理解一下就是 总的 9Tq, 45Mhz 拿来5分频就是9Mhz,波特率就是9Tq除以9Mhz等于1Mbps.

(3)CAN发送邮箱

我们STM32一共有3个发送邮箱,即最多可以缓存3个待发送的报文,

在每个发送邮箱中包含标识符寄存器CAN_TIxR,数据长度控制寄存器CAN_TDTxR及2个数据寄存器CAN_TDLxR,CAN_TDHxR,它们的功能见表发送邮箱的寄存器

f79950e60c3d4f1ca87418d27d00a769.png

当我们要使用CAN外设发送报文时,把报文的各个段分解,按位置写入到这些寄存器中,并对标识符寄存器CAN_TIxR中的发送请求寄存器位TMIDxR_TXRQ置1,即可把数据发送出去.

其中标识寄存器CAN_TIxR  将它的TXRQ置1 就可以发送出去数据,有一个地方比较特殊,就是当IDE置0的时候就是标准标识符,置1的时候就是扩展标识符,我们在标准标识符的时候因为总位数是11位数据,所以我们这个CAN_TIxR的寄存器只用在前11位,当我们是扩展标识符的时候,我们总位数是29位,所以就前29位完整的用起来了.

19b7b814966144f8a4065c63d277e441.png

(4)CAN接收FIFO

20e160a5213e47fcb43796c2ffe7ca9a.png

看在我们STM32的CAN外设有两个接收FIFO,每个FIFO中有3个邮箱,即最多可以缓存6个接收到的报文,当接收到报文时,FIFO的报文计数器会自增,而我们STM32内部读取FIFO数据之后,报文计数器会自减,我们通过状态寄存器可获知报文计数器的值,

463c33eeabf243f7ac9c2b01af81c507.png

 

和发送邮箱类似,每个接收FIFO中包含有标识寄存器CAN_RIxR,数据长度控制寄存器CAN_RDTxR及2个数据寄存器CAN_RDLxR,CAN_RDHxR,它们的功能如下图

cff63ed67db64b719306d93c6fb7f273.png

我们读取这些寄存器的值即可把接收到的报文加载到STM32的内存中

(5)验收筛选器

我们一共28个筛选器组,每个筛选器组有2个寄存器,CAN1和CAN2公用的筛选器.

在CAN协议中,消息的标识符与节点地址无关,但是和消息内容有关.因此,发送节点将报文广播给所有接收器时,接收节点会根据报文标识符的值来确定软件是否需要该消息,

为了简化软件的工作.STM32的CAN外设接收报文前会先使用验收筛选器检查,只接收需要的报文到FIFO中.

筛选器工作的时候,可以调整筛选ID的长度以及过滤模式.根据筛选ID长度来分类有以下两种:

(1)检查STDID[10:0],EXTID[17:0],IDE和RTR位,一共31位

(2)检查STDID[10:0],RTR,IDE和EXTID[17:15],一共16位

通过配置筛选尺度寄存器CAN_FSIR的FSCx位可以设置筛选器工作在哪个尺度

6bae8b9122044bf98934c78c5b6f1e3c.png

而根据过滤的方法分为以下两种模式:

(1)标识符列表模式,它要把接收报文的ID列成一个表,要求报文ID与列表中的某一个标识符完全相同才可以接收,白名单管理

(2)掩码模式,它把可接受收报文ID的某几位作为列表,这几位被称为掩码,可以理解成关键字搜索,只要掩码(关键字)相同,就符合要求,报文就会被保存到FIFO

通过配置筛选尺度寄存器CAN_FSIR的FBMx位可以设置筛选器工作在哪个模式

d8ad1eb5fa4a4667b6cd69558a77821e.png

具体全部总结如下图

8b43a3d5af224b03ae7393dbe413275e.png

每组筛选器包含2个32位的寄存器,分别位CAN_FxR1和CAN_FxR2,他们用来存储要筛选的ID或掩码,各个寄存器位代表的意义与下图所示一致

5f44bfbf27e44ea0936ed2d416a33add.png

我们举个例子,大概理解一下

d597bbda2d42472d8cdccba6c0113692.png

就像这个表格,

在掩码模式下的时候,第一个寄存器存储的就是要筛选的ID,第二个寄存器存储的掩码,

这个掩码为1的地方,表示该位必须与ID中的内容一样,而0的话就是表示该位可以是0也可以是1

最后筛选的ID 就是第三行所示

如果是标识符模式,2个寄存器存储的都是要筛选的ID,不一样的直接丢弃掉.

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac下使用homebrew管理多版本mysql同时

Mac下使用homebrew管理多版本mysql同时启动 思路 给每个版本分配不同的数据目录和配置文件即可 本文尝试了使用 brew 安装管理多个MySQL版本,同时运行、直接切换 安装 如果已有数据文件请自行备份以及使用 安装 mysql 5.7 brew install mysql5.7在 /opt/home…

Github 2024-04-04 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-04统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5TypeScript项目2Go项目1Jupyter Notebook项目1Java项目1C++项目1非开发语言项目1Vue项目1编程面试大学:成为软件工程师的全面学习计…

【opencv】教程代码 —video(1) 对象追踪

CamShift算法、MeanShift追踪算法来追踪视频中的一个目标 camshift.cpp CamShift算法 // 引入相关的头文件 #include <iostream> // 包含C的输入输出流库 #include <opencv2/imgcodecs.hpp> // OpenCV图像编解码功能 #include <opencv2/imgproc.hpp> // Open…

Jenkins 持续集成 【CICD】

持续集成 &#xff08;Continuous integration&#xff0c;简称CI&#xff09; 持续集成是一种开发实践&#xff0c;它倡导团队成员频繁的集成他们的工作&#xff0c;每次集成都通过自动化构建&#xff08;包括编译、构建、打包、部署、自动化测试&#xff09;来验证&#xff…

Django之REST Client插件

一、接口测试工具介绍 在开发前后端分离项目时,无论是开发后端,还是前端,基本都是需要测试API接口的内容,而目前我们需要开发遵循RESTFul规范的项目,也是必然的(自己不开发前端页面)。 在网上有很多这样的工具,常用的postman,但还是需要下载安装。在这我们介绍一个VSCod…

Spark-Scala语言实战(12)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的join,rightOuterJoin,leftOuterJoin三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢…

练习 21 Web [GXYCTF2019]BabySQli

SQL联合查询&#xff0c;注意有源码看源码&#xff0c;Base64以及32的区别&#xff0c;MD5碰撞 打开后有登录框&#xff0c;先随意登录尝试 只有输入admin才是返回wrong pass&#xff01; 其他返回wrong user 所以用户名字段一定要输入admin 养成好习惯&#xff0c;先查看源码…

Unity:2D SpriteShape

1.1 简介 Sprite Shape 可以很灵活的更改sprite的轮廓。比如&#xff1a; 它由两部分组成&#xff1a;Sprite Shape Profile、Sprite Shape Controller&#xff0c;需要导入2D Sprite Shape Package. 1.1.1 Sprite导入要求 Texture Type - ‘Sprite (2D and UI)’.Sprite Mo…

替代 Redis 和 Memcached:25 倍吞吐量! | 开源日报 No.213

dragonflydb/dragonfly Stars: 22.4k License: NOASSERTION Dragonfly 是一个内存数据存储&#xff0c;适用于现代应用工作负载&#xff0c;可替代 Redis 和 Memcached。与传统的内存数据存储相比&#xff0c;Dragonfly 提供了 25 倍的吞吐量、更高的缓存命中率和更低尾部延…

ChatGPT/GPT4科研应用与绘图技术及论文写作

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

我与C++的爱恋:类与对象(一)

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&…

【贪玩巴斯】Mac的M芯片(M1/2...)下载homebrew方法(24年最新且已验证可行)

1. 按照目前广为流传的方法&#xff08;M1会出现一些问题&#xff09;&#xff1a; 终端输入&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 使用国内镜像下载。 2. 输入后按照要求步骤执行即可&#xff…

使用c语言libexpat开源库解析XML数据

1 libexpat简介 Expat 是一个用 C 语言编写的开源 XML 解析库&#xff0c;以其高性能和小巧的体积著称。Expat 兼容多种操作系统平台&#xff0c;包括但不限于 Windows、Linux、macOS 等。由于其跨平台特性和简单易用的API&#xff0c;Expat 成为了许多C/C程序员解析XML文档的…

原型模式详解

原型模式简单的理解来说,就是复制品,用一个已经做好的成品作为原型,然后通过复制它得到新的产品。就好像细胞分裂一样。用Java来说,就是用对象创建对象,而不是通过类来创建对象。 原型模式的目的是从原型实例克隆出新的实例 ,对于那些有非常复杂的初始化过程的对象或者是…

第三方短信-短信合作-106短信

第三方短信-短信合作-106短信 1、你是否也有需要发送短信的业务、但是自己没有短信服务的情况 2、是否需要大量发送短信、但是又不想通过自己的真实手机号发 3、您是否是开发者、但是没有自己的短信服务&#xff0c;需要发送短信可以使用/借用我的短信服务进行发送&#xff0c…

Docker 哲学 - docker swarm

Docker Swarm 模式下的集群管理和服务恢复机制 Docker Swarm 是 Docker 的集群管理和编排功能。在 Swarm 模式下&#xff0c;你可以将多个 Docker 主机组合成一个虚拟主机&#xff0c;称为 Swarm 集群。Swarm 集群由一个或多个管理节点&#xff08;manager nodes&#xff09;和…

Flutter-发布插件到pub上传不上问题

问题1&#xff1a; 尝试指令&#xff1a; flutter packages pub publish --serverhttps://pub.dartlang.org问题2&#xff1a; 问题1解决后&#xff0c;进入验证身份&#xff0c;点击终端显示的链接&#xff0c;跳转到google验证&#xff0c;记得这里要科*学上网&#xff0c;点…

理解pytorch的广播语义

目录 什么是广播运算 广播的条件 示例 示例1 示例2 示例3 补1 示例4 原位运算 示例5 参与广播运算的两个tensor&#xff0c;必须是从右向左对齐 总结规律 两个tensor可以做广播运算的条件&#xff1a; 两个可以互相广播的tensor运算的步骤&#xff1a; 例子&#x…

pycharm pyspark连接虚拟机的hive表 读取数据

方法&#xff1a; hive配置hiveserver2和metastore url <!-- 指定hiveserver2连接的host --> <property><name>hive.server2.thrift.bind.host</name><value>hadoop111</value> </property><!-- 指定hiveserver2连接的端口号 -…

接口的总结与面试题

接口本身不能创建对象&#xff0c;只能创建接口的实现类对象&#xff0c;接口类型的变量可以与实现类对象构成多态引用。 声明接口用interface&#xff0c;接口的成员声明有限制&#xff1a; &#xff08;1&#xff09;公共的静态常量 &#xff08;2&#xff09;公共的抽象方…