细说STM32F407单片机轮询方式CAN通信

news2025/1/7 4:59:44

目录

一、项目介绍

二、项目配置

1、时钟、DEBUG、USART6、NVIC、GPIO、CodeGenerator

2、CAN1

(1)Bit Timings Parameters组,位时序参数

(2)Basic Parameters组,基本参数

(3)Advanced Parameters组,高级参数

三、软件设计

1、KEYLED

2、can.h

3、can.c

4、main.c 

四、下载与调试 


        本文旨在以案例说明STM32F407单片机轮询方式CAN通信的方法。本文仍然使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。需要参考本文作者的其他文章:

        参考文章1:细说STM32F407单片机轮询方式读写SPI FLASH W25Q16BV_stm32f407 spiflash驱动程序-CSDN博客  https://wenchm.blog.csdn.net/article/details/144587209

        参考文章2:细说STM32F407单片机CAN基础知识及其HAL驱动程序-CSDN博客  https://wenchm.blog.csdn.net/article/details/144769950

一、项目介绍

        本文实例的动作说明:使用开发板上的按键S2、S3,按下S2后,发送一个数据帧,按下S3后,发送一个遥控帧。开发板上的LED1、LED2,依次响应按键的动作。按下S6后,开发板复位。

[S2]KeyUp  = Send a Data Frame.   LED1 ON
[S3]KeyDown= Send a Remote Frame. LED2 ON

        示例还有以下功能:

  • 使用CAN测试模式中的回环模式,进行自发自收的测试。
  • 设置筛选器组,只接收消息ID为奇数的消息。
  • 使用轮询方式接收数据。

        开发板上CAN收发器型号是VD230。相关跳线的操作在这里省略10000字。有关CAN的原理图如下:

二、项目配置

1、时钟、DEBUG、USART6、NVIC、GPIO、CodeGenerator

        与参考文章1相同或近似。其中的时钟在本例中,HCLK=100MHz,PCLK1=25MHz,PCLK2=50MHz。

2、CAN1

CAN1的参数设置分为3个部分:

(1)Bit Timings Parameters组,位时序参数

        位时序和波特率的原理详见参考文章2,这里设置的参数如下:

  • Prescaler,预分频系数,这里设置为5,可设置范围是1~1024。CAN1的时钟频率f_{CAN}由PCLK1经过分频后得到,本例中PCLK1=25MHz,经过5分频后,f_{CAN}=5MHz。
  • Time Quantum,时间片。在设置预分频系数后,时间片会被自动计算:tq=1/(5×1000000)=200ns。
  • Time Quantam in Bit Segment 1,位段1的时间片个数为m,范围为1~16,本例设置为4。
  • Time Quantam in Bit Segment 2,位段2的时间片个数为n,范围为1~8,本例设置为3。
  • ReSynchronization Jump Width(SJW),再同步跳转宽度,设置范围为1~4,本例设置为1。CAN通信的波特率由同步段、BS1、BS2的时间片个数决定,波特率计算公式如下:Baudrate=1/(1+m+n)=1s/(8×200ns)=625kbit/s。

        注意,STM32F407的CAN控制器在闭环CAN网络中波特率范围是125kbit/s~1Mbit/s,如果计算的实际波特率不在这个范围内,则需要调整分频系数或各位段的时间片个数。 

