STM32CubeMX系列教程5:串口接收不定长数据

摘要

  基本串口通信通常只能接收到定长数据,无法稳定接收不定长数据,本章介绍利用STM32单片机的IDLE空闲中断,接收不定长数据。

配置工程

  复制 STM32CubeMX系列教程0:创建工程 创建的工程目录GPIO_test,修改文件目录名称为USART_IDLE,双击打开GPIO_test.ioc。

配置串口及DMA

  使能串口1的异步串行通信模式,开启Usart1的全局中断。添加DMA通道。
在这里插入图片描述

生成源码

  使用Stm32Cubemx生成源码, 打开生成的源码,删除whiel循环中的语句。

修改源码

重定向printf

  打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方引入stdio.h头文件
在这里插入图片描述
  打开usart.c文件,在USER CODE BEGIN 0USER CODE END 0之间添加下列代码。

#if 1   struct __FILE { 
  int handle; 
}; 

FILE __stdout;  //定义_sys_exit()以避免使用半主机模式    void _sys_exit(int x) 
{ 
  x = x; 
} 
//重定义fputc函数
int fputc(int ch, FILE *f){ 	
  while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
  USART1->DR=(uint8_t)ch;      
  return ch;
}#endif

添加串口接收所需变量

  打开uart.c文件,在文件顶部的USER CODE BEGIN 0下方添加下列变量

volatile uint8_t rx1_len = 0;  //接收一帧数据的长度
volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志
uint8_t rx1_buffer[BUFFER_SIZE]={0};  //接收数据缓存数组

添加串口及IDLE处理函数

  打开uart.c文件,在文件末尾的USER CODE BEGIN 1下方添加下列函数

void Usart1_IDLE(void)      //USART1的IDLE接收
{   
	uint32_t tmp_flag = 0;   
	uint32_t temp;
   	tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
   if((tmp_flag != RESET))//idle标志被置位
   {
   		__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
   		HAL_UART_DMAStop(&huart1); //  停止DMA传输,防止
   		temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
   		rx1_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
   		rec1_end_flag = 1;	// 接受完成标志位置1	
   }
}

void Usart1_Handle()     //USART1对接收的一帧数据进行处理
{
   DMA_Usart1_Send(rx1_buffer, rx1_len);  //将接收到的数据回发给发送端
   rx1_len = 0;//清除计数
   rec1_end_flag = 0;//清除接收结束标志位
   HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);//重新打开DMA接收
}

void DMA_Usart1_Send(uint8_t *buf,uint8_t len) //串口发送封装
{   
	if(HAL_UART_Transmit_DMA(&huart1,buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
	{
  		Error_Handler();
 	}
}

在这里插入图片描述

声明变量及函数

  打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方添加如下语句

#include "stdio.h"
#include "string.h"
#define BUFFER_SIZE  100  

extern volatile uint8_t rx1_len;  //接收一帧数据的长度
extern volatile uint8_t rec1_end_flag; //一帧数据接收完成标志
extern uint8_t rx1_buffer[BUFFER_SIZE];  //接收数据缓存数组

void Usart1_Handle(void);
void DMA_Usart1_Send(uint8_t *buf,uint8_t len);//串口发送封装
void Usart1_IDLE(void);

在这里插入图片描述

启用IDLE中断

  进入main.c文件,找到入口函数void mian(void), 在USER CODE BEGIN 2下方开启串口1的DILE中断,并打开DMA接收。

	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断	
  	HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);  //开启DMA接收

  在while语句中添加接收查询语句。

if(rec1_end_flag)  //判断是否接收到1帧数据
{
	Usart1_Handle();  //前往数据处理函数处理接收到的数据。
}		

在这里插入图片描述

修改中断函数

  打开stm32f4xx_it.c文件,在文件开头引入usart.h头文件。
在这里插入图片描述

  向下翻stm32f4xx_it.c文件,找到void USART1_IRQHandler(void)函数,此函数为串口1的中断入口函数。在此函数中添加之前在usart.c文件中创建的IDLE接收函数。
在这里插入图片描述

编译下载

  源码修改完毕后,编译下载,打开串口助手,随意发送100个字节以内的任意长度内容进入单片机,都可得到同样的回复。
在这里插入图片描述

  STM32单片机程序下载方法有多种,有需要请跳转

STM32程序下载0:STM32CubeProgrammer安装
STM32程序下载1:通过keil-ST-Link方式下载
STM32程序下载2:通过STM32CubePro-ST-Link下载
STM32程序下载3:通过STM32CubePro-UART下载
STM32程序下载4:通过STM32CubePro-USB下载

  选择你所需要的下载方法。

  如果有疑问请留言

  • 9
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
stm32cubemx是一款适用于STM32微控制器的图形化配置工具,可以帮助开发人员快速配置各种外设及功能,并生成相应的初始化代码。如果需要在STM32微控制器上实现串口接收不定数据,可以通过使用stm32cubemx来配置串口外设,并结合中断实现。 首先,在stm32cubemx中选择需要的串口外设,并配置相应的参数,如波特率、数据位数、停止位数等。接着,在中断配置中使能串口接收中断并编写中断服务函数,当串口接收数据时,中断服务函数将被触发。 在中断服务函数中,可以通过轮询的方式或者使用缓冲区来接收不定数据。一种常见的做法是使用循环队列或者循环指针来缓存接收到的数据,当接收到新数据时,将数据写入缓冲区,并判断是否达到预定的数据度。当达到预定的数据度时,可以进行数据处理或者触发相应的事件。 另外,也可以结合DMA(直接内存存取)来实现串口接收不定数据,通过配置DMA通道来自动接收数据并存储到指定的缓冲区中,当接收到预定度的数据时,DMA将触发相应的中断或者事件,通知程序进行后续的处理。 综上所述,通过stm32cubemx串口配置和中断/ DMA的使用,可以在STM32微控制器上实现串口接收不定数据的功能。开发人员可以根据具体需求和项目要求选择合适的方案来实现串口接收不定数据的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌新程序猿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值