一点一点把CAN总线通信吃透

**

不如直接去看stm32中文参考手册

**

CAN定义

CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络

CAN相关芯片

1.CAN控制器
2.CAN收发器:CAN收发器的作用是负责逻辑电平和信号电平之间的转换。
即从CAN控制芯片输出逻辑电平到CAN收发器,然后经过CAN收发器内部转换将逻辑电平转换为差分信号输出到CAN总线上,CAN总线上的节点都可以决定自己是否需要总线上的数据。
一点一点把CAN总线通信吃透_第1张图片
CAN收发器引脚定义
一点一点把CAN总线通信吃透_第2张图片

3.CAN过滤器
stm32 can的屏蔽位模式:

关于帧id怎么设定

在http://blog.csdn.net/flydream0/article/details/8148791CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时,根据标识符(CAN ID)的值决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。()

CAN总线ID是包含在报文帧中的。

1、主要用作CAN总线的仲裁使用,所以一般来说网络上的每个节点(向总线上发送)的ID应该有所不同。ID值越低,报文优先级越高,在两组不同ID报文同时上线时候,仲裁机制使得ID值低的占用总线,ID值高的退出。

2、ID域可以是11位和29位,其值和含义可以由用户自定义,可以用作高层协议的管理,比如CANopen等协议中把ID的部分做为“源地址”,部分作为“目的地址”,这样CAN报文从哪来到哪去都清晰了。

3、ID的另一个作用是配合接收方滤波使用,就是说一般接收的滤波器可以设定接收ID的范围等,用于过滤掉不需要接收的信息,减轻CPU的处理负担。

ID是赋给帧的,不是直接给节点的,只是某节点知道自己要接收某个ID的帧。总线上的节点来说它只管取总线上他应该取的ID的帧,并不管是谁发的。
即使是远程帧,发出请求的节点在获得相应时也仅仅是根据帧ID判定,并不影响其他节点的接收。

我们要从总线的角度去看待CAN,不要从节点的角度出发

CAN报文的优先级

当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送
通过帧id判定优先级 越小优先级越高
当多个发送邮箱挂起时,发送顺序由邮箱中所存储消息的标识符来确定。根据 CAN 协议的
仲裁,标识符值最低的消息具有最高的优先级。如果标识符值相等,则首先安排发送编号较
小的邮箱。

过滤器的两种过滤模式-屏蔽位模式和标识符列表模式

https://blog.csdn.net/qq_42282258/article/details/81783621?ops_request_misc=&request_id=&biz_id=102&utm_term=can%E6%8A%A5%E6%96%87%E7%9A%84%E4%BC%98%E5%85%88%E7%BA%A7&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-5-81783621.pc_search_es_clickV2&spm=1018.2226.3001.4187
STM32的标识符过滤是一个比较复杂的东东,它的存在减少了CPU处理CAN通信的开销。STM32的过滤器组最多有28个(互联型),但是STM32F103ZET6只有14个(增强型),每个滤波器组x由2个32为寄存器,CAN_FxR1和CAN_FxR2组成

为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。
为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。

stm32 can的屏蔽位模式:
一个是标识符寄存器,一个是屏蔽位寄存器。
凡是屏蔽位寄存器里为1的位所对应的标识符寄存器的位,这些位是必须匹配的,也就是说,你接受到的Message里面的标识符(ID)里面对应的位必须跟标识符寄存器里对应的位相同,才能被接受。
例如:
标识符寄存器的bit15=0,屏蔽位寄存器的bit15=1,那么接受的Message里面的标识符的bit15必须为0才可能被硬件接受。
如果屏蔽位寄存器的bit15=0,Message里面的标识符的bit15无论为什么值,bit15都能匹配通过。
当bit0~bit31都能通过时。此Message就会被硬件接受。

CAN的配置—讲解

void CAN1_Config_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //ʹGPIOAʱÖÓ	          											 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//ʹÄÜCAN1ʱÖÓ	

