以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);
}
以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);
}
举报