初出茅庐的小李博客之STM32F103实现CAN通信

news2025/1/31 22:42:06

CAN通信基础知识

参考上一篇博客
https://editor.csdn.net/md/?articleId=131026450

原理图

在这里插入图片描述
转换芯片是 TJA1050

代码实现思路

发送思路:定时发送 按键测试发送
接收思路:中断接收

CAN代码实现

  • 第一步

定义了两个全局变量TxMessage和RxMessage,
分别用于发送和接收CAN消息的邮箱结构体。


CanTxMsg TxMessage = {0};//发送邮箱结构体
CanRxMsg RxMessage = {0};//接收邮箱结构体

  • 第二步

配置对应的引脚模式
通过GPIO_InitTypeDef结构体初始化了GPIOA的引脚12,配置为复用推挽输出。接着,初始化了引脚11,配置为浮空输入。

CAN_RX的模式

对于CAN接收引脚,可以选择使用浮空输入模式或上拉输入模式,具体取决我们硬件设计和应用要求。

浮空输入模式(Floating Input)是指将引脚置为高阻态,不连接到任何电平源,允许外部信号自由驱动引脚电平。在CAN总线中,通常使用终端电阻(通常为120欧姆)来驱动CAN引脚电平。这样可以确保在总线空闲状态时,引脚电平为高阻态。

上拉输入模式(Pull-up Input)是指在引脚和VDD之间连接一个上拉电阻,将引脚电平拉高到VDD(逻辑高电平)或外部信号源。在CAN总线中,上拉输入模式可用于引脚电平的恢复和传输。

选择浮空输入模式还是上拉输入模式取决于具体应用的要求。通常,如果CAN总线上的其他设备已经提供了终端电阻,可以选择使用浮空输入模式。如果的硬件设计中没有终端电阻,您可以选择使用上拉输入模式,并使用外部上拉电阻将引脚电平拉高到逻辑高电平。

CAN_TX的模式

在CAN通信中,CAN_TX模式是用于配置CAN发送引脚的模式。选择适当的CAN_TX模式取决于我们的硬件设计和应用需求。

常见的CAN_TX模式有以下两种:

  1. 推挽输出模式(Push-Pull Output):在该模式下,CAN发送引脚被配置为推挽输出,可以提供较高的驱动能力,能够输出高电平和低电平两种电平状态。这种模式适用于直接驱动总线上的终端电阻,提供较强的信号驱动能力。

  2. 开漏输出模式(Open-Drain Output):在该模式下,CAN发送引脚被配置为开漏输出,只能提供低电平输出,而高电平状态是通过外部上拉电阻拉高到逻辑高电平。这种模式适用于与其他设备共享总线的情况,需要使用外部上拉电阻来拉高总线电平。

选择CAN_TX模式取决于我们的硬件设计和连接配置。如果我们的硬件设计中包含终端电阻,并且CAN总线上没有其他设备需要共享总线,您可以选择推挽输出模式。如果我们的硬件设计中没有终端电阻或需要与其他设备共享总线,则可以选择开漏输出模式。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,  ENABLE);//使能CAN1时钟


	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF_PP;	//复用推挽
	GPIO_Init(GPIOA, &GPIO_InitStructure);		//初始化IO

	GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_IN_FLOATING;//上拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化IO
  • 第三步
    配置CAN相关参数
    定义了一个CAN_InitTypeDef结构体CAN_InitStructure,用于配置CAN的工作模式和速率。在这里,设置了CAN的模式为正常模式,速率为1Mbps。同时,设置了同步跳转宽度(SJW)为1个时间单位,位时间1(BS1)为2个时间单位,位时间2(BS2)为3个时间单位,预分频器(Prescaler)为6。

通过CAN_Init函数对CAN进行初始化,传入了上述配置结构体。

然后,定义了一个CAN_FilterInitTypeDef结构体CAN_FilterInitStructure,用于配置CAN的过滤器。在这里,设置了过滤器0,使用标识符屏蔽模式,并且过滤掉所有的标识符和掩码。将过滤器与FIFO0相关联,并激活过滤器。
通过CAN_FilterInit函数对CAN过滤器进行初始化,传入了上述配置结构体。

