STM32上的CAN通讯是什么?CAN模式功能的详细分析

发布者:BlissfulMoments最新更新时间:2024-05-13 来源: elecfans关键字:STM32  CAN通讯 手机看文章 扫描二维码
随时随地手机看文章

CAN模式

一.工作模式 通过CAN_MCR寄存器控制INRQ和SLEEP1.初始化INRQ=1 SLEEP=0软件初始化应该在硬件2.正常INRQ=0 SLEEP=0在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文3.睡眠SLEEP=1 bxCAN可工作在低功耗的睡眠模式


二.测试模式 通过CAN_BTR寄存器控制LBKM和SILM1. 静默 可以接受不能发送

2. 循回 可以发送不能接受3.环回静默 只能自发自收

三.调试模式

STM32标识符筛选器

在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的优先级相关的。因此,节点在接收报文时-根据标识符的值-决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU开销。

STM32普通型芯片的 CAN 有14组过滤器组(互联型有28组过滤器组) ,用以对接收到的帧进行过滤。每组过滤器包括了2个可配置的32位寄存器:CAN_FxR1和 CAN_FxR2。对于过滤器组,通过设置CAN_FM0R的FBMx位,1.屏蔽位模式这样 CAN_FxR0中保存的就是标识符匹配值,CAN_FxR2中保存的是屏蔽码,即 CAN_FxR2中如果某一位为1,则 CAN_FxR1中相应的位必须与收到的帧的标志符中的相应位吻合才能通过过滤器。CAN_FxR2中为0的位表示 CAN_FxR1中的相应位可不必与收到的帧进行匹配。

2.标识符列表模式此时 CAN_FxR1和CAN_FxR2中的都是要匹配的标识符,收到的帧的标识符必须与其中的一个吻合才能通过过滤。

理解:标识符列表模式是为了过滤出一个标识符,而屏蔽位模式因为屏蔽了某些位所以可以过滤出一组标识符,对于不需要用筛选器组的应处以禁用状态

一般我们用的都是普通型的,所以在本文中可以说 STM32有14组过滤器组。根据配置,每1组过滤器组可以有1个,2个或4个过滤器。这些过滤器相当于关卡,每当收到一条报文时,CAN 要先将收到的报文从这些过滤器上”过”一下,能通过的报文是有效报文,收进 FIFO,不能通过的是无效报文(不是发给”我”的报文),直接丢弃。通过对两个可配置寄存器值得改变可以选择过滤器的数量。在一组过滤器中,整组的过滤器都使用同一种工作模式。

另外,每组过滤器中的过滤器宽度是可变的,可以是32位或16位。按工作模式和宽度,一个过滤器组可以变成以下几中形式之一:

(1) 1个32位的屏蔽位模式的过滤器。(2) 2个32位的列表模式的过滤器。(3) 2个16位的屏蔽位模式的过滤器。(4) 4个16位的列表模式的过滤器。

所有的过滤器是并联的,即一个报文只要通过了一个过滤器,就是算是有效的。每组过滤器组有两个32位的寄存器用于存储过滤用的”标准值”,分别是 FxR1,FxR2。

解读:1.在32位的屏蔽位模式下:有1个过滤器。FxR2用于指定需要关心哪些位,FxR1用于指定这些位的标准值。

2.在32位的列表模式下:

有两个过滤器。FxR1指定过滤器0的标准值,收到报文的标识符只有跟 FxR1完全相同时,才算通过。

FxR2指定过滤器1的标准值。

3.在16位的屏蔽位模式下:有2个过滤器。FxR1配置过滤器0,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值。

FxR2配置过滤器1,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值。

4.在16位的列表模式下:有4个过滤器。FxR1的[15-0]位配置过滤器0,FxR1的[31-16]位配置过滤器1。FxR2的[15-0]位配置过滤器2,FxR2的[31-16]位配置过滤器3。

FIFO

STM32的 CAN 有两个 FIFO,分别是 FIFO0和 FIFO1。为了便于区分,下面 FIFO0写作FIFO_0,FIFO1写作 FIFO_1。

每组过滤器组必须关联且只能关联一个 FIFO。复位默认都关联到 FIFO_0。所谓“关联”是指假如收到的报文从某个过滤器通过了,那么该报文会被存到该过滤器相连的 FIFO。从另一方面来说,每个 FIFO 都关联了一串的过滤器组,两个 FIFO 刚好瓜分了所有的过滤器组。每当收到一个报文,CAN 就将这个报文先与 FIFO_0关联的过滤器比较,如果被匹配,就将此报文放入 FIFO_0中。如果不匹配, 再将报文与 FIFO_1关联的过滤器比较, 如果被匹配, 该报文就放入 FIFO_1中。如果还是不匹配,此报文就被丢弃。

