其他分享
首页 > 其他分享> > STM32F429 CubeMX DMA+空闲中断实现RS485不定长度自动收发

STM32F429 CubeMX DMA+空闲中断实现RS485不定长度自动收发

作者:互联网

STM32F429 CubeMX DMA+空闲中断实现RS485不定长度自动收发

建立工程

  1. 选择好芯片后,首先设置RCC 在这里插入图片描述

  2. 设配置时钟,我这里选择了外部晶振,配置到180MHZ的频率。 在这里插入图片描述

  3. 调试借口用的是jlink的SWD,HAL库的时基选择systick 在这里插入图片描述

  4. 配置USART1为异步串口在这里插入图片描述

  5. 添加DMA接收,单字节,正常模式 在这里插入图片描述

  6. 添加DMA发送,单字节,正常模式 在这里插入图片描述

  7. 打开串口中断 在这里插入图片描述

  8. 配置NVIC分组为2,这里还可以配置各个中断的优先级 在这里插入图片描述

  9. 配置了两个GPIO,一个是LED,还有一个是485的收发控制引脚U1_EN在这里插入图片描述

  10. 配置工程IDE为mdk工程 在这里插入图片描述

  11. 勾选此处为每个外设单独创建c和h文件 在这里插入图片描述

  12. 这里默认都是HAL库
    在这里插入图片描述

  13. 最后点击生成GENERATE CODE,生成代码,然后直接打开MDK工程

添加代码

  1. “usart.h”中创建一个串口收发缓存结构体
/* USER CODE BEGIN Private defines */
#define USART_BUFF_SIZE	512
typedef struct 
{
	uint8_t Rxbuff[USART_BUFF_SIZE];
	uint8_t Txbuff[USART_BUFF_SIZE];
	uint16_t Rxlen;
	uint16_t Txlen;
} _USART_Buff;
/* USER CODE END Private defines */
  1. “usart.c”中创建串口收发缓存全局变量,添加"string.h"头文件
/* USER CODE BEGIN 0 */
#include "string.h"
_USART_Buff	USART1_Buff;
/* USER CODE END 0 */
  1. 在MX_USART1_UART_Init中添加代码
  /* USER CODE BEGIN USART1_Init 2 */
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);   //开启IDLE中断,以帧方式接收不定长数据
	HAL_UART_Receive_DMA(&huart1, USART1_Buff.Rxbuff, USART_BUFF_SIZE);	//开始DMA接收
  /* USER CODE END USART1_Init 2 */
  1. “usart.c”文件末尾添加空闲中断处理程序
/* USER CODE BEGIN 1 */
void UsartReceive_IDLE(UART_HandleTypeDef *huart)  //串口接收空闲中断
{
	
	if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
	{
		if(huart->Instance == USART1)
		{
			__HAL_UART_CLEAR_IDLEFLAG(huart);		//清中断
			HAL_UART_AbortReceive(huart);	//已经接收完一帧数据,所以这里要停止接收,然后再重新接收			

			USART1_Buff.Rxlen=USART_BUFF_SIZE-hdma_usart1_rx.Instance->NDTR;	//获取接收到的数据数量
			memcpy(USART1_Buff.Txbuff,USART1_Buff.Rxbuff,USART1_Buff.Rxlen);	//将接收到的数据复制到发送缓冲区
			
			USART1_Buff.Txlen=USART1_Buff.Rxlen;	//设置发送的字节数
			if(USART1_Buff.Txlen>0)
			{
				HAL_GPIO_WritePin(U1_EN_GPIO_Port,U1_EN_Pin,GPIO_PIN_SET);	//U1_EN置高电平为发送模式
				HAL_UART_Transmit_DMA(huart,USART1_Buff.Txbuff,USART1_Buff.Txlen);	//DMA发送数据
			}
			memset(USART1_Buff.Rxbuff,0x00,USART_BUFF_SIZE);	//清空缓存,重新接收
			HAL_UART_Receive_DMA(huart,(uint8_t *)&USART1_Buff.Rxbuff,USART_BUFF_SIZE); //开启DMA接收
		}
	}
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)	//HAL的发送完成回调函数
{
	HAL_GPIO_WritePin(U1_EN_GPIO_Port,U1_EN_Pin,GPIO_PIN_RESET);	//U1_EN置低电平为接收模式
}
/* USER CODE END 1 */
  1. “usart.h”添加串口空闲中断程序的声明
/* USER CODE BEGIN Prototypes */
void UsartReceive_IDLE(UART_HandleTypeDef *huart);
/* USER CODE END Prototypes */
  1. "stm32f4xx_it.c"添加usart.h头文件
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */
  1. USART1_IRQHandler中断服务函数里面添加空闲中断处理程序
  /* USER CODE BEGIN USART1_IRQn 0 */
  UsartReceive_IDLE(&huart1);
  /* USER CODE END USART1_IRQn 0 */
  1. 最后在“main.c"的大循环里添加LED闪烁程序
  while (1)
  {
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		HAL_Delay(500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  1. xcom串口测试,数据回环很稳定
    在这里插入图片描述

标签:DMA,CODE,HAL,UART,RS485,USER,CubeMX,USART1,Buff
来源: https://blog.csdn.net/szccxy/article/details/121044702