(2)Basic Parameters组,基本参数

        基本参数与CAN主控制寄存器CAN_MCR中的一些位对应,对CAN模块的一些特性进行设置。

  • Time Triggered Communication Mode(TTCM位),时间触发通信模式。设置为Disable表示禁止时间触发通信模式,若启用TTCM,则在发送或接收消息时,会加上一个内部计数器的计数值。
  • Automatic Bus-Off Management(ABOM位),自动的总线关闭管理。设置为Disable表示不使用自动的总线关闭。
  • Automatic Wake-Up Mode(AWUM位),自动唤醒模式。这个参数用于控制CAN模块在睡眠模式下接收消息时的行为,如果设置为Enable,则表示只要接收消息,就通过硬件自动退出睡眠模式。
  • Automatic Retransmission(NART位),自动重发。若设置为Enable,CAN模块将自动重发消息,直到发送成功为止。若设置为Disable,则无论发送结果如何,消息只发送一次。这个设定值实际是对NART位值取反,因为NART表示禁止自动重发。
  • Receive Fifo Locked Mode(RFLM位),接收FIFO锁定模式。若设置为Disable,表示FIFO上溢不锁定,下一条新消息覆盖前一条消息。若设置为Enable,则表示上溢后锁定,丢弃下一条新消息。
  • Transmit Fifo Priority(TXFP位),发送FIFO优先级。若设置为Disable,表示消息优先级由标识符决定;若设置为Enable,表示优先级由请求顺序决定。

(3)Advanced Parameters组,高级参数

  • Operating Mode,用于设置CAN模块的工作模式,有4种工作模式可选,即正常(Normal)、静默(Silent)、回环(Loopback)、回环静默(Loopback combined with Silent)。其中,后3种是CAN模块的测试模式。本例设置为Loopback,使用其自发自收功能进行CAN收发功能的测试。

        本例使用轮询方式测试CAN模块的数据发送和接收功能,所以不开启CAN1的任何中断。

三、软件设计

1、KEYLED

        本例的项目中要使用KEYLED,其中的keyled.c和keyled.h的使用方法与参考文章1相同。

2、can.h

/* USER CODE BEGIN Prototypes */
HAL_StatusTypeDef CAN_SetFilters();
void CAN_TestPoll(uint8_t msgID,uint8_t frameType);
/* USER CODE END Prototypes */

3、can.c

/* USER CODE BEGIN 0 */
#include <stdio.h>
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
//设置筛选器,要在完成CAN初始化之后调用此函数
HAL_StatusTypeDef CAN_SetFilters()
{
	CAN_FilterTypeDef canFilter;//筛选器结构体变量

 // Configure the CAN Filter
	canFilter.FilterBank = 0;	//筛选器组编号
	canFilter.FilterMode = CAN_FILTERMODE_IDMASK;	//ID掩码模式
	canFilter.FilterScale = CAN_FILTERSCALE_32BIT;	//32位长度

//设置1:接收所有帧
//	canFilter.FilterIdHigh = 0x0000;		//CAN_FxR1 的高16位
//	canFilter.FilterIdLow = 0x0000;			//CAN_FxR1 的低16位
//	canFilter.FilterMaskIdHigh = 0x0000;	//CAN_FxR2 的高16位,所有位任意
//	canFilter.FilterMaskIdLow = 0x0000;		//CAN_FxR2 的低16位,所有位任意

//设置2:只接收stdID为奇数的帧
	canFilter.FilterIdHigh = 0x0020;		//CAN_FxR1 的高16位
	canFilter.FilterIdLow = 0x0000;			//CAN_FxR1 的低16位
	canFilter.FilterMaskIdHigh = 0x0020;	//CAN_FxR2 的高16位
	canFilter.FilterMaskIdLow = 0x0000;		//CAN_FxR2 的低16位

	canFilter.FilterFIFOAssignment = CAN_RX_FIFO0;		//应用于FIFO0
	canFilter.FilterActivation = ENABLE;	//使用筛选器
	canFilter.SlaveStartFilterBank = 14;	//从CAN控制器筛选器起始的Bank

	HAL_StatusTypeDef result=HAL_CAN_ConfigFilter(&hcan1,&canFilter);
	return result;
}

