STM32CAN通讯

CAN 协议简介

CAN 是控制器局域网络(Controller Area Network) 的简称,它是由研发和生产汽车电子产品著称
的德国BOSCH 公司开发的,并最终成为国际标准(ISO11519),是国际上应用最广泛的现场总
线之一。
CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以
CAN 为底层协议专为大型货车和重工机械车辆设计的J1939 协议。近年来,它具有的高可靠性
和良好的错误检测能力受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射
强及振动大的工业环境。

与I2C、SPI 等具有时钟信号的同步通讯方式不同,CAN 通讯并不是以时钟信号来进行同步的,
它是一种异步通讯,只具有CAN_High 和CAN_Low 两条信号线,共同构成一组差分信号线,以
差分信号的形式进行通讯。

闭环总线网络

CAN 物理层的形式主要有两种,图CAN 闭环总线通讯网络中的CAN 通讯网络是一种遵循
ISO11898 标准的高速、短距离“闭环网络”,它的总线最大长度为40m,通信速度最高为1Mbps,
总线的两端各要求有一个“120 欧”的电阻。

 

开环总线网络

图CAN 开环总线通讯网络中的是遵循ISO11519-2 标准的低速、远距离“开环网络”,它的最大
传输距离为1km,最高通讯速率为125kbps,两根总线是独立的、不形成闭环,要求每根总线上
各串联有一个“2.2 千欧”的电阻。

通讯节点

从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 输出到
控制器中。
例如,STM32 的CAN 片上外设就是通讯节点中的控制器,为了构成完整的节点,还要给它外接一个收发器,在我们实验板中使用型号为TJA1050 的芯片作为CAN 收发器。CAN 控制器与CAN
收发器的关系如同TTL 串口与MAX3232 电平转换芯片的关系,MAX3232 芯片把TTL 电平的串
口信号转换成RS-232 电平的串口信号,CAN 收发器的作用则是把CAN 控制器的TTL 电平信号
转换成差分信号(或者相反)。

差分信号

差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输
时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示
逻辑0 和逻辑1。见图差分信号,它使用了V+ 与V-信号的差值表达出了图下方的信号。

相对于单信号线传输的方式,使用差分信号传输具有如下优点:
• 抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关
心两个信号的差值,所以外界的共模噪声可以被完全抵消。
• 能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射
的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。
• 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依
靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更
适合于低幅度信号的电路。
由于差分信号线具有这些优点,所以在USB 协议、485 协议、以太网协议及CAN 协议的物理层
中,都使用了差分信号传输。
CAN 协议中的差分信号

CAN 协议中对它使用的CAN_High 及CAN_Low 表示的差分信号做了规定,见表CAN 协议标准
表示的信号逻辑及图CAN 的差分信号高速。以高速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_Tx 线接收到来自CAN 控制器的低电平信号时(逻辑0),它会使
CAN_High 输出3.5V,同时CAN_Low 输出1.5V,从而输出显性电平表示逻辑0。

在CAN 总线中,必须使它处于隐性电平(逻辑1) 或显性电平(逻辑0) 中的其中一个状态。假如
有两个CAN 通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,类似I2C 总线
的“线与”特性将使它处于显性电平状态,显性电平的名字就是这样来的,即可以认为显性具有
优先的意味。
由于CAN 总线协议的物理层只有1 对差分线,在一个时刻只能表示一个信号,所以对通讯节点
来说,CAN 通讯是半双工的,收发数据需要分时进行。在CAN 的通讯网络中,因为共用总线,
在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收。

协议层

CAN 的波特率及位同步

由于CAN 属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步
通讯那样,节点间使用约定好的波特率进行通讯,特别地,CAN 还会使用“位同步”的方式来抗
干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常。

位时序分解

为了实现位同步,CAN 协议把每一个数据位的时序分解成如图CAN 位时序分解图所示的SS 段、
PTS 段、PBS1 段、PBS2 段,这四段的长度加起来即为一个CAN 数据位的长度。分解后最小的
时间单位是Tq,而一个完整的位由8~25 个Tq 组成。为方便表示,图CAN 位时序分解图中的高
低电平直接代表信号逻辑0 或逻辑1(不是差分信号)。

