基于stm32cubeIDE学习can通信

2023-05-16

can通信

TO DO
1
CAN_FilterTypeDef 中的SlaveStartFilterBank 为从过滤器配置,用来选择从过滤器的寄存器号
当选择双CAN模式的时候,这个参数要跟CAN2的filternumber 一致。
//filternumber 是啥
2
can在发送的时候怎么决定是送到FIFO0还是FIFO1?
3
看这个

WHY
发送信息的时候 邮箱是怎么选的。为什么我按照例程重新写句柄和发送函数的时候即使发第一个消息也会跳转到邮箱1,而且发送失败。。

 /* Select one empty transmit mailbox */
  if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
  {
    transmitmailbox = 0;
  }
  else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
  {
    transmitmailbox = 1;
  }

CAN 的硬件结构

CAN总线系列学习笔记
在这里插入图片描述
左边是高速CAN总线的拓扑结构,右边是低速CAN总线的拓扑结构。所以高速和低速的设备是不能混用的【吧】
在这里插入图片描述

CAN 的信息格式

太多了,拿一个典型的给大家康康
在这里插入图片描述
下面的描述也是简化版本,具体还有很多细节没提到。
ID 确定顺序用的【canopen里用来划分帧的功能和子设备号】
控制段 确定数据的长度用的 【canopen里的SDO还另外用数据段里的内容又指定一次数据长度,搁这套娃呢】
数据段 8字节,只能少不能多
CRC 校验
ACK 回应
帧结束 7个隐性位

Can总线何时是空闲的

当总线连续表现为11个位的隐形电平(高电平),则总线为空闲状态。但是Can总线不是说5个相同位后就会有一个反转位码,那是发生在发送数据时。总线空闲时没有发送数据,发送数据时不会出现这么多隐性位。

CAN消息的有效长度。uint8_t len

每一帧CAN消息能够传递最多8个无符号整形数据,或者说能够传递8*8的bool类型的数据。这里的len最大值为8,如果该帧CAN消息中有些位没有数据,这里的len就会小于8。

NOTE
1开发板上的两个 CAN 都分别拥有自己的发送邮箱和接收 FIFO,但是他们共用 28 个 滤波器
2CAN有两个接收FIFO ,每个滤波器要设定对应的FIFO // ‘FIFO’ ==先入先出

CAN总线有接收邮箱和发送邮箱:
”发送邮箱“是用于CAN总线数据发送的,总共有3个,并且存在优先级关系。优先级越高表示其里面的数据会被优先发送。数据在发送前都会被送到优先级最高且空闲的发送邮箱,然后依次发送。最后说明一点:“发送邮箱有3个,且每个邮箱只能装一个报文”。
”接收邮箱“是用于CAN总线数据接收用的,在接收数据端会有一个过滤器处于”接收邮箱“的前面,过滤器使用于删选”标识符“的,只有标识符符合的报文才会被放入到”接收邮箱“当中。注意:”接收邮箱不同于发送邮箱,接收邮箱只有2(FIFO0、FIFO1)个,但是每一个有三层,每层都可以存放一个报文,即每一个接收邮箱可以接收三个报文。但读取时只能读到最先收到的报文,等这个读完之后,才能读下一个报文”。

3滤波器初始化里的CAN1_FilerConf.BankNumber=14;用来设置CAN2 起始存储区。

FIFO溢出时的策略
STM32有两种策略来处理当FIFO溢出时的报文:

一:当FIFO溢出时,首先抛弃FIFO内最老的报文,然后再存入新接收到的报文,即滚动接收模式。
二:当FIFO溢出时,抛弃新接收到的报文,即FIFO锁定模式。

如何采用以上何种策略,取决于具体应用需求。
如何设置?CAN主控制器寄存器(CAN_MCR)设置RFLM位为0,则为FIFO滚动接收模式,设为1,则为FIFO锁定模式。

基础设施

指示灯,按键中断以及NVIC中断允许,can的引脚和波特率配置,SYS调试引脚选第一项S… W… 记不清了
在这里插入图片描述
文件管理把生成.c .h文件勾选上
在这里插入图片描述

