STM32串口:DMA空闲中断实现接收不定长数据(基于HAL库)

STM32串口:DMA空闲中断实现接收不定长数据(基于HAL库):


第一步:设置rcc,时钟频率,下载方式

设置system core->RCC如图所示:(即High Speed Clock和Low Speed Clock都选择第二个)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d9fe743edf044420b825958eae1fdb65.png![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/668a5c2f7696417680d144b7be22bb71.png


设置时钟频率,我选择的是stm32f103c8t6,f1系列最大时钟频率都是72M,因此设置为72M,点击Clock Configuration选择HCLK,输入72,然后回车,确定
在这里插入图片描述
下载方式设置如下图:(我使用的方式是stlink)
在这里插入图片描述


第二步:设置串口为DMA中断发送和接受,并开启nvic,如图设置:

在这里插入图片描述
开启nvic中断:
在这里插入图片描述

添加dma发送接受通道
在这里插入图片描述

以上就是cubemx的全部设置,生成代码

第三步:代码编写:

需要写的代码,我全部写在main.c文件,需要复制的请看本文最后

接下来开始写代码逻辑,我打算写一个接受不定长数据的中断函数,然后再中断函数中再把这个数据原封不动的发送出去,以此来验证发送和接收功能是否正常

首先定义一个较大的数组来用于存放接收的数据,由于我们要用中断来接收数据的,因此要定义再main函数之外,即定义为全局变量才行:
在这里插入图片描述


然后在while循环之前加入以下内容:
在这里插入图片描述
这两行代码,第一行的作用是开启串口的dma空闲中断功能,第二行的作用是禁止dma传输过半中断,这里的dma传输过半是相对我们上一步定义的那个接受数组的总长度而言的,我定义的是100,因此只要连续接收到50个字节的数据,就会触发中断,如果连续接收的数据小于50个字节,接受空闲了,那就不会触发过半的中断,而是直接触发空闲中断。这样来看的话,这个dma传输过半中断对于我们的接受逻辑并没有太大用,因此将其禁止了!


接下来编写串口的dma空闲中断函数,它是HAL库弱定义的一个函数,我把它重写再main.c文件中,如下:
在这里插入图片描述


if里面第一行就是将接收到的数据发送出去,第二行,第三行再次重复上一步的操作具体略

整个main.c文件如下:

/* 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"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* 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 ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t r_data[100];void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)//Size参数是本次接受到的数据长度
{if(huart==&huart2){HAL_UART_Transmit_DMA(&huart2, r_data, Size);HAL_UARTEx_ReceiveToIdle_DMA(&huart2, r_data, sizeof(r_data));//重新启动接收__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);//禁止DMA传输过半中断}
}
/* 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_DMA_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_UARTEx_ReceiveToIdle_DMA(&huart2, r_data, sizeof(r_data));//设置串口接收DMA空闲中断(用于接受不定长数据)__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);//禁止DMA传输过半中断/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* 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();}
}/*** @brief USART2 Initialization Function* @param None* @retval None*/
static void MX_USART2_UART_Init(void)
{/* USER CODE BEGIN USART2_Init 0 *//* USER CODE END USART2_Init 0 *//* USER CODE BEGIN USART2_Init 1 *//* USER CODE END USART2_Init 1 */huart2.Instance = USART2;huart2.Init.BaudRate = 115200;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart2.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart2) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART2_Init 2 *//* USER CODE END USART2_Init 2 */}/*** Enable DMA controller clock*/
static void MX_DMA_Init(void)
{/* DMA controller clock enable */__HAL_RCC_DMA1_CLK_ENABLE();/* DMA interrupt init *//* DMA1_Channel6_IRQn interrupt configuration */HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);/* DMA1_Channel7_IRQn interrupt configuration */HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}/* 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 */

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

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

相关文章

ansible基础与基础命令模块

一Ansible 1. ansible 的概念 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 Ansible能批量配置、部署、…

手机群控软件开发必备源代码分享!

随着移动互联网的飞速发展,手机群控技术在市场推广、自动化测试、应用管理等领域的应用越来越广泛,手机群控软件作为一种能够同时控制多台手机设备的工具,其开发过程中,源代码的编写显得尤为重要。 1、设备连接与识别模块 设备连…

java Day7 正则表达式|异常

文章目录 1、正则表达式1.1 常用1.2 字符串匹配,提取,分割 2、异常2.1 运行时异常2.2 编译时异常2.3 自定义异常2.3.1 自定义编译时异常2.3.2 自定义运行时异常 1、正则表达式 就是由一些特定的字符组成,完成一个特定的规则 可以用来校验数据…

AHU 汇编 实验二

一、实验名称:实验二 不同寻址方式的灵活运用 二、实验内容:定义数组a[6],用多种寻址方式访问对应元素,实现(a[0]a[1])*(a[2]-a[3])/a[4],将结果保存在内存a[5]中,用debug查询结果。 实验过程&a…

压缩自定义格式压缩包<2>:python使用DEFLATE 算法打包并解压成功,但是解压后的文件格式是固定后缀。

打包 import zlib import osdef compress_folder(input_folder, output_filename):"""使用 DEFLATE 算法压缩文件夹下的所有文件。Parameters:input_folder: str要压缩的文件夹路径。output_filename: str输出压缩文件名。"""# 创建一个空的字节…

GPT与R 在生态环境领域数据统计分析

