打印
[信息]

CAN通信详解(全)

[复制链接]
2332|44
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层

本章我们将向大家介绍如何使用STM32自带的CAN控制器来实现两个开发板之间的CAN通讯,并将结果显示在TFTLCD模块上。本章分为如下几个部分:

30.1 CAN简介

30.2 硬件设计

30.3 软件设计

30.4 下载验证
30.1 CAN简介


使用特权

评论回复
42
loyal248| | 2024-4-29 11:56 | 只看该作者
有完整的文档吗?

使用特权

评论回复
41
laocuo1142| | 2021-3-4 16:19 | 只看该作者
真的非常详细,楼主费心了

使用特权

评论回复
40
zljiu| | 2021-3-4 13:14 | 只看该作者
这些段需要咱们自己进行区分吗

使用特权

评论回复
39
tfqi| | 2021-3-4 13:13 | 只看该作者
发送ack是自主发送的吗

使用特权

评论回复
38
nawu| | 2021-3-4 13:11 | 只看该作者
请问什么叫做隐性位啊

使用特权

评论回复
37
wiba| | 2021-3-4 13:10 | 只看该作者
过滤器用不好啊

使用特权

评论回复
36
qcliu| | 2021-3-4 13:09 | 只看该作者
使用自带的can模块吗

使用特权

评论回复
35
梅花香自123|  楼主 | 2021-2-24 23:57 | 只看该作者
该寄存器主要用来设置标识符(包括扩展标识符),另外还可以设置帧类型,通过TXRQ值1,来请求邮箱发送。因为有3个发送邮箱,所以寄存器CAN_TIxR有3个。

   第四个,我们介绍CAN发送邮箱数据长度和时间戳寄存器 (CAN_TDTxR) (x=0~2),该寄存器我们本章仅用来设置数据长度,即最低4个位。比较简单,这里就不详细介绍了。

   第五个,我介绍的是CAN发送邮箱低字节数据寄存器 (CAN_TDLxR) (x=0~2),该寄存器各位描述如图30.1.19所示:

图30.1.19 寄存器CAN_TDLxR各位描述

使用特权

评论回复
34
梅花香自123|  楼主 | 2021-2-24 23:57 | 只看该作者
环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。
第三个,我们介绍CAN发送邮箱标识符寄存器(CAN_TIxR)(x=0~3),该寄存器各位描述如图30.1.18所示:

图30.1.18 寄存器CAN_TIxR各位描述

使用特权

评论回复
33
梅花香自123|  楼主 | 2021-2-24 23:56 | 只看该作者
STM32提供了两种测试模式,环回模式和静默模式,当然他们组合还可以组合成环回静默模式。这里我们简单介绍下环回模式。
在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。也就是环回模式是一个自发自收的模式,如图30.1.17所示:

图30.1.17 CAN环回模式

使用特权

评论回复
32
梅花香自123|  楼主 | 2021-2-24 23:55 | 只看该作者
第二个,我们介绍CAN位时序寄存器(CAN_BTR),该寄存器用于设置分频、Tbs1、Tbs2以及Tsjw等非常重要的参数,直接决定了CAN的波特率。另外该寄存器还可以设置CAN的工作模式,该寄存器各位描述如图30.1.16所示:
图30.1.16 寄存器CAN_BTR各位描述

使用特权

评论回复
31
梅花香自123|  楼主 | 2021-2-24 23:55 | 只看该作者
该寄存器的详细描述,请参考《STM32参考手册》22.9.2节(439页),这里我们仅介绍下INRQ位,该位用来控制初始化请求。

软件对该位清0,可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清’0’。

软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置’1’。

