STM32--CAN通讯实验

Posted 警官001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--CAN通讯实验相关的知识,希望对你有一定的参考价值。

目录

CAN协议介绍

物理层

闭环总线网络

开环总线网络

 通讯节点

差分信号

协议层简介

CAN的波特率

位时序

帧类型、作用及格式

数据帧

STM32CAN外设

 CAN 发送邮箱

 CAN 接收 FIFO

 有效消息

 接收处理

上溢

 标识符筛选

CAN1与CAN2整体逻辑

HAL库函数


CAN协议介绍

物理层

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

CAN的物理层有两种拓扑结构,闭环总线网络和开环总线网络,我们将依次介绍他们。

闭环总线网络

闭环网络的特点是:高速、近距离。

它的总线最大长度为 40m,通信速度最高为1Mbps,总线的两端各要求有一个“120 欧”的电阻。

CAN闭环总线网络拓扑结构

开环总线网络

闭环网络的特点是:低速、远距离。

它的最大传输距离为1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2 千欧”的电阻。

CAN闭环总线网络拓扑结构

 通讯节点

CAN 总线上可以挂载多个通讯节点,节点之间的信号 经过总线传输,实现节点间通讯。

由于 CAN 通讯协议不对节点进行地址编码,而是对数据内容进行编码的,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。

CAN 通讯节点由一个 CAN 控制器及 CAN 收发器组成,控制器与收发器之间通过 CAN_Tx 及 CAN_Rx 信号线相连,收发器与 CAN 总线之间使用 CAN_High 及 CAN_Low 信号线相连。而 CAN_High 及 CAN_Low 是一对差分信号线,使用差分信号。

差分信号

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

 差分信号传输具有如下优点:

  • 抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上。所以外界的共模噪声可以被完全抵消。
  • 能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。
  • 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。
CAN信号高速CAN低速CAN
电平显性隐性显性隐性
CAN_H

3.50

2.504.001.75
CAN_L1.502.501.003.25
电位差2.0003.00-1.50

 由于CAN总线的仲裁机制采取“线与”的方式对总线上的信号进行仲裁。因此,假如有两个 CAN 通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,“线与”的总线仲裁机制将使它处于显性电平状态。因此低电平“0”被成为显性电平。

物理层特征总结

协议层简介

CAN的波特率

由于 CAN 属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用约定好的波特率进行通讯

总线上的各个通讯节点只要约定好 1 个 Tq 的时间长度以及每一个数据位占据多少个Tq,就可以确定 CAN 通讯的波特率。

位时序

为了实现位同步,在STM32数据手册中通过将标称位时间划分为以下三段

  • 同步段 (SYNC_SEG):位变化应该在此时间段内发生。它只有一个时间片的固定长度 (1 x tCAN)
  • 位段 1 (BS1):定义采样点的位置。它包括 CAN 标准的 PROP_SEG 和 PHASE_SEG1。 其持续长度可以在 1 到 16 个时间片之间调整,但也可以自动加长,以补偿不同网络节 点的频率差异所导致的正相位漂移。
  • 位段 2 (BS2):定义发送点的位置。它代表 CAN 标准的 PHASE_SEG2。其持续长度可 以在 1 到 8 个时间片之间调整,但也可以自动缩短,以补偿负相位漂移。

 关于同步,还有硬件同步、再同步等操作。更多关于位时序的内容可以参看 ISO 11898 标准。

帧类型、作用及格式

为了更有效地控制通讯,CAN 一共规定了 5 种类型的帧:

我们在这里主要介绍一下数据帧

数据帧

数据帧由 7 个段构成:

  • 帧起始:表示数据帧开始的段.
  • 仲裁段:表示该帧优先级的段。
  • 控制段:表示数据的字节数及保留位的段。
  • 数据段:数据的内容,可发送 0~8 个字节的数据。
  • CRC段:检查帧的传输错误的段。
  • ACK段:表示确认正常接收的段。
  • 帧结束:表示数据帧结束的段。

帧起始

表示帧开始的段。1 个位的显性位。

仲裁段

表示数据的优先级的段。

标准格式和扩展格式在此的构成有所不同。

控制段

控制段由 6 个位构成,表示数据段的字节数。标准格式和扩展格式的构成有所不同。

数据段

数据段可包含 0~8 个字节的数据。从 MSB(最高位)开始输出。

CRC段

CRC 段是检查帧传输错误的帧。由 15 个位的 CRC 顺序和 1 个位的 CRC 界定符(用于分隔的位)构成。

ACK段 

 ACK 段用来确认是否正常接收。由 ACK 槽(ACK Slot)和 ACK 界定符 2 个位构成。

