STM32F103ZET6_HAL_CAN

news2025/4/8 9:45:35

1定义时钟

2定义按键

按键上拉电阻

3开启串口

4打开CAN(具体什么意思上一篇讲了)

5生成代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
 *       CAN 发送一组数据
 *  	数据  长度
 */
uint8_t can_send_msg(  uint8_t *data, uint8_t len )
{
    //发的结构体
		CAN_TxHeaderTypeDef can_tx;

		can_tx.DLC=len;         // 数据长度代码
		can_tx.ExtId=0x00;// 扩展标识符
		can_tx.IDE=CAN_ID_EXT;// 标识符类型为扩展帧                            //标识符的长度
		can_tx.RTR=CAN_RTR_DATA;// 远程传输请求为数据帧
		can_tx.StdId=0x12;// 标准标识符                                           //can的ID
		//can_tx.TransmitGlobalTime=ENABLE;// 使用全局时间    ENABLE开启   DISABLE关闭   时间戳
	
		uint32_t as=CAN_TX_MAILBOX0;
	if(HAL_CAN_AddTxMessage(&hcan,&can_tx,data,&as)==HAL_OK){
				
				int as1=HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
				char aa[28];
				sprintf(aa,"数据发送成功,邮箱个数为:%d\n",as1);
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,27,50);
				
			}
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3); /* 等待发送完成,所有邮箱为空 */
    return 0;
}

/**
 *        CAN 接收数据查询
	//    数据
 */
void can_receive_msg(  uint8_t *data )
{
   //接收的结构体
		// 声明一个变量来存储接收到的消息的头部信息
		CAN_RxHeaderTypeDef can_rx;
 
		//can_rx.DLC			// 数据长度
		//can_rx.ExtId				//扩展标识符
		//can_rx.FilterMatchIndex// 过滤器匹配索引
		//can_rx.IDE			// 标识符类型为扩展帧
		//can_rx.RTR			// 远程传输请求为数据帧
		//can_rx.StdId;			// 标准标识符
		//can_rx.Timestamp	;	// 时间戳
		
		if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &can_rx, data)== HAL_OK)
				{
				char aa[28]={"接收成功\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
				}else{
					
				char aa[28]={"接收失败\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
				}
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  
    CAN_FilterTypeDef sFilterConfig;

    //配置CAN过滤器
    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.FilterFIFOAssignment = CAN_FILTER_FIFO0;    /* 过滤器0关联到FIFO0 */
    sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig.SlaveStartFilterBank = 14;

    // 过滤器配置 
    if ( HAL_CAN_ConfigFilter( &hcan, &sFilterConfig ) != HAL_OK )
    {
        return 2;
    }

    // 启动CAN外围设备 
    if ( HAL_CAN_Start( &hcan ) != HAL_OK )
    {
        return 3;
    }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)== GPIO_PIN_SET){
		 HAL_Delay(20);
		 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==HAL_OK){
			char a[]={"按键按下了\n"};
			HAL_UART_Transmit(&huart1,(uint8_t*)a,11,50);
		
			uint8_t tx_data[8] = {"ABCDEFGH"}; // 消息数据

			 uint8_t rx_data[8]; // 接收数据缓冲区
	
			can_send_msg(  tx_data, 8 );
			
			if(HAL_CAN_GetRxFifoFillLevel(&hcan ,CAN_RX_FIFO0)){
				can_receive_msg(  rx_data );
			}else{
				char aa[28]={"无数据\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
			}

			HAL_Delay(500);
			HAL_UART_Transmit(&huart1,rx_data,8,500);
		}
	 }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

6编写过程

1编写接收函数

**
 *        CAN 接收数据查询
	//    数据
 */
void can_receive_msg(  uint8_t *data )
{
   //接收的结构体
		// 声明一个变量来存储接收到的消息的头部信息
		CAN_RxHeaderTypeDef can_rx;
 
		//can_rx.DLC			// 数据长度
		//can_rx.ExtId				//扩展标识符
		//can_rx.FilterMatchIndex// 过滤器匹配索引
		//can_rx.IDE			// 标识符类型为扩展帧
		//can_rx.RTR			// 远程传输请求为数据帧
		//can_rx.StdId;			// 标准标识符
		//can_rx.Timestamp	;	// 时间戳
		
		if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &can_rx, data)== HAL_OK)
				{
				char aa[28]={"接收成功\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
				}else{
					
				char aa[28]={"接收失败\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
				}
}

2编写发送函数

/**
 *       CAN 发送一组数据
 *  	数据  长度
 */
uint8_t can_send_msg(  uint8_t *data, uint8_t len )
{
    //发的结构体
		CAN_TxHeaderTypeDef can_tx;

		can_tx.DLC=len;         // 数据长度代码
		can_tx.ExtId=0x00;// 扩展标识符
		can_tx.IDE=CAN_ID_EXT;// 标识符类型为扩展帧                            //标识符的长度
		can_tx.RTR=CAN_RTR_DATA;// 远程传输请求为数据帧
		can_tx.StdId=0x12;// 标准标识符                                           //can的ID
		//can_tx.TransmitGlobalTime=ENABLE;// 使用全局时间    ENABLE开启   DISABLE关闭   时间戳
	
		uint32_t as=CAN_TX_MAILBOX0;
	if(HAL_CAN_AddTxMessage(&hcan,&can_tx,data,&as)==HAL_OK){
				
				int as1=HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
				char aa[28];
				sprintf(aa,"数据发送成功,邮箱个数为:%d\n",as1);
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,27,50);
				
			}
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3); /* 等待发送完成,所有邮箱为空 */
    return 0;
}

