打印
[STM32F1]

STM32 基础篇——CAN

[复制链接]
楼主: aizaixiyuanqian
手机看帖
扫描二维码
随时随地手机跟帖
21
aizaixiyuanqian|  楼主 | 2018-3-14 21:16 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
CAN_AWUM:表示是否使用睡眠模式自动唤醒。在 CAN 正常工作
的时候有三种模式,一种是初始化模式,一种是正常模式和一种睡
眠模式。只有在正常模式的时候,CAN 才能正常收发报文。一般睡
眠模式是工作在低功耗下休眠的。我们这里不使用,所以设置为:
DISABLE。

使用特权

评论回复
22
aizaixiyuanqian|  楼主 | 2018-3-14 21:16 | 只看该作者
CAN_NART:表示是否使用非自动重传输。按照 CAN 标准,CAN
硬件在发送报文失败时会一直自动重传直到发送成功。(在时间模式
下不使用。)我们这里要使用自动重传输,设置为:DISABLE。

使用特权

评论回复
23
aizaixiyuanqian|  楼主 | 2018-3-14 21:19 | 只看该作者
CAN_RFLM:表示是否使用 FIFO 锁定模式。这个 FIFO 锁定模式的
意义在于,FIFO 未被锁定时,接收溢出时,当接收 FIFO 的报文未
被读出,下一个收到的报文会覆盖原有的报文;FIFO 被锁定时,接
收溢出时,当接收 FIFO 的报文未被读出,下一个收到的报文会被丢
弃。我们这里不锁定,也就是新数据会覆盖旧数据,所以设置为:
DISABLE。

使用特权

评论回复
24
aizaixiyuanqian|  楼主 | 2018-3-14 21:19 | 只看该作者
本帖最后由 aizaixiyuanqian 于 2018-3-14 21:30 编辑

CAN_Mode:表示选择 CAN 要使用的模式。在 CAN 模式类别中,
可以分为:工作模式和测试模式。工作模式我们上面有提到过一下,
主要有初始化模式、正常模式和睡眠模式。测试模式有静默模式、
环回模式和静默环回模式。我们正常通信的时候,一般使用的是正
常模式。不过我们测试可以使用环回模式,在环回模式下,bxCAN
把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接
收邮箱里。在库函数中它提供了四种模式选择,如下图


使用特权

评论回复
25
antusheng| | 2018-3-14 21:55 | 只看该作者
感觉还是要学习这个协议本身啊。

使用特权

评论回复
26
aizaixiyuanqian|  楼主 | 2018-3-14 22:16 | 只看该作者
CAN_SJW:表示设置重新同步跳跃宽度。即在每位中可以延长或缩
短多少个时间单位的上限。大家不理解也没有关系,我们这里设置
为 1 个时间单位:CAN_SJW_1tq。

使用特权

评论回复
27
aizaixiyuanqian|  楼主 | 2018-3-14 22:18 | 只看该作者
CAN_BS1:这个参数和下面的 CAN_BS2、CAN_Prescaler。来决定
CAN 总线的波特率的。(设置波特率要注意,要根据 CAN 总线上面
的波特率来设置,也就是说同一个 CAN 总线上面的波特率要相同
的。)我们先来看一下波特率的公式它是怎么算的:


使用特权

评论回复
28
aizaixiyuanqian|  楼主 | 2018-3-14 22:31 | 只看该作者
根据上面的公式,我们知道,只要我们知道 TBS1、TBS2 和 Tq,
然后在知道 APB1 时钟周期,那么我们就可以算出 CAN 的波特率。根据上面
的公式,一般 APB1 的时钟为 36MHZ,那么我们可以推导出:波特率 = 36K
/ ((CAN_BS1 + CAN_BS2 + 1) * CAN_Prescaler),比如我们设置 CAN_BS1 =
8,CAN_BS2 = 7,CAN_Prescaler = 5 时,波特率就是 450K。
 CAN_BS2:参与设置波特率,可以查看 CAN_BS2 的设置。
 CAN_Prescaler:参与设置波特率,可以查看 CAN_BS2 的设置。