CAN_InitTypeDef   CAN_InitStructure;
	
	CAN_InitStructure.CAN_TTCM=DISABLE;						
	CAN_InitStructure.CAN_ABOM=DISABLE;						
	CAN_InitStructure.CAN_AWUM=ENABLE;						 
	CAN_InitStructure.CAN_NART=DISABLE;						 
	CAN_InitStructure.CAN_RFLM=DISABLE;						
	CAN_InitStructure.CAN_TXFP=DISABLE;						 

	CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;	         //模式设置

  //1Mbits  500K  
	CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
	CAN_InitStructure.CAN_BS1       = CAN_BS1_2tq;
	CAN_InitStructure.CAN_BS2       = CAN_BS2_3tq;      
	CAN_InitStructure.CAN_Prescaler = 6; //6分频

	CAN_Init(CAN1, &CAN_InitStructure);   

	CAN_FilterInitTypeDef    CAN_FilterInitStructure;

	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; 

	CAN_FilterInit(&CAN_FilterInitStructure);

  • 第四步

通过CAN_ITConfig函数使能CAN1的FIFO0接收中断。

然后,定义了一个NVIC_InitTypeDef结构体NVIC_InitStructure,用于配置CAN接收中断的中断优先级。在这里,设置了中断通道为USB_LP_CAN1_RX0_IRQn,主优先级为1,次优先级为0,并使能中断。

最后,在CAN_Config函数中进行了CAN总线的配置和初始化,并完成了中断的设置。

CAN接收逻辑实现

中断方式

 //CAN接收数据的函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)//查询标志位 
	{
		CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //接收信息
		
		// 打印接收到的数据
		printf("Rece CAN message: ID:0x%02X, DLC:%d, Data:", RxMessage.StdId, RxMessage.DLC);
		for(uint8_t i = 0; i < RxMessage.DLC; i++)
		{
			printf("%02X ", RxMessage.Data[i]);
		}
		printf("\n");
		//CAN_BAOWENJIANCE()
		//打印信息 串口1 串口2 printf都可以 
	
		CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0); // 清除中断标志位
	}
}

CAN发送逻辑的实现


//CAN发送数据的接口函数
uint8_t CAN_SendMessage(uint32_t StdId, uint8_t* pData, uint8_t Length)
{
	uint8_t MailBox   = 0;
	TxMessage.StdId   = StdId;
	TxMessage.ExtId   = 0x00;
	TxMessage.IDE     = CAN_ID_STD;
	TxMessage.RTR     = CAN_RTR_DATA;
	TxMessage.DLC     = Length;
	for (uint8_t i = 0; i < Length; i++)
	{
		TxMessage.Data[i] = pData[i];//发送的数据赋值
	}
	
  // 打印接发送的数据
	printf("Send CAN message: ID:0x%02X, DLC:%d, Data:", TxMessage.StdId, TxMessage.DLC);
	for(uint8_t i = 0; i < TxMessage.DLC; i++)
	{
		printf("%02X ", TxMessage.Data[i]);
	}
	printf("\n");
	
	MailBox = CAN_Transmit(CAN1, &TxMessage);
	while((CAN_TransmitStatus(CAN1, MailBox)==CAN_TxStatus_Failed));
	return TxMessage.DLC;		//返回值是发送了几个字节
}

发送信息

这是一条标准数据帧 由MCU发出

 //发送信息在这里填写
uint32_t StdId     =  0x55;//数据帧ID
uint8_t  TxData[8] =  {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};//8字节数据内容
uint8_t  Length    =  8;//发送字节个数

接收信息

这是一条标准数据帧 由在这里插入图片描述
上位机CAN调试助手发出

测试效果

在这里插入图片描述

代码演示

STM32实现CAN收发通信

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

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

相关文章

Unity如何实现Microphone判断录入音频的频率是低音还是高音

