STM32CubeMX 配置CAN通信 HAL库

news2024/11/15 8:29:29

一、CAN总线波特率计算

CAN总线通信的各节点通信时会产生相位差,所以要进行位同步,两个节点保持步调一致。
CAN_SJW:重新同步跳跃宽度(SJW) 。定义了在每位中可以延长或缩短多少个时间单元的上限。其值可以编程为1到4个时间单元。
CAN_BS1:时间段1(BS1):定义采样点的位置。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
CAN_BS2:时间段2(BS2):定义发送点的位置。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。
CAN_Prescaler:直观理解就是分频率。


CAN总线的波特率是取自于总线APB1(PCLK1),通过函数RCC_PCLK1Config给PCLK1配置频率。设置了以上的四个值之后,
CAN总线的波特率=PCLK1/((CAN_SJW +CAN_BS1 + CAN_BS2)*CAN_Prescaler)
假设PCLK1=36MHz、CAN_SJW=1、CAN_BS1=8、CAN_BS2=7、CAN_Prescaler=9
则CAN总线的波特率=PCLK1/((1 + 8 + 7) * 9) = 36MHz / 16 / 9 = 250Kbits

二、查看数据手册(stm32F407ZG),看CAN挂载在哪条总线上面,以及对应的引脚 

三、CAN过滤器介绍

typedef struct
{
  __IO uint32_t FR1;           //标识符屏蔽位模式中标识符寄存器,配置ID
  __IO uint32_t FR2;           //标识符屏蔽位模式中屏蔽寄存器
}CAN_FilterRegister_TypeDef;  //标识符列表模式中为2个标识符寄存器,配置ID

例如:屏蔽位寄存器的bit15=1,标识符寄存器的bit15=0,那么接受的Message里面的标识符的bit15必须为0才可能被硬件接受。如果屏蔽位寄存器的bit15=0,Message里面的标识符的bit15无论为什么值,bit15都能匹配通过。

32位屏蔽位模式下:1个过滤器。FR2指定需要关心哪些位,FR1指定这些位的标准值
32位列表模式下:2个过滤器,FR1指定过滤器0的标准值,FR2指定过滤器1的标准值
16位屏蔽位模式下:2个过滤器。FR1高位配置过滤器0标准值,低位配置给过滤器1的标准值。FR2高位配置过滤器0关心的位,低位配置给过滤器1的关心的位。
16位列表模式下:4个过滤器。FR1低位配置过滤器0,高位配置过滤器1。FR2配置过滤器2和过滤器3

IDE=0为标准ID,IDE=1为扩展ID。
RTR=0代表数据帧,RTR=1代表远程帧。
MASKID设置屏蔽码,ID设置标准值。

四、STM32CubeMX配置CAN通信

(1)通过配置分频值和三个时间的比例,可以得出CAN的波特率

(2)针对CAN基本参数设置,具体含义如下

在这里插入图片描述

这些是配置基本参数用的:

  1. 时间触发模式:会自动为报文生成时间戳,没有研究过,暂时默认关闭。
  2. 自动总线关闭管理:没有研究过,暂时默认关闭。
  3. 自动唤醒模式:使能后,当CAN外设在休眠状态时如果CAN总线有数据,则自动唤醒CAN外设。
  4. 自动重发:使能后,如果因为仲裁失败(总线冲突)或是其他原因导致发送失败,会自动重发。建议使能。
  5. 接收FIFO锁定模式:如果使能,当接收FIFO满时,下一条数据会被丢失。如果不使能,则覆盖前面的数据。
  6. 发送FIFO优先级:当发送邮箱中同时有多个帧,是按照先进先出的顺序发送还是按照ID的优先级发送。如果不使能,则按照ID优先级发送。如果使能,则按照先进先出优先级发送。

使能CAN接收中断

(3)CAN几种模式

Advanced Parameters

在这里插入图片描述

这一项主要是用来调试用的,如果只是正常使用,选择 Normal 模式。

  1. 正常模式:CAN外设正常地向CAN总线发送数据并从CAN总线上接收数据。
  2. 回环模式:CAN外设正常向CAN总线发送数据,同时接收自己发送的数据,但不从CAN总线上接收数据。
  3. 静默模式:CAN外设不向CAN总线发送数据,仅从CAN总线上接收数据,但不会应答。一般用于检测CAN总线的流量。
  4. 静默回环模式:CAN外设不会往CAN总线收发数据,仅给自己发送。一般用于自检。