3配置过滤器(不配置不可接收数据

  
    CAN_FilterTypeDef sFilterConfig;

    //配置CAN过滤器
    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.FilterFIFOAssignment = CAN_FILTER_FIFO0;    /* 过滤器0关联到FIFO0 */
    sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig.SlaveStartFilterBank = 14;

    // 过滤器配置 
    if ( HAL_CAN_ConfigFilter( &hcan, &sFilterConfig ) != HAL_OK )
    {
        return 2;
    }

    // 启动CAN外围设备 
    if ( HAL_CAN_Start( &hcan ) != HAL_OK )
    {
        return 3;
    }

4编写按键实现收发数据

while (1)
  {
	  if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)== GPIO_PIN_SET){
		 HAL_Delay(20);
		 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==HAL_OK){
			char a[]={"按键按下了\n"};
			HAL_UART_Transmit(&huart1,(uint8_t*)a,11,50);
		
			uint8_t tx_data[8] = {"ABCDEFGH"}; // 消息数据

			 uint8_t rx_data[8]; // 接收数据缓冲区
	
			can_send_msg(  tx_data, 8 );
			
			if(HAL_CAN_GetRxFifoFillLevel(&hcan ,CAN_RX_FIFO0)){
				can_receive_msg(  rx_data );
			}else{
				char aa[28]={"无数据\n"};
				HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);
			}

			HAL_Delay(500);
			HAL_UART_Transmit(&huart1,rx_data,8,500);
		}
	 }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

效果

注意

1过滤器

主页中有免费的CAN资料和项目文件

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

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

相关文章

vue+elementplus模拟“山野愚人居”简单实现个人博客

目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客:山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…

RedHat8.4离线升级内核(漏洞编号CVE-2024-1086)

一、背景 针对Linux内核提取权限漏洞 (漏洞编号CVE-2024-1086),整理离线环境的修复方案。本文以离线修复方案为主进行说明,第八章对在线修复方案进行说明。 (一) 漏洞简介 近日,绿盟科技CERT监测网上有研究员公开披露了一个Lin…

解决electron设置透明背景后,引入element-plus样式问题

