STM32速成笔记(14)—CAN通信

发布者:Yuexiang888最新更新时间:2024-04-15 来源: elecfans关键字:STM32  CAN通信  控制器  局域网络 手机看文章 扫描二维码
随时随地手机看文章

一、CAN通信简介

1.1 CAN简介

CAN全称是Controller Area Network,控制器局域网络,是ISO国际标准化的串行通信协议。CAN是国际上应用最广泛的现场总线之一。

CAN通信只有两根信号线,分别是CAN_H和CAN_L,CAN 控制器根据这两根线上的电位差来判断总线电平。总线申平分为显性电平和隐性申平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。


  • • 2.0V---------逻辑0------显性电平

  • • 0 V-----------逻辑1------隐性电平

CAN总线遵从“线与”机制, 显性电平可以覆盖隐性电平 。这就导致 只有所有节点都发送隐形电平时总线才处于隐性状态 。

图片

CAN通信示意图

1.2 CAN协议特点

  • • 多主控 在总线空闲时所有单元都可以发送消息。当两个以上单元发送消息时,会根据标识符(ID)决定发送的优先级。

  • • 通信速度较快 ,最高可达1Mbps。 通信距离较远 。当速度为1Mbps时,传输距离小于40m。当速度小于500Kbps时,传输距离最远可达10Km。

  • • 具有错误检测,错误通知和错误恢复功能 。CAN总线上的任意一个单元都可以检测错误,当任意一个单元检测出错误时,会立刻通知其他单元。正在发送消息的单元一旦检测出错误,会强制结束当前发送。强制结束的单元会不断重新发送消息,直到发送成功。

  • • 故障封闭功能 CAN可以判断出错误的类型是总线上暂时的数据错误还是持续的数据错误。当总线上持续出现数据错误时,可以将引起故障的单元从总线上隔离出去。

  • • 连接节点多 理论上连接单元没有数量限制,但是连接单元越多,速度就会越低。

11.3 CAN通信的帧类型

CAN通信有5种帧类型

1.jpg

在上述的几种帧里,数据很和遥控帧有标准帧和扩展帧两种。标准帧有11位ID,扩展帧有29位ID。

1.4 数据帧结构

CAN通信数据帧的构成如下

图片

CAN通信数据帧结构

  • • 帧起始 表示数据帧开始的段,标准帧和扩展帧的帧起始都是由1个位的显性电平组成。

  • • 仲裁段 表示数据帧优先级的段。
    图片
    仲裁段

RTR是用来表示是否是远程帧(遥控帧)。RTR为0是数据帧,RTR为1是远程帧。扩展帧中的IDE是标识符的选择位,如果为0,使用标准标识符,如果为1,使用扩展标识符。扩展帧的SRR相当于标准帧中的RTR位。 标准帧的ID禁止高七位是隐性电平 。

  • • 控制段 控制段由6位构成,表示数据段的字节数。
    图片
    控制段
    扩展帧的r0和r1是保留位,保留位必须全部以显性电平发送。DLC是数据的长度码,数据的字节数范围是0~8。IDE是标识符的选择位,如果为0,使用标准标识符,如果为1,使用扩展标识符。

  • • 数据段 数据段可以包含0~8个字节的数据。从MSB(最高位)开始传输。标准帧和扩展帧的数据段相同。

  • • CRC段 CRC段用于校验,检查帧传输是否存在错误。CRC段包含15位CRC序列和1位CRC界定符。标准帧和扩展帧的CRC段相同。
    图片
    CRC段

  • • ACK段 ACK段用来确认是否正常接收。由ACK槽和ACK界定符2位组成。标准帧和扩展帧的ACK段相同。
    图片
    ACK段

  • • 帧结束 由7位隐形电平组成,表示帧的结束。标准帧和扩展帧的帧结束相同。

    11.5 CAN的位时序

    由发送单元在非同步状态下每秒钟发送的位数称为 位速率 。一个位可以分成4段。

  • • 同步段 SS

  • • 传播时间段 PTS

  • • 相位缓冲段1 PBS1

  • • 相位缓冲段2 PBS2