//引脚配置
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11¸´ÓÃΪCAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12¸´ÓÃΪCAN1

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;	//
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//

GPIO_Init(GPIOA, &GPIO_InitStructure);			//³õʼ»¯IO

//CAN单元配置
CAN_InitStructure.CAN_TTCM=DISABLE;			//非时间触发通信模式
CAN_InitStructure.CAN_ABOM=ENABLE;			//软件自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE;			//睡眠模式通过软件唤醒
CAN_InitStructure.CAN_NART=ENABLE;			    //使能报文自动发送
CAN_InitStructure.CAN_RFLM=DISABLE;		 	//报文不锁定,新的覆盖旧的
CAN_InitStructure.CAN_TXFP=DISABLE;		    	//优先级由报文标识符决定
CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;	        //正常模式或者 回环模式 
//设置波特率
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;				//
CAN_InitStructure.CAN_BS1=CAN_BS1_12tq; 			//
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;				//
CAN_InitStructure.CAN_Prescaler=CAN1_PRESCALER;        //

CAN_Init(CAN1, &CAN_InitStructure);        	//初始化CAN1 

//滤波器配置
CAN_FilterInitStructure.CAN_FilterNumber = 0;	//过滤器0
CAN_FilterInitStructure.CAN_FilterMode	=	CAN_FilterMode_IdMask; 	//屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale	=	CAN_FilterScale_32bit; 	//32位宽
//全部设置为零,不过滤id
CAN_FilterInitStructure.CAN_FilterIdHigh		=	0;
CAN_FilterInitStructure.CAN_FilterIdLow			=   0;	
CAN_FilterInitStructure.CAN_FilterMaskIdHigh	=	0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow		=	0;

CAN_FilterInitStructure.CAN_FilterFIFOAssignment	=	CAN_Filter_FIFO0;//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0

CAN_FilterInit(CAN1,&CAN_FilterInitStructure);			/

//CAN1 NVIC  中断配置
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次级优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);				//FIFO0消息挂号中断允许	    

}

CAN中没有节点地址只有帧id

CAN总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于CAN通讯协议不对节点进行地址编码,而是对数据内容进行编码,所以网络中的节点个数理论上不 受限制,只要总线的负载足够即可,可以通过中继器增强负载。
CAN通讯节点由一个CAN控制器及CAN收发器组成,控制器与收发器(电平转换)之间通过CAN_Tx及CAN_Rx信号线相连,收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。
当CAN节点需要发送数据时,控制器把要发送的二进制编码通过CAN_Tx线发送到收发器,然后有收发器把这个普通的逻辑电平转化为差分信号,通过差分线CAN_High和CAN_Low线输出到CAN总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的CAN_High及CAN_Low信号转化为普通的逻辑电平信号,通过CAN_Rx输出到控制器中。
由于CAN总线协议的物理层只有1对差分线,在一个时刻只能表示一个信号,所以对通讯节点来说,CAN通讯是半双工的,收发数据需要分时进行。在CAN的通讯网络中,因为共用总线,在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收。

原文链接:https://blog.csdn.net/simonforfuture/article/details/79405663

CAN的过滤器(以及过滤器和FIFO的关系)

STM32普通型芯片的CAN有14组过滤器组,互联型有28组过滤器组.
所有的过滤器是并联的,即,一个报文只要通过了一个过滤器,就是算是有效的.

每组过滤器组有两种工作模式: 标识符列表模式,标识符屏蔽位模式.
在标识符列表模式下,收到报文的标识符必须与过滤器的值完全相等,才能通过.
在标识符屏蔽位模式下,可以指定标识符的哪些位为何值时,就算通过.这其实就是限定了处于某一范围的标识符能够通过.
在一组过滤器中,整组的过滤器都使用同一种工作模式.

