HAL库STM32CubeMX_串口DMA空闲中断接收

HAL库STM32CubeMX_串口DMA空闲中断接收

主要转载来自【STM32】HAL库 STM32CubeMX教程十一—DMA (串口DMA发送接收)(仅供学习交流,侵删)

主要是为了简单记录一下,以便后日使用。

顺带:HAL库STM32CubeMX_串口DMA发送(printf重定向)


CubeMX配置

在这里插入图片描述
在这里插入图片描述

代码修改

usart.c

  • 前面添加相关定义
/* USER CODE BEGIN 0 */
volatile uint8_t rx_len = 0;  //接收一帧数据的长度
volatile uint8_t recv_end_flag = 0; //一帧数据接收完成标志
uint8_t rx_buffer[BUFFER_SIZE]={0};  //接收数据缓存数组
/* USER CODE END 0 */
  • void MX_USART1_UART_Init(void)中添加

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//开启第一次的接收

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
  
//下方为自己添加的代码
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
	HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//DMA接收函数,此句一定要加,不加接收不到第一次传进来的实数据,是空的,且此时接收到的数据长度为缓存器的数据长度

  /* USER CODE END USART1_Init 2 */

}

usart.h

  • 添加相关定义
/* USER CODE BEGIN Private defines */
#define BUFFER_SIZE  10  
extern  volatile uint8_t rx_len ;  //接收到一帧数据的长度
extern volatile uint8_t recv_end_flag; //一帧数据接收完成标志
extern uint8_t rx_buffer[BUFFER_SIZE];  //接收数据缓存数组
/* USER CODE END Private defines */

stm32f1xx_it.c

  • 在前面添加引用

#include “usart.h”

  • void USART1_IRQHandler(void)中添加

uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
if((tmp_flag != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
rx_len = BUFFER_SIZE - temp;
recv_end_flag = 1;
}

#include "usart.h"

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

	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);//清除标志位
		//temp = huart1.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
		//temp = huart1.Instance->DR; //读取数据寄存器中的数据
		//这两句和上面那句等效
		HAL_UART_DMAStop(&huart1); //
		temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
		//temp  = hdma_usart1_rx.Instance->NDTR;//读取NDTR寄存器 获取DMA中未传输的数据个数,
		//这句和上面那句等效
		rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
		recv_end_flag = 1;	// 接受完成标志位置1	
	 }
	
	
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

使用例:

#include <string.h>
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
	  if(recv_end_flag == 1){

	//如果两个字符串的长度和内容一样,返回0
		if(strcmp(rx_buffer,"hello")==0){//若收到“hello”,发送“yes”
			HAL_UART_Transmit_DMA(&huart1, "yes", 3);	
		}
			
			memset(rx_buffer, 0, rx_len);//清空接收到的内容
			rx_len = 0;//清除计数
			recv_end_flag = 0;//清除接收结束标志位
			HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收		
		}

    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

再次申明:主要转载来自【STM32】HAL库 STM32CubeMX教程十一—DMA (串口DMA发送接收)(仅供学习交流,侵删)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值