首先给当前窗口设置自定义窗口以及背景色。 const mainWindow new BrowserWindow({width: 900,height: 670,show: false,autoHideMenuBar: true,...(process.platform linux ? { icon } : {}),webPreferences: {preload: join(__dirname, ../preload/index.js),sandbox: fal…

问题:棕色试剂瓶用于盛装见光易分解的试剂或溶剂。 #其他#学习方法#微信

问题:棕色试剂瓶用于盛装见光易分解的试剂或溶剂。 A、正确 B、错误 参考答案如图所示

高创新 | CEEMDAN-VMD-BiLSTM-Attention双重分解+双向长短期记忆神经网络+注意力机制多元时间序列预测

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 高创新 | CEEMDAN-VMD-BiLSTM-Attention双重分解双向长短期记忆神经网络注意力机制多元时间序列预测 本文提出一种基于CEEMDAN 的二次分解方法,通过样本熵重构CEEMDAN 分解后的序列,复…

【iOS】KVC相关总结

目录 1. 什么是KVC?2. 访问对象属性常用方法声明基础使用KeyPath路径多值操作 3. 访问集合属性4. 集合运算符自定义集合运算符 5. 非对象值处理访问基本数据类型访问结构体 6. 属性验证7. 设值和取值原理基本的Getter搜索模式基本的Setter搜索模式NSMutableArray搜索…

webpack代码分割

webpack代码分割方式 entry配置:通过多个 entry 文件来实现动态加载(按需加载):通过主动使用import来动态加载抽取公共代码:使用splitChunks配置来抽取公共代码 基础概念 概念含义Entry入口,Webpack 执行构建的第一步将从 Entr…

vue 中多个表单元素控一个校验规则

1. 场景一 <el-form-itemlabel"确认时长方式"prop"preSubResourceDurationDay" ><div class"confirmDurationDay">最晚使用日期前<el-input-numberv-model"form.preSubResourceDurationDay":precision"0"cla…

vue.js有哪几种甘特图库?Vue.js的5大甘特图库分享!

vue.js有哪几种甘特图库?Vue.js的5大甘特图库分享&#xff01; 如今&#xff0c;软件市场为任何复杂程度的项目提供了各种现成的计划和调度工具&#xff0c;但这些解决方案可能包含过多的功能或缺乏一些必要的功能。这就是为什么许多公司更愿意投资开发基于网络的定制解决方案…

嵌入式实训day3

1、 planet_list["水星","金星","火星","木星"] print(planet_list)planet_list.insert(2,"地球") print(planet_list)planet_list.append("土星") planet_list.append("天王星") planet_list.append(&…

web刷题记录(6)

题 [GXYCTF 2019]BabyUpload 文件上传&#xff0c;先传个普通的一句话木马试试 &#xff0c;发现提示被限制了&#xff0c;文件后缀不可以有ph&#xff0c;那么php3,php5,phtml等后缀自然无法使用了 那这里的思路我觉得应该是&#xff0c;先判断到底是文件内容被黑名单了&…

6.13--CSS

行内样式 <!DOCTYPE html> <html lang"en"> <head> <title>This is title</title> </head> <body> <p style"font-size: 16px; color: red;">大家好</p> </body> </html> 内部样式表…

讯飞有一个可以根据描述文本自动生成PPT的AI接口,有趣

文档&#xff1a;https://www.xfyun.cn/doc/spark/PPTGeneration.html 价格方面提供了免费1000点的额度&#xff0c;生成一次是10点&#xff0c;正好100次&#xff0c;如果要购买的话最低要购买1344元的&#xff0c;没有按量付费的模式&#xff0c;个人小开发者可买不起。 让我…

【灵动之链】打造高效处理架构的双轨组合模式实战

文章目录 打造高效处理架构的双轨组合模式实战目标概述场景一&#xff1a; 注解驱动的Chain设计说明 场景二&#xff1a;工作流调度 - List与Set注入的Chain设计说明 总结 打造高效处理架构的双轨组合模式实战 目标概述 本教程旨在阐述两种不同的组合模式实现方式&#xff0c;…

【计算机毕业设计】258基于微信小程序的课堂点名系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

MathWorks的介绍,以及Simscape 的主要特点

MathWorks 是一家美国的软件公司&#xff0c;以其科学计算软件为广泛知名&#xff0c;特别是 MATLAB 和 Simulink。这两款产品广泛用于工程、科学研究、学术界和工业应用中&#xff0c;帮助用户进行数学计算、算法开发、数据可视化、数据分析&#xff0c;以及仿真和模型构建。 …

前缀和(一维前缀和+二维前缀和)

前缀和 定义&#xff1a; 前缀和是指某序列的前n项和&#xff0c;可以把它理解为数学上的数列的前n项和&#xff0c;而差分可以看成前缀和的逆运算。合理的使用前缀和与差分&#xff0c;可以将某些复杂的问题简单化。 用途&#xff1a; 前缀和一般用于统计一个区间的和&…

GoldWave 6.80最新版软件安装包下载+详细安装步骤

​GoldWave是一款易上手的专业级数字音频编辑软件&#xff0c;从最简单的录制和编辑到最复杂的音频处理&#xff0c;恢复&#xff0c;增强和转换&#xff0c;它可以完成所有工作&#xff0c;包括WAV、OGG、VOC、 IFF、AIFF、 AIFC、AU、SND、MP3、 MAT、 DWD、 SMP、 VOX、SDS、…

【Intel CVPR 2024】通过图像扩散模型生成高质量360度场景,只需要一个语言模型

在当前人工智能取得突破性进展的时代&#xff0c;从单一输入图像生成全景场景仍是一项关键挑战。大多数现有方法都使用基于扩散的迭代或同步多视角内绘。然而&#xff0c;由于缺乏全局场景布局先验&#xff0c;导致输出结果存在重复对象&#xff08;如卧室中的多张床&#xff0…

【Go】用 Go 原生以及 Gorm 读取 SQLCipher 加密数据库

本文档主要描述通过 https://github.com/mutecomm/go-sqlcipher 生成和读取 SQLCipher 加密数据库以及其中踩的一些坑 用 go 去生成读取 SQLCipher 数据库用 gorm 去读取 SQLCipher 数据库在生成后分别用 DBeaver、db browser 和 sqlcipher 读取 SQLCipher 数据库&#xff0c;…