每个 FIFO 的所有过滤器都是并联的,只要通过了其中任何一个过滤器,该报文就有效。如果一个报文既符合 FIFO_0的规定,又符合 FIFO_1的规定,显然,根据操作顺序,它只会放到 FIFO_0中。

每个 FIFO 中只有激活了的过滤器才起作用,换句话说,如果一个 FIFO 有20个过滤器,但是只激话了5个,那么比较报文时,只拿这5个过滤器作比较。一般要用到某个过滤器时,在初始化阶段就直接将它激活。需要注意的是,每个 FIFO 必须至少激活一个过滤器,它才有可能收到报文。如果一个过滤器都没有激活,那么是所有报文都报废的。一般的,如果不想用复杂的过滤功能, FIFO 可以只激活一组过滤器组,且将它设置成 32位的屏蔽位模式,两个标准值寄存器(FxR1,FxR2)都设置成0。这样所有报文均能通过。(STM32提供的例程里就是这么做的! )

过滤器匹配序号

过滤器编号用于加速 CPU 对收到报文的处理。收到一个有效报文时, CAN 会将收到的报文 以及它所通过的过滤器编号, 一起存入接收邮箱中。CPU 在处理时,可以根据过滤器编号,快速的知道该报文的用途,从而作出相应处理。

不用过滤器编号其实也是可以的, 这时候 CPU 就要分析所收报文的标识符, 从而知道报文的用途。由于标识符所含的信息较多,处理起来就慢一点了。

STM32使用以下规则对过滤器编号:

(1) FIFO_0和 FIFO_1的过滤器分别独立编号,均从0开始按顺序编号。(2) 所有关联同一个 FIFO 的过滤器,不管有没有被激活,均统一进行编号。(3) 编号从0开始,按过滤器组的编号从小到大,按顺序排列。(4) 在同一过滤器组内,按寄存器从小到大编号。FxR1配置的过滤器编号小,FxR2配置的过滤器编号大。(5) 同一个寄存器内,按位序从小到大编号。[15-0]位配置的过滤器编号小,[31-16]位配置的过滤器编号大。(6) 过滤器编号是弹性的。 当更改了设置时,每个过滤器的编号都会改变。但是在设置不变的情况下,各个过滤器的编号是相对稳定的。

这样,每个过滤器在自己在 FIFO 中都有编号。

在 FIFO_0中,编号从0 – (M-1), 其中 M 为它的过滤器总数。

在 FIFO_1中,编号从0 – (N-1),,其中 N 为它的过滤器总数。

一个 FIFO 如果有很多的过滤器,,可能会有一条报文, 在几个过滤器上均能通过,这时候,,这条报文算是从哪儿过来的呢?STM32在使用过滤器时,按以下顺序进行过滤:

(1) 位宽为32位的过滤器,优先级高于位宽为16位的过滤器。(2) 对于位宽相同的过滤器,标识符列表模式的优先级高于屏蔽位模式。(3) 位宽和模式都相同的过滤器,优先级由过滤器号决定,过滤器号小的优先级高。

按这样的顺序,报文能通过的第一个过滤器,就是该报文的过滤器编号,被存入接收邮箱中。

上面的例子说明了bxCAN的过滤器规则:在接收一个报文时,其标识符首先与配置在标识符列表模式下的过滤器相比较;如果匹配上,报文就被存放到相关联的FIFO中,并且所匹配的过滤器的序号被存入过滤器匹配序号中。如同例子中所显示,报文标识符跟#4标识符匹配,因此报文内容和FMI4被存入FIFO。如果没有匹配,报文标识符接着与配置在屏蔽位模式下的过滤器进行比较。如果报文标识符没有跟过滤器中的任何标识符相匹配,那么硬件就丢弃该报文,且不会对软件有任何打扰。

发送

发送报文的流程

