一、CAN协议的介绍
CAN是控制器局域网络(Controller Area Network)的简称,CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,近年来,它具有的高可靠性和良好的错误检测能力受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射强及振动大的工业环境。
二、CAN的特点
CAN比较高级,它只存在一些较高级的单片机中(叫做CAN总线),一些低端单片机需要接CAN控制器及电平转换器才能使用CAN通信。有自带CAN总线的单片机控制CAN通信实际上也是操作单片机内部的寄存器来实现。
三、CAN协议的物理层
与I2C、 SPI等具有时钟信号的同步通讯方式不同, CAN通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。CAN物理层的形式主要分为闭环总线及开环总线网络两种,一个适合于高速通讯,一个适合于远距离通讯。
四、CAN协议的通信过程
CAN总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。
CAN通讯节点由一个CAN控制器及CAN收发器组成,控制器与收发器之间通过CAN_Tx及CAN_Rx信号线相连,收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。其中CAN_Tx及CAN_Rx使用普通的类似TTL逻辑信号,而CAN_High及CAN_Low是一对差分信号线,使用比较特别的差分信号。当CAN节点需要发送数据时,控制器把要发送的二进制编码通过CAN_Tx线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线CAN_High和CAN_Low线输出到CAN总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的CAN_High及CAN_Low信号转化成普通的逻辑电平信号,通过CAN_Rx输出到控制器中。
五、CAN工作原理
1、 以广播的形式发送报文.当CAN总线上的某个节点需要给其他节点发送消息时,会以广播的形式发送给总线上所有的节点,因为总线上的节点不适用地址来进行配置CAN系统,而是根据报文的开头的11位标识符决定是否要接受其他节点发来的报文.(面向内容的编制方案)
2、 每个节点都有自己的处理器和CAN总线接口控制器;
3、当一个节点需要发送数据到另一个节点时,自身节点的处理器需要将要发送的数据和自己的标识符传给自身的总线控制接口,处于准备状态;当获取到总线的使用权后,将数据和标识符组装成报文,将报文以一定格式发出,此时其他的节点处于接收状态.至于其他节点是否接收,由其他节点决定,是都会对某些报文进行过滤.
4、 当新增的节点仅仅是纯粹的数据接收设备时,只需要该设备直接从总线上接收数据即可.
六、差分信号
差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方
式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0和逻辑1。
CAN协议中对它使用的CAN_High及CAN_Low表示的差分信号做了规定。以高速CAN协议为例,当表示逻辑1时(隐性电平), CAN_High和
CAN_Low线上的电压均为2.5v,即它们的电压差VH-VL=0V;而表示逻辑0时(显性电平), CAN_High的电平为3.5V, CAN_Low线的电平为1.5V,即它们的电压差为VH-VL=2V。
七、编程步骤
①、根据自己使用的单片机,在该单片机的芯片开发手册/参考手册上找出所有带CAN标题的书签,定位好资料位置。然后打开编程环境,建立工程,把单片机的底层代码文件包含进来。
②、封装CAN初始化函数(这个基本不用解释为什么,大多数外设运用都要初始化唤醒功能)。
1、 初始化硬件需求的单片机引脚(不同单片机对引脚初始化有不同的规则有些低端的8位单片机甚至不需要引脚初始化),使能相关的时钟信号(可能包括系统时钟、引脚时钟、外设CAN的时钟,也是根据自己用的单片机型号而定);
2、按要求配置位时序寄存器CAN_BTR(关于工作模式、波特率设置);
3、按要求配置主状态寄存器CAN_MCR(设置通信相关控制位)。
③、按需求配置筛选器(鄙人认为是为了保证数据的正确率相当于滤波器保证信号稳定)
1、配置主筛选器寄存器CAN_FMR(设置FINIT为1筛选器进入初始化模式);
2、配置筛选器激活寄存器CAN_FA1R,激活其中一个筛选器;
3、配置筛选器尺度寄存器CAN_FS1R,设置筛选尺度;
4、配置筛选器模式寄存器CAN_FM1R,设置筛选器工作模式。
5、配置筛选器FIFO分配寄存器CN_FFA1R(设置通过筛选器的数据存储到哪个FIFO存储器),注意每个筛选器的在寄存器设置位不一样,如FFA1位,设置的是筛选器1;
6、配置主筛选器寄存器CAN_FMR(设置FINIT为0筛选器结束初始化模式)。
④、如果需要CAN收发中断,则要配置中断使能寄存器CAN_IER。并写中断服务函数。对应地,也要根据单片机的不同做相应的单片机中断初始化。
⑤封装发送数据函数。
它是以数据帧的格式发送一串n多位的二进制数来达到发送0-8个字节数据的目的。
数据帧分为几个部分如下:
1)帧起始。表示数据帧开始的段。
2)仲裁段。表示该帧优先级的段。
3)控制段。表示数据的字节数及保留位的段。
4)数据段。数据的内容,一帧可发送0~8个字节的数据。
5)CRC段。检查帧的传输错误的段。
6)ACK段。表示确认正常接收的段。
7)帧结束。表示数据帧结束的段。
发送方法:
首先数据帧的数据都是在对应的寄存器里的,我们查手册可以知道,然后以下步骤:
1、检查发送状态寄存器CAN_TSR相应位看看有没有空数据的邮箱(有三个缓存数据的邮箱);
2、判断数据帧中的IDE看看是不是拓展格式,然后根据情况发送对应数据到CAN发送 FIFO邮箱标识符寄存器(CAN_TIxR)(x=0/1),再配置CAN发送FIFO邮箱数据长度和时 间戳寄存器(CAN_TDTxR) (x=0/1)记录数据长度字节大小等,再用对应算法把数据帧的数 据段的数据传到CAN发送邮箱数据寄存器(CAN_TDLxR/CAN_TDHxR) (x=0~2),最后邮箱 标识符寄存器(CAN_TIxR)的TXRQ置1表示请求发送数据;
3、检查发送状态寄存器CAN_TSR相应位,等待发送成功。
⑥、封装接收数据
同样是操作相关寄存器,如下顺序
1、 检查FIFO x CAN寄存器CAN_RFxR(x=0/1),读取相应状态,看看是否有数据接收;
2、判断数据帧中的IDE看看是不是拓展格式,然后根据情况发送对应数据到CAN接收 FIFO邮箱标识符寄存器(CAN_RIxR)(x=0/1) ,和发送差不多,同样要配置再配置CAN 接收FIFO邮箱数据长度和时 间戳寄存器(CAN_RDTxR) (x=0/1)记录数据长度字节大 小等,再用对应算法把数据帧的数 据段的数据传到CAN发送邮箱数据寄存器 (CAN_RDLxR/CAN_RDHxR) (x=0~2);
3、 把CAN接收FIFO寄存器(CAN_RF0R/CAN_RF1R)的RFOM0/RFOM1位置1,表示释 放指定的FIFO的输出邮箱,如果三个邮箱都有数据无法读下一条数据。
八、具体函数
初始化结构体: CAN_InitTypeDef
发送及接收结构体: CanTxMsg及CanRxMsg
筛选器结构体: CAN_FilterInitTypeDef
CAN的GPIO初始化函数:CAN_GPIO_Config()
CAN模式配置函数:CAN_Mode_Config(void)
CAN筛选器函数:CAN_Filter_Config(void)
CAN中断控制器函数:CAN_NVIC_Config()
CAN初始化函数:CAN_Config()
CAN发送函数
CAN接收函数