CAN总线详解及STM32的CAN通信编程指南

这篇具有很好参考价值的文章主要介绍了CAN总线详解及STM32的CAN通信编程指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

对于CAN通信而言,本人之前也未接触了解过,由于实习的技术要求,因此也花费了一段时间对CAN通信进行学习,并且实现了基于STM32的CAN环回静默模式通信,因此写一遍比较详细的文章对该内容进行总结。本文的参考资料有STM32的中文参考手册、协议手册等。话不多说开始吧!

什么是CAN?

CAN是一种通信的方式,就是用来传递数据的,是属于串行通信的一种,是异步的半双工通讯,根据通信速率的不同可以分为高速CAN和低速CAN,主要的区别是在于对总线电平和数据传输速率(波特率)的定义,分别遵循ISO的不同标准。

低速CAN   通信速率 10-125Kbps,总线长度可达1000米。

高速CAN(ISO11898)通信速率125kbps~1Mbps,总线长度≤40米  经典CAN 。

CAN FD     通信速率可达5Mbps,并兼容经典CAN,遵循ISO 11898-1 做数据收发。

CAN的总线组成为:CAN控制器(芯片内的CAN外设),CAN收发器(CAN的收发器芯片),

CAN_High和CAN_Low两根线构成的总线结构

stm32can总线,stm32,嵌入式硬件,单片机

对于CAN_High、CAN_Low是共同组成一组差分的信号线,CAN网络中的物理信号是基于差分信号进行传输的,其终端的电阻是在高速CAN中防止信号反射和振铃。

stm32can总线,stm32,嵌入式硬件,单片机低速的CAN是属于开环总线,高速的CAN是属于闭环总线。对于CAN总线有以下特点:多主控制,每个设备都是可以主动的发送数据,当然这一点就会涉及到优先级的问题,这个问题会在后面详细介绍。在CAN中是没有类似于地址的信息,数据是以广播的形式,所以这个特点也就涉及到CAN的ID相关信息。

写到现在,可以简单的回答一下几个问题:一个节点的MCU向总线上那么多的节点的某一个节点

发送消息的?一个节点又是如何知道某个信息是发送给自己或者不是发送给自己呢?这个就会涉及到CAN的ID 和CAN控制器的过滤器的内容啦。

CAN的简洁的物理层必须要配上一套更加复杂的协议

CAN的总线是使用差分信号,其物理媒介是一对双绞线,这样差分信号的优点可以实现对干扰信号的抵消,总线上是CAN_High、CAN_Low.通过电位差来判断总线的电平,当然在这个地方高速CAN和低速CAN是不一样的。

stm32can总线,stm32,嵌入式硬件,单片机

 在经典CAN及高速CAN中:

 显性电平:总线上逻辑0表示显性,遇0得0,显性最强  差分信号的电压差一般为2V

 隐形电平:总线上逻辑1表示隐形,隐形的攻击性不强 差分信号的电压差一般为0

stm32can总线,stm32,嵌入式硬件,单片机

在低速CAN中

显性电平:逻辑0表示显性 显性的电压差一般为3V

隐形电平:逻辑1表示隐性 隐性的电压差一般为-1.5V

刚刚说到,显性电平是逻辑0,并且是具有正的电压差的,因此显性电平是具有优先权的,只要有一个节点输出显性电平,总线上即为显性电平。但是隐性电平是需要所有的节点都输出隐性电平,总线上才是才是隐形电平。从逻辑上来说这是一种与逻辑,其物理的实现是通过集电极开路电路实现的。

stm32can总线,stm32,嵌入式硬件,单片机

说到这些电平是需要CAN的收发器实现的,目前CAN的收发器芯片有TAJ1050、TJA1042、SIST1050T。CAN收发器芯片能够将微控制器的逻辑电平转换为CAN总线所使用的物理层电平,并负责将数据发送到总线上,同时接收总线上的数据并将其转换为适合微控制器处理的逻辑电平。收发器芯片还包含其他功能,如滤波、保护电路等,以确保可靠的通信。有了CAN的收发器实现差分信号到逻辑信号的转换之后,我们就可以基于CAN的控制器实现CAN的帧的通信。CAN的协议定义了五种类型的帧。

