STM32中CAN总线接口发送和接收数据

发布时间:2024-03-26  

☆ CAN协议基础知识

I2C.SPI总线多用于短距离传输,协议简单,数据量少,主要用于IC之间的通讯,而 CAN 总线则不同,CAN(Controller Area Network) 总线定义了更为优秀的物理层、数据链路层,并且拥有种类丰富、简繁不一的上层协议。与I2C、SPI有时钟信号的同步通讯方式不同,CAN通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。

CAN物理层的形式主要分为闭环总线及开环总线网络两种,一个适合于高速通讯,一个适合于远距离通讯。CAN闭环通讯网络是一种遵循ISO11898标准的高速、短距离网络,它的总线最大长度为40m,通信速度最高为1Mbps,总线的两端各要求有一个

“120欧”的电阻来做阻抗匹配,以减少回波反射。


☆ 闭环总线网络409c8e00-a4d9-11ec-952b-dac502259ad0.jpg

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

☆ 开环总线网络

40b0dd9c-a4d9-11ec-952b-dac502259ad0.jpg

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输出到控制器中。

☆ 差分信号

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

相对于单信号线传输的方式,使用差分信号传输具有如下优点:

  • 抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关心两个信号的差值,所以外界的共模噪声可以被完全抵消。

  • 能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。

  • 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。

  • 由于差分信号线具有这些优点,所以在USB协议、485协议、以太网协议及CAN协议的物理层中,都使用了差分信号传输。

☆ CAN协议中的差分信号

CAN协议中对它使用的CAN_High及CAN_Low表示的差分信号做了规定。以高速CAN协议为例,当表示逻辑1时(隐性电平),CAN_High和CAN_Low线上的电压均为2.5v,即它们的电压差V H -V L =0V;而表示逻辑0时(显性电平),CAN_High的电平为3.5V,CAN_Low线的电平为1.5V,即它们的电压差为V H -V L =2V。

40bef288-a4d9-11ec-952b-dac502259ad0.jpg


☆ CAN 总线的特点

CAN 总线网络是一种真正的多主机网络,在总线处于空闲状态时,任何一个节点单元都可以申请成为主机,向总线发送消息。其原则是:最先访问总线的节点单元可以获得总线的控制权;多个节点单元同时尝试获取总线的控制权时,将发生仲裁事件,具有高优先级的节点单元将获得总线控制权。

CAN 协议中,所有的消息都以固定的数据格式打包发送。两个以上的节点单元同时发送信息时,根据节点标识符(常称为 ID,亦打包在固定的数据格式中)决定各自优先级关系,所以 ID 并非表示数据发送的目的地址,而是代表着各个节点访问总线的优先级。如此看来,CAN 总线并无类似其他总线“地址”的概念,在总线上增加节点单元时,连接在总线的其他节点单元的软硬件都不需要改变。

CAN 总线的通信速率和总线长度有关,在总线长度小于 40m 的场合中,数据传输速率可以达到 1Mbps,而即便总线长度上升至 1000m,数据的传输速率仍可达到 50Kbps,无论在速率还是传输距离都明显优于常见的 RS232、RS485 和 I2C 总线。

对于总线错误,CAN 总线有错误检测功能、错误通知功能、错误恢复功能三种应对措施,分别应对于下面三点表述:所有的单元节点都可以自动检测总线上的错误;检测出错误的节点单元会立刻将错误通知给其他节点单元;若正在发送消息的单元检测到当前总线发生错误,则立刻强制取消当前发送,并不断反复发送此消息至成功为止。

CAN 总线上的每个节点都可以通过判断得出,当前总线上的错误是暂时的错误(如瞬间的强干扰)还是持续的错误(如总线断裂)。当总线上发生持续错误时,引起故障的节点单元会自动脱离总线。

CAN 总线上的节点数量在理论上没有上限,但在实际上受到总线上的时间延时及电气负载的限制。降低最大通信速率,可以增加节点单元的连接数;反之,减少节点单元的连接数,则最大通信速率可以提高。

CAN总线的数据通信是以数据帧的格式进行的,而数据帧又是由位场组成的,其中每一个位又被划分为四段.即SS(SYNC SEG),PTS(PROP SEG--传播时间段),PBS1(PHASE SEG1--相位缓冲段1),PBS2(PHASE SEG1--相位缓冲段2).

数据帧的结构图:

