基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据

2023-05-16

基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据


  • ✨申明:本文章仅发表在CSDN网站,任何其他网见此内容均为盗链和爬取,请多多尊重和支持原创!
  • 🍁对于文中所提供的相关资源链接将作不定期更换。
  • 📌相关参考《HAL库教程9:串口接收不定长数据》

🎉对于串口接收不定长数据的处理方案网上有很多,个人觉得采用定时器的方式最为简单,容易理解。

  • 🎬串口数据收发演示:
    在这里插入图片描述

📑原理实现:就是利用串口接收中断,来开启对应的定时器计时,只要串口有数据进来就会进入串口接收中断函数里面执行相关内容,在接收中断函数里面,提供两种方式来处理计时方法,在一定时间内没有进入串口中断,那么定时器计时就会溢出,产生定时中断,来判断一次串口数据流的接收。

  • ✨本示例基于STM32G070RBT6单片机,64MHz频率。如果匹配到不同型号的单片机需要注意在配置定时器分频参数需要根据选定的单片机主频时钟来配置。
    在这里插入图片描述

🛠在内置的STM32CubeMX配置

  • 🌿基本定时器7配置如下:
    在这里插入图片描述
    在这里插入图片描述

🍁间隔的时间常常与通信的波特率是相关的。在9600波特率下,一个字节的数据共 起始+8数据+结束=10位,一位是104us,所以一个字节的数据是1.04ms,3.5个字节,我们就认为是4ms。有时可能有校验位,稍微保险一点,5ms吧。假如使用115200的波特率,5ms已经算是非常“奢侈”了。本文使用定时器7来计时,配置的PSC为63,ARR为4999,即5ms的溢出时间。这是按传输每一位数据来设定数据超时时间的,当然你也可以将串口接收中断作为定时器开始计时起点,然后定一个固定的时长来中断串口数据流的接收,具体看使用场合。

  • 🔰如果串口接收数据频率比较高(数据流传输间隔小于500ms),那么就选择第一种方式按传输数据位来设定时长。
  • 🔰如果串口接收数据频率不是很高(大于500ms),那么就选择一个固定的时长来中断串口数据流的接收。
  • 🌴串口1配置
    在这里插入图片描述
    在这里插入图片描述

📝主程序代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 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 "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
//#include <string.h>		//包含memset清空数组函数(这里没有使用到)
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define REC_LENGTH  20		//定义接收数据长度,根据使用需求自定义
uint8_t UART1_Rx_Buf[REC_LENGTH];	//接收数据存储
uint8_t UART1_Rx_flg=0;		//定时器中断标志位
uint8_t UART1_Rx_cnt=0;		//串口接收数据下标
uint8_t Rxbuff[1]; //串口接收数据缓冲

/* 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 */

/* 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_USART1_UART_Init();
  MX_TIM7_Init();
  /* USER CODE BEGIN 2 */
  /* 初始化定时器7 */
  //   HAL_TIM_Base_Start_IT(&htim7);//可以不开启

  HAL_UART_Receive_IT(&huart1, (uint8_t *)Rxbuff,1);//打开串口中断接收

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  if(UART1_Rx_flg)//表示接收完成或超�??
	     {
	       HAL_UART_Transmit(&huart1,UART1_Rx_Buf,UART1_Rx_cnt,0xffff);    //发�?�接收到的数�?????????
	       for(int i = 0;i<UART1_Rx_cnt;i++)
	         UART1_Rx_Buf[i] = 0;
	       UART1_Rx_cnt = 0;
	       UART1_Rx_flg = 0;
	     }


  }
  /* USER CODE END 3 */
}

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

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** 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.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 16;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

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