该图中表示的CAN 通讯信号每一个数据位的长度为19Tq,其中SS 段占1Tq,PTS 段占6Tq,PBS1
段占5Tq,PBS2 段占7Tq。信号的采样点位于PBS1 段与PBS2 段之间,通过控制各段的长度,可
以对采样点的位置进行偏移,以便准确地采样。
各段的作用如介绍下:
• SS 段(SYNC SEG)
SS 译为同步段,若通讯节点检测到总线上信号的跳变沿被包含在SS 段的范围之内,
则表示节点与总线的时序是同步的,当节点与总线同步时,采样点采集到的总线电平
即可被确定为该位的电平。SS 段的大小固定为1Tq。
• PTS 段(PROP SEG)
PTS 译为传播时间段,这个时间段是用于补偿网络的物理延时时间。是总线上输入比
较器延时和输出驱动器延时总和的两倍。PTS 段的大小可以为1~8Tq。
• PBS1 段(PHASE SEG1),
PBS1 译为相位缓冲段,主要用来补偿边沿阶段的误差,它的时间长度在重新同步的
时候可以加长。PBS1 段的初始大小可以为1~8Tq。
• PBS2 段(PHASE SEG2)
PBS2 这是另一个相位缓冲段,也是用来补偿边沿阶段误差的,它的时间长度在重新同步时可以缩短。PBS2 段的初始大小可以为2~8Tq。

通讯的波特率

总线上的各个通讯节点只要约定好1 个Tq 的时间长度以及每一个数据位占据多少个Tq,就可以
确定CAN 通讯的波特率。
例如,假设上图中的1Tq=1us,而每个数据位由19 个Tq 组成,则传输一位数据需要时间T1bit
=19us,从而每秒可以传输的数据位个数为:
1x106
/19 = 52631.6 (bps)
这个每秒可传输的数据位的个数即为通讯中的波特率。

CAN 的报文种类及结构

CAN 协议给出的解决方案是对数据、操
作命令(如读/写) 以及同步信号进行打包,打包后的这些内容称为报文。

报文的种类
在原始数据段的前面加上传输起始标签、片选(识别) 标签和控制标签,在数据的尾段加上CRC
校验标签、应答标签和传输结束标签,把这些内容按特定的格式打包好,就可以用一个通道表达
各种信号了,各种各样的标签就如同SPI 中各种通道上的信号,起到了协同传输的作用。当整个
数据包被传输到其它设备时,只要这些设备按格式去解读,就能还原出原始数据,这样的报文就
被称为CAN 的“数据帧”。

数据帧以一个显性位(逻辑0) 开始,以7 个连续的隐性位(逻辑1) 结束,在它们之间,分别有仲
裁段、控制段、数据段、CRC 段和ACK 段。

• 帧起始
SOF 段(Start Of Frame),译为帧起始,帧起始信号只有一个数据位,是一个显性电平,它用于通
知各个节点将有数据传输,其它节点通过帧起始信号的电平跳变沿来进行硬同步。
• 仲裁段
当同时有两个报文被发送时,总线会根据仲裁段的内容决定哪个数据包能被传输,这也是它名称
的由来。

仲裁段的内容主要为本数据帧的ID 信息(标识符),数据帧具有标准格式和扩展格式两种,区别
就在于ID 信息的长度,标准格式的ID 为11 位,扩展格式的ID 为29 位,它在标准ID 的基础上
多出18 位。在CAN 协议中,ID 起着重要的作用,它决定着数据帧发送的优先级,也决定着其它
节点是否会接收这个数据帧。CAN 协议不对挂载在它之上的节点分配优先级和地址,对总线的
占有权是由信息的重要性决定的,即对于重要的信息,我们会给它打包上一个优先级高的ID,使
它能够及时地发送出去。也正因为它这样的优先级分配原则,使得CAN 的扩展性大大加强,在
总线上增加或减少节点并不影响其它设备。
报文的优先级,是通过对ID 的仲裁来确定的。根据前面对物理层的分析我们知道如果总线上同
时出现显性电平和隐性电平,总线的状态会被置为显性电平,CAN 正是利用这个特性进行仲裁。
若两个节点同时竞争CAN 总线的占有权,当它们发送报文时,若首先出现隐性电平,则会失去对总线的占有权,进入接收状态。见图仲裁过程,在开始阶段,两个设备发送的电平一样,所以
它们一直继续发送数据。到了图中箭头所指的时序处,节点单元1 发送的为隐性电平,而此时节
点单元2 发送的为显性电平,由于总线的“线与”特性使它表达出显示电平,因此单元2 竞争总
线成功,这个报文得以被继续发送出去。