五、使能CAN通信

HAL_CAN_Start(&hcan1);

六、发送数据

写法一:测试时直接发送

CAN_TxHeaderTypeDef can_Tx;
uint8_t sendBuf[5] = {"hello"};
uint32_t box;

int main(void)
{
  	HAL_Init();
 	SystemClock_Config();
  	MX_GPIO_Init();
  	MX_CAN_Init();

    HAL_CAN_Start(&hcan1);//使能CAN通信
  
    can_Tx.StdId = 0x123;
    can_Tx.ExtId = 0;
    can_Tx.IDE = CAN_ID_STD;
    can_Tx.RTR = CAN_RTR_DATA;
    can_Tx.DLC = 5;
    can_Tx.TransmitGlobalTime = DISABLE;

  	while (1)
  	{
      	HAL_CAN_AddTxMessage(&hcan1, &can_Tx, sendBuf, &box);
      	HAL_Delay(100);
  	}
}

写法二:测试成功后可以封装成发送函数,下面之所以有while循环等待发送完成是为了避免出现发送5条数据,只能接受到一条数据的情况

uint8_t can1_send_msg(uint32_t id, uint8_t *msg, uint8_t len)
{
     uint16_t t = 0;
    uint32_t TxMailbox = CAN_TX_MAILBOX0;
    
    g_canx_txheader.StdId = id;         /* 标准标识符 */
    g_canx_txheader.ExtId = id;         /* 扩展标识符(29位) */
    g_canx_txheader.IDE = CAN_ID_STD;   /* 使用标准帧 */
    g_canx_txheader.RTR = CAN_RTR_DATA; /* 数据帧 */
    g_canx_txheader.DLC = len;

    if (HAL_CAN_AddTxMessage(&hcan1, &g_canx_txheader, msg, &TxMailbox) != HAL_OK) /* 发送消息 */
    {
        return 1;
    }
    
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3)   /* 等待发送完成,所有邮箱为空 */
    {
        t++;
        
        if (t > 0xFFF)
        {
            HAL_CAN_AbortTxRequest(&hcan1, TxMailbox);     /* 超时,直接中止邮箱的发送请求 */
            return 1;
        }
    }
    
    return 0;
}

七、配置过滤器接收数据

写法一:直接主函数测试接收是否配置成功

#include <stdio.h>

CAN_RxHeaderTypeDef can_Rx;
uint8_t recvBuf[8];

int main(void)
{
  	HAL_Init();
 	SystemClock_Config();
  	MX_GPIO_Init();
  	MX_CAN_Init();
    MX_USART1_UART_Init()

    CAN_FilterTypeDef can_Filter = {0};
    
    can_Filter.FilterIdHigh = 0;
    can_Filter.FilterIdLow = 0;
    can_Filter.FilterMaskIdHigh = 0;
    can_Filter.FilterMaskIdLow = 0;
    can_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    can_Filter.FilterBank = 0;
    can_Filter.FilterMode = CAN_FILTERMODE_IDMASK;
    can_Filter.FilterScale = CAN_FILTERSCALE_32BIT;
    can_Filter.FilterActivation = CAN_FILTER_ENABLE;
    HAL_CAN_ConfigFilter(&hcan1, &can_Filter);
    
    HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
    
    HAL_CAN_Start(&hcan1);

  	while (1)
  	{

  	}
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &can_Rx, recvBuf);


}

写法二:让CAN接收更加系统化 

(1) 直接加在CAN1初始化的下面即可,配置过滤器,只有配置了过滤器之后才能接收数据

/* 配置CAN过滤器 */
	CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 0;                             /* 过滤器0 */
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;                      /* 32位ID */
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig.SlaveStartFilterBank = 14;				//设置CAN2的起始过滤器组(对于单CAN的CPU或从CAN此参数无效;对于双CAN的CPU此参数为从CAN的起始过滤器组编号)
    HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);/* 过滤器配置 */

(2) 除开之前在cubemx配置时使能了CAN接收总中断,还需要打开CAN的FIFO消息挂起中断请求(也就是CAN外设的中断使能位)。

HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

(3)重写CAN接收中断回调函数 

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &can_Rx, recvBuf);

	/*下面是你用来处理收到数据的代码,
	可以通过串口把内容发送出来,
	也可以用来控制某些外设*/
}

