学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?
项目中解决的问题
CAN与串口操作基本类似,主要就是读写操作。但除此之外,CAN还多了一个报文过滤器的设置。利用7个CAN协议驱动实现VI,编写出几乎所有场合下都能使用的CAN通信程序。
做题思路
(1)CAN初始化
CAN初始化函数CAN Init.vi主要用来设置CAN通信速率、发送模式以及引脚重映射,如图
其中,STM32中的bxCAN属于高速CAN,最大支持1MHz的波特率,为了用户的使用方便,我们提供了5Kbps~1Mbps共23档选择;发送方式有“正常发送”与“环回模式”,当用户只有一块My_ARM学习板或一个CAN节点时,可以使用“环回模式”进行自发自收,来验证程序的功能性是否合理。当然,如果有多个CAN节点相互通信时,选择“正常模式”即可。
其实,CAN的3种映射分别与USB、SDIO(TIM4)、LCD重合,因此,如果用户想要完全独立地使用CAN总线接口,需要舍弃其中一项,比如USB或者SD卡,然后再将CAN映射到与之对应的物理引脚上。
My_ARM学习板上默认使用的是PB8和PB9引脚,虽然与SDIO部分引脚重合,但是我们提供的SD卡驱动采用的是SPI串行通信,并非SDIO并行通信,因此,刚好可以避开。
(2)CAN过滤器设置
一个CAN节点想要接收指定特征的报文,就需要提前设置过滤器,只有满足条件的报文才能顺利通过。CAN过滤器函数CAN Filter Set.vi需要设置的参数有以下6类:接收的是数据帧还是远程帧(回读命令);ID号有多少位,是标准帧还是扩展帧;启用哪个过滤器(范围:Filter0~13);想要接收的报文ID号;ID屏蔽位(U32),就是确定接收到的报文中的ID号、帧类型,哪些位是必须与前面设置的参数完全一致还是可不关心,如果设置成0xFFFFFFFF,表示外部发送过来的报文必须与过滤器中预期设置的参数完全一致,反之,如果设置为0x00000000,则表示前面所有的设置无效,任何报文都可以接收,过滤器呈完全放开状态,可以看出,ID屏蔽位其实就是子网掩码;最后选择开启还是关闭这个过滤器,默认都是开启,如果用户想要取消这组过滤器带来的限制条件,则可以选择关闭该过滤器。所有参数设置如图
由于STM32最多可以设置14个硬件过滤器,也就说最多可以通过硬件筛选出14个指定的ID号,即14个不同类型的报文。如果用户需要获取更多类型的报文,则可以使用ID子网掩码配合软件过滤来实现,但是需要通过软件编程,消耗一点CPU和RAM资源。
(3)发送报文
CAN最重要的功能就是报文的发送,这个功能可以利用CAN Send Frame.vi函数来实现,如图
一般情况下,要想发送一帧报文,需要设置以下4项:输入报文ID号,如果是11位的标准帧,那么ID的范围就是0211-1,如果是29位的扩展帧则是0229-1,可见在一个CAN网络中,传递的报文帧数量可以很多,而且,ID号越小优先级越高;ID号的位数决定了该帧属于标准帧还是扩展帧;发送的是携带重要数据的数据帧还是回读命令的远程帧;最后是数据场,一帧数据最多不能超过8个字节。该VI可以返回发送该帧报文的邮箱编号(Mailbox Number)以及是否发送成功。
(4)获取接收缓冲区报文数量
在读取报文之前,我们需要先获取一下当前开辟的接收缓冲区当中,到底有多少帧报文以及缓冲区中的有效字节数,类似于串口缓冲区中的字节数。获取报文数量可以利用CAN Frame Count.vi函数来完成,如图
其中,Frame Counts返回的是接收到的有效报文数量,但是每帧报文中的有效数据字节数(数据场)不一定都相同;总的数据字节数量通过Buffer Counts返回。
(5)读取指定数量的报文
知道了当前接收缓冲区中的报文数量,就可以利用CAN Read Frame.vi函数来读取这些数据,如图
该VI返回的是一个二维数组:数组中的每一行表示一帧数据,每一行中的前4个字节为报文ID号,大端格式,即最低位在索引0;第5个字节表示接收到的是数据帧(0)还是远程帧(1);第6个字节为该帧报文中携带的有效数据字节数量;余下的数组元素就是用户需要得到的数据场数据。