应用程序选择1个空置的发送邮箱;设置标识符,数据长度和待发送数据;然后对CAN_TIxR寄存器的TXRQ位置’1’,来请求发送。 TXRQ位置’1’后,邮箱就不再是空邮箱;而一旦邮箱不再为空置,软件对邮箱寄存器就不再有写的权限。 TXRQ位置1后,邮箱马上进入挂号状态,并等待成为最高优先级的邮箱,参见发送优先级。一旦邮箱成为最高优先级的邮箱,其状态就变为预定发送状态。一旦CAN总线进入空闲状态,预定发送邮箱中的报文就马上被发送(进入发送状态)。一旦邮箱中的报文被成功发送后,它马上变为空置邮箱;硬件相应地对CAN_TSR寄存器的RQCP和TXOK位置1,来表明一次成功发送。如果发送失败,由于仲裁引起的就对CAN_TSR寄存器的ALST位置’1’,由于发送错误引起的就对TERR位置’1’。

发送优先级

一.标识符决定当有超过1个发送邮箱在挂号时,发送顺序由邮箱中报文的标识符决定。根据CAN协议,标识符数值最低的报文具有最高的优先级。如果标识符的值相等,那么邮箱号小的报文先被发送。由发送请求次序决定。

二.由发送请求次序决定通过对CAN_MCR寄存器的TXFP位置’1’,可以把发送邮箱配置为发送FIFO。在该模式下,发送的优先级由发送请求次序决定。该模式对分段发送很有用。

中止通过对CAN_TSR寄存器的ABRQ位置’1’,可以中止发送请求。邮箱如果处于挂号或预定状态,发送请求马上就被中止了。如果邮箱处于发送状态,那么中止请求可能导致2种结果。如果邮箱中的报文被成功发送,那么邮箱变为空置邮箱,并且CAN_TSR寄存器的TXOK位被硬件置’1’。如果邮箱中的报文发送失败了,那么邮箱变为预定状态,然后发送请求被中止,邮箱变为空置邮箱且TXOK位被硬件清’0’。因此如果邮箱处于发送状态,那么在发送操作结束后,邮箱都会变为空置邮箱。

接受

接受流程FIFO从空状态开始,在接收到第一个有效的报文后, FIFO状态变为挂号_1(pending_1),硬件相应地把CAN_RFR寄存器的FMP[1:0]设置为’01’(二进制01b)。软件可以读取FIFO输出邮箱来读出邮箱中的报文,然后通过对CAN_RFR寄存器的RFOM位设置’1’来释放邮箱,这样FIFO又变为空状态了。如果在释放邮箱的同时,又收到了一个有效的报文,那么FIFO仍然保留在挂号_1状态,软件可以读取FIFO输出邮箱来读出新收到的报文。如果应用程序不释放邮箱,在接收到下一个有效的报文后, FIFO状态变为挂号_2(pending_2),硬件相应地把FMP[1:0]设置为’10’(二进制10b)。重复上面的过程,第三个有效的报文把FIFO变为挂号_3状态(FMP[1:0]=11b)。此时,软件必须对RFOM位设置1来释放邮箱,以便FIFO可以有空间来存放下一个有效的报文;否则,下一个有效的报文到来时就会导致一个报文的丢失。

溢出

当FIFO处于挂号_3状态(即FIFO的3个邮箱都是满的),下一个有效的报文就会导致溢出,并且一个报文会丢失。此时,硬件对CAN_RFR寄存器的FOVR位进行置’1’来表明溢出情况。至于哪个报文会被丢弃,取决于对FIFO的设置:

● 如果禁用了FIFO锁定功能(CAN_MCR寄存器的RFLM位被清’0’),那么FIFO中最后收到的报文就被新报文所覆盖。这样,最新收到的报文不会被丢弃掉。● 如果启用了FIFO锁定功能(CAN_MCR寄存器的RFLM位被置’1’),那么新收到的报文就被丢弃,软件可以读到FIFO中最早收到的3个报文。

接收相关的中断

一旦往FIFO存入一个报文,硬件就会更新FMP[1:0]位,并且如果CAN_IER寄存器的FMPIE位为’1’,那么就会产生一个中断请求。

当FIFO 变 满 时( 即 第3 个 报 文 被 存 入) , CAN_RFR 寄 存 器 的FULL 位 就 被 置’1’ , 并 且 如 果CAN_IER寄存器的FFIE位为’1’,那么就会产生一个满中断请求。

在溢出的情况下, FOVR位被置’1’,并且如果CAN_IER寄存器的FOVIE位为’1’,那么就会产生一个溢出中断请求。

位时序

位时间特性逻辑通过采样来监视串行的CAN总线,并且通过与帧起始位的边沿进行同步,及通过与后面的边沿进行重新同步,来调整其采样点。

它的操作可以简单解释为,如下所述把名义上的每位时间分为3段:

● 同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 xtCAN)。● 时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。

其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。

● 时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。

