STM32-CAN通信
CAN基础知识
CAN协议经过ISO标准化后有两个标准:ISO11898标准和ISO11519-2标准。其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准,而ISO11519-2是针对通信速率为125Kbps以下的低速通信标准。
CAN协议的特点
- 多主控制:总线空闲时,所有单元都可发送消息,而两个以上的单元同时开始发送消息时,根据标识符(ID,非地址)决定优先级。两个以上的单元同时开始发送消息时,对各消息ID 的每个位进行逐个仲裁比较。仲裁获胜(优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。
- 系统柔软性:连接总线的单元,没有类似“地址”的信息,因此,在总线上添加单元时,已连接的其他单元的软硬件和应用层都不需要做改变。
- 速度快,距离远:最高1Mbps(距离<40M),最远可达10KM(速率<5Kbps)。
- 具有错误检测、错误通知和错误恢复功能:所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。
- 故障封闭功能:CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
- 连接节点多:CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。
CAN的物理层特征
CAN 控制器根据CAN_L和CAN_H上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。
显性电平对应逻辑:0 | 隐性电平对应逻辑:1 |
---|---|
CAN_H和CAN_L之差为2V左右 | CAN_H和CAN_L之差为0V |
显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平。而隐形电平则具有包容的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平(显性电平比隐性电平更强)。另外,在CAN总线的起止端都有一个120Ω的终端电阻,来做阻抗匹配,以减少回波反射。
CAN的帧种类
帧类型 | 帧用途 |
---|---|
数据帧 | 用于发送单位向接收单位传送数据的帧 |
遥控帧 | 用于接收单位向具有相同ID的发送单元请求数据的帧 |
错误帧 | 用于当检测出错误时向其他单元通知错误的帧 |
过载帧 | 用于接收单元通知其尚未做好接收准备 |
间隔帧 | 用于将数据帧和遥控帧与前面的帧分离开来的帧 |
其中,数据帧和遥控帧有标准格式和扩展格式两种格式。
标准格式有11 个位的标识符(ID),扩展格式有29 个位的ID 。
数据帧格式
帧类型 | 帧用途 |
---|---|
帧起始 | 表示数据帧开始的段 |
仲裁段 | 表示该帧优先级的段 |
控制段 | 表示数据的字节数及保留位的段 |
数据段 | 数据的内容,一帧可发送0~8个字节的数据 |
CRC段 | 检查帧的传输错误的段 |
ACK段 | 表示确认正常接收的段 |
帧结束 | 表示数据帧结束的段 |
CAN位时序
位速率。由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位一般可以分为如下四段:
位时间=1/波特率
STM32的CAN将传播时间段和相位缓冲时间段1合并成时间段1
一个位的构成
位时序计算
STM32F103,设TS1=8、TS2=7、BRP=3,波特率=36000/[(9+8+1)*4]=500Kbps。
STM32 CAN控制器
STM32自带了基本扩展CAN外设,又称bxCAN,bxCAN的特点如下:
- 支持CAN协议2.0A和2.0B主动模式
- 波特率最高达1Mbps
- 支持时间触发通信
- 具有3个发送邮箱
- 具有3级深度的2个接收FIFO
- 可变的筛选器组(也称过滤器组,最多28个)
运行模式
- 工作模式
- 初始化模式(INRQ=1,SLEEP=0)
- 正常模式(INRQ=0,SLEEP=0)
- 睡眠模式(SLEEP=1)
- 测试模式
- 静默模式( LBKM=0,SILM=1 )
- 环回模式( LBKM=1,SILM=0 )
- 环回静默模式(LBKM=1,SILM=1)
- 调试模式
bxCAN的框图
标识符筛选器
- CAN的标识符不表示目的地址而是表示发送优先级。接收节点根据标识符的值,来决定是否接收对应消息。
- 筛选器可配置为:屏蔽位模式和标识符列表模式。在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟筛选器标识符相同。
- 通过CAN_FM1R和CAN_FS1R可配置筛选器的位宽和模式:
- 为了过滤出一组标识符,应该设置筛选器组工作在屏蔽位模式。
- 为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。
- 应用程序不用的筛选器组,应该保持在禁用状态(通过CAN_FA1R设置)。
- 筛选器组中的每个筛选器,都被编号为(即:筛选器编号)从0开始,到某个最大数值-取决于筛选器组的模式和位宽的设置。
- 通过CAN_FFA1R的设置,可以将筛选器组关联到FIFO0/FIFO1
例:设置筛选器组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表示不关心)。
CAN发送流程
- 程序选择1个空置的邮箱(TME=1)
- 设置标识符(ID),数据长度和发送数据
- 设置CAN_TIxR的TXRQ位为1,请求发送
- 邮箱挂号(等待成为最高优先级)
- 预定发送(等待总线空闲)
- 发送
- 邮箱空置
CAN接收流程
- FIFO空
- 收到有效报文
- 挂号_1(存入FIFO的一个邮箱,这个由硬件控制,我们不需要理会)
- 收到有效报文
- 挂号_2
- 收到有效报文
- 挂号_3
- 收到有效报文
- 溢出
CAN收到的有效报文,存储在3级邮箱深度的FIFO中。FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。
报文FIFO具有锁定功能(由CAN_MCR,RFLM位控制),锁定后,新数据将丢弃,不锁定则新数据将替代老数据
初始化流程
- 配置相关引脚的复用功能,使能CAN时钟。
要用CAN,先要使能CAN的时钟,CAN的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,这里我们需要设置PA11为上拉输入(CAN_RX引脚)PA12为复用输出(CAN_TX引脚),并使能PA口的时钟 - 设置CAN工作模式及波特率等。
通过先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位。再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。 最后设置INRQ为0,退出初始化模式。 - 设置滤波器。
本例程,我们将使用筛选器组0,并工作在32位标识符屏蔽位模式下。先设置CAN_FMR的FINIT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后**筛选器,并退出初始化模式。