使用特权

评论回复
29
aizaixiyuanqian|  楼主 | 2018-3-14 22:52 | 只看该作者
CAN 的发送
讲了 CAN 的初始化,那么我们接着来讲怎么使用 CAN 来发送数据。数
据的发送流程为:应用程序选择 1 个空置的发送邮箱;设置标识符,数据长
度和待发送数据;然后对 CAN_TIxR 寄存器的 TXRQ 位置’1’,来请求发
送。那么首先我们先来配置邮箱,并将要传送的数据放入到邮箱里面。
数据发送可以使用 CAN_Transmit()函数来发送,这个函数有两个参数:
第一个参数为选择你要使用的 CAN,我们使用 CAN 就设置为 CAN1。
第二个参数传递一个结构体 CanTxMsg 的指针。这个结构体的成员有:
 StdId:表示标准的 ID。
 ExtId:表示拓展的 ID。
 RTR:表示发送的帧类型。如:数据帧、远程帧等。
 IDE:表示要发送的是标准帧还是拓展帧。
 DLC 表示发送的数据长度。
 Data:这个是以个 8 个成员的数据,也就是用来存放你要发送的数
据。

使用特权

评论回复
30
aizaixiyuanqian|  楼主 | 2018-3-14 23:47 | 只看该作者
在 CAN 协议里,报文的标识符不代表节点的地址,而是跟报文的内容
相关的。因此,发送者乙广播的形式把报文发送给所有的接收者。节点在接
收报文时根据标识符的值决定软件是否需要该报文;如果需要,就拷贝到
SRAM 里;如果不需要,报文就被丢弃且无需软件的干预。
在这里呢,首先来了解一下 CAN 的过滤器,在 CAN 中,为了方便接收
我们想要的 ID,它设有一个过滤器,用来过滤掉我们不想要的 ID。,在互联
型的产品中它一共有 28 组过滤器,而其它产品中有 14 组过滤器。而每一组
过滤器呢又有两个 32 位的寄存器。

使用特权

评论回复
31
aizaixiyuanqian|  楼主 | 2018-3-14 23:47 | 只看该作者
在屏蔽位模式下呢,每组过滤器中的两个寄存器分为标示符寄存器和屏
蔽寄存器两种,标示符寄存器用来设置你想接收的 ID,而屏蔽寄存器呢,用
来设置你关心的位(即你想比较的位)。如说:标准格式 11 位的 ID 里面,
你只关心第一位,它必须为 1,其他位你不关心,那么你就可以设置屏蔽寄
存器第一位为 1(也就是必须比较),然后设置标示符寄存器的第一位也为
1(也就是要跟 1 比较),这样子 CAN 接收的时候它就只比较接收的 ID 第一位
是 1 的 ID,其他它不管。又比如说,当你值接收一个固定的 ID 的时候,你
把屏蔽寄存器全部设置为 1(即必须比较),然后在标示符寄存器里面存放你
想要的接收的 ID,那么当 CAN 总线上面出现你想要的 ID 的时候,它就将
它接收,其他的不接收。

使用特权

评论回复
32
aizaixiyuanqian|  楼主 | 2018-3-14 23:49 | 只看该作者
在屏蔽列表模式下呢,就更加简单了,在屏蔽列表模式下,每组过滤器
中的两个寄存器全部用来做标示符寄存器,也就是说当接收的 ID 必须跟表
示符寄存器中的 ID 相同的时候才接收。

使用特权

评论回复
33
aizaixiyuanqian|  楼主 | 2018-3-14 23:50 | 只看该作者
明白了屏蔽寄存器和标示符寄存器的作用之后,我们来看一下过滤器的
结构,首先我们要了解过滤器是可以设置成两种模式的,一种是 16 位的,
一种是 32 位的,毕竟我们的 ID 可以分为标准 ID(11 位)和拓展 ID(29 位)。
接下来我们来看一个图


