首页 > 其他分享 >【STM32】串口不定长接收 保姆级教程

【STM32】串口不定长接收 保姆级教程

时间:2024-05-26 13:59:44浏览次数:17  
标签:教程 HAL UART STM32 中断 串口 buf 空闲

为什么要使用串口不定长接收

正常的接收函数

HAL_UART_Receive(UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size,uint32_t Timeout)
huart:句柄
pData:盛放接收数据的变量
Size:接收数据的大小

中断接收函数

HAL_UART_Receive_IT(UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size)
huart:句柄
pData:盛放接收数据的变量
Size:接收数据的大小

        这两个接收函数有一个共有特性,就是定长接收,Size参数就是接收数据的长度,当串口发送长度不固定的数据时,会出现吞字符的现象,会使指令信息不完整。所以,为了保证下位机接收到完整的指令,需要串口可以完整接收不定长度的数据,常用方法有两个,一是使用串口空闲中断实现,二是使用串口空闲中断+DMA实现。

什么是串口空闲中断

        串口空闲中断是指当串口接收缓冲区中没有数据时,串口控制器产生的一种中断信号。在串口通信中,当接收到一个完整的数据帧后,通常会有一个停止位,表示数据的传输结束。当接收缓冲区中没有数据时,串口控制器会检测到停止位的连续空闲状态,并产生空闲中断信号。使用串口空闲中断可以消除轮训接收缓冲区的需要,提高系统的性能和效率。

注意:

(1)空闲中断的允许需要手动解除中断屏蔽

(2)空闲中断必须手动清零,不然中断会一直置位,系统会不断进入中断处理函数

方法一:通过串口空闲中断 实现串口不定长接收

思路:

        每次接收一个字符触发中断,这样每次进接收中断就保存下当前接到的字符到一个数组里,然后下一个字符来的时候就继续保存到数组里的下一个元素中,以此类推每次中断保存一个字符,那当发完的时候就保存完了,同时触发空闲中断,在空闲中断中那个保存数组就是接收到的数据。然后就可以对这个数组进行判断发送等操作了。

步骤:

 一定要注意相关函数添加在的位置!!!!

1、

2、

3、

4、

5、

6、

相关部分代码

1、main.c 内 设计全局变量

/* USER CODE BEGIN 0 */
	uint8_t buf[128]={0};
	 uint8_t buf_recv[64];
/* USER CODE END 0 */

2、主函数

//串口空闲中断+串口接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);	//使能空闲中断
HAL_UART_Receive_IT(&huart1,buf,1);//每次接收一个,然后每次都进中断

3、stm32g0xx_it.c 内修改中断函数中的全局变量

/* USER CODE BEGIN 0 */
uint8_t len=0;
extern uint8_t buf_recv[64];
uint8_t buff[64];
/* USER CODE END 0 */

4、修改中断函数  记得添加头文件#include<string.h>

  /* USER CODE BEGIN USART1_IRQn 0 */

    //使用串口接收中断+空闲中断
	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))	
	{                               // 1. 获得串口空闲中断标志	
		__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_IDLEF);	 // 2. 清除空闲中断标志
		//3.这里写中断执行
		HAL_UART_Transmit(&huart1,buf_recv,sizeof(buf_recv),1000);
		len=0;
		memset(buf_recv,0,sizeof(buf_recv));
	}else
	{			
				buf_recv[len]=USART1->RDR; 
				len++;
				HAL_UART_Receive_IT(&huart1,buff,1);
	}

  /* USER CODE END USART1_IRQn 0 */

方法二:串口空闲中断+DMA

原理: 接收足够的长度,当串口空闲时进中断,直接计算当前接收数组实际接收值,然后停止接收即可。

步骤:

1、main.c

2、

3、中断函数改写

 

 

 效果演示

相关代码 

注意代码位置

1、main.c定义全局变量

/* USER CODE BEGIN 0 */
uint8_t buf_ctl[64];
/* USER CODE END 0 */

2、循环接收数据

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		       HAL_UART_Receive_DMA(&huart1,buf_ctl,64);	//接收DMA使能
		__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);	//开启串口空闲中断

  }

3、中断函数 添加头文件#include<string.h>

添加全局变量

/* USER CODE BEGIN TD */
extern uint8_t buf_ctl[64];//拿到main.c的buf_ctl
uint8_t len;

/* USER CODE END TD */