八、CAN调试心得

(1)如果使用CAN盒调试CAN通信时,出现发送或者接收数据失败,将CAN配置为静默回环模式,先排除硬件文件,保证软件无误

(2)发送5帧数据只能接收到一帧数据,说明CAN发送较快,发送完一帧数据之后可以等待发送完成在发送下一帧数据,修改CAN配置

(3)如果静默回环模式配置正确,使用CAN盒通信时只能接收错误帧,检查CAN波特率是否正确。有两种可能性,第一种就是CAN的波特率计算错误,第二种就是系统时钟配置错误,倒是CAN时钟不是默认时钟

九、配置两个CAN通信

如果配置两个CAN通信,他们的过滤器配置需要稍作修改

CAN1

/* 配置CAN过滤器 */
	CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 0;                             /* 过滤器0 */
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;                      /* 32位ID */
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig.SlaveStartFilterBank = 14;				 设置CAN2的起始过滤器组(对于单CAN的CPU或从CAN此参数无效;对于双CAN的CPU此参数为从CAN的起始过滤器组编号)
    HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);/* 过滤器配置 */

CAN2 

CAN_FilterTypeDef sFilterConfig;
    sFilterConfig.FilterBank = 14;                             /* 过滤器14 */
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;                      /* 32位ID */
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig.SlaveStartFilterBank = 28;				    //无效
    HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);/* 过滤器配置 */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2057053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录一次搭建uniapp-vue3的基础项目

1.使用 HBuilder X 创建uniapp vue3的基础项目 2.安装 自动导包插件 unplugin-auto-import npm install unplugin-auto-import或者 pnpm install unplugin-auto-import2.1 根目录下创建 vite.config.js 复制粘贴以下内容 import { defineConfig } from vite import uni fro…

QT基础知识4

思维导图 项目文件里面要加texttospeech模块 widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime>//时间类 #include <QTextToSpeech>//语音播报类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass…

“论数据分片技术及其应用”写作框架,软考高级,系统架构设计师

论文真题 数据分片就是按照一定的规则&#xff0c;将数据集划分成相互独立、正交的数据子集&#xff0c;然后将数据子集分布到不同的节点上。通过设计合理的数据分片规则&#xff0c;可将系统中的数据分布在不同的物理数据库中&#xff0c;达到提升应用系统数据处理速度的目的…

企业高性能web服务器---nginx详解(基础介绍配置,核心配置)

目录 一、web服务器介绍 1.1 Apache prefork 模型 1.2 Apache worker 模型 ​编辑 1.3 Apache event模型 1.4 Nginx-高性能的web服务端 1.5 服务端 I/O 流程 1.5.1 磁盘 I/O 1.5.2 网络 I/O 二 、nginx 架构及安装 2.1 nginx 进程结构 2.2源码编译安装nginx 2.2.1…

vscode+pyqt5环境搭建

参考&#xff1a;https://blog.csdn.net/qq_37080185/article/details/121616507 一、安装Python 从Python官网上下载安装包&#xff08;https://www.python.org/&#xff09; 安装Python&#xff0c;将安装目录添加到环境变量中。 二、安装Pyqt5 PyQt5以及PyQt5-tools(des…

将光谱数据图片转换成数值格式

文章目录 任务所需工具步骤一&#xff1a;安装必要的Python库步骤二&#xff1a;图像OCR识别步骤三&#xff1a;提取光谱数值并存储完整代码 任务 现测量收集到一批目标色彩样本的光谱响应数据截图(图片保存在spectrum_screenshots文件夹内&#xff0c;截图样例见图1)。其中&a…

PyQt5中如何只使用一个dateEdit控件实现自动选择日期区间功能

wxpython设计GUI&#xff1a;选中wxFormBuilder工具wxCalendarCtrl控件&#xff0c;实现自动选择日期功能 wxPython设计界面转PyQt5设计界面&#xff0c;相同的界面功能&#xff0c;通过移植wxPython源代码实现PyQt5相同界面功能&#xff0c;在实现上述链接提到的自动选择日期…

Windows电脑设置开启自启动Java程序,并且不出现黑窗口