使用特权

评论回复
34
aizaixiyuanqian|  楼主 | 2018-3-14 23:53 | 只看该作者
上面这个寄存器组结构呢,就是过滤器组的结构。通过上图我们看到四
种四组寄存器的说明。分别是 16 位的屏蔽位模式、32 位的屏蔽位模式、16
位的标示符列表模式、32 的标示符列表模式。在上面的图中,有个地方,我
们要注意了!!!就是寄存器中 ID 的起始位置!因为在下面我们设置接收过
滤器的时候,是要设置接收 ID,当时 ID 在寄存器中起始位置并不是从寄存
器一开始的。上面图中的 STID 才是 ID,EXID 是拓展 ID,IDE 是标准帧和
拓展帧的标示。

使用特权

评论回复
35
aizaixiyuanqian|  楼主 | 2018-3-14 23:56 | 只看该作者
我们现在了解了,CAN 过滤器的结构之后我们接下来看一下怎么使用库
函数来设置 CAN 的过滤器。
我们可以通过 CAN_FilterInit()函数来设置,这个函数有一个参数,就是
传递一个结构体的指针,这个结构体的成员主要有:

使用特权

评论回复
36
aizaixiyuanqian|  楼主 | 2018-3-14 23:56 | 只看该作者
CAN_FilterIdHigh:表示标示符寄存器的 ID。CAN_FilterIdHigh:表
示接收的过滤器。在这里呢,它可以填 0~13 里面的任意数。(不过
在库函数说明中它却说是 1 到 13,这个有点奇怪,在数据手册中是
说有 14 组过滤器的,不过我试过了 0 也是可以过滤的。如若哪里有
错的,欢迎大家指正。)我们这里使用第一组寄存器设置为:1。

使用特权

评论回复
37
aizaixiyuanqian|  楼主 | 2018-3-15 12:06 | 只看该作者
CAN_FilterMode:表示过滤模式。我们上面讲到它有屏蔽位模式和
标 示 符 列 表 模 式 。 我 们 使 用 屏 蔽 位 模 式 , 所 以 设 置 为 :
CAN_FilterMode_IdMask。

使用特权

评论回复
38
aizaixiyuanqian|  楼主 | 2018-3-15 12:07 | 只看该作者
CAN_FilterIdHigh:这个是标示符寄存器的高 16 位。从介绍的图中,
我们可以看到 16 位的时候,标准 ID 的起始位置是从第 5 位开始的,
所以我们设置 ID 的时候要将 ID 左移 5 位。从第 5 位开始放起。而
在 32 位模式的时候,大家从图上可以看出 ID 是从 32 位寄存器的第
3 位开始放置的(在这里还有个知识点,就是拓展帧的结构,拓展帧
的结构并不是标准 ID11 位 + 28 位这样子的结构的,而是 28 位添加
的 ID 放在前面,接着 11 位标准 ID 放在后面这样子的)。所以我们
这里设置的时候,这里的高 16 位放置拓展帧是要右移 13 位,也就
是从拓展帧的第 13 位开始。

使用特权

评论回复
39
aizaixiyuanqian|  楼主 | 2018-3-15 12:07 | 只看该作者
CAN_FilterIdLow:这个是标示符寄存器的低 16 位。这里的设置跟
上面的高 16 位设置差不多。在 16 位模式下是一样的设置,而在 32
位模式下拓展帧左移 3 位在放置。

使用特权

评论回复
40
aizaixiyuanqian|  楼主 | 2018-3-15 12:09 | 只看该作者
CAN_FilterMaskIdHigh:这个是屏蔽寄存器高字节的设置,如果你想
要关心哪一位你就 ID 对应的位设置为 1。如果你要全部比较就全部
设置 ID 对应的位全部设置为 1。它的对应位置是跟标示符寄存器是
一样的。

使用特权

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

本版积分规则