void CAN_TestPoll(uint8_t msgID, uint8_t frameType)
{
//1. 要发送的数据
	uint8_t TxData[8];	//发送数据缓存区,最多8字节
	TxData[0]=msgID;
	TxData[1]=msgID+11;

	CAN_TxHeaderTypeDef TxHeader;	//发送消息的结构体变量
	TxHeader.StdId = msgID;			//stdID
	TxHeader.RTR = frameType;		//数据帧或遥控帧,CAN_RTR_DATA或CAN_RTR_REMOTE
	TxHeader.IDE = CAN_ID_STD;		//标准格式
	TxHeader.DLC = 2;   			//数据字节数
	TxHeader.TransmitGlobalTime = DISABLE;//禁用时间戳

	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) < 1) {
	} //等待有可用的发送邮箱

	uint32_t TxMailbox;				//临时变量,用于返回使用的邮箱编号
	/* 将消息发送到邮箱 */
	if(HAL_CAN_AddTxMessage(&hcan1,&TxHeader,TxData,&TxMailbox) != HAL_OK)
	{
		printf("Transmit error.\r\n");
		return;
	}
	printf("Send MsgID= %X\r\n",msgID);

//2. 轮询方式接收消息
	/* 等待邮箱发送完毕,也就是等待空闲邮箱个数恢复为3 */
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) {
	}

	CAN_RxHeaderTypeDef RxHeader;	//接收消息的结构体变量
	uint8_t             RxData[8]; 	//接收数据缓存区

	HAL_Delay(1);
	if(HAL_CAN_GetRxFifoFillLevel(&hcan1,CAN_RX_FIFO0) != 1)
	{
		printf("Message is not received.\r\n");
		return;
	}
	printf("Message is received.\r\n");
	if(HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&RxHeader,RxData) == HAL_OK)
	{
		printf("StdID= %lX\r\n",RxHeader.StdId);
		printf("RTR(0=Data,2=Remote)= %lX\r\n",RxHeader.RTR);
		printf("IDE(0=Std,4=Ext)= %lX\r\n",RxHeader.IDE);
		printf("DLC(Data length)= %lX\r\n",RxHeader.DLC);
		//数据帧,显示数据内容,遥控帧没有数据
		if (TxHeader.RTR == CAN_RTR_DATA)
		{
			printf("Data[0]= %X\r\n",RxData[0]);
			printf("Data[1]= %X\r\n",RxData[1]);
		}
	}
}
/* USER CODE END 1 */

        在文件can.h中有两个自定义函数,其中函数CAN_SetFilters()用于筛选器设置。

4、main.c 

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
  printf("Demo18_1_CAN:CAN Polling.\r\n");
  printf("Test mode:Loopback.\r\n");
  if (CAN_SetFilters() == HAL_OK)   //设置筛选器
  	printf("ID Filter: Only Odd IDs.\r\n");
  if (HAL_CAN_Start(&hcan1) == HAL_OK)  //启动CAN1模块
	printf("CAN is started.\r\n");

  printf("[S2]KeyUp  = Send a Data Frame.\r\n");
  printf("[S3]KeyDown= Send a Remote Frame.\r\n");

  // MCU output low level LED light is on
  LED1_OFF();
  LED2_OFF();
  /* USER CODE END 2 */
 /* USER CODE BEGIN WHILE */
  uint8_t msgID=1;
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);

	if (curKey==KEY_UP)
	{
		CAN_TestPoll(msgID++,CAN_RTR_DATA);	  //发送数据帧
		LED1_ON();
		LED2_OFF();
	}
	else if (curKey==KEY_DOWN)
	{
		CAN_TestPoll(msgID++,CAN_RTR_REMOTE); //发送遥控帧
		LED1_OFF();
		LED2_ON();
	}
	printf("** Reselect menu or reset **\r\n");
	HAL_Delay(500);
  }
  /* USER CODE END 3 */

        在进入while循环之前,显示了菜单提示信息。

        在while()循环中,检测按键输入,当KeyUp键按下时,调用函数CAN_TestPoll()测试发送数据帧,当KeyDown键按下时,调用函数CAN_TestPoll()测试发送遥控帧。函数CAN_TestPoll()是在文件can.c中实现的自定义函数。 函数CAN_TestPoll()用于测试CAN1模块在轮询方式下的数据发送和接收。