另外,每组过滤器中的过滤器宽度是可变的,可以是32位或16位.
由工作模式和宽度,一个过滤器组可以变成以下几中形式之一:
(1) 1个32位的屏蔽位模式的过滤器.
(2) 2个32位的列表模式的过滤器.
(3) 2个16位的屏蔽位模式的过滤器.
(4) 4个16位的列表模式的过滤器.
所有的过滤器是并联的,即,一个报文只要通过了一个过滤器,就是算是有效的.

每组过滤器组有两个32位的寄存器用于存储过滤用的"标准值",分别是FxR1,FxR2.
在32位的屏蔽位模式下:
有1个过滤器,
FxR2用于指定需要关心哪些位,FxR1用于指定这些位的标准值.
在32位的列表模式下:
有两个过滤器.
FxR1指定过滤器0的标准值,收到报文的标识符只有跟FxR1完全相同时,才算通过.
FxR2指定过滤器1的标准值.
在16位的屏蔽位模式下:
有2个过滤器.
FxR1配置过滤器0,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值.
FxR2配置过滤器1,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值.
在16位的列表模式下:
有4个过滤器.
FxR1的[15-0]位配置过滤器0,FxR1的[31-16]位配置过滤器1.
FxR2的[15-0]位配置过滤器2,FxR2的[31-16]位配置过滤器3.

STM32的CAN有两个FIFO,分别是FIFO0,FIFO1.为了便于区分,下面FIFO0写作FIFO_0,FIFO1写作FIFO_1.
每组过滤器组必须关联且只能关联一个FIFO.复位默认都关联到FIFO_0.
所谓"关联",是指假如收到的报文从某个过滤器通过了,那么该报文会被存到该过滤器相连的FIFO.
从另一方面来说,每个FIFO都关联了一串的过滤器组,两个FIFO刚好瓜分了所有的过滤器组.

每当收到一个报文,CAN就将这个报文先与FIFO_0关联的过滤器比较,如果被匹配,就将此报文放入FIFO_0中.
如果不匹配,再将报文与FIFO_1关联的过滤器比较,如果被匹配,些报文就放入FIFO_1中.
如果还是不匹配,此报文就被丢弃.

每个FIFO的所有过滤器都是并联的,只要通过了其中任何一个过滤器,该报文就有效.
如果一个报文既符合FIFO_0的规定,又符合FIFO_1的规定,显然,根据操作顺序,它只会放到FIFO_0中.

每个FIFO中只有激活了的过滤器才起作用,换句话说,如果一个FIFO有20个过滤器,但是只激话了5个,
那么比较报文时,只拿这5个过滤器作比较.
一般要用到某个过滤器时,在初始化阶段就直接将它激活.
需要注意的是,每个FIFO必须至少激活一个过滤器,它才有可能收到报文.如果一个过滤器都没有激活,
那么是所有报文都报废的.
一般的,如果不想用复杂的过滤功能,FIFO可以只激活一组过滤器组,且将它设置成32位的屏蔽位模式,
两个标准值寄存器(FxR1,FxR2)都设置成0.这样所有报文均能通过.

STM32 CAN中,另一个较难理解的就是过滤器编号.
过滤器编号用于加速CPU对收到报文的处理.
收到一个有效报文时, CAN会将收到的报文, 以及它所通过的过滤器编号, 一起存入接收邮箱中,
CPU在处理时,可以根据过滤器编号,快速的知道该报文的用途,从而作出处理.
不用过滤器编号其实也是可以的, 这时候CPU就要分析所收报文的标识符, 从而知道报文的用途.
由于标识符所含的信息较多,处理起来就慢一点了.

STM32使用以下规则对过滤器编号:
(1) FIFO_0和FIFO_1的过滤器分别独囗立编号,均从0开始按顺序编号.
(2) 所有关联同一个FIFO的过滤器,不管有没有被激活,均统一进行编号.
(3) 编号从0开始,按过滤器组的编号从小到大,按顺序排列.
(4) 在同一过滤器组内,按寄存器从小到大编号.FxR1配置的过滤器编号小,FxR2配置的过滤器编号大.
(5) 同一个寄存器内,按位序从小到大编号. [15-0]位配置的过滤器编号小,[31-16]位配置的过滤器编号大.
(6) 过滤器编号是囗弹性的. 当更改了设置时,每个过滤器的编号都会改变.
但是在设置不变的情况下,各个过滤器的编号是相对稳定的.

