STM32 HAL库实现UART的不定长度DMA数据传输(二)
目录
STM32 HAL库实现UART的不定长度DMA数据传输(二)
一、开发环境
- 软件:MDK-ARM V5、STM32CubeMX
- 硬件:STM32F407VGT7
二、项目需求
STM32 HAL库实现UART的不定长度DMA数据传输
三、项目分析
1.参考链接
2. 实现分析
(1)使能UART IDLE中断
(2)进入IDLE中断后,获取DMA读取的数据长度
(3)主函数中显示读取的数据长度和内容
四、练习步骤
1.UART、DMA、时钟等基本配置
参考STM32 HAL库实现UART的不定长度DMA数据传输(一)
2.不定长数据接收实现
(1)使能UART IDLE中断
//使能UART IDLE中断
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
添加上述代码,使能UART IDLE中断
(2)进入UART IDLE中断处理函数,获取数据长度
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint32_t temp;
if(USART2==huart2.Instance)
{
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
HAL_UART_DMAStop(&huart2);
temp=__HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
rx_len=BUF_SIZE-temp;
recv_end_flag=1;
}
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
(3)在滴答定时器中断中,定时获取接收到的内容和长度,并将数据内容和长度打印出来
//打印接收数据内容和长度
void UART2_DMA_Get()
{
if(recv_end_flag==1)
{
recv_end_flag=0;
printf("帧长度:%d 帧内容:%s\n",rx_len,rx_buf);
}
HAL_UART_Receive_DMA(&huart2,(uint8_t*)rx_buf,BUF_SIZE);
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
static uint8_t tickNum = 0;
tickNum++;
if (tickNum == 100)
{
tickNum = 0;
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED2_Pin);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED3_Pin);
}
UART2_DMA_Get(); //DMA接收数据
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
这样,基本的软件编写就搞定啦。
3.测试结果
如上图所示,获得正确的结果,UART2将接收到的数据重新打印出来,显示内容和长度与实际发送数据的内容和长度完全一致。
五、软件调试
略
六、总结与讨论
1.总结
整个过程分以下步骤进行:
(1)时钟、下载方式的基本配置
(2)UART配置
注意:需要使用中断
(3)DMA配置
注意:采用字节方式传递数据
(4)使能UART IDLE中断
(5)在中断中获取数据长度,DMA获取内容
2.讨论
(1)原理性的内容可以参考上述链接
(2)多做实操,practice makes perfect