所以我们在CAN初始化的时候,先要设置该位为1,然后进行初始化(尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置该位为0,让CAN进入正常工作模式。

使用特权

评论回复
30
梅花香自123|  楼主 | 2021-2-24 23:54 | 只看该作者
图中还给出了CAN波特率的计算公式,我们只需要知道BS1和BS2的设置,以及APB1的时钟频率(一般为36Mhz),就可以方便的计算出波特率。比如设置TS1=6、TS2=7和BRP=4,在APB1频率为36Mhz的条件下,即可得到CAN通信的波特率=36000/[(7+8+1)*5]=450Kbps。

   接下来,我们介绍一下本章需要用到的一些比较重要的寄存器。首先,来看CAN的主控制寄存器(CAN_MCR),该寄存器各位描述如图30.1.15:

图30.1.15 寄存器CAN_MCR各位描述

使用特权

评论回复
29
梅花香自123|  楼主 | 2021-2-24 23:54 | 只看该作者
FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。

   接下来,我们简单看看STM32的CAN位时间特性,STM32的CAN位时间特性和之前我们介绍的,稍有点区别。STM32把传播时间段和相位缓冲段1(STM32称之为时间段1)合并了,所以STM32的CAN一个位只有3段:同步段(SYNC_SEG)、时间段1(BS1)和时间段2(BS2)。STM32的BS1段可以设置为1~16个时间单元,刚好等于我们上面介绍的传播时间段和相位缓冲段1之和。STM32的CAN位时序如图30.1.14所示:
图30.1.14 STM32 CAN位时序

使用特权

评论回复
28
梅花香自123|  楼主 | 2021-2-24 23:53 | 只看该作者
上图中,还包含了很多其他处理,不强制退出发送(ABRQ=1)和发送失败处理等。通过这个流程图,我们大致了解了CAN的发送流程,后面的数据发送,我们基本就是按照此流程来走。接下来再看看CAN的接收流程。

   CAN接收流程

   CAN接收到的有效报文,被存储在3级邮箱深度的FIFO中。FIFO完全由硬件来管理,从而节省了CPU的处理负荷,简化了软件并保证了数据的一致性。应用程序只能通过读取FIFO输出邮箱,来读取FIFO中最先收到的报文。这里的有效报文是指那些正确被接收的(直到EOF都没有错误)且通过了标识符过滤的报文。前面我们知道CAN的接收有2个FIFO,我们每个滤波器组都可以设置其关联的FIFO,通过CAN_FFA1R的设置,可以将滤波器组关联到FIFO0/FIFO1。

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

   这个流程里面,我们没有考虑从FIFO读出报文的情况,实际情况是:我们必须在FIFO溢出之前,读出至少1个报文,否则下个报文到来,将导致FIFO溢出,从而出现报文丢失。每读出1个报文,相应的挂号就减1,直到FIFO空。CAN接收流程如图30.1.13所示:


图30.1.13 FIFO接收报文

使用特权

评论回复
27
梅花香自123|  楼主 | 2021-2-24 23:53 | 只看该作者
  举个简单的例子,我们设置过滤器组0工作在:1个32为位过滤器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即我们希望收到的映像(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而0XFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0XFFxx00xx,才算是正确的(x表示不关心)。

   关于标识符过滤的详细介绍,请参考《STM32参考手册》的22.7.4节(431页)。接下来,我们看看STM32的CAN发送和接收的流程。



   CAN发送流程

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

图30.1.12 发送邮箱

使用特权

评论回复
26
梅花香自123|  楼主 | 2021-2-24 23:52 | 只看该作者
通过CAN_FMR寄存器,可以配置过滤器组的位宽和工作模式,如图30.1.11所示:
图30.1.11 过滤器组位宽模式设置

为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。

为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。

应用程序不用的过滤器组,应该保持在禁用状态。

过滤器组中的每个过滤器,都被编号为(叫做过滤器号,图30.1.11中的n)从0开始,到某个最大数值-取决于过滤器组的模式和位宽的设置。

使用特权

评论回复
25
梅花香自123|  楼主 | 2021-2-24 23:52 | 只看该作者
STM32每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:

● 1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位

● 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位

此外过滤器可配置为,屏蔽位模式和标识符列表模式。

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

而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。

使用特权

评论回复
24
梅花香自123|  楼主 | 2021-2-24 23:51 | 只看该作者
在STM32互联型产品中,带有2个CAN控制器,而我们使用的STM32F103ZET6属于增强型,不是互联型,只有1个CAN控制器。双CAN的框图如图30.1.10所示:
图30.1.10 双CAN框图
从图中可以看出两个CAN都分别拥有自己的发送邮箱和接收FIFO,但是他们共用28个滤波器。通过CAN_FMR寄存器的设置,可以设置滤波器的分配方式。

   STM32的标识符过滤是一个比较复杂的东东,它的存在减少了CPU处理CAN通信的开销。STM32的过滤器组最多有28个(互联型),但是STM32F103ZET6只有14个(增强型),每个滤波器组x由2个32为寄存器,CAN_FxR1和CAN_FxR2组成。

使用特权

评论回复
23
梅花香自123|  楼主 | 2021-2-24 23:50 | 只看该作者
STM32的bxCAN的主要特点有:

l 支持CAN协议2.0A和2.0B主动模式

l 波特率最高达1Mbps

l 支持时间触发通信

l 具有3个发送邮箱

l 具有3级深度的2个接收FIFO

l 可变的过滤器组(最多28个)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

1196

帖子

0

粉丝