AIR32F103(九) CAN总线的通信和ID过滤机制及实例 您所在的位置:网站首页 can总线屏蔽码 AIR32F103(九) CAN总线的通信和ID过滤机制及实例

AIR32F103(九) CAN总线的通信和ID过滤机制及实例

2024-06-15 01:13| 来源: 网络整理| 查看: 265

目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外设库的项目模板 AIR32F103(四) 27倍频216MHz,CoreMark跑分测试 AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码 AIR32F103(六) ADC,I2S,DMA和ADPCM实现的录音播放功能 AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存 AIR32F103(八) 集成Helix MP3解码库播放MP3 AIR32F103(九) CAN总线的通信和ID过滤机制及实例 AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL AIR32F103(十一) 在AIR32F103上移植微雪墨水屏驱动 AIR32F103(十二) 搭载 AIR32F103CBT6 的Bluepill核心板 CAN 总线

CAN是 Controller Area Network 的简称, 最初由BOSCH公司开发, 后来成为国际标准(ISO 11898), 是当前应用最广泛的现场总线之一, 是汽车控制系统和嵌入式工业控制局域网事实上的标准.

CAN 总线的物理连接

相对于近距离传输的I2C, SPI协议, 以及RS485总线, CAN 总线定义了更先进的物理层和链路层, 以及种类丰富的上层协议. 与I2C, SPI等基于时钟信号同步的通讯方式不同, CAN通讯不使用时钟信号进行同步, 它是一种异步通讯, 只有 CAN_High 和 CAN_Low 两条信号线, 共同构成一组差分信号线, 以差分信号的形式进行通讯.

CAN 物理层主要分为闭环总线及开环总线网络两种形式, 一个适合于高速通讯, 一个适合于远距离通讯.

CAN闭环通讯网络是一种遵循 ISO11898 标准的高速, 短距离网络, 总线最大长度为40m, 通信速度最高为1Mbps, 总线的两端各要求有一个120欧的电阻做阻抗匹配, 减少回波反射. CAN开环总线网络是遵循 ISO11519-2 标准的低速, 远距离网络, 最大传输距离为1km, 最高通讯速率为125kbps, 两根总线互相独立, 不形成闭环, 要求每根总线上各串联有一个 2.2KR 的电阻. 关于共地

CAN 在多个收发器之间的连接, 可以不共地, 只需要 CANH 和 CANL 两线连接.

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

差分信号

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

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

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

CAN协议中的差分信号

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

CAN 总线的特点

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

CAN 协议中, 所有的消息都以固定的数据格式打包发送. 两个以上的节点单元同时发送信息时, 根据节点标识符(常称为 ID, 打包在固定的数据格式中)决定各自优先级关系, CAN 总线没有其他总线的地址概念, 在总线上增加节点单元时, 连接在总线的其他节点单元的软硬件都不需要改变.

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

对于总线错误, CAN 总线有错误检测功能, 错误通知功能, 错误恢复功能三种应对措施, CAN 总线上的每个节点都可以通过判断得出, 当前总线上的错误是暂时错误(如瞬间的强干扰)还是持续错误(如总线断裂). 当总线上发生持续错误时, 引起故障的节点单元会自动脱离总线.

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

CAN 总线通信 CAN 数据位传输时间

为了实现位同步, CAN协议把每一个数据位(bit)的时序分解成SS段, PTS段, PBS1段, PBS2段, 这四段的长度加起来即为一个CAN数据位的长度.

CAN传输的最小的时间单位是Tq(即CAN外设的时钟周期), 一个完整的位由8~25个Tq组成.

CAN 的数据帧

CAN 总线的数据通信是以数据帧的格式进行的, 了解CAN的数据帧, 可以帮助了解CAN的过滤机制. 下面是一个完整的CAN数据帧的结构

CAN Data Frame

SOF 应该是 start of frame, 一个bit位拉低总线用于开始传输 Identifier 就是数据的 ID, 11个bit RTR (Remote Transmission Request) 用于声明这是一个数据帧还是一个远程帧 IDE 用于声明使用的标准ID还是扩展ID r 是一个保留 bit DLC 用于声明后面携带的数据字节数量 Data Field 包含的是发送的数据, 最多不超过8个字节 Checksum 和 DEL 是校验码和对应的分隔符 ACK 和 DEL 是响应位和对应的分隔符 CAN 数据帧对应的代码

用C语言描述的CAN帧整体结构为

CAN_TxHeaderTypeDef TxHeader; uint8_t TxData[8]; uint32_t TxMailbox; TxHeader 用于存储头信息, 包含了 RTR, DLC 等, 在SPL中对应的类型为 CAN_TxHeaderTypeDef TxData 用于存储传输的数据 TxMailbox 用于发送此消息的 mailbox

帧头的结构和帧数据

TxHeader.StdId = 0x446; TxHeader.RTR = CAN_RTR_DATA; // Remote or data frame TxHeader.IDE = CAN_ID_STD; // Standard or extended // reserved bit TxHeader.DLC = 2; // Data length in bytes CAN_ID_STD 表示使用了标准ID模式(非扩展ID) 0x446 就是发送的ID, 位宽最大为 11-bit CAN_RTR_DATA 表示这个帧为数据帧 DLC 标识后面数据的字节长度, 因为发送两个字节, 所以这里是2 随后在 TxData 中存储两个字节 TxData[0] = 50; TxData[1] = 0xAA; AIR32F103 / STM32 的 CAN 外设

以下的描述适用于AIR32F103和STM32.

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

CAN波特率的计算

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

BS1段时间

Tbs1 =Tq x (TS1[3:0] + 1)