上面的这些段由称为Time Quantum( Tq )的最小时间单位组成。1个位分成4个段,一个段又分成若干个Tq,这成为 位时序 。

图片

位构成

采样点是读取总线电平,并将读到的电平作为位值的点。

1.6 CAN的仲裁功能

在总线空闲态,最先开始发送消息的单元获得发送权。当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连 续输出显性电平最多的单元可继续发送 。

图片

仲裁过程

二、STM32F1的CAN

2.1 bxCAN简介

STM32F1芯片自带bxCAN 控制器 (Basic Extended CAN),即基本扩展CAN,可与 CAN 网络进行交互,它支持 2.0A 和 B 版本的CAN 协议。STM32F1的bxCAN有以下特点

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

  • • 波特率最高达 1Mbps

  • • 支持时间触发通信

  • • 具有 3 个发送邮箱

  • • 具有 3 级深度的 2 个接收 FIFO

  • • 可变的过滤器组(STM32F103ZET6有14个)

bxCAN模块可以完全自动地接收和发送CAN报文,且完全支持标准标识符(11位)和扩展标识符(29位)。

2.2 bxCAN工作模式

bXCAN有3个主要的工作模式: 初始化模式 、正常模式和 睡眠模式 。除此之外,还有测试模式,静默模式,环回模式。

2.2.1 初始化模式

首先看一下CAN主控制寄存器 (CAN_MCR)的INRQ位。

图片

寄存器介绍CAN_MCR

图片

寄存器CAN_MSR介绍

通过介绍可以直到,想要进入初始化模式,软件先将CAN_MCR的INRQ位置1。然后等待硬件将CAN主状态寄存器(CAN_MSR)的INAK位置1。此时进入初始化模式。

当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。

2.2.2 正常模式

在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。继续看上面对于CAN主控制寄存器INRQ位的介绍。软件将INRQ位清0,可以使CAN从初始化模式进入正常模式。此时等待硬件将CAN主状态寄存器的INAK位清0即可。

2.2.3 睡眠模式

bxCAN可工作在低功耗的睡眠模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。

图片

寄存器CAN_MSR介绍

可以看出,软件将CAN主控制寄存器的SLEEP置1,即可请求进入睡眠模式。清零该位,退出睡眠模式。另外,如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。

2.2.4 静默模式

将CAN_BTR寄存器的SILM位置’1’,来选择静默模式。

图片

寄存器CAN_BTR介绍

在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。

图片

静默模式

2.2.5 环回模式

将CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。

图片

寄存器CAN_BTR寄存器介绍

环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。

图片

环回模式

2.3 位时序和波特率

STM32将每一位分成三段

  • • 同步段 SS

  • • 时间段1 BS1

  • • 时间段2 BS2

图片

位时序

其中tpclk是APB1总线的时钟频率,默认为36MHz。

三、CAN配置步骤

  • • 使能CAN时钟,将对应引脚复用映射为CAN功能 。STM32F103ZET6只有一个CAN,对应引脚如下

1.jpg

CAN_RX配置为上拉输入模式,CAN_TX配置为复用推挽输出。


• 设置CAN工作模式,波特率等 。库函数提供了一个结构体和一个函数来配置。初始化函数为

uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)


结构体成员如下

1.jpg

2.jpg

波特率 = Fpclk1 / ((CAN_BS1 + CAN_BS2 + 1)* CAN_Prescaler)


• 设置CAN筛选器(过滤器) 库函数也提供了筛选器的配置函数

void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)


结构体内容如下

1.jpg

2.jpg

选择CAN中断类型,开启中断 库函数提供了一个中断的配置函数

void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)

CAN的中断类型有很多,这里就不再一一介绍了。