前言 Unity中使用Microphone可以通过麦克风录制AudioClip音频,我们可以通过它实现录音功能,然后可以通过录入的音频数据对音频进行分析,比如音量大小,频率高低,等等。 我们今天就来分析一下音频的高音低音。 如何判断高音低音 科普:一般人们习惯将音响划分一定的频段…

参数估计(点估计和区间估计)

参数估计&#xff08;点估计和区间估计&#xff09; 1.1 点估计 点估计的理解示意图 下图中样本均值就是对总体均值的点估计 1.1.1 矩估计 关于什么是矩&#xff1f;可以参考马同学。传送门&#xff1a;如何理解概率论中的“矩”&#xff1f; 根据大数定律&#xff0c;样本…

007: vue中修改el-select选中颜色不生效的办法

第007个 查看专栏目录: 按照VUE知识点 ------ 按照element UI知识点 echarts&#xff0c;openlayers&#xff0c;cesium&#xff0c;leaflet&#xff0c;mapbox&#xff0c;d3&#xff0c;canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏…

apm装机教程(一):无人车

文章目录 前言一、下载固件二、设置参数 前言 APM4.2.3 差速小车 pix2.4.8 MP地面站 一、下载固件 pix2.4.8使用的是fmuv3的固件&#xff0c;可以在官网上下载 https://firmware.ardupilot.org/Rover/stable-4.2.3/fmuv3/ 或者从我的网盘下载 链接&#xff1a;https://pan.b…

【算法题】面试题 01.01. 判定字符是否唯一

题目来源&#xff1a;《程序员面试金典&#xff08;第 6 版&#xff09;》 1、Problem: 面试题 01.01. 判定字符是否唯一 文章目录 面试题 01.01. 判定字符是否唯一一、题目描述二、解决方案&#xff08;一&#xff09;方案一1、解题思路2、解题方法3、复杂度4、代码实现 &…

数据分析手册-R语言

1 数据准备 1.1 数据录入 1.1.1 R中导入数据 &#xff08;1&#xff09;导入excel 1.2 修改工作路径 https://wenku.baidu.com/view/2785ff37b4360b4c2e3f5727a5e9856a561226c9.html 1.3 如何计算样本量 https://www.bilibili.com/video/BV19t411u7TW?spm_id_from333.…

亚马逊云科技Serverless构建的实时数仓解决方案,助力猎豹降低30%成本

也许你也听过这样一句话&#xff1a;“21世纪什么最贵&#xff1f;人才&#xff01;”当数字经济全面席卷而来&#xff0c;这个问题的答案不可置否地变为了“数据”。通过数据分析获取近乎实时的洞察&#xff0c;以驱动业务的全流程&#xff0c;是企业数字化转型的必经之路。借…

【网络编程】计算机网络基础知识总结 | 运输层 |TCP协议

文章目录 前言一、计算机网络层次结构二、网络层三、运输层3.1、TCP/IP协议介绍3.2、端口&#xff08;协议端口号&#xff09;3.3、套接字3.4、TCP实现原理3.4.1、TCP的特点3.4.2、停止等待协议3.4.3、滑动窗口协议3.4.4、拥塞控制3.4.5、TCP连接的三个阶段 3.5、UDP实现原理 前…

day50_mybatis

今日内容 0 复习昨日 一、分页插件 二、ORM映射【重点】 三、多表联查 【重点】 四、动态SQL 【重点】 五、$和# 零、复习昨日 mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心 思考MyBatis到底帮你省了哪些事情? jdbc第四步sql自己编写之外,其他mybatis都做了…

C++标准库模板(STL)-输入/输出库

C 包含两个输入/输出库&#xff1a;现代的、基于流的 I/O 库和 C 风格 I/O 函数的标准集合。 基于流的 I/O 基于流的输入/输出库围绕抽象的输入/输出设备组织。这些抽象设备允许相同代码处理对文件、内存流或随即进行任意操作&#xff08;例如压缩&#xff09;的自定义适配器…

编译原理 | 课程设计 — PL/0编译程序语法分析