一要设置波特率

【重要性类比串口的波特率】
在这里插入图片描述

首先知道自己的APB1是45M
在这里插入图片描述
后面的参数就是45M/5(1+5+3)=1Mbps 想换频率只要改Prescaler就好 //但是这个频率好像太高了,ioc那边有警报。 现在用45M/9(1+5+4)=0.5Mbps

二是设置过滤器

自己新建个结构体 设定参数,调用句柄。可以像我一样新建个函数来初始化,也可以直接写在can的init函数里。

列表模式:只能接收指定ID的消息。

消息发送时的ID为0x0-0x7FF 【0000 0111 1111 1111】因此只有11个位有效 而过滤器的4个16位数据的存储方式是顶格存储的 所以过滤器设置1000 0000 1000 0000 从前面开始取值是 100 0000 0100 0000 0 对应的是 ID 404 【即过滤器里的后5位是废弃的】。截图里的设置是我的测试方式,大家也试一遍想必印象会更深刻。在这里插入图片描述

当将消息的ID设置为0x0404时,过滤器列表应设为0x8080才能挑出ID为0404的消息。也就是说这个设置不能接收到ID为0201的消息,能接收到306的消息。另外我尝试了反向翻译一下过滤器设为0404的ID,ID是0020.开发板能接收。

【另外,我通信协议学的是canopen 这11个位里的前四位是报文的功能码,剩下的是从机编号(所以能有127个从机)】

屏蔽模式

举个简单的例子,我们设置过滤器组 0 工作在:1 个 32 位过滤器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。
其中存放到 CAN_F0R1 的值就是期望收到的ID,即我们希望收到的 ID(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而 0XFF00FF00就是设置我们需要必须关心的 ID,表示收到的 ID,其位[31:24]和位[15:8]这 16 个 位的必须和 CAN_F0R1 中对应的位一模一样,而另外的 16 个位则不关心,可以一样,也可以 不一样,都认为是正确的 ID,即收到的 ID 必须是0xFFxx00xx,才算是正确的(x 表示不关心)

三 通信中断使能

HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
开启中断,开的是CAN_IT_RX_FIFO0_MSG_PENDING 接收中断

四 打开can通信

HAL_CAN_Start(&hcan1);

五 发送

数据帧

数据帧中有两种模式,一种是标准帧,一种是扩展帧。区别就只有ID的长短,但是同样是发送0x601,只有标准帧能被canopen识别,我不清楚这是因为canopen只能识别标准帧还是说标准帧和扩展帧就算低位数相同也会被区分开。
在这里插入图片描述
在这里插入图片描述
上面是can通信的格式,基本上就只用管ID和实际数据内容,其他部分都给函数整好了【而且学数据帧就够用了,别的很少用的样子】

玩过过滤就会搞ID 其余的设置对应的就是帧的结构
在这里插入图片描述
在这里插入图片描述
发送扩展帧只是ID变多了。而且发送的时候上面那个Stdid作废,ExtId可以从0写到1fffffff。

CAN发送流程

程序选择 1 个空置的邮箱(TME=1)->设置标识符(ID),数据长度和 发送数据->设置CAN_TIxR的TXRQ位为 1,请求发送->邮箱挂号(等待成为最高优先级)->预定发送(等待总线空闲)->发送->邮箱空置

六 接收

在这里插入图片描述
FIFO 空->收到有效报文->挂号_1(存入 FIFO 的一个邮箱,这个由硬件控制,我们不需要理会)->收到有效报文->挂号_2->收到有效报文->挂号_3->收到有效报文-> 溢出。
这个流程里面,我们没有考虑从 FIFO 读出报文的情况,实际情况是:我们必须在 FIFO 溢出之前,读出至少 1 个报文,否则下个报文到来,将导致 FIFO 溢出,从而出现报文丢失。每读出 1 个报文,相应的挂号就减 1,直到 FIFO 空.
FIFO 接收到的报文数,我们可以通过查询 CAN_RFxR 的 FMP 寄存器来得到,只要 FMP 不为 0,我们就可以从 FIFO读出收到的报文

参考文献

微雪课堂
过滤器
理论讲解
运行200秒左右 can就不发数据了 3个发送邮箱都满了?哪的问题,怎么办?

void can_filter_init(CAN_HandleTypeDef *phcan)
{

CAN_FilterTypeDef  sFilterConfig;

  /* Configure the CAN Filter */
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.SlaveStartFilterBank = 14;
 
  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }

}
void CAN_Send(CAN_HandleTypeDef* phcan)
{

//HAL_CAN_ActivateNotification(&hcan, CAN_IT_TX_MAILBOX_EMPTY);//开启中断
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailbox=0;
uint8_t TxData[6] = {0x23, 0x81, 0x60, 0x00, 0x55, 0x55};

// HAL_Delay(1000);
TxHeader.StdId = 0x404; //标准帧ID �???�???11位,也就�???0x7FF
TxHeader.RTR = CAN_RTR_DATA; //帧类型是数据�??? 数据类型,由系统定义的,无需理会
TxHeader.IDE = CAN_ID_STD;//ID类型是标准帧 定义信息传输类型,系统内定,不予理会
TxHeader.DLC = 8;//指定即将传输的数据帧的长8字节长度
TxHeader.TransmitGlobalTime=DISABLE;

HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox);