STM32 的 CAN 外设简介

STM32 的芯片中具有bxCAN 控制器(Basic Extended CAN),它支持CAN 协议2.0A 和2.0B 标准。
该CAN 控制器支持最高的通讯速率为1Mb/s;可以自动地接收和发送CAN 报文,支持使用标准
ID 和扩展ID 的报文;外设中具有3 个发送邮箱,发送报文的优先级可以使用软件控制,还可以
记录发送的时间;具有2 个3 级深度的接收FIFO,可使用过滤功能只接收或不接收某些ID 号的
报文;可配置成自动重发;不支持使用DMA 进行数据收发。

·CAN 控制内核
·CAN 发送邮箱
·CAN 接收 FIFO
验收筛选器
整体控制逻辑

STM32 的有两组 CAN 控制器其中 CAN1 是主设备,框图中的“存储访问控制器”是由 CAN1 控制的,CAN2 无法直接访问存储区域,所以使用 CAN2 的时候必须使能 CAN1 外设的时钟。

各个工作模式介绍如下:
• 正常模式
正常模式下就是一个正常的CAN 节点,可以向总线发送数据和接收数据。
• 静默模式
静默模式下,它自己的输出端的逻辑0 数据会直接传输到它自己的输入端,逻辑1 可
以被发送到总线,所以它不能向总线发送显性位(逻辑0),只能发送隐性位(逻辑1)。
输入端可以从总线接收内容。由于它只可发送的隐性位不会强制影响总线的状态,所
以把它称为静默模式。这种模式一般用于监测,它可以用于分析总线上的流量,但又不会因为发送显性位而影响总线。
• 回环模式
回环模式下,它自己的输出端的所有内容都直接传输到自己的输入端,输出端的内容
同时也会被传输到总线上,即也可使用总线监测它的发送内容。输入端只接收自己发
送端的内容,不接收来自总线上的内容。使用回环模式可以进行自检。
• 回环静默模式
回环静默模式是以上两种模式的结合,自己的输出端的所有内容都直接传输到自己
的输入端,并且不会向总线发送显性位影响总线,不能通过总线监测它的发送内容。
输入端只接收自己发送端的内容,不接收来自总线上的内容。这种方式可以在“热自
检”时使用,即自我检查的时候,不会干扰总线。

CAN 发送邮箱

回到图25‑5 中的CAN 外设框图,在标号处的是CAN 外设的发送邮箱,它一共有3 个发送邮箱,
即最多可以缓存3 个待发送的报文。
每个发送邮箱中包含有标识符寄存器CAN_TIxR、数据长度控制寄存器CAN_TDTxR 及2 个数据
寄存器CAN_TDLxR、CAN_TDHxR,它们的功能见表发送邮箱的寄存器。

当我们要使用CAN 外设发送报文时,把报文的各个段分解,按位置写入到这些寄存器中,并对
标识符寄存器CAN_TIxR 中的发送请求寄存器位TMIDxR_TXRQ 置1,即可把数据发送出去。
其中标识符寄存器CAN_TIxR 中的STDID 寄存器位比较特别。我们知道CAN 的标准标识符的
总位数为11 位,而扩展标识符的总位数为29 位的。当报文使用扩展标识符的时候,标识符寄存
器CAN_TIxR 中的STDID[10:0] 等效于EXTID[18:28] 位,它与EXTID[17:0] 共同组成完整的29
位扩展标识符。

CAN 接收FIFO