这样,每个过滤器在自己在FIFO中都有编号.
在FIFO_0中,编号从0 – (M-1), 其中M为它的过滤器总数.
在FIFO_1中,编号从0 – (N-1), 其中N为它的过滤器总数.

一个FIFO如果有很多的过滤器, 可能会有一条报文, 在几个过滤器上均能通过,
这时候, 这条报文算是从哪儿过来的呢?
STM32在使用过滤器时,按以下顺序进行过滤
(1) 位宽为32位的过滤器,优先级高于位宽为16位的过滤器
(2) 对于位宽相同的过滤器,标识符列表模式的优先级高于屏蔽位模式
(3) 位宽和模式都相同的过滤器,优先级由过滤器号决定,过滤器号小的优先级高

按这样的顺序,报文能通过的第一个过滤器,就是该报文的过滤器编号,被存入接收邮箱中.

转载于:https://www.cnblogs.com/liufang/p/3988795.html

1.CAN报文标识符:并不代表节点的地址 而是和报文的内容有关 发送者以广播的形式发送消息 节点在接收报文时根据标识符(CAN ID)决定是否需要该报文

如果需要则拷贝到SRAM中 不需要则丢弃
实现硬件过滤 节省CPU开销

2.过滤器组 Filterx x为过滤器号
STM32总共提供14个过滤器组来处理CAN接收过滤问题,每个过滤器组包含两个32位寄存器CAN_FxR0和CAN_FxR1组成

原文链接:https://blog.csdn.net/GUOXINLAN123/article/details/79398940

CAN的接收邮箱和发送邮箱(FIFO)

对于CAN邮箱的理解:
CAN总线有接收邮箱和发送邮箱:
”发送邮箱“是用于CAN总线数据发送的,总共有3个,并且存在优先级关系。优先级越高表示其里面的数据会被优先发送。数据在发送前都会被送到优先级最高且空闲的发送邮箱,然后依次发送。最后说明一点:“发送邮箱有3个,且每个邮箱只能装一个报文”。
”接收邮箱“是用于CAN总线数据接收用的,在接收数据端会有一个过滤器处于”接收邮箱“的前面,过滤器使用于筛选”标识符“的,只有标识符符合的报文才会被放入到”接收邮箱“当中。注意:”接收邮箱不同于发送邮箱,接收邮箱只有2(FIFO0、FIFO1)个,但是每一个有三层,每层都可以存放一个报文,即每一个接收邮箱可以接收三个报文。但读取时只能读到最先收到的报文,等这个读完之后,才能读下一个报文”。
一点一点把CAN总线通信吃透_第3张图片

从图中可以看出两个CAN都分别拥有自己的发送邮箱和接收FIFO,但是他们共用28个滤波器。通过CAN_FMR寄存器的设置,可以设置滤波器的分配方式
邮箱:用于发送
FIFO:用于接收 FIFO0和FIFO1分别对应不同的接收中断函数————配置CAN时要注意,FIFO0和FIFO1的中断函数名字不一样。
fifo0和fifo1是暂存数据的,这两个fifo是给filter用的,也就是filter先过滤数据,发现需要接收就把这个数据放到filter表项里指定的fifo中去

CAN通信的位定时与同步

https://blog.csdn.net/weixin_40528417/article/details/79936476

1 位定时
1.1 比特率和波特率

  1. . 位速率:又叫做比特率(bit rata)、信息传输率,表示的是单位时间内,总线上传输的信息量,即每秒能够传输的二进制位的数量,单位是bit per second。
    2)波特率:又叫做传码率、信号传输率,表示的是单位时间内传输的码元的数量,当两相调制时,一个码元用一个二进制位表示,此时波特率在数值上和比特率是一样的,CAN总线正是两项调制这种情况。