/* USER CODE BEGIN 4 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)		//定义 USART1 接收完成回调函数功能
{
//	if(huart->Instance==USART1)
//	  {
	//	__HAL_TIM_SET_COUNTER(&htim7,0);//定时器清
		  /* Read data from the RX data register */
			//	HAL_UART_Receive_IT(&huart1,(uint8_t *)Rxbuff,1);//每接收一个数据,就打1次串口中断接收,否则只会接收1个数据就停止接收
	           if(0 == UART1_Rx_cnt)
	           {
	        	   __HAL_TIM_CLEAR_FLAG(&htim7,TIM_FLAG_UPDATE);
	        	   HAL_TIM_Base_Start_IT(&htim7);//�?启定�?
	           }
		__HAL_TIM_SET_COUNTER(&htim7,0);//清空计数�?


	        	  UART1_Rx_Buf[UART1_Rx_cnt] = Rxbuff[0];
	        	   UART1_Rx_cnt++;
	        	   HAL_UART_Receive_IT(&huart1,Rxbuff,1);

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	 if(htim==(&htim7))
	  {

	    UART1_Rx_flg = 1;
	    HAL_TIM_Base_Stop_IT(&htim7);//关闭定时
	  }
	 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
}

/* 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 */

📚程序源码

  • ✨申明:本文章仅发表在CSDN网站,任何其他网见此内容均为盗链和爬取,请多多尊重和支持原创!
  • 🍁对于文中所提供的相关资源链接将作不定期更换。