重新同步跳跃宽度(SJW)定义了,在每位中可以延长或缩短多少个时间单元的上限。其值可以编程为1到4个时间单元。

有效跳变被定义为,当bxCAN自己没有发送隐性位时,从显性位到隐性位的第1次转变。如果在时间段1(BS1)而不是在同步段(SYNC_SEG)检测到有效跳变,那么BS1的时间就被延长最多SJW那么长,从而采样点被延迟了。相反如果在时间段2(BS2)而不是在SYNC_SEG检测到有效跳变,那么BS2的时间就被缩短最多SJW那么长,从而采样点被提前了。为了避免软件的编程错误,对位时间特性寄存器(CAN_BTR)的设置,只能bxCAN处于初始化状态下进行。

中断

● 发送中断可由下列事件产生:─ 发送邮箱0变为空, CAN_TSR寄存器的RQCP0位被置’1’。─ 发送邮箱1变为空, CAN_TSR寄存器的RQCP1位被置’1’。─ 发送邮箱2变为空, CAN_TSR寄存器的RQCP2位被置’1’。

● FIFO0中断可由下列事件产生:─ FIFO0接收到一个新报文, CAN_RF0R寄存器的FMP0位不再是’00’。─ FIFO0变为满的情况, CAN_RF0R寄存器的FULL0位被置’1’。─ FIFO0发生溢出的情况, CAN_RF0R寄存器的FOVR0位被置’1’。

● FIFO1中断可由下列事件产生:

─ FIFO1接收到一个新报文, CAN_RF1R寄存器的FMP1位不再是’00’。─ FIFO1变为满的情况, CAN_RF1R寄存器的FULL1位被置’1’。─ FIFO1发生溢出的情况, CAN_RF1R寄存器的FOVR1位被置’1’。

● 错误和状态变化中断可由下列事件产生:─ 出错情况,关于出错情况的详细信息请参考CAN错误状态寄存器(CAN_ESR)。─ 唤醒情况,在CAN接收引脚上监视到帧起始位(SOF)。─ CAN进入睡眠模式。

关于标识符筛选器和筛选器匹配序号的理解

这两个概念理解起来有点麻烦下面举个例子来理解。面前有很多门,门上写着不同的属性,人得依据属性进门,比如说小门1 小门2 中门 大门1 大门2 其中小门1要求身高恰恰等于1.87的人进入 而中门要求身高小于1.90大于1.87的人进入 这2个概念就是标志筛选器的概念一个是标志符列表,另一个是屏蔽位 而进入门的人在后面的环节中 有测量身高这一环 为了快速获知他们的身高 我们可以用他们进的门来表示,因为门实际上包含了他们的身高信息这就是筛选器匹配的概念 筛选器匹配就是在很多门中有可能同时都可以使这个人进入 但是只有那一个门的身高和人得身高最接近 比如说人高1.70 门A要求1.68-1.12 门B要求1.70 那么就是门B由此筛选出门B这个匹配序号 可以直接获知这个人得身高信息


关键字:STM32  CAN通讯 引用地址:STM32上的CAN通讯是什么?CAN模式功能的详细分析

上一篇:基于STM32单片机ADC连续采集和DMA循环转换
下一篇:浅析STM32的五大嵌入式操作系统的特点及不足

推荐阅读最新更新时间:2024-11-16 21:23