#define IS_CAN_IT(IT)        (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0)  ||

                             ((IT) == CAN_IT_FF0)  || ((IT) == CAN_IT_FOV0)  ||

                             ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1)   ||

                             ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG)   ||

                             ((IT) == CAN_IT_EPV)  || ((IT) == CAN_IT_BOF)   ||

                             ((IT) == CAN_IT_LEC)  || ((IT) == CAN_IT_ERR)   ||

                             ((IT) == CAN_IT_WKU)  || ((IT) == CAN_IT_SLK))

• CAN发送和接收消息 CAN发送消息的函数是

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)


发送之前需要配置好消息的结构体,消息结构体成员如下

1.jpg

选择CAN中断类型,开启中断 库函数提供了一个中断的配置函数

void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)

CAN的中断类型有很多,这里就不再一一介绍了。


#define IS_CAN_IT(IT)        (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0)  ||

                             ((IT) == CAN_IT_FF0)  || ((IT) == CAN_IT_FOV0)  ||

                             ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1)   ||

                             ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG)   ||

                             ((IT) == CAN_IT_EPV)  || ((IT) == CAN_IT_BOF)   ||

                             ((IT) == CAN_IT_LEC)  || ((IT) == CAN_IT_ERR)   ||

                             ((IT) == CAN_IT_WKU)  || ((IT) == CAN_IT_SLK))

• CAN发送和接收消息 CAN发送消息的函数是

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)


发送之前需要配置好消息的结构体,消息结构体成员如下

1.jpg

CAN状态获取 库函数提供了很多可以获取CAN状态标志的函数,比如

uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)


FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG);

四、实战项目

4.1 CAN初始化

/*

 *==============================================================================

 *函数名称:Drv_Can_Init

 *函数功能:初始化CAN

 *输入参数:tsjw:重新同步跳跃宽度(Tsjw);tbs1:BS1长度;tbs2:BS2长度;

                        brp:Tq大小;mode:CAN工作模式

 *返回值:无

 *备  注:无

 *==============================================================================

 */

void Drv_Can_Init (u8 tsjw,u8 tbs1,u8 tbs2,u16 brp,u8 mode)

{

    // 结构体定义

    GPIO_InitTypeDef GPIO_InitStructure;

    CAN_InitTypeDef CAN_InitStructure;

    CAN_FilterInitTypeDef CAN_FilterInitStructure;

    

    // 开启时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);   // 打开CAN1时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // PA端口时钟打开

    

    // 初始化GPIO

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;   // PA11 CAN_RX   

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   // 上拉输入模式

    GPIO_Init(GPIOA, &GPIO_InitStructure); 


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;   // PA12 CAN_TX   

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // IO口速度为50MHz

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    

    // 初始化CAN

    CAN_InitStructure.CAN_TTCM=DISABLE;   // 非时间触发通信模式   

    CAN_InitStructure.CAN_ABOM=DISABLE;   // 软件自动离线管理   

    CAN_InitStructure.CAN_AWUM=DISABLE;   // 睡眠模式通过软件唤醒(清除CAN- >MCR的SLEEP位)

    CAN_InitStructure.CAN_NART=ENABLE;   // 使用报文自动传送 

    CAN_InitStructure.CAN_RFLM=DISABLE;   // 报文不锁定,新的覆盖旧的  

    CAN_InitStructure.CAN_TXFP=DISABLE;   // 优先级由报文标识符决定 

    CAN_InitStructure.CAN_Mode= mode;   //CAN工作模式设置 

    CAN_InitStructure.CAN_SJW=tsjw;   // 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq

    CAN_InitStructure.CAN_BS1=tbs1;   // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq

    CAN_InitStructure.CAN_BS2=tbs2;   // Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq

    CAN_InitStructure.CAN_Prescaler=brp;   //分频系数(Fdiv)为brp+1 

    CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1

    

    // 初始化过滤器

    CAN_FilterInitStructure.CAN_FilterNumber=0;   // 过滤器0

    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;   // 掩码模式

    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;   // 32位 

    CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;   // 32位ID

    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;   // 32位MASK

    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;   // 过滤器0关联到FIFO0

    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;   // 激活过滤器0

    CAN_FilterInit(&CAN_FilterInitStructure);   // 过滤器初始化

}

