stm32之不定长接收
使用STM32CUBE_MAX配置工程,可以简化编程工作量,但是这样我们会遇到一些麻烦,比如利用串口接收不知道长度的数据的时候,我们可能会无从下手,前段时间看到他人程序中的串口不定长接收,此次特意总结,包括3类芯片串口不定长配置。
STM32F103ZET6
配置工程:
- 选择USART1,配置波特率为115200,并开启串口中断,DMA中断



配置程序
- 在配置工程后,我们需要在工程中printf重定向函数fputc()和重写串口接收函数 UsartReceive_IDLE()代码如下:
// 在头文件中定义结构体
#define RX_LEN 1024 typedef struct
{
uint8_t RX_flag:; //IDLE receive flag
uint16_t RX_Size; //receive length
uint8_t RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE; void UsartReceive_IDLE(UART_HandleTypeDef *huart);
extern USART_RECEIVETYPE UsartType1;//定义结构体
USART_RECEIVETYPE UsartType1; // printf重定向
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, , 0xFFFF);
return ch;
} // USART不定长接收
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp; if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(huart); // Clears the UART IDLE pending flag.
HAL_UART_DMAStop(huart); // Stops the DMA Transfer.
temp = huart->hdmarx->Instance->CNDTR; // Read DMA stream x number of data register
huart->hdmarx->Instance->CNDTR = ; // Clear DMA stream x number of data register
if(huart == &huart1) // Checks whitch USART
{
UsartType1.RX_Size = RX_LEN - temp;
UsartType1.RX_flag=; // Set RX_flag
HAL_UART_Receive_DMA(&huart1,UsartType1.RX_pData,RX_LEN); // start DMA interrupt and receives an amount of data in non blocking mode.
}
}
}配置完成后,需要在xxx_it.c中断函数中添加相应串口的UsartReceive_IDLE( ) 函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UsartReceive_IDLE(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */
}在主函数中需要开启DMA接收中断,和串口空闲中断,程序如下:
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */ HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN); // Receives an amount of data in non blocking mode.
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // Enable the specified UART interrupt. printf("**************C print 重定向*************\r\n");
printf("**********USART_IDLE 不定长接收**********\r\n"); /* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
if(UsartType1.RX_flag )
{
UsartType1.RX_flag = ;
HAL_UART_Transmit(&huart1, UsartType1.RX_pData, UsartType1.RX_Size, 0xffff);
}
}
运行结果

STM32F429IGT6 & STM32F767IGT6
配置工程:
- 工程配置与 STM32F103ZET6 相同。
配置程序:
- printf重定向函数fputc()和重写串口接收函数 UsartReceive_IDLE()代码如下:
// 在头文件中定义结构体
#define RX_LEN 1024 typedef struct
{
uint8_t RX_flag:; //IDLE receive flag
uint16_t RX_Size; //receive length
uint8_t RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE; void UsartReceive_IDLE(UART_HandleTypeDef *huart);
extern USART_RECEIVETYPE UsartTy// printf重定向// printf重定向
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, , 0xFFFF);
return ch;
} // USART不定长接收
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp; if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(huart); // Clears the UART IDLE pending flag.
HAL_UART_DMAStop(huart); // Stops the DMA Transfer.
temp = huart->hdmarx->Instance->NDTR; // Read DMA stream x number of data register
huart->hdmarx->Instance->NDTR = ; // Clear DMA stream x number of data register
if(huart == &huart1) // Checks whitch USART
{
UsartType1.RX_Size = RX_LEN - temp;
UsartType1.RX_flag=; // Set RX_flag
HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN); // start DMA interrupt and receives an amount of data in non blocking mode.
}
}
}在xxx_it.c中断函数中添加相应串口的UsartReceive_IDLE( ) 函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UsartReceive_IDLE(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */
}在主函数中需要开启DMA接收中断,和串口空闲中断,程序如下:
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); printf("**************C print 重定向*************\r\n");
printf("**********USART_IDLE 不定长接收**********\r\n");
/* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
if(UsartType1.RX_flag)
{
HAL_UART_Transmit(&huart1, UsartType1.RX_pData, UsartType1.RX_Size, 0xff);
UsartType1.RX_flag = ;
} /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
运行结果:

stm32之不定长接收的更多相关文章
- STM32 HAL库使用中断实现串口接收不定长数据
以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT ...
- STM32串口接收不定长数据原理与源程序(转)
今天说一下STM32单片机的接收不定长度字节数据的方法.由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的A ...
- STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷
STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...
- STM32之串口DMA接收不定长数据
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...
- Stm32使用串口空闲中断,基于队列来接收不定长、不定时数据
串口持续地接收不定长.不定时的数据,把每一帧数据缓存下来且灵活地利用内存空间,下面提供一种方式供参考.原理是利用串口空闲中断和DMA,每当对方发来一帧完整的数据后,串口接收开始空闲,触发中断,在中断处 ...
- STM32 HAL库利用DMA实现串口不定长度接收方法
参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...
- 关于socket客户端接收不定长数据的解决方案
#!/usr/bin/env python3.5 # -*-coding:utf8-*- """ 本实例客户端用于不断接收不定长数据,存储到变量res "&qu ...
- Python3的tcp socket接收不定长数据包接收到的数据不全。
Python Socket API参考出处:http://blog.csdn.net/xiangpingli/article/details/47706707 使用socket.recv(pack_l ...
- 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类 Python中函数参数定义及调用函数时传参 ...
随机推荐
- leetcode — path-sum-ii
import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...
- Google SwipeRefreshLayout(Goolge官方下拉刷新控件)尝鲜
前天Google官方终于出了Android刷新控件——SwipeRefreshLayout. 使用前先需要将android.support.v4.jar升级到19.1.升级后,可能会出现SDK版本与A ...
- springboot情操陶冶-web配置(二)
承接前文springboot情操陶冶-web配置(一),在分析mvc的配置之前先了解下其默认的错误界面是如何显示的 404界面 springboot有个比较有趣的配置server.error.whit ...
- 如何热更新线上的Java服务器代码
一.前言 1.热更新代码的场景 (1)当线上服务器出现问题时,有些时候现有的手段不足以发现问题所在,可能需要追加打印日志或者增加一些调试代码,如果我们去改代码重新部署,会破坏问题现场,可以通过热部署的 ...
- VisualStudio2017集成GitHub
1 概述 通过使用VisualStudio2017来编写C语言版本的helloworld程序,然后上传至GitHub 2 VisualStudio2017安装GitHub插件 前提条件: 必须完成Vi ...
- 2016年Scrum状态调查报告
背景 Scrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发,包括一系列实践和预定义角色的过程骨架.Scrum由Jeff Sutherland和Ken Schwaber在一次IBM项目合作中研究 ...
- Linux学习笔记之Python3的安装以及创建虚拟环境(CentOS)
安装python3 一.安装需要编译的关联库 yum instal -y zlib zlib-devel (根据自己系统的情况,安装需要的关联库,同样用yum安装即可) yum install ope ...
- netfilter及iptables基本概念
网络访问控制 网络访问控制可以简单理解为防火墙,常用的网络访问控制有:哪些IP可以访问服务器, 可以使用哪些协议,哪些接口,是否需要对数据包进行修改等. netfilter netfilter是通过i ...
- OpenUDID 和 IDFA 比较
iOS标识符 现今来比较下,不同情况下两种标识符的变化情况.以下试验,每种标识符均分为存于Keychain和未存于Keychain的两种情况做比较. 广告标识符(IDFA-identifierForI ...
- Grafana 利用Grafana Variables变量配置快速切换不同主机的图表数据展示
用Grafana Variables变量配置快速切换不同主机的图表数据展示 by:授客 QQ:1033553122 测试环境 需求描述 操作步骤 结果展示 测试环境 influxdb-1.5.2. ...