Tips: 比特率和波特率并不是一回事儿,这一定一定要牢记。

1.2 位时间
1.2.1 位时间的概念
位时间:表示的是一个二进制位在总线上传输时所需要的时间。
所以:

						       **位速率=1/位时间**

首先了解以下CAN总线系统中的两个时钟: 晶振时钟周期CAN时钟周期
晶振时钟周期:是由单片机振荡器的晶振频率决定的,指的是振荡器每震荡一次所消耗的时间长度,也是整个系统中最小的时间单位。
CAN时钟周期:CAN时钟是由系统时钟分频而来的一个时间长度值,实际上就是一个时间份额Tq。可以按照下面的公式计算:
CAN时钟周期=2×晶振时钟周期×BRP
CAN时钟周期=2×晶振时钟周期×BRP

其中BRP叫做波特率预分频值(baudrate prescaler)。
一点一点把CAN总线通信吃透_第4张图片

1.2.2 位时间的分段
如上文所述,在CAN的位定时中,一个CAN时钟周期称为一个时间量子 — Tq。
如下图所示:位时间分为四个段:同步段、传播段、相位缓冲段1、相位缓冲段2,总共8~25个时间量子(Tq)。

							**tBit=tSS+tPS+tPBS1+tPBS2**

tBit:位时间
tSS:同步段时间
tPS:传播段时间
tPBS1:时间段1
tPBS2:时间段2
一点一点把CAN总线通信吃透_第5张图片
BitRate = Fpclk/( (BRP+1) * ((Tseg1+1)+(Tseg2+1)+1)

CAN波特率计算公式

波特率:简单理解为每秒钟传输的二进制位数
位时间:传播一位二进制数需要的时间,简单理解为波特率的倒数
所以  : 波特率 = 

CAN波特率=系统时钟/分频数/(1*tq+tBS1+tBS2)

其中
tBS1=tq*(TS1[3:0]+1)
tBS2=tq*(TS2[2:0]+1)
tq=(BRP[9:0]+1)*tPCLK
这里tq表示1个时间单元
tPCLK=APB时钟的时间周期
BRP[9:0],TS1[3:0]和TS2[2:0]在CAN_BTR寄存器中定义
总体配置保持
tBS1>=tBS2,tBS2>=1个CAN时钟周期,tBS2>=2tSJW

原文链接:

CAN的波特率配制

STM32 CAN控制器简介-位时序:https://blog.csdn.net/baidu_37366055/article/details/98070376
STM32的CAN位时序,如下图所示:
一点一点把CAN总线通信吃透_第6张图片
**STM32F103,设TS1=8、TS2=7、BRP=3,波特率=36000/[(9+8+1)*4]=500Kbps。

STM32F407,设TS1=6、TS2=5、BRP=5,波特率=42000/[(7+6+1)6]=500Kbps。*

通过对CAN***位定时寄存器CANBIT***以及CAN***波特率预分频扩展寄存器***CANBRPE的设置可以得到需要的CAN通信波特率。

CAN的位定时配置不当,将使得CAN模块无法按照目标波特率接入CAN网络,将导致CAN节点无法通信正常。
每个段由具体、可编程数量的时间份额(time quanta)组成,时间份额是位时间的基本时间单元,它的长度(tq)由CAN控制器的系统时钟(fcan)和波特率预分频器BRP定义:tq=BRP/fcan

由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为 4 段。
l 同步段(SS)

l 传播时间段(PTS)

l 相位缓冲段1(PBS1)

l 相位缓冲段2(PBS2)
这些段又由可称为 Time Quantum(汉语意思:时间量;时间片;时间段;时间份额;时间配额)(以下称为Tq)的最小时间单位构成。

1 位分为4 个段,每个段又由若干个Tq 构成,这称为位时序。

1 位由多少个Tq 构成、每个段又由多少个Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。各段的作用和 Tq 数如表30.1.2所示:
一点一点把CAN总线通信吃透_第7张图片

CAN仲裁

在总线空闲态,最先开始发送消息的单元获得发送权。

当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。实现过程

当多个发送邮箱挂起时,发送顺序由邮箱中所存储消息的标识符来确定。根据 CAN 协议的
仲裁,标识符值最低的消息具有最高的优先级。如果标识符值相等,则首先安排发送编号较
小的邮箱。

CAN相关寄存器

CAN数据帧–帧类型–帧格式

帧类型:标准帧 扩展帧
帧格式:数据帧 远程帧(远程帧)错误帧 扩展帧 间隔帧
数据帧和遥控帧有标准格式和扩展格式两种格式

数据帧 用于发送单元向接收单元传送数据的帧
遥控帧 用于接收单元向具有相同 ID 的发送单元请求数据的帧
错误帧 用于当检测出错误时向其它单元通知错误的帧
过载帧 用于接收单元通知其尚未做好接收准备的帧
间隔帧 用于将数据帧及遥控帧与前面的帧分离开来的帧

简单介绍数据帧 ,数据帧一般由7个段构成,即:

(1) 帧起始。表示数据帧开始的段。

(2) 仲裁段。表示该帧优先级的段。

(3) 控制段。表示数据的字节数及保留位的段。

(4) 数据段。数据的内容,一帧可发送0~8个字节的数据。

(5) CRC段。检查帧的传输错误的段。

(6) ACK段。表示确认正常接收的段。

(7) 帧结束。表示数据帧结束的段。
数据帧每一段的介绍:https://blog.csdn.net/hanchaoman/article/details/70059072?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.no_search_link

显性与隐性电平的解释:

CAN的数据总线有两条,一条是黄色的CAN_High,一条是绿色的CAN_Low。当没有数据发送时,两条线的电平一样都为2.5V,称为静电平,也就是隐性电平。当有信号发送时,CAN_High的电平升高1V,即3.5V,CAN_Low的电平降低1V,即1.5V。

按照定义的:

CAN_H-CAN_L < 0.5V 时候为隐性的,逻辑信号表现为"逻辑1"- 高电平。

CAN_H-CAN_L > 0.9V 时候为显性的,逻辑信号表现为"逻辑0"- 低电平。

CAN的发送与CAN的接收----芯片级别

发送过程: CAN控制器将CPU传来的信号转换为逻辑电平(即逻辑0-显性电平或者逻辑1-隐性电平)。CAN发射器接收逻辑电平之后,再将其转换为差分电平输出到CAN总线上。
一点一点把CAN总线通信吃透_第8张图片
接收过程: CAN接收器将CAN_H 和 CAN_L 线上传来的差分电平转换为逻辑电平输出到CAN控制器,CAN控制器再把该逻辑电平转化为相应的信号发送到CPU上。
一点一点把CAN总线通信吃透_第9张图片

STM32 CAN控制器简介-发送流程和接收流程

CAN发送流程为:

程序选择1个空置的邮箱(TME=1)->设置标识符(ID),数据长度和发送数据->设置CAN_TIxR的TXRQ位为1,请求发送->邮箱挂号(等待成为最高优先级)->预定发送(等待总线空闲)->发送->邮箱空置
一点一点把CAN总线通信吃透_第10张图片
CAN接收流程为:

FIFO空->收到有效报文->挂号_1(存入FIFO的一个邮箱,这个由硬件控制,我们不需要理会)->收到有效报文->挂号_2->收到有效报文->挂号_3->收到有效报文->溢出。

CAN收到的有效报文,存储在3级邮箱深度的FIFO中。FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。

原文链接:https://blog.csdn.net/qq_38721302/article/details/82989171
一点一点把CAN总线通信吃透_第11张图片

你可能感兴趣的:(STM32,stm32,can)