40d83a90-a4d9-11ec-952b-dac502259ad0.png图中D表示显性电平,R表示隐形电平.ID:高位在前,低位在后。基本ID,禁止高7位都为隐性,即不能:ID=1111111XXXX。RTR,远程请求位。0,数据帧;1, 远程帧;SRR,替代远程请求位。设置为1(隐性电平);IDE,标识符选择位。0,标准标识符;1,扩展标识符;r0,r1:保留位。必须以显现电平发送,但是接收可以是隐性电平。DLC:数据长度码。0~8,表示发送/接收的数据长度(字节)。IDE,标识符选择位。0,标准标识符;1,扩展标识符; ☆ 位时序分解

为了实现位同步,CAN协议把每一个数据位的时序分解成SS段、PTS段、PBS1段、PBS2段,这四段的长度加起来即为一个CAN数据位的长度。分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq组成。

40f7d45e-a4d9-11ec-952b-dac502259ad0.png


☆ STM32中的CAN接口

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

4110b67c-a4d9-11ec-952b-dac502259ad0.jpg

1. CAN控制内核2. CAN发送邮箱3. CAN接收FIFO

4. 验收筛选器

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

STM32至少配备一个bxCAN(basic extend can )控制器,支持2.0A和2.0B协议,最高数据传输速率可达1M bps,支持11位标准帧格式和29位扩展帧格式的接收和发送,具备三个发送邮箱和两个接收FIFO,此wa此外还有三级可编程滤波器,STM32的bxCAN非常适应CAN总线网络y网络应用发展需求,其主要主要特征如下 :

  • 支持CAN协议2.0A和2.0B主动模式

  • 波特率最高可达1Mbps

  • 支持时间触发通讯功能

数据发送特性:具备三个发送邮箱;发送报文的优先级可以通过软件配置,可记录发送时间的时间戳。

数据接收特性:具备三级深度和两个接收FIFO;具备可变的过滤器组,具备可编程标识符列表,可配置FIFO溢出处理方式,记录接收时间的时间戳报文管理:中断可屏蔽;邮箱单独占有一块地址空间,便于提高软件效率。本文的实验设计将利用STM32 的bxCAN控制器的环回工作模式,实现bxCAN控制器的自收发过程,并使用串口设备跟踪监视数据收发情况。程序流程如下图

4125a906-a4d9-11ec-952b-dac502259ad0.png

本程序设计主要围绕bxCAN控制器的初始化初始化配置展开,其要点罗列如下:

1. 初始化RCC寄存器,配置PLL输出72MHZ时钟,APB1总线频率为36MHZ,分别打开CAN,GPIO和USART1的设备时钟。

2. 设置CAN的Tx引脚(即PA12)为复用推挽模式,并设置Rx引脚(即PA1)为上拉输入模式,其中三个重要的参数如下配置:

CAN_InitStructure.CAN_SJW配置为CAN_SJW_1tq;CAN_InitStructure.CAN_BS1配置为CAN_BS1_8tq;CAN_InitStructure.CAN_BS2配置为CAN_BS2_7tq;


3. 最后分频数配置为5,配置接受接受缓冲区标识符为0x00AA0000,配置过滤器为32位屏蔽位模式,过滤器屏蔽标识符为0x00FF0000.

4. 初始化USART设备

5. 使用扩展帧shu帧数据格式,ID为0xAA,数据长度长度为8


STM32的CAN控制器设计的重点集中在CAN寄存器组的初始化过程中,而CAN初始化的重点在于波特率的设置,过滤器的设置和位时序的设置,以下作详细叙述。

(1)CAN波特率的计算

计算波特率是任何一种总线的zhon重要内容之一,CAN总线也不例外.从STM32微控制器的官方参考手册里可以查找到关于CAN波特率的计算公式如下.

通过配置位时序寄存器CAN_BTR的TS1[3:0]及TS2[2:0]寄存器位设定BS1及BS2段的长度后,就可以确定每个CAN数据位的时间:

BS1段时间:

T S1 =Tq x (TS1[3:0] + 1),

BS2段时间:

T S2 = Tq x (TS2[2:0] + 1),

一个数据位的时间:

T 1bit =1Tq+T S1 +T S2 =1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)= N Tq

其中单个时间片的长度Tq与CAN外设的所挂载的时钟总线及分频器配置有关,CAN1和CAN2外设都是挂载在APB1总线上的,而位时序寄存器CAN_BTR中的BRP[9:0]寄存器位可以设置CAN外设时钟的分频值 ,所以:

Tq = (BRP[9:0]+1) x T PCLK其中的PCLK指APB1时钟,默认值为36MHz。