1、任务描述 基于第二章的词法分析程序&#xff0c;使用C/C语言编写PL/0编译程序的语法分析程序。 2、编程要求 完成上述编程任务&#xff0c;将C/C语言源程序复制粘贴到右侧代码编辑器&#xff0c;点击“评测”按钮&#xff0c;运行程序&#xff0c;系统会自动进行结果对比。 …

CoreDX DDS应用开发指南(4)DDS实体h和主题

6 DDS实体 DDS标准定义了一个体系结构,该体系结构表示构成DDS API实体的面向对象模型。这些实体充当中间件和应用软件之间的接口。为了开发支持DDS的应用程序,开发人员必须创建、交互并销毁这些DDS实体。 本章概述了DDS实体和相关概念。 6.1 DDS实体层次结构 构成DDS API的主…

马斯克最大的挑战是什么?

“硅谷钢铁侠”马斯克&#xff0c;最大的挑战是什么&#xff1f; 有纠错反馈循环&#xff0c;并保持这个循环 我们常说的“迭代”&#xff0c;就是打造“反馈系统” 趣讲大白话&#xff1a;需要一面不扭曲的镜子 【趣讲信息科技192期】 **************************** 2017年&a…

通过浏览器,将webp格式图片转jpg格式

概述 我们网络上下载的图片&#xff0c;很多的是webp格式的图片&#xff0c;而目前支持这种图片格式的软件较少&#xff0c;比如Windows 照片查看器&#xff0c;是不能直接打开图片的。安装其他专业图像软件又麻烦。 因此&#xff0c;本文介绍利用电脑常用的软件&#xff0c;…

运营-20.产品社区化和内容化

产品社区化和内容化 为什么现在很多产品都在往社区化、内容化发展&#xff1f; 1.拓展产品线&#xff0c;满足用户的多元需求 分享、交流、炫耀、虚荣&#xff0c;这些是人类永恒的情感需求&#xff0c;社区是一个能很好的满足这些需求的工具&#xff1b; 2.打造归属感&…

TiDB亿级数据亚秒响应查询Dashboard使用

目录 1 集群概况1.1 QPS1.1.1 延迟1.1.2 Top SQL 语句1.1.3 最近的慢查询 2 集群信息2.1 实例列表2.1.1 表格列解释2.1.2 实例状态解释 2.2 主机列表2.2.1 表格列解释 2.3 SQL语句分析2.3.1 执行列表页2.3.2 执行详情页面 2.4 慢查询2.4.1 慢查询列表页2.4.2 查看执行详情 2.5 …

2023-06-10 Untiy进阶 C#知识补充1——.Net介绍

文章目录 一、.Net 介绍二、.Net 跨语言的实现三、.Net 跨平台的实现&#xff08;一&#xff09;.Net Framework&#xff08;二&#xff09;.Net Core&#xff08;三&#xff09;Mono 四、总结 一、.Net 介绍 ​ 微软的 .Net 既不是编程语言也不是框架&#xff0c;是类似于互联…

Tomcat部署和优化

文章目录 Tomcat概述Tomcat的核心组件Tomcat的功能组件结构Container 结构分析Tomcat 请求过程&#xff1a; Tomcat 服务部署Tomcat 虚拟主机配置HTTP 请求过程 Tomcat优化常用的优化相关参数如下 Tomcat概述 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的…

Spring高手之路4——深度解析Spring内置作用域及其在实践中的应用

文章目录 1. Spring的内置作用域2. singleton作用域2.1 singleton作用域的定义和用途2.2 singleton作用域线程安全问题 3. prototype作用域3.1 prototype作用域的定义和用途3.2 prototype作用域在开发中的例子 4. request作用域&#xff08;了解&#xff09;5. session作用域&a…

002docker 安装

官网安装https://docs.docker.com/engine/install/ 系统要求 Centos7 Linux 内核&#xff1a;官方建议 3.10 以上查看Linux内核版本 用于打印当前系统的相关信息(内核版本号,硬件架构,主机名称和操作系统类型等 cat /proc/version uname -a 更新YUM源 生产环境中此步操作…