第一步&#xff1a;创建需要运行的批处理文件&#xff08;.bat 文件&#xff09; 在jar文件同级目录下新建文本输入以下内容&#xff0c;其中tunnel-monitoring-server.jar改为自己的程序名称&#xff0c;保存文件后缀改为bat。如下图1&#xff1a; echo off java -jar tunne…

开源的Umi-OCR 文字识别工具

开源的Umi-OCR 文字识别工具&#xff1a;OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生成二维码。内置多国语言库。 可以将图片PDF识别文字&#xff0c;并可以保存…

python | 字符串编码问题怎么破

python字符串常见两种类型&#xff1a;str和 bytes类型 str表示Unicode字符&#xff0c;bytes表示二进制数据 两者之间转换使用&#xff1a;encode()和decode()方法 一、enocde()和decode()方法 &#xff08;一&#xff09;encode()方法 encode()—编码&#xff0c;语法&…

软件测试之常见逻辑思维题

一个岔路口分别通向诚实国和说谎国。来了两个人&#xff0c;已知一个是诚实国的&#xff0c;另一个是说谎国的。诚实国永远说实话&#xff0c;说谎国永远说谎话。现在你要去说谎国&#xff0c;但不知道应该走哪条路&#xff0c;需要问这两个人。请问应该怎么问&#xff1f; 如…

[HDCTF 2023]Welcome To HDCTF 2023

方法一&#xff1a;找个炸弹死掉&#xff0c;flag就出现 方法二&#xff1a;查看页面源码&#xff0c;发现底部assets/js/game.js 复制后访问看到jsfuck编码 复制到控制台查看flag

上海交大周冰心博士:锚定稀缺生物数据挑战,图神经网络重塑蛋白质理解与生成

8 月 12 日&#xff0c;上海交通大学 AI for Bioengineering 暑期学校正式开幕&#xff0c;吸引了来自国内外 30 余所高校和 27 家企业的百余名业内人士。在为期 3 天的学习交流中&#xff0c;多位行业专家、企业界代表及优秀青年学者&#xff0c;围绕 AI 与生物工程的融合与创…

【前缀和算法】--- 一维和二维前缀和模板

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Journey 本文开始,博主开始讲解有关前缀和的算法&#xff0c;本篇博客我们先来了解一下有关前缀和的两个模板。 &#x1f3e0; 一维前缀和模板 &…

CPU内部单总线数据通路各阶段的微操作序列利控制信号

1.内部总线与系统总线 内部总线是指同一部件&#xff0c;如CPU内部连接各寄存器及运算部件之间的总线&#xff1b; 系统总线是指同一台计算机系统的各部件&#xff0c;如CPU、内存、通道和各类/0接口间互相连接的总线。 2.寄存器之间数据传送 比如把PC内容送至MAR&#xff…

利用多Lora节省大模型部署成本|得物技术

一、背景 近期&#xff0c;我们在大模型集群的部署过程中遇到了一些挑战。公司有多个业务场景&#xff0c;每个场景都基于自身的数据进行微调&#xff0c;训练出相应的大模型并上线。然而&#xff0c;这些场景的调用量并不高&#xff0c;同时大模型的部署成本较为昂贵&#xf…

从0到1!如何利用GPT创作高质量的儿童绘本故事?(附提示词)

儿童绘本故事需要有趣、富有教育意义&#xff0c;并且简单易懂。利用GPT来创作这样的故事&#xff0c;可以让创意过程变得轻松且高效。以下是一份详细教程&#xff0c;帮助你用GPT创作出吸引孩子们的高质量绘本故事。 1. 明确故事目标和受众 在开始创作之前&#xff0c;明确故事…

Synchronized重量级锁原理和实战(五)

在JVM中,每个对象都关联这一个监视器,这里的对象包含可Object实例和Class实例.监视器是一个同步工具,相当于一个凭证,拿到这个凭证就可以进入临界区执行操作,没有拿到凭证就只能阻塞等待.重量级锁通过监视器的方式保证了任何时间内只允许一个线程通过监视器保护的临界区代码. …

Linux基础环境开发工具gcc/g++ make/Makefile

1.Linux编译器-gcc/g使用 1. 预处理&#xff08;进行宏替换) 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。 预处理指令是以#号开头的代码行。 实例: gcc –E hello.c –o hello.i 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。 选项“-o”是指目标…

第2章-01-网站中的资源介绍

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲。 🎉欢迎 👍点赞✍评论⭐收…