最终可以计算出CAN通讯的波特率:

BaudRate = 1/N Tq程序设计要点中强调的三个重要参数,其实是can总线物理层中所要求的位时序。共三个阶段,分别为SJW,BS1和BS2阶段,这三个阶段的时间长度都是以长度为tq的时间单元为单位的。这样可以逐步计算出CAN总线的波特率。因此要点提示中所要求的参数,实际上将CAN的波特率设置为450kdps。


过滤器的设置

can总线没有所谓地址的概念。总线上的每个报文都可以被各个节点接收。这是一种典型的广播式网络。在实际应用中。某个节点往往只希望接收到特定类型的数据, 这就要借助过滤器来实现。顾名思义,过滤器的作用就是把节点不希望接收到的数据过滤掉。只将希望接收到的数据给予通行。

stm32的CAN控制器,提供14个过滤器。可以设置为屏蔽模式和列表模式对can总线上的报文进行过滤。当节点希望接收到一种报文时。可以用屏蔽位模式对can总线上的报文进行过滤。反之,当节点希望接受到单一类型报文时。则应该配置为列表模式。本机程序中使用了32位的屏蔽位模式。

下面仅对这种模式进行解析。can控制器的每个过滤器都具备一个寄存器。称为屏蔽寄存器。其中标识符寄存器的每一位都有屏蔽寄存器的每一位所对应。事实上,这也对应着can数据。事实上,这也对应着看标准数据帧中的标识符段。

如下图所示。415a97c4-a4d9-11ec-952b-dac502259ad0.png此处重点在于屏蔽寄存器的作用。通过查阅stm32微控制器参考文档可以知道。当过滤器工作在屏蔽模式下时。屏蔽寄存器被置为1的每一位都要求can接收到的数据帧标识符段必须和对应的接收缓冲区标识位相同。否则予以滤除。以本程序为例。要点中要求将节点接收缓冲标识符配置为0x00AA0000。过滤器屏蔽标识符为0x00FF0000。该节点接收到的数据帧的标识符段的位[23:16],必须和接收缓冲区标识符中的[23:16]匹配。否则予以滤除。但若满足了这一条件而即便如下的位不匹配。则该数据帧仍不会被滤除。正如本程序而言。即can接口仅仅接收标识符段的位[23:16]为0xAA的数据帧.

根据can总线物理层的要求。can总线的波特率和传输距离成反比关系。传输距离变化时,要根据位时序来调整can总线的波特率。

41791582-a4d9-11ec-952b-dac502259ad0.png

4192b352-a4d9-11ec-952b-dac502259ad0.jpg

程序代码如下:

void RCC_Config(void)

{


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE)

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE)

 

}

void GPIO_for_can_and_uart_Config(void)

