STM32
CAN
控制器局域网络CAN是由德国研发的BOSCh公司开发的,现已成为国际标准。
CAN具有CAN_High和CAN_Low两条信号线,CAN是以差分信号线的形式进行通信
CAN规定的数据帧的种类及作用
数据帧:用于发送单元向接收单元传送数据帧
遥控帧:用于接收单元向具有相同的ID的发送单元请求数据的帧
错误帧:用于当检测出错误时向其他单元通知错误的帧
过载帧:用于接收单元通知其商未做好接收准备的帧
帧间隔:用于将数据帧及遥控帧与前面的帧分离开来的帧
数据帧是CAN通信中最重要、最复杂的报文
数据帧以一个显性位(逻辑0)开始,以一个7个连续显性位(逻辑1)结束,在他们之间分为仲裁段,控制端,数据段,CRC段和ACK段。
(1)仲裁段的主要内容本数据帧的ID信息,分为标准格式和扩展格式。标准为11位,扩展为29位。ID决定了数据帧发送的优先级,决定是否接受数据帧。
(2)控制段中的r1和r0为保留位,默认位置为显性,最主要的为DLC段由4位组成,MSB先行,DLC段表示的数字为0~8
(3)数据段为数据帧的核心内容,它由0~8个字节组成,MSB先行。
(4)CRC段 为保证报文的正确传输,CAN的报文包含了一段15位的CRC检验码,若检验出错则反馈出错次那次或者重新发送,在CRC检验码之后,有一个CRC界定符,它为隐形,把CRC校验码与后面的ACk段隔开。
(5)ACK段 ACK段包括一个ACk槽位和ACk界定符,在ACK槽位中,发送端发送的为隐形位,接收段在这一位中性发送,在ACK界定槽和帧结束之间由ACK界定符隔开。
(6)帧结束段
由发送段发送7个隐形位表示结束。
CAN协议把一位的时序分解成如图的SS段,PTS段,PBS1段和PBS2段,这四段的长度加起来为一个CAN数据的吃那个度
SS段为同步段,PTS为传播时间段,PBS1段为相位缓冲段,PBS2段为另一个相位缓冲段,
CAN的同步分为硬同步和重新同步,硬同步时只是在有帧起始信号的时候起作用,无法确保后续连续,引入重新同步的方式在检测到
总线上的时序与节点使用的时序有相位差时(即总线上的跳变沿不在节点时序的SS 段范
围),通过延长PBS1 段或缩短PBS2 段来获得同步,这样的方式称为重新同步。
STM32中都具有bxCAN控制器,支持CAN的2.0A和2.0B协议
Tx Mailboxes(发送邮箱),Accepttance Filters( 接收过滤器),Receive FIFO( 接收FIFO )
CAN 接口。接着调用用户函数CAN_SetMsg() 把我们要发送的数据打包成报文并利用
printf() 输出这个报文的ID 及数据信息。生成报文后,调用库函数CAN_Transmit() 把这个
报文广播到CAN 网络上。发送完毕后进入等待状态,轮询标志变量flag 直到它变为0(这
个变量在本CAN 接口收到数据时在中断服务函数被赋值为0),本CAN 接收器接到数据
后,把接收到的报文信息打印到终端上。
CAN的GPIO复用配置
把PB8 配置成上拉输入、PB9 配置成复用推挽输出。敏感的读者会发现,PB8 及PB9 的默认复用功能是定时器TIM 或SDIO,GPIO 的重映射功能才是用作CAN 接口。
当我们使用GPIO 的重映射功能时,调用GPIO 重映射库函数GPIO_PinRemapConfig()开启此功能(代码的第17 行),并开启AFIO 时钟(代码的第13 行)
调用的GPIO_PinRemapConfi g() 函数中我们使用的参数为
GPIO_Remap1_CAN1,这个参数正是选择把CAN 信号映射到PB8、PB9 的GPIO 引脚
上。
GPIO_PinRemapConfig()的库函数
使用了CAN接收中断,因而需要配置中断向量
本实验中的主要为NVIC 的通道配置区别。本
NVIC_IRQChannel 被赋值为USB_LP_CAN1_RX0_IRQn,即CAN 的RX0 中断。这个中断号USB_LP_CAN1_RX0_IRQn 可以从启动文件startup_stm32f10x_hd.s中的中断向量列表中查找到
CAN的中断有发送中断、接收FIFO中断和错误中断构成,发送中断由三个发送邮箱任意一个为空的事件构成。接收FIFO 中断分为FIFO0 和FIFO1 的中断,接收FIFO 收到新的报文或报文溢出的事件可以引起中断。
1.CAN_TTCM:本成员用于配置CAN的时间触发通信模式
2.CAN_ABOM:当CAN检测到发送错误(TEC)或者接受错误(REC)超过一定时间时,会自动进入离线状态。
3.CNA_AWUM:本成员选择是否开启自动唤醒功能(automatic wakeupmode)。若使能了自动唤醒功能,并且CAN处于睡眠模式,检测到CAN总线活动时会自动进入正常模式,以便收发数据。
4.CAN_NART:本成员用于选择是否禁止报文自动重传。
5.CAN_RFLM:本成员用于选择是否禁止报文自动重传。
6.CAN_TXFP:本成员用于选择CAN报文发送优先级判定方法
7.CAN_Mode:本成员用于选择CAN处于工作模式状态还是测试模式状态。分别是一个正常工作模式(CAN_Mode_Normal),以及静默模式( CAN_Mode_Silent ) 、回环模式( CAN_Mode_LoopBack ) 和静默回环模式
(CAN_Mode_Silent_LoopBack)三个测试模式。
8.CAN——SJW,CAN——BS1,CAN_BS2及CAN_Prescaler:这几个成员用来配置CAN通信的位时序。
我们还要对CAN 的过滤器进行配置,使接
收FIFO 只接收特定的报文。所谓的过滤就是CAN 接口根据收到报文的ID,选择是否把
该报文保存到接收FIFO中
1.CAN_FilterNumber:本成员用于选择要配置的过滤器组,可以选择0到13,本实验选择过滤组0;
2.CAN_FilterMode:本成员用于配置过滤器的工作模式(CAN_FilterMode_IdList)和标识符屏蔽模式(CAN_FilterMode_IdMask)
3.CAN_FilterScale:本成员用于配置过滤器的长度,可设置为16位(CAN_FilterScale_16bit )和32 位(CAN_FilterScale_32bit )。
4.CAN_FilterIdHigh和CAN_FilterIdLow:这两个过滤器的第一个标识符寄存器的搞16为何低16位。
其标准ID部分(11 位)为0x000,其扩展部分(18 位)ID 为0x01314。
IDE 位为隐性位(宏CAN_ID_EXT :(uint32_t)0x00000004 )并且报文为数据帧,即RTR 位为显性位(宏CAN_RTR_DATA :(uint32_t)0x00000000)。
6.CAN_FilterFIFOAssignment 本成员用于设置过滤器与接收FIFO 的关联,即过滤
成功后报文的存储位置, 可配置为FIFIO0 ( CAN_Filter_FIFO0 ) 和FIFO1
(CAN_Filter_FIFO1 )两个接收位置。本实验设置存储位置为FIFO0
7.CAN_FilterActivation 本成员用于使能或关闭过滤器,默认为关闭。因而使用过
滤器时,我们要向它赋值ENABLE。对过滤器成员参数赋值完毕后我们调用库函数
CAN_FilterInit() 将它们写入寄存器。在本实验中由于我们使用中断来读取FIFO 数据,所
以在函数CAN_Filter_Confi g() 的最后我们调用库函数CAN_ITConfi g() 来开启FIFO0 消息
挂号中断使能(CAN_IT_FMP0),在CAN 接口的FIFO0 收到报文时,我们在中断服务函
数中从FIFO0 读数据到内存
1)初始化CAN 的GPIO。
2)配置好CAN 的工作模式,主要是对CAN 的位时序的配置。
3)若需要过滤报文,要设置CAN 的过滤器,根据需求选用标识符列表或标识符屏蔽
模式。
4)在发送报文前需要先对报文打包。