原文链接:GPT与R 在生态环境领域数据统计分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597092&idx2&sn0a7ac5cf03d37c7b4659f870a7b71a77&chksmfa823dc3cdf5b4d5ee96a928a1b854a44aff222c82b2b7ebb7ca44b27a621edc4c824115babe&…

Linux Centos系统 磁盘分区和文件系统管理 (深入理解)

CSDN 成就一亿技术人! 作者主页:点击! Linux专栏:点击! CSDN 成就一亿技术人! 前言———— 磁盘 在Linux系统中,磁盘是一种用于存储数据的物理设备,可以是传统的硬盘驱动器&am…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Progress)

进度条组件&#xff0c;用于显示内容加载或操作处理等进度。 说明&#xff1a; 该组件从API version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Progress(options: ProgressOptions<Type>) 创建进度组件&a…

【好书推荐-第十一期】《Java面试八股文:高频面试题与求职攻略一本通(视频解说版)》(博文视点出品)

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…

二,几何相交---4,BO算法---(2)比较和排序

在某一时刻xt&#xff0c;扫描线从左到右时&#xff0c;一部分线段会与扫描线相交&#xff0c;此时此刻&#xff0c;线段可以分成高低顺序&#xff0c; 那么对于给定两条线段&#xff0c;是如何变化的呢&#xff1f;有两个端点&#xff0c;左端点和右端点&#xff0c; 三种情况…

追寻工作与生活的和谐之道

在现代社会&#xff0c;人们往往被快节奏的工作和生活所困扰&#xff0c;如何在这两者之间找到平衡点&#xff0c;成为许多人关注的焦点。本文将为您介绍一些实用的方法和建议&#xff0c;帮助您实现工作与生活的和谐共处。 一、合理规划时间&#xff0c;提高工作效率 时间是实…

WorkPlus Meet提供高效、安全视频会议解决方案

WorkPlus Meet是一款私有部署和定制化的视频会议解决方案&#xff0c;为企业提供高效、安全的远程协作平台。随着全球数字化转型的加速&#xff0c;视频会议已成为企业必不可少的工作工具&#xff0c;而WorkPlus Meet的私有部署和定制化功能&#xff0c;为企业提供了更大的控制…

【MySQL系列 05】Schema 与数据类型优化

良好的数据库 schema 设计和合理的数据类型选择是 SQL 获得高性能的基石。 一、选择优化的数据类型 MySQL 支持的数据类型非常多&#xff0c;选择正确的数据类型对于获得高性能至关重要。不管存储哪种类型的数据&#xff0c;下面几个简单的原则都有助于做出更好的选择。 1. …

C语言学习-day19-函数2

自定义函数&#xff1a;自己定义的函数 以strcpy为例子&#xff1a; 自定义函数一样&#xff0c;需要函数名&#xff0c;返回值类型&#xff0c;函数参数。 函数的组成&#xff1a; ret_type fun_name(para1, *) { statement;//语句项 } ret_type 返回类型 fun_name 函数…

weiphp5.0存在远程代码执行漏洞

@[toc] 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. weiphp5.0简介 微信公众号搜索:南风漏洞复…

c++ 开发环境 LNK1104: 无法打开文件“carve.lib” 已解决

别人分享&#xff0c; 和自己最近遇到问题一摸一样。以为没什么用的静态资源&#xff0c;结果 无法编译。 昨天安装配置了&#xff0c;结果今天早上打开电脑&#xff0c;所以dll的工程全部报错&#xff1a; 1>------ 已启动全部重新生成: 项目: Dll_test, 配置: Debug x64…

pycharm中连接远程服务器

文章目录 概要文件进行映射将本地的project和远程的project进行映射&#xff0c;一定要使用sftp本地文件和远程的位置配置不想将远程的文件同步时候&#xff0c;可以进行下面设置 配置远程服务器的python解释器需要setting-->python interpreter-->add---> on ssh选择…

《Vue3 基础知识》事件总线 bus(与Vue2 有差异,使用 mitt 库)

前言 Vue2 与 Vue3 事件总线区别 Vue2 使用 $on&#xff0c;$off 和 $once 实例方法&#xff0c;创建一个事件总线&#xff0c;可在整个应用中做全局事件监听&#xff1b;Vue3 移除 $on&#xff0c;$off 和 $once 实例方法 &#xff0c;但提供了解决方案&#xff0c;使用库 m…

crossover玩不了qq游戏大厅怎么办 仍有五亿人坚持用QQ crossover玩游戏 Mac电脑玩QQ游戏

从1999年2月&#xff0c;QQ首个版本QICQ&#xff08;OPEN-ICQ&#xff09;上线。到2024年&#xff0c;靠着5亿月活用户&#xff0c;守住社交领域TOP2位置。你还记得QQ经典的铃声吗&#xff1f; 根据月狐数据2023年12月的统计&#xff0c;QQ月活跃账户数比微博和知乎加在一起还要…

分享10个ai人工智能ppt生成软件,一键轻松搞定PPT制作!

ai 人工智能发展至今&#xff0c;已经诞生了各式各样的 AI 软件&#xff0c;最常见的如 AI 写作软件、AI 绘画软件、AI 人工智能 ppt 生成器、AI 人工智能抠图软件等等。对每天要面对各类文档、演示文稿&#xff08;PPT&#xff09;的职场人来说&#xff0c;最被需要的 AI 软件…