TxData[0]++;
// HAL_UART_Transmit(&huart1,TxData,8,0xffff);//79 0B 00 08 C1 09 00 08

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于stm32cubeIDE学习can通信 的相关文章

  • 关于STM32 CAN 滤波器设置的记录

    滤波模式有以下两种 xff1a 屏蔽位模式 标识符列表模式 过滤器的位宽 xff1a 16位过滤器 32位过滤器 下面记录一下我做过测试的代码 代码说明 xff1a 这是CAN2的滤波器 xff0c stm32f107的两组CAN滤波器是共
  • ubuntu 使用虚拟can 与 socketCAN使用

    原文链接 xff1a https blog csdn net xiandang8023 article details 127990159 创建虚拟CAN接口 在Linux上能使用虚拟CAN接口之前 xff0c 需要在终端执行以下三个步骤
  • 一帧CAN数据需要多长时间发送

    1 CAN通讯速率 默认 500kbit s xff1b 2 xff1a 从下图CAN数据包的完整结构可知 xff0c 一包完整的扩展帧CAN数据总共包含 128bit xff1b 3 xff1a 发送一帧扩展帧CAN数据耗时 128 50
  • CAN总线 标准帧/扩展帧滤波器设置

    在CAN协议里 xff0c 报文的标识符不代表节点的地址 xff0c 而是跟报文的内容相关的 因此 xff0c 发送者以广播的形式把报文发送给所有的接收者 节点在接收报文时 根据标识符 CAN ID 的值决定软件是否需要该报文 xff1b
  • CAN通信矩阵的理解(CAN报文信号的属性)

    CAN通信矩阵 1 CAN通信矩阵是什么 CAN通信矩阵 xff08 CAN Communication Matrix xff09 通常由整车厂完成定义 xff0c 车辆网络中的各个节点需要遵循该通讯矩阵才能完成信息的交互和共享 我们知道C
  • CAN通信讲解(3)——错误据帧

    本文注意参考了 CAN入门书 xff0c 源于此书图片不再特殊标注 目录 3 1 总线错误的种类3 1 1 位错误3 1 2 ACK错误3 1 3 填充错误3 1 4 CRC错误3 1 5 格式错误 3 2 错误帧结构3 3 错误状态3 3
  • CAN总线通信协议详讲

    CAN简介 CAN是Controller Area Network 的缩写 xff08 以下称为CAN xff09 xff0c 是ISO国际标准化的串行通信协议 由德国电气商博世公司在1986 年率先提出 此后 xff0c CAN 通过IS
  • linux-can编程(一)

    建立can的socket int can create socket char name int fd struct sockaddr can addr struct ifreq ifr socklen t len 61 sizeof ad
  • CAN为什么会发送失败

    CAN总线调试过程中出现报文发送失败 xff0c 很多工程师都对此只知其一不知其二 xff0c 这里就CAN报文发送失败的问题我们来做一次探讨 在了解CAN报文为什么会发送失败之前我们先看看一条正确的CAN报文到底应该是怎么样的 xff0c
  • 基于NRF24L01的CAN数据透传

    闲谈 xff1a 闲来无聊 xff0c 恰好公司又经常用CAN数据的传输 xff0c 自己觉得要是用无线传送多好 xff0c 然后 xff0c 就是一个奇想 xff0c 就想做一个无线数据的透传 xff0c 恰好身边又有NRF24L01 那
  • STM32 CAN通信的学习笔记总结

    转载地址 xff1a STM32 CAN通信的学习笔记总结 xff08 从小白开始 xff09 目录 1 总体概述 1 1 基本概念1 2 通讯方式1 3 为什么使用CAN 1 4 CAN的协议及组成 2 上帝视角看CAN的通讯过程 2 1
  • STM32CubeIDE设置Flash烧录地址和大小(告别Keil魔术棒)

    STM32CubeIDE中设置Flash烧写地址和范围 在由Keil平台转到STM32CubeIDE平台过程中 我们熟悉的点开魔术棒进行相关烧录配置的方式已经不适用了 在STM32CubeIDE平台中我们需要通过修改文件的方式来实现 稍显麻
  • 山石岩读丨前沿领域探析——汽车CAN总线协议详解及攻击面分析

    1 CAN总线的基本概念以及由来 CAN Controller Area Network 总线协议是由 BOSCH 发明的一种基于消息广播模式的串行通信总线 它起初用于实现汽车内ECU之间可靠的通信 后因其简单实用可靠等特点 而广泛应用于工
  • 一文读懂CAN总线及通信协议

    CAN总线的汽车 CAN概念 CAN是控制器域网 Controller Area Network CAN 的简称 是由研发和生产汽车电子产品著称的德国BOSCH公司开发了的 并最终成为国际标准 ISO11898 是ISO国际标准化的串行通信
  • CAN资料整理(三):CAN的位时间、同步、位定时

    目录 一 位时间 二 同步 1 硬同步 2 重新同步 三 位定时 1 传播段延迟时间的确定 2 位定时参数确定 由于CAN属于异步通讯 没有时钟信号线 连接在同一个总线网络中的各个节点会像串口异步通讯那样 节点间会使用约定好的波特率进行通讯
  • 各种通信接口的简单对比

    对比表 同步方式与异步方式的主要区别在于 是否传输时钟信号 只要是通訊前雙方需要設定相同波特率的 都是異步傳輸方式 异步传输 Asynchronous Transmission 每次异步传输的信息都以一个起始位开头 它通知接收方数据已经到达
  • STM32学习心得三十二:CAN通信基础知识、原理、配置及实验

    记录一下 方便以后翻阅 主要内容 1 CAN通信基础知识 2 STM32 CAN控制器简介 3 相关实验代码解读 参考资料 STM32中文参考手册 V10 第22章 控制器局域网 bxCAN 实验功能 CAN实验需要两个开发板 系统启动后
  • Canoe 安装流程

    硬件 VN5620 软件 CANoe V15 0 软件 Vector License Client 6 2 驱动 Vector Driver Setup license 购买硬件时 vector会分配 参考文档 First Steps to
  • Keil转STM32CubeIDE工程移植问题记录

    Keil转STM32CubeIDE工程移植问题记录 1 编译报错问题处理 2 工程相关配置问题 3 调试器配置 从Keil软件转战STM32CubeIDE 转换的过程中遇到了不少问题 在此记录一下 防止以后再踩坑 也给同样有转软件需求的朋友
  • Ubuntu 周立功CAN分析仪 USBCAN-II 驱动

    首先从官网https www zlg cn Index Search search key linux的下载资料界面下载 Linux驱动 USBCAN I I II II 2A I MINI安装驱动 USBCAN II新版驱动基于libus

随机推荐