/* USER CODE BEGIN 4 */

//串口打印
int __io_putchar(int ch)
{
	HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);
	return ch;
}
/* USER CODE END 4 */

四、下载与调试 

        下载后,自动显示:

        按下S2键,可以按下多次: 

        按下S3键,可以按下多次: 

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

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

相关文章

linux装git

前言 以 deepin 深度系统为例&#xff0c;安装命 令行版 Git 非常简单。 安装 注意&#xff1a;需要输入账号密码&#xff0c;否则无法进行。 打开终端&#xff0c;执行如下命令即可。 sudo apt-get install git成功 如下图所示&#xff0c;输入 git &#xff0c;命令识别即…

微信小程序滑动解锁、滑动验证

微信小程序简单滑动解锁 效果 通过 movable-view &#xff08;可移动的视图容器&#xff0c;在页面中可以拖拽滑动&#xff09;实现的简单微信小程序滑动验证 movable-view 官方说明&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/component/movable-view.ht…

Kerberos用户认证-数据安全-简单了解-230403

hadoop安全模式官方文档&#xff1a;https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/SecureMode.html kerberos是什么 kerberos是计算机网络认证协议&#xff0c;用来在非安全网络中&#xff0c;对个人通信以安全的手段进行身份认证。 概念&#…

大麦抢票科技狠活

仅供学习参考&#xff0c;切勿再令您所爱的人耗费高昂的价格去购置黄牛票 ⚠️核心内容参考: 据悉&#xff0c;于购票环节&#xff0c;大麦凭借恶意流量清洗技术&#xff0c;于网络层实时甄别并阻拦凭借自动化手段发起下单请求的流量&#xff0c;强化对刷票脚本、刷票软件以及…

光伏电站的成本估算方式

绿虫仿真设计软件的成本估算功能主要通过以下方式实现&#xff1a; 依据设计方案自动生成材料清单&#xff1a;软件能够根据光伏项目的具体设计&#xff0c;确定所需的各种材料&#xff0c;如光伏组件、逆变器、线缆等。结合市场价格信息&#xff1a;它可以获取实时的市场价格…

结构生物学1-绪论:

请结合图片&#xff0c;详细解释图片中的内容&#xff0c;要求逻辑清晰&#xff0c;并给出整理与答疑1&#xff0c;x射线衍射&#xff1a; 1. X射线与光学显微镜的基本原理对比 X射线的特性&#xff1a;为了解析大约1-5埃&#xff08;0.1-0.5纳米&#xff09;的细小原子结构&…

yolo小damo合集

效果如下&#xff1a;这个是图片检测 效果如下&#xff1a;这个是视频检测 效果如下&#xff1a;这个是摄像头检测 1 相关库 除了yolov11所用库之外&#xff0c;本文所用到的额外库为pyqt5&#xff0c;输入指令进行安装 pip install pyqt5 导入所需要的库 import sys fro…

商标名称仅由常见姓氏构成,缺显驳回!

近日一个江苏网友给普推知产商标老杨发过来的一个商标驳回案例&#xff0c;商标驳回的原因与第一次驳回引证的商标居然是不一样的&#xff0c;引证的商标与第一次引证的商标也是不一样的。 看了下引证的两个商标与申请商标名称明显不太近似&#xff0c;或许还有做复审的机会&am…

Rockect基于Dledger的Broker主从同步原理

1.前言 此文章是在儒猿课程中的学习笔记&#xff0c;感兴趣的想看原来的课程可以去咨询儒猿课堂 这篇文章紧挨着上一篇博客来进行编写&#xff0c;有些不清楚的可以看下上一篇博客&#xff1a; RocketMQ原理简述&#xff08;二&#xff09;-CSDN博客 2.Broker的高可用 如果…

深入Android架构(从线程到AIDL)_08 认识Android的主线程

