以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增加
externUART_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 charucValue;
// 使用了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 SRucValue = https://www.it610.com/article/(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);
}
【STM32F103 UART中断接收 DMA发送】
推荐阅读
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 日常分享|共享充电宝方案原理,具体部件组成以及主控MUC参数
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- STM32|STM32的四种IO输出模式
- STM32 远程升级(ISP / IAP)
- stm32|stm32f103can总线过滤器配置
- STM32CubeMX配置SDIO模式(非DMA方式)
- STM32|如何建一个STM32F030标准库工程模板
- STM32 时钟RCC相关配置参考stm32f10x_rcc.h
- STM32 NVIC