对于CAN的帧有数据帧、遥控帧、错误帧、过载帧、间隔帧。我们今天主要是针对标准的数据帧进行实现。

数据帧是由七段来组成的,当然数据帧又分为标准帧CAN2.0A、扩展帧CAN2.0B 

stm32can总线,stm32,嵌入式硬件,单片机

帧起始:表示数据帧开始的段,是以显性信号表示,SOF发出后会产生一个跳变沿用于整个CAN网络的时间同步。

仲裁段:表示该帧优先级的段,该部分和CAN的过滤器相关,标准格式ID有11个位,从ID28到ID18被依次发,ID禁止设置高7位为隐性

控制段:表示数据的字节数和保留位的段,控制段是由6个位构成的,四个位为DLC,称数据长度码,表示后面要表示的数据的字节数,还有两个保留位

数据段:数据的内容,一帧可以发送0-8字节的数据

CRC段:检查帧的传输错误的段,由15个位的CRC顺序和一个位的CRC界定符构成

ACK段:表示确认正确接收的段,该段由两位组成,其中一位是界定符,对于发送单元而言在该段发两个隐性位,接收段在ACK Slot段发送显性位,通知发送单元是正常接收结束

帧结束:是以七个隐性电平表示数据帧的结束 

对CAN的位时序介绍:在CAN总线上我们是读取电平来实现表征数据0、1。对于没有时钟线的CAN总线里,是以“位时序”的机制,实现对电平的正确采样,位数据是由四段组成的:

同步段SS:1Tq

传播时间段PTS:1~8Tq

相位缓冲段PBS1:1~8 Tq

相位缓冲段PBS2:2~8Tq

此外因时钟的频率偏差,传送延迟等,各单元有同步午餐,SJW为再补偿宽度,其实我们对位同步而言不需要太深入的了解其实现,该部分主要是由硬件自动完成,我们在程序设计中该部分主要是对我们的CAN波特率进行了设置,以STM32F103C8T6为例子

//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024;  tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+tbs2+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
//则波特率为:36M/((8+9+1)*4)=500Kbps

stm32can总线,stm32,嵌入式硬件,单片机

在STM32中的位时序和CAN的标准位时序有一点区别,在STM32中 包含三段,分别是同步段SYNC-SEG、位段BS1、位段BS2.采样的点是在BS1、BS2的交界处,同步段的固定长度是1Tq,对BS1、BS2可以在位时序寄存器上CAN——BTR设置他们的时间长度,它们可以在重新同步期间增加或者缩短。SJW也可以在位时序寄存器中配置。

BS1段时间:

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

BS2段时间:

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

一个数据位的时间:

T1bit =1Tq+TS1+TS2 =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 TPCLK

其中的PCLK指APB1时钟,默认值为45MHz。

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

BaudRate = 1/N Tq

stm32can总线,stm32,嵌入式硬件,单片机

通过设置这些参数确定我们CAN总线的整体波特率。该部分也是我们在CAN的初始化过程中需要进行设置的。

关于报文寻址的问题

CAN网络中的通信基于与内容相关的寻址,因为CAN节点本身是没有ID的,但是可以通过ID区分CAN报文,所有CAN节点都会收到总线广播发送的所有CAN报文,每个接收方都根据自己的需求自行的选择CAN/报文。

STM32F103的CAN回环通信

stm32f103C8T6的最小系统板只有一个CAN的控制器,没有收发器,因此我们在实验中只能选择其回环模式进行测试。

CAN2.0A:只能处理标准数据帧且扩展帧的内容会识别错误

CAN2.0B  Active可以处理标准数据帧和扩展数据帧,

CAN2.0B Passive 只能出来标准数据帧且扩展帧的内容会忽略

STM32的CAN控制器功能如下:

stm32can总线,stm32,嵌入式硬件,单片机

 bxCAN模块可以完全自动的接收和发送CAN报文

我们可以通过控制、状态、配置寄存器实现

1.配置CAN参数,如波特率

2.请求发送报文

3.处理报文接收

4.管理中断

5.获取诊断信息

stm32can总线,stm32,嵌入式硬件,单片机