图STM32 的CAN 外设架构图中的CAN 外设框图,在标号处的是CAN 外设的接收FIFO,它一
共有2 个接收FIFO,每个FIFO 中有3 个邮箱,即最多可以缓存6 个接收到的报文。当接收到报
文时,FIFO 的报文计数器会自增,而STM32 内部读取FIFO 数据之后,报文计数器会自减,我
们通过状态寄存器可获知报文计数器的值,而通过前面主控制寄存器的RFLM 位,可设置锁定
模式,锁定模式下FIFO 溢出时会丢弃新报文,非锁定模式下FIFO 溢出时新报文会覆盖旧报文。
跟发送邮箱类似,每个接收FIFO 中包含有标识符寄存器CAN_RIxR、数据长度控制寄存器
CAN_RDTxR 及2 个数据寄存器CAN_RDLxR、CAN_RDHxR,通过中断或状态寄存器知道接收FIFO 有数据后,我们再读取这些寄存器的值即可把接收到的报文加载到STM32 的内存中。

验收筛选器

图STM32 的CAN 外设架构图中的CAN 外设框图,在标号处的是CAN 外设的验收筛选器,一共
有28 个筛选器组,每个筛选器组有2 个寄存器,CAN1 和CAN2 共用的筛选器的。
在CAN 协议中,消息的标识符与节点地址无关,但与消息内容有关。因此,发送节点将报文广
播给所有接收器时,接收节点会根据报文标识符的值来确定软件是否需要该消息,为了简化软件
的工作,STM32 的CAN 外设接收报文前会先使用验收筛选器检查,只接收需要的报文到FIFO
中。
筛选器工作的时候,可以调整筛选ID 的长度及过滤模式。根据筛选ID 长度来分类有有以下两
种:
(1) 检查STDID[10:0]、EXTID[17:0]、IDE 和RTR 位,一共31 位。
(2) 检查STDID[10:0]、RTR、IDE 和EXTID[17:15],一共16 位。
通过配置筛选尺度寄存器CAN_FS1R 的FSCx 位可以设置筛选器工作在哪个尺度。
而根据过滤的方法分为以下两种模式:
(1) 标识符列表模式,它把要接收报文的ID 列成一个表,要求报文ID 与列表中的某一个标识符
完全相同才可以接收,可以理解为白名单管理。
(2) 掩码模式,它把可接收报文ID 的某几位作为列表,这几位被称为掩码,可以把它理解成关键
字搜索,只要掩码(关键字) 相同,就符合要求,报文就会被保存到接收FIFO。

通过配置筛选模式寄存器CAN_FM1R 的FBMx 位可以设置筛选器工作在哪个模式。
不同的尺度和不同的过滤方法可使筛选器工作在图筛选器的4 种工作状态的4 种状态。


CAN 控制的相关结构体

/**
 * @brief CAN 初始化结构体
 */
 typedef struct {
 uint16_t CAN_Prescaler; /* 配置CAN 外设的时钟分频,可设置为1-1024*/
 uint8_t CAN_Mode; /* 配置CAN 的工作模式,回环或正常模式*/
 uint8_t CAN_SJW; /* 配置SJW 极限值*/
 uint8_t CAN_BS1; /* 配置BS1 段长度*/
 uint8_t CAN_BS2; /* 配置BS2 段长度*/
 FunctionalState CAN_TTCM; /* 是否使能TTCM 时间触发功能*/
 FunctionalState CAN_ABOM; /* 是否使能ABOM 自动离线管理功能*/
 FunctionalState CAN_AWUM; /* 是否使能AWUM 自动唤醒功能*/
 FunctionalState CAN_NART; /* 是否使能NART 自动重传功能*/
 FunctionalState CAN_RFLM; /* 是否使能RFLM 锁定FIFO 功能*/
 FunctionalState CAN_TXFP; /* 配置TXFP 报文优先级的判定方法*/
 } CAN_InitTypeDef;
 /**
 * @brief CAN Tx message structure definition
 * 发送结构体
 */
 typedef struct {
 uint32_t StdId; /* 存储报文的标准标识符11 位,0-0x7FF. */
 uint32_t ExtId; /* 存储报文的扩展标识符29 位,0-0x1FFFFFFF. */
 uint8_t IDE; /* 存储IDE 扩展标志*/
 uint8_t RTR; /* 存储RTR 远程帧标志*/
 uint8_t DLC; /* 存储报文数据段的长度,0-8 */
 uint8_t Data[8]; /* 存储报文数据段的内容*/
 } CanTxMsg;

 /**
 * @brief CAN Rx message structure definition
 * 接收结构体
 */
 typedef struct {
 uint32_t StdId; /* 存储了报文的标准标识符11 位,0-0x7FF. */
 uint32_t ExtId; /* 存储了报文的扩展标识符29 位,0-0x1FFFFFFF. */
 uint8_t IDE; /* 存储了IDE 扩展标志*/
 uint8_t RTR; /* 存储了RTR 远程帧标志*/
 uint8_t DLC; /* 存储了报文数据段的长度,0-8 */
 uint8_t Data[8]; /* 存储了报文数据段的内容*/
 uint8_t FMI; /* 存储了本报文是由经过筛选器存储进FIFO 的,0-0xFF */
 } CanRxMsg;