BS2段时间

Tbs2 = Tq x (TS2[2:0] + 1)

整个数据位的时间

Tbit = 1Tq + Tbs1 +Tbs2 = 1 + (TS1[3:0] + 1)+ (TS2[2:0] + 1)

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

Tq = brp * Tpclk = (BRP[9:0]+1) * Tpclk

其中的PCLK指APB1时钟, 默认值为36MHz. 可以计算出 CAN 的波特率:

BaudRate = 1 / Tbit = Fpclk / ((Tbs1 + Tbs2 + 1) * brp) CAN 波特率的设置 CAN_InitStructure.CAN_TTCM = DISABLE; // time triggered communication mode off CAN_InitStructure.CAN_ABOM = DISABLE; // automatic bus-off management off CAN_InitStructure.CAN_AWUM = DISABLE; // automatic wake-up mode off, wakeup by software cleaar CAN->MCR SLEEP bit CAN_InitStructure.CAN_NART = ENABLE; // no-automatic retransmission mode on CAN_InitStructure.CAN_RFLM = DISABLE; // rx FIFO Locked mode off CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority off CAN_InitStructure.CAN_Mode = mode; // Set baud rate CAN_InitStructure.CAN_SJW = tsjw; // synchronisation_jump_width, CAN_SJW_1tq ~ CAN_SJW_4tq CAN_InitStructure.CAN_BS1 = tbs1; // number of time quanta in Bit Segment 1, CAN_BS2_1tq ~ CAN_BS2_8tq CAN_InitStructure.CAN_BS2 = tbs2; // number of time quanta in Bit Segment 2, CAN_BS1_1tq ~ CAN_BS1_16tq CAN_InitStructure.CAN_Prescaler = brp; // clock prescaler, 1~1024 CAN_Init(CAN1, &CAN_InitStructure); CAN 的ID过滤机制

CAN 是一种典型的广播式网络, 在实际应用中, 如果只希望接收到特定类型的数据, 就要借助过滤器来实现. AIR32/STM32的CAN控制器包含14个过滤器, 可以设置为 屏蔽模式 或 列表模式 对CAN总线上的报文进行过滤. 当节点希望接收到一种报文时, 可以用屏蔽位模式进行过滤, 当节点希望接受到单一类型报文时, 应该配置为列表模式.

CAN控制器的每个过滤器都具备一个寄存器, 称为屏蔽寄存器。其中标识符寄存器的每一位都有屏蔽寄存器的每一位所对应.

AIR32/STM32 使用 CAN 外设内建的过滤器, 初始化代码为

CAN_FilterTypeDef canfilterconfig; canfilterconfig.FilterActivation = CAN_FILTER_ENABLE; canfilterconfig.FilterBank = 18; // 指定使用哪个过滤器 canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; canfilterconfig.FilterIdHigh = 0x103> (11 - 3)) & 0xFFF8; 测试示例 硬件准备 TJA1050 或 MCP2551 的 CAN 收发模块 x 2, 可以混合使用, TJA1050 与 MCP2551 可以互相通信 带 AIR32F103 的开发板

因为 TJA1050 和 MCP2551 都是5V供电, 因此开发板上要有5V输出, 否则需要单独供电

示例代码

代码仓库目录 https://github.com/IOsetting/air32f103-template/tree/master/Examples/NonFreeRTOS/CAN

这个目录下包含两个模式的例子, 一个是 Loopback, 一个是 Normal, 从合宙官方仓库的例子参考(抄)的.

Loopback 模式

Loopback 是测试模式, 发送的数据直接进入接收队列, 这个模式不需要CAN模块也能运行. 运行后在串口输入's', 会发送8个字节并将接收到的数据通过串口回显.

Normal 模式

正常的通信模式, 需要两套 MCU + CAN 收发器. CAN 收发器之间通过 CANH 和 CANL 连接. 代码中设置过滤器时, 使用的是相同的 ID 和 Mask 值, 对两个MCU编译烧录时需要将 ID_TARGET 和 ID_RECEIV 的值互换一下. 如果希望接收所有(不过滤), 可以将 Mask ID 设为 0.

运行后, 在一侧串口输入's', 在另一侧会通过串口显示接收到的数据.

问题 1. 电压应当使用5V

在测试中, 一开始给 TJA1050 错误使用了 3.3V 电压, 在 Loopback 模式工作正常, 但是在 Normal 模式工作不正常, 只有将两边收发器共地才能正常通信, 如果换成 MCP2551 则完全不能通信. 这些问题在将电压换成 5V 后就正常了.

2. TJA1050 的 1 脚判断

TJA1050 是 SOP8 封装, 但是与常见的 SOP8 封装不同的是没有圆点, 在手册第14页有特意说明, Pin 1 对应的是有斜面的那个边.

这个型号可能有不少厂家生产, 市面上有带圆点的也有不带圆点的, 不同来源的 TJA1050, Pin 间电阻差异很大. 有些 VCC 和 GND 之间电阻只有9K, 有些是1.2M, 而 RX TX 之间的电阻有些上M, 有些只有14K, 但是在同样的电路上, 都能正常工作.

CANH 和 CANL 之间串接的 120R 电阻, 换成 200R 也没问题.

SL 不能浮空, 需要接地才能正常通信.

参考 CAN Protocol in STM32 https://controllerstech.com/can-protocol-in-stm32/ Does The CAN Bus Need a Common Ground? https://www.edn.com/does-the-can-bus-need-a-common-ground/ STM32 CAN Communication || NORMAL Mode https://www.youtube.com/watch?v=KHNRftBa1Vc&t=104s


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有