STM32--CAN通讯实验
Posted 警官001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--CAN通讯实验相关的知识,希望对你有一定的参考价值。
目录
CAN协议介绍
物理层
CAN 通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有 CAN_High 和 CAN_Low 两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。
CAN的物理层有两种拓扑结构,闭环总线网络和开环总线网络,我们将依次介绍他们。
闭环总线网络
闭环网络的特点是:高速、近距离。
它的总线最大长度为 40m,通信速度最高为1Mbps,总线的两端各要求有一个“120 欧”的电阻。
开环总线网络
闭环网络的特点是:低速、远距离。
它的最大传输距离为1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2 千欧”的电阻。
通讯节点
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.50 | 4.00 | 1.75 |
CAN_L | 1.50 | 2.50 | 1.00 | 3.25 |
电位差 | 2.00 | 0 | 3.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
:指向负责接收的FIFOpHeader
:指向接收数据的配置结构体aData[]
:指向需要接收的数据
- 返回值
HAL_StatusTypeDef
:如果接收成功,返回HAL_OK
;如果失败,返回HAL_ERROR
以上是关于STM32--CAN通讯实验的主要内容,如果未能解决你的问题,请参考以下文章