/**
 * @brief CAN filter init structure definition
 * CAN 筛选器结构体
 */
 typedef struct {
 uint16_t CAN_FilterIdHigh; /*CAN_FxR1 寄存器的高16 位*/
 uint16_t CAN_FilterIdLow; /*CAN_FxR1 寄存器的低16 位*/
 uint16_t CAN_FilterMaskIdHigh; /*CAN_FxR2 寄存器的高16 位*/
 uint16_t CAN_FilterMaskIdLow; /*CAN_FxR2 寄存器的低16 位*/
 uint16_t CAN_FilterFIFOAssignment; /* 设置经过筛选后数据存储到哪个接收FIFO

 uint8_t CAN_FilterNumber; /* 筛选器编号,范围0-27*/
 uint8_t CAN_FilterMode; /* 筛选器模式*/
 uint8_t CAN_FilterScale; /* 设置筛选器的尺度*/
 FunctionalState CAN_FilterActivation; /* 是否使能本筛选器*/
 } CAN_FilterInitTypeDef;

CAN 发送及接收结构体
当需要使用 CAN 发送报文时, 先定义一个上面发送类型的结构体, 然后把报文的内容按成员赋值到该结构体中, 最后调用库函数 CAN_Transmit 把这些内容写入到发送邮箱即可把报文发送出去。
接收报文时, 通过检测标志位获知接收 FIFO 的状态, 若收到报文, 可调用库函数 CAN Receive 把接收 FIFO 中的内容读取到预先定义的接收类型结构体中,然后再访问该结构体即可利用报文。


CAN 一—通讯实验

 后面的有需要在继续看

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32是一种高性能的32位微控制器,具有广泛的应用领域。其中,CAN(Controller Area Network)通讯STM32最常用的通信协议之一。下面是关于STM32 CAN通讯例程的一些介绍。 STM32 CAN通讯例程是一种用于实现CAN通讯功能的开发示例。该例程提供了一套完整的CAN通讯工作流程,包括初始化CAN模块、配置CAN通讯参数、发送CAN帧和接收CAN帧等。 在使用STM32 CAN通讯例程之前,首先需要在STM32开发板上连接CAN总线,以实现外部设备和STM32通信。然后,需要通过调用相应的函数来初始化CAN模块,并设置通讯参数,如波特率、过滤器和模式等。 一旦CAN模块初始化完毕,就可以使用相应的函数来发送和接收CAN帧。发送CAN帧需要将数据打包为CAN帧的格式,并使用相应的标识符将其发送到总线上。接收CAN帧需要使用相应的函数持续监听总线上的数据,并将接收到的数据解析为可用的格式。 在进行CAN通讯时,还可以使用中断或DMA来处理接收和发送数据。中断可以实现数据的实时处理和异步通知,而DMA可以实现高速的数据传输,提高系统性能。 STM32 CAN通讯例程具有广泛的应用场景,如汽车电子系统、工业自动化控制和智能家居等。通过学习和理解STM32 CAN通讯例程,开发者可以更好地使用STM32的CAN通讯功能,实现各种实际应用的需求。 总之,STM32 CAN通讯例程提供了一套方便易用的开发示例,帮助开发者快速上手并实现CAN通讯功能。通过学习该例程,开发者可以扩展STM32的应用范围,实现更多有趣和实用的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值