链接: https://pan.baidu.com/s/11K9jzCrRAkC18RKtvoS_CQ
提取码: rhrp
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据 的相关文章

  • 如何给服务器传输文件,给服务器传输文件

    给服务器传输文件 内容精选 换一换 公有云通常指第三方供应商为用户提供的能够通过Internet使用的云端基础设施和服务 xff0c 其核心属性是共享资源服务 华为云是公有云品牌 xff0c 在SAP系统迁移的过程中 xff0c 您可以单独
  • 服务器架设文件服务器,服务器架设文件服务器

    服务器架设文件服务器 内容精选 换一换 安装完操作系统后的临时云服务器需要进行相关配置 xff0c 并安装原生的XEN和KVM驱动 xff0c 才能保证后续创建的云服务器正常使用 该任务指导用户完成Linux云服务器的相关配置与驱动安装 x
  • 基于YOLOv3的视频中无人机的目标检测(包括CUDA等环境配置)

    在SLAM毫无建树的我又投入了深度学习的大坑 xff0c 由于项目需求需要做无人机的目标检测 xff0c 这里把搭建系统中的一些问题记录下来 xff0c 方便之后复现 系统搭建 采用YOLOv3来进行无人机的检测 xff0c yolo的安装
  • 【CAN】CAN基础概念2

    摘自VECTOR官网E Learning的资料 9 帧类型 数据帧 为传输用户数据 xff0c ISO 11898 1定义了数据帧 数据帧可以传输的最大有效负载为八个字节 xff0c 即数据场 除了数据场 xff0c 数据帧还包括执行CAN
  • 如何设计一个锂电池充电电路(TP4056)

    这个是个单节18650锂电池的充电模块 xff0c 这个是个18650的锂电池 xff0c 18指的是它的直径是18mm xff0c 65指的是它的高度为65mm 这个18650电池的标称电压是3 7V xff0c 电池充满时电压为4 2V
  • 黑马程序员C++系统班学习笔记(一)——Linux操作系统一

    黑马程序员C 43 43 系统班链接 xff1a https www bilibili com video av37403127 from 61 search amp seid 61 5509409937472093685 本笔记旨在记录学
  • ubunbtu下基于c++实现MQTT客户端通信

    文章目录 一 MQTT简介1 1 MQTT 服务器 xff08 Broker xff09 是发布 订阅架构的核心1 2 MQTT 网络协议1 3 服务质量1 4 MQTT 数据包结构1 4 1 MQTT固定头1 4 2 MQTT可变头 Va
  • python 提取页面验证码

    以下代码都使用python 43 selenium 实现 xff0c 请先搭建好开发环境 1 页面的验证码若为静态验证码可以使用截屏的方式获取代码如下 driver save screenshot 39 C crawlerScript pi
  • 基于单片机的GPS开发 (four) GPS基础知识

    一 GPS硬件模块 xff1a VCC xff1a 兼容3 3V和5V GND xff1a 地 TXD xff1a 接51单片机的RXD P3 0 RXD xff1a 可接单片机的TXD P3 1 或者直接悬空 PPS xff1a 时钟脉冲
  • 记录:C++打印堆栈信息并优化打印结果

    1 介绍打印堆栈信息函数 头文件 xff1a span class token macro property span class token directive hash span span class token directive k
  • Ubuntu “无法定位软件包”

    Ubuntu 无法定位软件包 问题描述 xff1a 在使用Ubuntu 18 0 4 安装ceres库时安装依赖项时报错 xff0c 如图所示 xff1a 原因分析 xff1a libcxsparse3 1 2软件包是Ubuntu 14 0
  • NVIDIA Jetson TX2:TX2平台介绍

    一 xff1a TX2平台概述 TX2是快速高效的嵌入式AI计算设备 低功耗 xff08 标准 xff09 模式 xff08 7 5w xff09 xff1b 高功耗模式 xff08 15w xff09 xff0c 性能是TX1的两倍 具有
  • VSCode安装配置C++开发环境

    真相需要去探寻 之前已经在VSCode上配置了Golang的开发环境 xff0c 使用起来还是十分舒服的 xff0c 特别是设置了镜像下载地址和掌握了go mod的使用 xff0c 小巧轻便 xff0c 舒爽流畅 最近要用到C 43 43
  • 图像处理的基本操作(灰度化,二值化)

    基本的概念 xff1a 图像的深度 xff1a 图像中像素点占得bit位数 xff0c 就是图像的深度 xff0c 并不是每个像素点分配了多少位内存空间 xff0c 就一定能够要用完 xff0c 深度仅仅标识用于真真能表示颜色的位数 xff
  • Ubuntu如何切换Python版本

    这几天一直在搞小米官方提供的ESP32 WiFi SDK xff0c 过程中遇到了很多坑 xff0c 其中包括Python版本兼容的问题 xff0c 我的Ubuntu 上安装的Python版本是Python3 xff0c 而脚本的使用的是p
  • C++面试宝典:__FILE__,__func__,__LINE__

    C语言中 xff0c FILE xff0c func xff0c LINE 常用于logout xff0c debug调试 注意 xff1a 其使用不需要定义 xff0c FILE 指示当前文件名 xff0c func 指示当前函数名 xf
  • C++面试宝典:头文件引用的顺序

    头文件引用的顺序 当我们有多个头文件的时候 xff0c 特定情况下要注意引用的顺序 如果要在文件a h中声明一个在文件b h中定义的变量 xff0c 而不引用b h 那么要在a cpp文件中引用b h文件 xff0c 并且要先引用b h x
  • c++部署yolov5模型

    C 43 43 部署yolov5模型 前言一 准备模型二 Fastdeploy准备三 调用总结 前言 不可否认 xff0c yolov5在目标检测方面大杀四方 xff0c 在 SOTA 榜上留下过万众瞩目的成绩 xff0c 但是官网代码给的
  • 【信息技术】【2004】基于计算机视觉的无人机自主避障系统中的目标跟踪研究

    本文为瑞典皇家理工学院 xff08 作者 xff1a Johan Driessen xff09 的硕士论文 xff0c 共68页 这篇硕士论文的目的是研究利用商用货架 COTS 硬件和免费 公开可用的计算机视觉库开发一个足够有效的实时自主避
  • 将寄存器地址设为宏对寄存器的值进行操作

    将寄存器地址设为宏 对寄存器的值进行操作 搞了半天才捋清楚 首先 定义一个指针变量 int p 再定义一个变量 int q 61 1 将指针p指向q xff1a p 61 amp q 通过指针对改变q的值 xff1a p 61 0x10 此

随机推荐