{

/*定义一个GPIO_InitTypeDef类型的结构体*/

GPIO_InitTypeDef GPIO_InitStructure;

 


/*设置can的RX--pa.11引脚*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;


GPIO_Init(GPIOA, &GPIO_InitStructure);


/*设置can的TX--pa.12引脚*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*设置usart1 的RX 脚 -PA.10为父浮空输入脚*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;


GPIO_Init(GPIOA, &GPIO_InitStructure);

 

}

 

void Can_Config(void)

{

CAN_InitTypeDef          CAN_InitStructure;

CAN_FilterInitTypeDef  CAN_FilterInitStructure;

 

CAN_DeInit(CAN1);

 

CAN_StructInit(&CAN_InitStructure);

CAN_InitStructure.CAN_TTCM=DISABLE;

CAN_InitStructure.CAN_ABOM=DISABLE;

CAN_InitStructure.CAN_AWUM=DISABLE;

CAN_InitStructure.CAN_NART=DISABLE;

CAN_InitStructure.CAN_RFIM=DISABLE;

CAN_InitStructure.CAN_TXFP=DISABLE;

 

CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;

CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;

 

CAN_InitStructure.CAN_Prescaler=5;

CAN_Init(CAN1,&CAN_InitStructure);

 

CAN_FilterInitStructure.CAN_FilterNumber=0;

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;

CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3;

CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00FF<<3;

CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;

CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

 

}

 

void main(void)

{

u8 TransmitMailbox=0;

CanTxMsg   TxMessage;

CanRxMsg   RxMessage;

RCC_Config();

GPIO_for_can_and_uart_Config();

USART_Config();

Can_Config();

 

TxMessage.ExtId=0x00aa0000;

TxMessage.RTR=CAN_RTR_Data;

TxMessage.IDE=CAN_ID_EXT;

TxMessage.DLC=8;

TxMessage.Data[0]=0x00;

TxMessage.Data[1]=0x12;

TxMessage.Data[2]=0x34;

TxMessage.Data[3]=0x56;

TxMessage.Data[4]=0x78;

TxMessage.Data[5]=0xab;

TxMessage.Data[6]=0xcd;

TxMessage.Data[7]=0xef;

 

TransmitMailbox=CAN_Transmit(CAN1,&TxMessage);

while((CAN_TransmitStatus(CAN1,TransmitMailbox))!=CANTXOK);

printf("rnThe CAN has send data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn",

TxMessage.Data[0],TxMessage.Data[1],TxMessage.Data[2],TxMessage.Data[3],

TxMessage.Data[4],TxMessage.Data[5],TxMessage.Data[6],TxMessage.Data[7],);

 

while((CAN_MessagePending(CAN1,CAN_FIFO0)==0));


RxMessage.StdId=0x00;

RxMessage.IDE=CAN_ID_EXT;

RxMessage.DLC=0;

RxMessage.Data[0]=0x00;

RxMessage.Data[1]=0x12;

RxMessage.Data[2]=0x34;

RxMessage.Data[3]=0x56;

RxMessage.Data[4]=0x78;

RxMessage.Data[5]=0xab;

RxMessage.Data[6]=0xcd;

RxMessage.Data[7]=0xef;

 

CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);

printf("rnThe CAN has received data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn",

RxMessage.Data[0],RxMessage.Data[1],RxMessage.Data[2],RxMessage.Data[3],

RxMessage.Data[4],RxMessage.Data[5],RxMessage.Data[6],RxMessage.Data[7],);

while(1);

 

 

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    节点间通讯协议的实现对于整个系统的稳定性和可靠性具有重要的影响。其重要性主要体现在以下四个方面:1)保证数据的实时性:CAN总线的数据传输速率较快,可以实现毫秒级别的响应时间,因此在控制和监测系统中广泛使用。节点间通讯协议的实现需要保证数据......
    系统可靠性并降低成本。 CPLD技术的出现,为我们提供了一种有效的解决办法:在CAN驱动器接口与LPC2131之间接一块CPLD,对CPLD进行功能编程,使其负责串行总线的数据传输和防止CAN发送反射。 选择......
    还可作为CAN网络的数据传输控制器,来与网络中的节点实现数据交换。 1 、硬件设计方案 目前计算机的发展,除了少数专门的工控机还在使用ISA总线以外,PC机上使用最为普遍的就是PCI总线了。PCI总线......
    之间的一项联合。其后不久(1998年),参与各方建立了一个自主的实体,即MOST公司,由它控制总线的定义工作。MOST总线采用光纤作为物理层的传输介质,专门用于满足要求严格的车载环境,在车载多媒体数据传输应用较多。传统......
    了重量和电线成本。 • 减少了错误的发生。 • 可快速交换数据。其使用仲裁过程,因此最高优先级的数据可获得总线的访问权。 • 提升了应用范围。 • 标准的CAN 2.0允许11位的数据传输(这意味着,总共可以引入2048......
    FIFO里存放的数据达到设定的阈值后,数据就会被移走。阈值可以设置为从1个字到4个字的深度。 启用DMA的FIFO可以最大程度地避免数据传输过程中的溢出问题,可以减少DMA对内存的访问次数从而减少总线......
    总线是一种高速CAN总线,支持更快的数据传输速率和更大的数据负载。它是CAN总线的进化版,可用于支持更高带宽的应用,例如高级驱动辅助系统(ADAS)和无人驾驶系统(AV)。 LIN总线 …… 局部......
    …… CANFD总线是一种高速CAN总线,支持更快的数据传输速率和更大的数据负载。它是CAN总线的进化版,可用于支持更高带宽的应用,例如高级驱动辅助系统(ADAS)和无人驾驶系统(AV)。 LIN总线......
    CAN线故障的排查分析;CAN线故障常见容错性 CAN总线的物理层是将ECU连接至总线的驱动电路。ECU的总数将受限于总线上的电气负荷。物理层定义了物理数据在总线上各节点间的传输过程,主要......
    图:    17.1.3 IIC总线的数据传输格式   发送到 SDA 线上的每个字节必须是 8 位的,每次传输可以发送的字节数量不受限制。每个字节后必须跟一个响应位。   首先传输的是数据......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>