有三个发送邮箱来发送报文,发送调度器是根据优先级来决定那个邮箱的报文被发送。通过接收过滤器对广播的报文进行过滤,过滤器是和接收的邮箱进行连接的,在STM32F103中有14个位宽可变/可配置的标识符过滤器组,有两个接收的FIFO,每个FIFO都可以存放3个完整的报文。

对于CAN的控制器有三种工作模式:

初始化模式   该模式下对寄存器进行配置

正常模式       CAN总线同步,开始数据的接收和发送

睡眠模式        当我们复位后是进入睡眠模式,可降低功耗

同样的CAN的控制器有以下测试模式

静默模式:只向总线发送1不能发送0,可以从总线接收数据,可以实现对总线的统计。

stm32can总线,stm32,嵌入式硬件,单片机

环回模式:发送的数据直接到输入(总线可以监测数据),不能从总线接收数据,可用于自检

stm32can总线,stm32,嵌入式硬件,单片机

环回静默模式:发送的数据直接到输入(总线不可监测到数据),也不能从总线接收到数据 可用于自检并且不影响总线

stm32can总线,stm32,嵌入式硬件,单片机

 发送处理的流程如下:

 stm32can总线,stm32,嵌入式硬件,单片机

接收处理的流程如下:stm32can总线,stm32,嵌入式硬件,单片机

CAN的初始化结构体

CAN的外设功能非常的多,涉及的寄存器也是十分的丰富,我们可以通过标准库里面的各种结构体函数及库函数对这些控制过程实现简化。文章来源地址https://www.toymoban.com/news/detail-674211.html

/* Initialization and Configuration functions *********************************/ 
uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);//初始化CAN的过滤器
void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct);//初始化CAN的控制器
void CAN_SlaveStartBank(uint8_t CAN_BankNumber); //启动CAN从机过滤器
void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState);//控制CAN控制器的调试模式
void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState);//控制CAN控制器的TT-COM模式

/* Transmit functions *********************************************************/
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);//用于CAN消息的发送
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);//用于获取CAN消息发送状态
void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox);//取消发送

/* Receive functions **********************************************************/
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);//CAN消息接收
void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber);//清空缓冲区
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber);//获取CAN接收FIFO中待处理的消息数量

/* Operation modes functions **************************************************/
uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
uint8_t CAN_Sleep(CAN_TypeDef* CANx);
uint8_t CAN_WakeUp(CAN_TypeDef* CANx);

/* Error management functions *************************************************/
uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx);
uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx);
uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx);

/* Interrupts and flags management functions **********************************/
void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState);
FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT);
void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT);
		CAN_InitTypeDef CAN_InitStruct;
		CAN_InitStruct.CAN_TTCM=DISABLE;//非时间触发通信模式
		CAN_InitStruct.CAN_ABOM =DISABLE;//软件自动离线管理
		CAN_InitStruct.CAN_AWUM=DISABLE;//睡眠模式通过软件自动唤醒
		CAN_InitStruct.CAN_NART=DISABLE;//使用报文自动传送
		CAN_InitStruct.CAN_RFLM=DISABLE;//报文不锁定,新的报文可以对旧报文覆盖
		CAN_InitStruct.CAN_TXFP=DISABLE;//报文的优先级可以由标识符决定
		CAN_InitStruct.CAN_Mode=mode;//回环模式
		CAN_InitStruct.CAN_SJW=tsjw;
		CAN_InitStruct.CAN_BS1=tbs1;
		CAN_InitStruct.CAN_BS2=tbs2;
		CAN_InitStruct.CAN_Prescaler=brp;
		CAN_Init (CAN1,&CAN_InitStruct);
		CAN_FilterInitTypeDef CAN_FilterInitStruct;
		CAN_FilterInitStruct.CAN_FilterNumber=0;//选择过滤器0
    CAN_FilterInitStruct.CAN_FilterActivation=ENABLE;//激活过滤器0
		CAN_FilterInitStruct.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
		CAN_FilterInitStruct.CAN_FilterIdHigh=0x0000;
		CAN_FilterInitStruct.CAN_FilterIdLow=0x0000;
		CAN_FilterInitStruct.CAN_FilterMaskIdHigh=0x0000;
		CAN_FilterInitStruct.CAN_FilterMaskIdLow=0x0000;
		CAN_FilterInitStruct.CAN_FilterMode= CAN_FilterMode_IdMask;
		CAN_FilterInitStruct.CAN_FilterScale=CAN_FilterScale_32bit;
		CAN_FilterInit(&CAN_FilterInitStruct);