4.2 CAN发送

/*

 *==============================================================================

[1] [2]
关键字:STM32  CAN通信  控制器  局域网络 引用地址:STM32速成笔记(14)—CAN通信

上一篇:STM32基础知识:串口通信-中断方式
下一篇:用STM32_FLASH模拟实现EEPROM功能

推荐阅读最新更新时间:2024-11-22 15:19

38. ADC实验
一。ADC通道与引脚的对应关系 二。常用库函数 三。ADC初始化函数 ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); 例: 四。ADC使能函数,ADC使能软件转换函数 不使用外部触发,使用软件触发,所以调用使能软件转换函数。 五。实验步骤 void Adc_Init(void); // 完成步骤1--4 //初始化ADC //这里我们仅以规则通道为例 //我们默认将开启通道0~3 void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_In
[单片机]
38. ADC实验
基于16位控制器的汽车车身电子控制系统解决方案
随着汽车车身控制应用复杂性的提高,对16位微控制器(MCU)的性能要求也越来越高。以前曾用机械方法实现的门控、座椅调节、车内照明和空调系统现在都改成了电子控制。这样一个电子化汽车车身控制系统包括电源系统、CAN收发器、多开关检测接口、输出系统、电子马达控制、嵌入式仿真以及内存编程等几个主要部分,本文不仅介绍了一系列芯片,而且将使设计工程师对汽车电子控制系统有一个比较概要和全面的认识。 随着汽车车身控制应用复杂性的提高,对16位微控制器(MCU)的性能要求也越来越高。以前曾用机械方法控制的门控、座椅调节、车内照明和空调系统现在都改成了电子控制。许多半导体厂商包括摩托罗拉公司所提供的大量专用半导体解决方案使这些新的电子控制应用成为可能
[嵌入式]
一种基于μC/OS-III及STM32的多功能控制器
电动轨道车控制系统一般分为多个子系统,子系统受一个主控器控制。这样的结构设计繁琐,编程复杂。采用μC/OS-III操作系统、STM32F103RC微控制器、12864液晶屏、PVC按键、无线串口模块、锂电池等实现具有人机界面、无线串口功能的总线主控器。该控制器具有人机界面、轨道车主控器、遥控接收器、遥控面板等多种功能,并且能在不同项目中使用。μC/OS-III从官网上下载,文件名为Micrium_uC-Eval-STM32F107_uCOS-III,版本为V1.29.01.00. 1硬件结构 从系统接口看,该控制器具有显示、按键、无线收发、串口、485总线等接口,作遥控面板时用电池供电,内部具有电池和充电电路。硬件框图如图
[单片机]
一种基于μC/OS-III及<font color='red'>STM32</font>的多功能<font color='red'>控制器</font>
stm32专题三十一:电源管理
stm32的电源管理 上电复位与掉电复位(POR PDR): 这个滞回电压,是为了让单片机容忍一定程度的电压波动,而不是只要电压稍微一变化,就立刻掉电复位。 可编程电压监测器PVD: PVD中断的上升沿或下降沿,表示的是VDD电压是超过阈值还是低于阈值,关于PVD中断的描述如下: stm32电源系统 为了方便进行电源管理,STM32 把它的外设、内核等模块跟据功能划分了供电区域,其内部电源区域划分如图: CPU内核为1.8V供电,以降低功耗,整个1.8V供电区域由电压调节器单独供电,有时CPU可以休眠,有时可以不休眠,这是由电压调节器来提供的。 关于时钟的具体描述: 这里,值得注意的是后备供电区
[单片机]
<font color='red'>stm32</font>专题三十一:电源管理
基于自抗扰控制器的PMSM矢量控制系统设计与实现
永磁同步电机PMSM(Permanent Magner Synchronous Machine)具有功率密度高、体积小、效率高、惯量小等优点,广泛应用于数控机床领域 。然而PMSM是一个非线性、强耦合、参数摄动的多变量系统,对于外界扰动以及系统参数变化比较敏感,因此对于控制系统要求较高,既要具有高性能的软硬件结构,又要具有高性能的控制策略和控制算法 。  为了提高PMSM控制性能, 国内外学者展开了广泛研究。参考文献 提出一种基于状态观测和反馈的控制策略, 参考文献 提出一种基于自抗扰控制器的控制策略,这些方法具有良好的动静态性能,却未考虑电流环中耦合非线性因素的影响,无法从根本上解决非线性问题;参考文献 提出一种基于模糊自适应P
[嵌入式]
STM32控制器应用于Pebble智能手表
意法半导体(STMicroelectronics,简称ST)的STM32微控制器被Pebble智能手表所采用,用于控制这款创新的兼容iPhone手机和安卓智能手机的穿戴式产品。 Pebble智能手表通过蓝牙无缝连接到iPhone和安卓智能手机,当有来电、电子邮件和短信时,可通过静音振动通知用户。Pebble智能手表内置实时性能和能效俱佳的STM32 F2微控制器,使手表在功能性和电池使用寿命之间实现完美平衡,为用户提供全定制功能,配备精美的表盘下载和实用的联网应用软件。 Pebble创始人、首席执行官Eric Migicovsky表示:“Pebble穿戴式产品的用户想要一个这样的手表,它能够无缝连接其它设备,连续运行几
[单片机]
基于STM32的多功能γ能谱仪设计
摘要:文中介绍了一种基于STM32微处理器的γ能谱仪的研制。该仪器由主探测器、主控电路,GPS模块,SD卡存储模块,USB接口电路构成。是一种集辐射强度检测、辐射源地理位置定位,数据存储,USB传输等功能于一体的监测系统,大大丰富并提高了能谱仪的性能。 随着对天然辐射场中低能量γ谱学及其应用的深入研究,γ能谱仪不仅在固体矿产勘探、油气普查、水文和工程地质调查等工业生产及科学研究方面,甚至在民用的环境辐射场调查、建材与建筑装饰材料放射性检测方面,都得到广泛的应用,应用场合的复杂多样化对核辐射测量仪器提出新的需求。传统的核辐射测量仪器常采用探头与主控仪器分离的方式,而且主控仪器通常采用32位ARM7处理器甚至8位单片机系统来进行控
[单片机]
基于<font color='red'>STM32</font>的多功能γ能谱仪设计
两轮电动车触摸屏对触摸控制器提出的独特要求
虽然无数关于未来交通的文章都以四轮电动车作为讨论重点,但在印度、马来西亚、泰国和印度尼西亚等诸多国家,出行更依赖于经济的两轮电动车,包括踏板式摩托车、重型摩托车、电动摩托车、电动轻便摩托车和电动自行车。这些两轮电动车紧跟四轮电动车的设计趋势,采用触摸屏进行控制,而不用物理旋钮、按钮和机械表盘。 采用触摸屏进行控制,便于两轮电动车设计人员设计出具有现代化外观、灵活布局和风格的车辆,并且让他们可以按不同车型甚至具体车辆轻松定制。易于使用的菜单系统可满足两轮电动车更复杂的控制、显示和功能要求,同时实现导航、信息娱乐系统、远程支付和车辆安全等增值功能。 两轮电动车的触摸屏经常暴露在恶劣的户外环境中,容易受到雨雪、灰尘或泥沙等
[嵌入式]
两轮电动车触摸屏对触摸<font color='red'>控制器</font>提出的独特要求
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved