STM32F103 UART中断接收 DMA发送

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/lee_xuwei/article/details/85280341

以USART3为例,

(1)首先在【stm32f1xx_hal_conf.h】中使能DMA模块,工程增加stm32f1xx_hal_dma.c。

(2)main.c中头部增加以下声明

UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma1_uart3;

(3)main.c中增加USART的初始化

/* USART3 init function */
static void MX_USART3_UART_Init(void)
{
	huart3.Instance = USART3;
	huart3.Init.BaudRate = 115200;
	huart3.Init.WordLength = UART_WORDLENGTH_8B;
	huart3.Init.StopBits = UART_STOPBITS_1;
	huart3.Init.Parity = UART_PARITY_NONE;
	huart3.Init.Mode = UART_MODE_TX_RX;
	huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart3.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart3) != HAL_OK)
	{
		Error_Handler();
	}
}

(4)stm32f1xx_hal_msp.c增加

extern  UART_HandleTypeDef huart3;
extern DMA_HandleTypeDef hdma1_uart3;

......................

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

	GPIO_InitTypeDef GPIO_InitStruct;
	
	if (huart->Instance == USART3)
	{
		/* USER CODE BEGIN USART3_MspInit 0 */

		/* USER CODE END USART3_MspInit 0 */
		/* Peripheral clock enable */
		__HAL_RCC_USART3_CLK_ENABLE();
		__HAL_RCC_DMA1_CLK_ENABLE();

		/**USART3 GPIO Configuration
		PB10     ------> USART3_TX
		PB11     ------> USART3_RX
		*/
		GPIO_InitStruct.Pin = GPIO_PIN_10;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

		GPIO_InitStruct.Pin = GPIO_PIN_11;
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
		
		
		hdma1_uart3.Instance = DMA1_Channel2;
		hdma1_uart3.Init.Direction = DMA_MEMORY_TO_PERIPH;
		hdma1_uart3.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma1_uart3.Init.MemInc = DMA_MINC_ENABLE;
		hdma1_uart3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma1_uart3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma1_uart3.Init.Mode = DMA_NORMAL;
		hdma1_uart3.Init.Priority = DMA_PRIORITY_LOW;
		HAL_DMA_DeInit(&hdma1_uart3);
		HAL_DMA_Init(&hdma1_uart3);
		
		__HAL_LINKDMA(huart, hdmatx, hdma1_uart3);	

		HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 2, 0);
		HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);		
		
		/* Peripheral interrupt init */
		HAL_NVIC_SetPriority(USART3_IRQn, USART_IRQn_PP, 0);
		HAL_NVIC_EnableIRQ(USART3_IRQn);
		
		__HAL_UART_ENABLE_IT(&huart3, USART_IT_RXNE);//使能串口3  读数据寄存器非空中断RXNE
		/* USER CODE BEGIN USART3_MspInit 1 */

		/* USER CODE END USART3_MspInit 1 */
	}

}

void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{

	if (huart->Instance == USART3)
	{
		/* USER CODE BEGIN USART3_MspDeInit 0 */

		/* USER CODE END USART3_MspDeInit 0 */
		/* Peripheral clock disable */
		__HAL_RCC_USART3_CLK_DISABLE();
		__HAL_RCC_DMA1_CLK_DISABLE();
		
		/**USART3 GPIO Configuration
		PB10     ------> USART3_TX
		PB11     ------> USART3_RX
		*/
		HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10 | GPIO_PIN_11);
		HAL_DMA_DeInit(&hdma1_uart3);
		/* Peripheral interrupt DeInit*/
		HAL_NVIC_DisableIRQ(USART3_IRQn);
		HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
		
		__HAL_UART_DISABLE_IT(&huart3, USART_IT_RXNE);
		/* USER CODE BEGIN USART3_MspDeInit 1 */

		/* USER CODE END USART3_MspDeInit 1 */
	}

}

(5)stm32f1xx_it.c增加

extern UART_HandleTypeDef huart3;
extern DMA_HandleTypeDef hdma1_uart3;

.............................

/******************************************************
函数名称:USART3_Own_IRQHandler
函数描述:USART3中断服务自定义代码部分
输入参数:pLinuxClass:传入LINUX_OBJECT
返回值:无
******************************************************/
void USART3_Own_IRQHandler(LINUX_CLASS *pLinuxClass)
{
	unsigned char  ucValue;

	// 使用了DMA发送,一定要加UART_FLAG_RXNE判断,否则成功回复一次后,会一直进下面这段,不知道原因
	if ((__HAL_UART_GET_IT_SOURCE(&huart3, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE)!= RESET))// 接收中断
	{								
		pLinuxClass->Rx_FROM_linux[pLinuxClass->Rx_FROM_linux_Counter] = (uint8_t)(huart3.Instance->DR & 0x00FF);
		pLinuxClass->Rx_FROM_linux_Counter++;
		
		if (pLinuxClass->Rx_FROM_linux_Counter >= RX_LINUX_MAX)
		{
			pLinuxClass->Rx_FROM_linux_Counter = 0; 
		}
		
		pLinuxClass->RX_BYTE_TimeoutCounter_Lock = 0;		// 接收数据字节间超时计时器开启
		pLinuxClass->RX_BYTE_TimeoutCounter = 0;
		
		__HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_RXNE );
	}
	
	if ((__HAL_UART_GET_IT_SOURCE(&huart3, UART_IT_TC) != RESET) && (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TC)!= RESET))
	{
		huart3.State = HAL_UART_STATE_BUSY_RX;
		
		__HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_TC );		
		
		WRITE_485UN; // 485通讯方式
	}
	
		// 溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
	if (__HAL_UART_GET_FLAG(&huart3,USART_FLAG_ORE) != RESET) 
	{
		__HAL_UART_CLEAR_FLAG(&huart3,USART_FLAG_ORE);  // read SR																						
			
		ucValue = (uint8_t)( huart3.Instance->DR & (uint8_t)0x00FF); // read DR 
	}
	
	(void)ucValue;
}

void USART3_IRQHandler(void)
{
	/* USER CODE BEGIN USART3_IRQn 0 */
	USART3_Own_IRQHandler(&LINUX_OBJECT);	
	/* USER CODE END USART3_IRQn 0 */

	/* USER CODE BEGIN USART3_IRQn 1 */

	/* USER CODE END USART3_IRQn 1 */
}

void DMA1_Channel2_IRQHandler(void)
{
	HAL_DMA_IRQHandler(&hdma1_uart3);
}

猜你喜欢

转载自blog.csdn.net/lee_xuwei/article/details/85280341