STM32数组越界问题
前段时间在写STM32程序时,发现定义的局部变量会发生莫名其妙的数组越界,改变其定义顺序问题竟然得到解决,怀疑是堆栈空间没有分配够,于是决定追根溯源,查到一些资料,将startup_stm32f10x_hd.s中的栈空间改大即可: Stack_Size EQU 0x00000400;栈空间大小; AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp ; h Heap Configuration ; o Heap Size (in B
[单片机]
STM32程序移植之_内部flash开机次数管理lib库建立
1. 测试环境:STM32C8T6 2. 测试接口: 3. 串口使用串口一,波特率9600 单片机引脚------------CH340引脚 VCC--------------------VCC GND-------------------GND PA9--------------------RXD PA10-------------------TXD 1. 紧接011,下面进行lib可的移植 2. 需要移植好的程序和密码初始化 3. 将移植好的程序复制一份,改名为lib库建立,打开编译 4. 将所有的文件删除,留下两个文件 5. 编译成库,编译成功之后将STM32.lib库复制出
[单片机]
<font color='red'>STM32</font>程序移植之_内部flash开机次数管理lib库建立
STM32】HAL库 STM32CubeMX教程十三---RTC时钟
前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/ STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 知识概括: 通过本篇博客您将学到: RTC时钟原理 STM32CubeMX创建RTC例程 HAL库定时器RTC函数库 PS: 这里的RTC讲解,我们只将原理,不讲寄存器,如果要看RTC的寄存器,请看这篇文章 【STM32】RTC实时时钟,步骤超细详解,一文看懂RTC 什么是RTC RTC (Rea
[单片机]
【<font color='red'>STM32</font>】HAL库 STM32CubeMX教程十三---RTC时钟
STM32学习二:理解位绑定
学习STM32首先要理解的就是对寄存器的操作了,因为在STM32中对各IO口的操作实际就是对寄存器中各个位的操作。 在看了一个关于寄存器位绑定操作的教学视频后仍然是一头雾水,只能去网上查询各种资料,如比较有用的有《STM32位绑定操作的理解》,加上其他文章,形成了自己对位绑定的理解。 STM32将寄存器映射到了位带区(bit_band region),这样就可以通过统一的线性寻址空间直接操作寄存器了,这个空间就是0x00000000~0xFFFF FFFF共4GB大小,寄存器只是其中一小部分,其他包括程序存储区、数据存储区、输入输出端口等。这样的映射有两段,分别是0x2000 0000~0x200F FFFF(SRAM)及
[单片机]
<font color='red'>STM32</font>学习二:理解位绑定
使用STM32的单个普通定时器产生4路不同频率的方波
1)设置计数器为向上计数模式,将自动重装载寄存器设置为0xFFFF;这样计数器会循环计数。 2)每个定时器通道设置为输出比较模式,并设置比较匹配时对应的输出管脚翻转输出。 3)按照输出波形的半波周期计算出一个数值称作Half_Cyc。例如:定时器的时钟频率是72MHz,需要产生3456Hz的方波,则Half_Cyc = 72M/(3456*2) = 41667;如需要产生200kHz的方波,则Half_Cyc = 72M/(200k*2) = 180。 4)设置每个通道在输出比较匹配时产生中断,在中断中将比较寄存器的数值读出并加上Half_Cyc的数值,如果计算出的数值超过16位则舍弃超出的部分,再把这个新的数值写回相
[单片机]
stm32 开发环境MDK+库文件配置
stm32 是一款arm cortex-m3 架构的芯片 结合库函数使用 可以更方便的实现各种功能 尤其是结合各种总线开发应用时 因为库函数已经封装很多总线的处理方法和驱动 直接调用对应库函数 就可以操作各个总线 相比于 直接操作寄存器来说 操作I2C SPI CAN 等总线结构 会简单很多 stm32 的开发工具有很多MDK ADS AVR 等 我用的是MDk 其实就是可以编译arm的keil 界面和keil是一样的 之前安装过keil 直接把MDK 覆盖原来的keil 就可以支持51单片机和arm的芯片的开发 MDK官网下载地址 : https://www.keil.com/arm/demo/eval/arm.htm stm
[单片机]
STM32-USMART学习笔记
USMART移植步骤: 1.将usmart组件添加到工程文件夹下,在选项和组管理即 中,配置好头文件路径和组文件。 2.usmart.c主要包含两个函数void usmart_init(u8 sysclk)和void usmart_scan(void),第一个函数里有个条件编译#if USMART_ENTIM2_SCAN==1,这个在usmart.h里设置。这个宏定义初始化定时器2,本实验在定时器2的中断处理函数中执行usmart_dev.scan();进行行usmart扫描,为了便于移植,中断初始化及处理函数写在了usamrt.c里,time.c里面的初始化和终端处理被注释掉了。 3.特别注意:这个组件使用串口发送调试函数,u
[单片机]
详解STM32定时器捕获功能
一、STM32定时器捕获功能 STM32的定时器是支持信号输入捕获的,何为输入捕获?主要做什么应用? 输入捕获:通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变的时候,将当前的定时器的值(TIMx_CNT)存放到对应的捕获比较寄存器里面,完成一次捕获。输入捕获主要应用于测量信号的脉宽或频率。 下图是定时器原理图的输入捕获框图部分 第一部分是设置滤波器,用来对信号进行滤波,信号从TI1输入,通过滤波器,输出TIF信号,正常情况下信号没有抖动,TI1F信号等于TI1的输入信号。 ICF 用来设置输入采样频率的数字滤波器的长度,如ICF=0011,会在捕获上升沿时,以fCK_INT的频率连续采样八次通道1的信号电平,
[单片机]
详解<font color='red'>STM32</font>定时器捕获<font color='red'>功能</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved