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

这篇具有很好参考价值的文章主要介绍了基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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


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

🎉对于串口接收不定长数据的处理方案网上有很多,个人觉得采用定时器的方式最为简单,容易理解。文章来源地址https://www.toymoban.com/news/detail-700813.html

  • 🎬串口数据收发演示:
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收
📑原理实现:就是利用串口接收中断,来开启对应的定时器计时,只要串口有数据进来就会进入串口接收中断函数里面执行相关内容,在接收中断函数里面,提供两种方式来处理计时方法,在一定时间内没有进入串口中断,那么定时器计时就会溢出,产生定时中断,来判断一次串口数据流的接收。
  • ✨本示例基于STM32G070RBT6单片机,64MHz频率。如果匹配到不同型号的单片机需要注意在配置定时器分频参数需要根据选定的单片机主频时钟来配置。
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收

🛠在内置的STM32CubeMX配置

  • 🌿基本定时器7配置如下:
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收
🍁间隔的时间常常与通信的波特率是相关的。在9600波特率下,一个字节的数据共 起始+8数据+结束=10位,一位是104us,所以一个字节的数据是1.04ms,3.5个字节,我们就认为是4ms。有时可能有校验位,稍微保险一点,5ms吧。假如使用115200的波特率,5ms已经算是非常“奢侈”了。本文使用定时器7来计时,配置的PSC为63,ARR为4999,即5ms的溢出时间。这是按传输每一位数据来设定数据超时时间的,当然你也可以将串口接收中断作为定时器开始计时起点,然后定一个固定的时长来中断串口数据流的接收,具体看使用场合。
  • 🔰如果串口接收数据频率比较高(数据流传输间隔小于500ms),那么就选择第一种方式按传输数据位来设定时长。
  • 🔰如果串口接收数据频率不是很高(大于500ms),那么就选择一个固定的时长来中断串口数据流的接收。
  • 🌴串口1配置
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收
    hal库接收不定长数据包,STM32CubeMX自动配置工程系列,stm32,STM32CubeIDE,串口不定长数据接收

📝主程序代码

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

到了这里,关于基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HAL STM32基于系统滴答定时器(SysTick)实现多任务时间片轮询

    📑RTOS(实时操作系统)和定时器时间片轮询是两种不同的任务调度和执行方式的差异简介 🔖 以下部分内容,由AI给出的解答: 🔖RTOS(实时操作系统): 🌿RTOS是一种专门设计用于实时系统的操作系统,它可以有效地管理多个任务,提供任务调度、同步和通信等功能。 🌿

    2024年02月21日
    浏览(47)
  • 基于HAL库的STM32的单定时器的多路输入捕获测量脉冲频率(外部时钟实现)

    目录 写在前面 一般的做法(定时器单通道输入捕获) 以外部时钟的方式(高低频都适用) 测试效果 STM32的定时器本身有输入捕获的功能。可选择双端捕获,上升沿捕获或者是下降沿捕获。对应捕获频率来说,连续捕获上升沿或下降沿的时间间隔就是其脉冲的周期. 定时器设置频率

    2024年02月08日
    浏览(48)
  • 2.基于正点原子STM32F103的定时器中断实验(HAL库实现)(cubeMX)

      基本上每一款MCU都会配备定时器这个外设,STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 同样,STM32F1系列的定时器功能也很强大,包括: TIM1和TIM8两个高级定时器; TIM2~TIM5是个通用寄存器; TIM7,TIM8,两个基本定时器。 由于本次实验适用于新手入门

    2023年04月26日
    浏览(162)
  • STM32控制步进电机:基于HAL库定时器中断的闭环步进电机驱动+精准控制脉冲数

    该篇文章中用到的步进电机闭环驱动器为Emm42_V4.0步进电机闭环驱动器。该闭环驱动器自带FOC矢量闭环控制算法,能实现力矩、速度、位置三环控制。 如下图所示,该42步进闭环电机驱动器的A+、A-、B+、B-连接步进电机,通过右侧的使能、脉冲、方向端对步进电机进行驱动控制

    2024年02月01日
    浏览(56)
  • 基于HAL库的STM32单定时器多路输入捕获测量PWM的频率和占空比实现(状态机方式实现)

    目录  写在前面 先回顾下定时器的单路捕获PWM 多路捕获PWM的频率和占空比(状态机实现) 我的思路: 状态图 配置 给出示例代码 测试效果         先有了这篇文章实现了单定时器的多通道测量频率,以外部时钟的方式可测量任意频率的方波),奈何不能多路测试PWM波的频率,

    2024年02月12日
    浏览(51)
  • STM32 HAL库-定时器中断

    关闭或开启所有中断;代码如下: STM32F407 有众多的定时器,其中包括 2 个基本定时器(TIM6 和 TIM7)、10 个通用定时 器(TIM2 ~ TIM5、TIM9 ~TIM14)、2 个高级控制定时器(TIM1 和 TIM8),这些定时器彼此完 全独立,不共享任何资源。 选择定时器,配置时钟源,设置预分频系数,计

    2024年01月25日
    浏览(65)
  • stm32——hal库学习笔记(定时器)

    使用纯软件(CPU死等)的方式实现定时(延时)功能 使用精准的时基,通过硬件的方式,实现定时功能 递增计数模式实例说明 中心对齐模式实例说明 TIM6 和TIM7 控制寄存器 1(TIMx_CR1) TIM6 和TIM7 DMA/中断使能寄存器(TIMx_DIER) TIM6 和TIM7 状态寄存器(TIMx_SR) TIM6 和TIM7 计数器(TIMx_CNT)

    2024年02月21日
    浏览(56)
  • 基于STM32CubeMX和keil采用STM32F407的基本定时器中断实现LED闪烁

    定时器有三种,基本定时器,通用定时器,以及高级定时器。 这篇博客以最简单的基本定时器为例,实现LED的闪烁。 后面两种定时器的用法后面再写。 实现功能: TIM6控制LED每隔0.5s变一次状态。 TIM7控制LED1常量2s后熄灭。 因为都是用到LED,所以和上一篇基于STM32CubeMX与keil采

    2024年02月04日
    浏览(64)
  • STM32 HAL库 STM32CubeMX -- TIM(定时器中断)

    STM32F1 系列中,除了一些特殊的型号,大部分F1有8 个定时器,分为 基本定时器,通用定时器和高级定时器 。 基本定时器TIM6 和TIM7 是一个16 位的只能向上计数的定时器,只能定时,没有外部IO。 通用定时器TIM2/3/4/5 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出

    2024年02月16日
    浏览(77)
  • STM32 HAL库 STM32CubeMX -- TIM(定时器输入捕获)

    输入捕获可以对 输入的信号的上升沿、下降沿或者双边沿进行捕获 ,常用的有 测量输入信号的脉宽 和 测量PWM 输入信号的频率 和 占空比 这两种。 输入捕获的原理 就是,当捕获到信号的跳变沿的时候,把计数器CNT 的值锁存到捕获寄存器CCR 中,把前后两次捕获到的CCR 寄存

    2023年04月14日
    浏览(103)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包