帧结束 

 帧结束是表示该该帧的结束的段。由 7 个位的隐性位构成。

STM32CAN外设

 从图上我们可以看到,CAN 1与CAN 2为主从关系,CAN 1为Master ( 主 ) ,CAN 2为Slave ( 从 ) 。CAN 1和CAN 2有各自的3个发送邮箱,2个FIFO Buffer缓冲,6个接收邮箱。但是,28个Filter 过滤器却是共用的,我们可以规定,哪些Filter给那个CAN用,甚至可以在程序运行的时候调控。

● CAN1:主 bxCAN,用于管理 bxCAN 与 512 字节 SRAM 存储器之间的通信。

● CAN2:从 bxCAN,无法直接访问 SRAM 存储器。

● 两个 bxCAN 单元共享 512 字节 SRAM 存储器

 CAN 发送邮箱

CAN 1和CAN 2有各自的3个发送邮箱,最多可以缓存 3 个待发送的报文。

为了发送消息,程序必须在请求发送之前选择一个空的发送邮箱,使邮箱退出空的状态,进入挂起状态。此时,对于挂起的邮箱,软件无法再对其访问。进入挂起状态后,优先级高的邮箱将优先发送。发送后的邮箱将恢复到空的状态。

 CAN 接收 FIFO

 为了接收 CAN 消息,提供了构成 FIFO 的三个邮箱。为了节约 CPU 负载,FIFO 完全由硬件进行管理。应用程序通过 FIFO 输出邮箱访问 FIFO 中所存储的消息。

 有效消息

当消息依据 CAN 协议正确接收并且成功通过标识符筛选后,该消息将视为有效。

 接收处理

当接收到报文时,FIFO 的报文计数器会自增,而 STM32 内部读取 FIFO 数据之后,报文计数器会自减,我们通过状态寄存器可获知报文计数器的值

上溢

 标识符筛选

 在 CAN 协议中,消息的标识符与节点地址无关,但与消息内容有关。因此,发送器将消息广播给所有接收器。在接收到消息时,接收器节点会根据标识符的值来确定软件是否需要该消息。STM32 的 CAN 外设接收报文前会先使用验收筛选器检查,只接收需要的报文到 FIFO 中。

CAN1与CAN2整体逻辑

CAN2 外设的结构与 CAN1 外设是一样的,他们共用筛选器且由于存储访问控制器由 CAN1 控制,所以要使用 CAN2 的时候必须要使能 CAN1 的时钟。

HAL库函数

HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
  • 参数
    • hcan:指向CAN配置结构体
    • ActiveITs:表明哪个中断会被启动,开启改中断的消息提示
  • 返回值
    • HAL_StatusTypeDef:如果开启成功,返回HAL_OK;如果失败,返回HAL_ERROR
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
  • 参数
    • hcan:指向CAN配置结构体
  • 返回值
    • HAL_StatusTypeDef:如果开启成功,返回HAL_OK;如果失败,返回HAL_ERROR
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig);
  • 参数
    • hcan:指向CAN配置结构体
    • sFilterConfig:指向Filter过滤器配置结构体
  • 返回值
    • HAL_StatusTypeDef:如果开启成功,返回HAL_OK;如果失败,返回HAL_ERROR
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox);
  • 参数
    • hcan:指向CAN配置结构体
    • pHeader:指向发送数据的配置结构体
    • aData[]:指向需要发送的数据
    • pTxMailbox:该函数会返回用于储存发送数据的发送邮箱编号到该变量
  • 返回值
    • HAL_StatusTypeDef:如果添加成功,返回HAL_OK;如果失败,返回HAL_ERROR
uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
  • 参数
    • hcan:指向CAN配置结构体
    • TxMailboxes:指向发送数据的发送邮箱
  • 返回值
    • uint32_t:如果有发送数据正在等待发送,返回1;如果没有,返回0
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
  • 在写代码的时候,在main.c中创建HAL_CAN_RxFifo0MsgPendingCallback函数
  • 在该函数中填写在FIFO 0中已经没有正在等待接收的数据的时候开启中断,需要执行的代码
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
  • 参数
    • hcan:指向CAN配置结构体
    • RxFifo:指向负责接收的FIFO
    • pHeader:指向接收数据的配置结构体
    • aData[]:指向需要接收的数据
  • 返回值
    • HAL_StatusTypeDef:如果接收成功,返回HAL_OK;如果失败,返回HAL_ERROR

以上是关于STM32--CAN通讯实验的主要内容,如果未能解决你的问题,请参考以下文章

STM32CAN总线接口发送和接收数据

STM32 CAN 过滤器设置

STM32------- CAN

STM32------- CAN

stm32的can发送时序不准

STM32 CAN环回模式