目录 3、 认识Android的主线程(又称UI线程) 复习&#xff1a; 各进程(Process)里的主线程​编辑 UI线程的责任&#xff1a; 迅速处理UI事件 举例 3、 认识Android的主线程(又称UI线程) 复习&#xff1a; 各进程(Process)里的主线程 UI线程的责任&#xff1a; 迅速处理UI事…

个人博客自我介绍

你好&#xff0c;我是Chiawei&#xff01; 大家好&#xff0c;我是Chiawei&#xff0c;一个热爱编程和探索新知识的人。很高兴能在这里与大家分享我的编程之旅。今天&#xff0c;我想和大家聊聊我的自我介绍、编程目标、学习计划以及一些个人想法。 自我介绍 我是一个对技术充…

logback之自定义过滤器

logback有两种过滤器&#xff0c;一种是context中的过滤器叫TurboFilter&#xff0c;是一个全局的过滤器&#xff0c;会影响所有的日志记录。另一种是Appender中的过滤器&#xff0c;只对所在的append有效。两者大同小异&#xff0c;这里我们以Appender的过滤器为例。 &#x…

AcWing练习题:面积

给定三个浮点数 A&#xff0c;B 和 C。 然后&#xff0c;计算如下图形的面积&#xff1a; 底边为 A&#xff0c;高为 C 的三角形。半径 C 的圆。&#xff08;π3.14159&#xff09;底边为 A 和 B&#xff0c;高为 C 的梯形。边长为 B 的正方形。边长为 A 和 B 的长方形。 输…

三甲医院等级评审八维数据分析应用(一)--组织、制度、管理可视化篇

一、引言 1.1 研究背景与意义 在当今医疗领域,三甲医院作为医疗服务的核心载体,肩负着保障民众健康、推动医学进步的重任。随着信息技术的飞速发展,数据已成为医院运营管理、医疗质量提升以及科学决策的关键要素。三甲医院等级评审作为衡量医院综合实力与服务水平的重要标…

Spring Bean的初始化过程是怎么样的?

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ Spring Bean 的初始化过程主…

快速上手LangChain(四)LangChain Hub和LangSmith

文章目录 快速上手LangChain&#xff08;四&#xff09;LangChain Hub和LangSmith什么是LangChain HubLangChain Hub功能 LangSmith使用 快速上手LangChain&#xff08;四&#xff09;LangChain Hub和LangSmith 什么是LangChain Hub LangChain Hub官网地址&#xff1a;https:…

无人机遥控器频率解析!

1.4GHz无人机遥控器工作核心技术 传输距离&#xff1a;1.4GHz频率的无人机遥控器具有较远的传输距离&#xff0c;这使得无人机可以在较大范围内与地面控制站或其他通信节点进行可靠的通信。这种特性特别适用于需要覆盖较大区域的任务或远距离飞行的场景。 穿透力&#xff1a;…

TypyScript从入门到精通

TypyScript从入门到精通 TypyScript 是什么&#xff1f;增加了什么环境搭建二、为何需要 TypeScript三、编译 TypeScript四、类型声明五、类型推断基本类型六、类型总览JavaScript 中的数据类型TypeScript 中的数据类型1. 上述所有 JavaScript 类型2. 六个新类型&#xff1a;3.…

RabbitMq的Java项目实践

在现代软件开发中&#xff0c;消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;作为一种重要的组件&#xff0c;承担着上下游消息传递和通信的重任。RabbitMQ作为一款流行的开源消息队列中间件&#xff0c;凭借其高可用性、可扩展性和易用性等特点&#xff0c…

CK40N或CK24标准成本发布出现标记不到物料的情况:评估视图中允许的成本核算变式选择错误

用户打电话反馈标准成本发布在标记环节出现错误&#xff1a; 检查&#xff1a; 1、MM03已经维护了税价1。 2、CK13N&#xff1a; 没有成本没本滚算。 用户是用CK40N处理的&#xff0c; 我让他用CK11N/CK24再处理一次。 仍然报错. 我也试了一个也是报错。 准备CRK1删除原来的…