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

一、CUBEMX的配置

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

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第1张图片

2.配置时钟

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第2张图片
如果说主频选择的不对,那么你的HAL_Delay就不准,用串口监视器看到的输出就是一堆乱码

3.设置串口

串口的基本配置
STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第3张图片

4.开启全局中断

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第4张图片

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

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第5张图片

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

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第6张图片

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

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第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()函数中

STM32 CUBEMX 串口通信 不定长数据 DMA循环接收并转发_第8张图片

你可能感兴趣的:(STM32,stm32)