STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发

一、CUBEMX的配置

1.选择好芯片进入配置界面

1

2.配置时钟

时钟树
如果说主频选择的不对,那么你的HAL_Delay就不准,用串口监视器看到的输出就是一堆乱码

3.设置串口

串口的基本配置
串口基本配置

4.开启全局中断

中断

5.开启DMA,将接收设置成循环接收,发送就不用了

DMA

6.设置一下中断,等级看你需要

在这里插入图片描述

7.文件生成的时候这几个选项

在这里插入图片描述

二、代码

1.串口重定向

在usart.c文件中
下面展示一些 内联代码片

#include "stdio.h"
#include "string.h"
#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

2.IDLE中断接收

main.c
下面展示一些 内联代码片

volatile uint16_t rx1_len = 0;  //接收一帧数据的长度
volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志
uint8_t rx1_buffer[BUFFER_SIZE];  //接收数据缓存数组
char DataBuffer[BUFFER_SIZE];//转发串口数据的缓存数组
// An highlighted block
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_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能IDLE中断
	
  HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);		//启动串口DMA接收
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	if (rec1_end_flag==1)  
	{
		rec1_end_flag=0;
		memset(DataBuffer,0,sizeof(DataBuffer));
	   	memset(rx1_buffer,0,sizeof(rx1_buffer));
    
	}

在usart.c中
下面展示一些 内联代码片

// A code block
#include "stdio.h"
#include "string.h"
extern volatile uint8_t rx1_len;  //接收一帧数据的长度
extern volatile uint8_t rec1_end_flag; //一帧数据接收完成标志
extern uint8_t rx1_buffer[BUFFER_SIZE];  //接收数据缓存数组
extern	char DataBuffer[BUFFER_SIZE];
// An highlighted block
void UART_IDLEHandler(void)								//串口DMA循环接收数据,将huart1接收的数字转存到新的数组,然后再发送。在主函数里面对两个数组清零
{

	//uint8_t DataBuffer[BUFFER_SIZE];
	uint32_t temp;

	uint32_t Len = 0;
	static uint32_t CurrentIndex = 0;

	if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
	{
		rec1_end_flag =1;
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
		temp = huart1.Instance->SR;
		temp = huart1.Instance->DR;
		//HAL_UART_DMAStop(&huart1);
		temp = 0;
		Len =  BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
		while(CurrentIndex != Len)
		{
			DataBuffer[temp++] = rx1_buffer[CurrentIndex++];
			if(CurrentIndex >= BUFFER_SIZE)
				CurrentIndex = 0;

		}
		
		RxLen = temp;
		HAL_UART_Transmit(&huart1,(uint8_t *)DataBuffer,(uint32_t)RxLen,100);
		//printf("这一个字节是:%X\r\n",DataBuffer[2]);//测试数据接收是否正确
		//HAL_UART_Receive_DMA(&huart1,(uint8_t *)rx1_buffer,BUFFER_SIZE);
	}

}

2.将UART_IDLEHandler()放入USART1_IRQHandler()函数中

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值