到了这里,关于CAN总线详解及STM32的CAN通信编程指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32的CAN总线调试经验分享

    CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 最近负责的一个项目用的主控芯片是 STM32F407IGT6 ,需要和几个电机控制器进行通讯,有很多参数需要进行监控。负责固件开发的同事一直搞不定一个问题。就是开启 CAN 的接收中断,接收不到数据

    2024年01月20日
    浏览(36)
  • STM32 CAN总线过滤器设置

                                                                                                         CAN过滤器配置以及常见问题总结 过滤器组 在具有两个CAN的产品中,CAN1和CAN2分享28个过滤器组,只有一个CAN的系列产品中有14个过滤器组,用以对接收到的帧进行过

    2024年01月17日
    浏览(28)
  • CAN总线(五)STM32的CAN波特率设置方法(完整版)

     ①HSI是高速内部时钟,RC振荡器,频率为8MHz。   ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤PLL为锁相环倍频输出,其时钟输入

    2024年02月07日
    浏览(23)
  • STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

    目录 一、CAN总线简介         1.1 CAN概述         1.2 CAN总线较其他串行通信优势         1.3 CAN总线通信          1.4 报文种类及格式          1.5 CAN应用 二、CAN工程创建及配置         2.1 工程设计及原理框图          2.2 工程创建接配置 三、代码设计

    2023年04月15日
    浏览(41)
  • STM32+收发器实现CAN和485总线

    RS485总线是一种常见的(Recommended Standard)串行总线标准(485是它的标识号),采用平衡发送与差分接收的方式,因此具有抑制共模干扰的能力。CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络,属于CSMA(多路载波侦听)/CD(冲突检测

    2024年02月05日
    浏览(41)
  • STM32基于CAN总线协议控制步进电机

    如上图所示,实现了以下功能: 1.两块stm32单片机通过CAN控制器与收发器进行半双工通信; 2.stm32主机通过检测按键,切换不同的模式,将不同模式的case值发送给stm32从机; 3.stm32从机根据收到的case值,控制步进电机进行不同的运动操作; 4.OLED用于显示收发内容与按键状态等

    2024年01月19日
    浏览(38)
  • STM32 基础知识(探索者开发板)--159讲 CAN总线

    CAN基础知识:ISO国际标准化的串行通信协议,为了减少线束的数量 a.多主控制  每个设备都可以主动发送数据 b.通信速度较快,通信距离远。最高1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps) c.具有错误检测、错误通知和错误恢复功能 d.故障封闭功能  能发现故障,且可以把故

    2024年01月17日
    浏览(37)
  • STM32——CAN通信

    STM32F103有两个CAN,都分别有自己的发送接收邮箱。 发送邮箱共有3个来发送报文,发送调度器根据优先级决定哪个邮箱的报文先被发送。 共有2个接收FIFO,每个FIFO都可以存放3个完整的报文。它们完全由硬件来管理。 CAN通信通过CAN_H、CAN_L两根线实现通信,电平特性分为显性电

    2024年02月08日
    浏览(38)
  • STM32—CAN通信

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! CAN全称是Controller Area Network,控制器局域网络,是ISO国际标准化的串行通信协议。CAN是国际上应用最广泛的现场总线之一。CAN通信只有两根信号线,分别是CAN_H和CAN_L,CAN 控制

    2024年02月16日
    浏览(34)
  • 【零基础 STM32通过CAN通信驱动Maxon电机】第三章 STM32 CAN通信回环模式测试及Maxon电机通信

    第三章 STM32 CAN通信回环模式测试及Maxon电机通信 正点原子官方给的CAN通信例程需要lcd显示屏和两块板子,本章修改代码,仅用一块STM32进行回环模式的测试。 首先下载修改后的程序,运行并烧录(接线方式和运行方式与上一章完全相同)。注意板子右侧的接线帽要接正确,

    2024年01月21日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包