ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-10-30 20:03:28  阅读:592  来源: 互联网

标签:DMA CODE HAL UART RS485 USER CubeMX USART1 Buff


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有