修改中断函数

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))	
	{                               // 1. 获得串口空闲中断标志	
		__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_IDLEF);													 // 2. 清除空闲中断标志
		HAL_UART_DMAStop(&huart1);	 // 3. 清除->空闲->停止DMA		
		len = 64 - hdma_usart1_rx.Instance->CNDTR;
            // 4. 设定的传输长度-剩余传输数量(DMA_CNDTRx)=实际长度
		buf_ctl[len]='\0';
		HAL_UART_Transmit(&huart1,buf_ctl,sizeof(buf_ctl),500);
		memset(buf_ctl,0,sizeof(buf_ctl));
		HAL_UART_Receive_DMA(&huart1, buf_ctl, 64);
								     // 6. 重新开启DMA
	}
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

标签:教程,HAL,UART,STM32,中断,串口,buf,空闲
From: https://blog.csdn.net/a1547998353/article/details/139193387

相关文章

  • Visio 2021下载教程|visio流程图软件的完整安装步骤
    Visio是微软公司(Microsoft)推出的一款流程图和图表制作软件。它提供了丰富的图形库和工具,可以帮助用户创建各种类型的图表、流程图、组织结构图、平面布局图等。目前最新版也是用的最广泛的版本为Visio2021。MicrosoftVisio2003-2021全版本软件安装包下载:https://pan.baid......
  • 亿图图示使用教程
    一、引言亿图图示(EdrawMax)是一款功能强大且易于使用的图形设计软件。它可以帮助用户快速创建各种类型的图示,如流程图、思维导图、网络图、组织结构图、UML图、平面设计图等。本文将详细介绍亿图图示的基本使用方法及其在不同场景中的应用,帮助用户快速上手并充分发挥其强大......
  • 【QGIS入门实战精品教程】10.7: 基于DEM的地形因子分析(坡度、坡向、粗糙度、山体阴影、
    文章目录一、加载dem二、山体阴影三、坡度四、坡向五、地形耐用指数六、地形位置指数七、地表粗糙度一、加载dem二、山体阴影方法一:符号系统利用符号系统中的山体阴影,渲染出阴影效果。方法二:山体阴影工具该算法计算输入中的数字化地形模型的山体阴......
  • 【前端】VS Code 前端环境搭建教程
    ......
  • 快团团团长如何修改团的商品分类信息?免费教程教你怎么做!
    一、功能说明商品分类能够帮助你团购中的商品展示的更清晰,并且还可以调整分类的顺序,将主推品类展示在前面。二、具体操作步骤(一)如何在商品库增加/修改/删除分类?在“个人中心”→“商品库”中找到“分类管理”,在分类管理中可以:A.添加分类:分类最多可以添加200个B.删除分......
  • 快团团大团长帮卖团长如何使用【直播工具】进行跨团直播?免费教程一学就会!
    快团团大团长帮卖团长如何使用【直播工具】进行跨团直播?在快团团直播卖货,动销快、做活动方便,为许多团长生意带来显增。各类目团长的直播百花齐放,盲盒开箱、生鲜冷链、跨境美妆、母婴个护……有团长的直播间观看人均价值高达65RMB,几乎百分百转化!一场2小时带货几十万!【直播团......
  • 快团团大团长帮卖团长直播如何授权摄像头和麦克风?免费教程一学就会!
    小程序首页点击右上角三个点打开【设置】允许使用【摄像头】【麦克风】  如何成为这些大团长的帮卖团长?排名靠前的很多要求非常的高,普通人一般也进不去,不过可以找平替的大团长也是一样的,不用纠结是否是跟着这些明星团长混,也还有很多非常优质的团长等着大家呢,可......
  • 毕业设计项目 stm32的人体健康状态检测系统(项目开源)
    文章目录0前言1硬件电路2软件设计3跌倒检测算法4软件部分MLX90614红外温度传感器5关键代码6最后0前言......
  • STM32F1之I2C通信·软件I2C代码编写
    目录1. 软件I2C代码编写 1.1 I2C起始方法一方法二方法三方法四1.2 I2C终止1.3 发送一个字节 1.4 接收一个字节1.5 发送应答1.6 接收应答1. 软件I2C代码编写     由于软件I2C不受引脚限制,随便找两个普通的GPIO口就可以使用,首先我们......
  • STM32F1之SPI通信·软件SPI代码编写
    目录1. 简介2. 硬件电路移位示意图3. SPI时序基本单元3.1  起始条件3.2 终止条件3.3  交换一个字节(模式0)3.4 交换一个字节(模式1)3.5 交换一个字节(模式2)3.6 交换一个字节(模式3)4. 代码编写4.1 引脚初始化4.2 引脚置高低电平封装4.2.1  S......