【STM32学习6】HAL库通过DMA连续传输数据

HAL库中阻塞式的串口发送函数HAL_UART_Transmit()会导致程序阻塞,很容易破坏实时性。DMA作为专门搬运数据的工具,可以避免程序阻塞。HAL库提供的DMA串口发送函数为HAL_UART_Transmit_DMA(),但在实际应用中,不能简单的将HAL_UART_Transmit()直接替换为HAL_UART_Transmit_DMA(),还需要进行一些配置。

HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

在函数参数配置上,二者大体相同,都需要填入串口句柄,待传输数据指针与长度。阻塞式传输还需要设定超时时间,单位ms。

以STM32F407为例,通过DMA连续将内存中的数据传输到串口外设USART2。

1 初始化相关DMA与串口

这一步可以通过cubeMX自动生成,实例代码如下:

DMA_HandleTypeDef  g_dma_handle_usart2;

g_dma_handle_usart2.Instance = DMA1_Stream6;
g_dma_handle_usart2.Init.Channel = DMA_CHANNEL_4;
g_dma_handle_usart2.Init.Direction = DMA_MEMORY_TO_PERIPH;
g_dma_handle_usart2.Init.PeriphInc = DMA_PINC_DISABLE;
g_dma_handle_usart2.Init.MemInc = DMA_MINC_ENABLE;
g_dma_handle_usart2.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
g_dma_handle_usart2.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
g_dma_handle_usart2.Init.Mode = DMA_NORMAL;
g_dma_handle_usart2.Init.Priority = DMA_PRIORITY_HIGH;
    
/* interrupt configuration DMA中断初始化 */  
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
    
HAL_DMA_Init(&g_dma_handle_usart2);
__HAL_LINKDMA(&g_usart2_handler,hdmatx,g_dma_handle_usart2);
// g_usart2_handler是对应串口句柄

注意,一定要开启DMA传输完成中断。不开也能进行连续传输,但速度会莫名奇妙地很慢。

2 调用HAL_UART_Transmit_DMA()进行传输 

直接在需要发送的地方调用此函数即可,其余操作均在中断中完成。

3 在传输完成中断中清除标志并关闭DMA,为下一次传输做准备。

在DMA中断处理函数中完成操作,一般在名字类似stm32f4xx_it.c的文件中。

void DMA1_Stream6_IRQHandler(void)
{
    if (__HAL_DMA_GET_FLAG(&g_dma_handle_usart2, DMA_FLAG_TCIF2_6))
    {
        __HAL_DMA_CLEAR_FLAG(&g_dma_handle_usart2, DMA_FLAG_TCIF2_6);
        __HAL_UART_CLEAR_FLAG(&g_usart2_handler, UART_FLAG_TC);
        HAL_UART_DMAStop(&g_usart2_handler);      /* 关闭串口DMA */  
    }
}

HAL自带的函数HAL_DMA_IRQHandler(&g_usart2_handler)也可以完成清除标值,进入中断后处理函数等操作,但是效率不是很高,不如自己来清标值。

对于Normal模式,好像是每传输一次需要关一下DMA再开始下一次传输,所以加上

 HAL_UART_DMAStop(&g_usart2_handler);      /* 关闭串口DMA */  

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: stm32f407芯片可以使用hal库中的DMA功能进行不定长数据传输。DMA是直接内存访问(Direct Memory Access)的缩写,它是一种通过硬件控制的方式,将存储器与外设之间进行数据传输的技术。使用DMA可以有效地减轻CPU的负担,提高系统的效率。 在使用DMA进行数据传输时,需要对DMA进行初始化配置。具体步骤如下: 1. 根据需要设置DMA数据传输方向和传输模式。 2. 配置DMA传输的源地址和目的地址。 3. 设置数据传输的长度,并开启DMA传输。 在程序运行过程中,DMA的传输是通过中断来完成的。中断服务程序会在数据传输完成后自动调用。 使用DMA进行数据传输,可以提高系统的效率,减少CPU的负担,实现更加高效和稳定的数据传输。在stm32f407hal库中,DMA功能已经被完善地实现,并提供了使用手册和范例代码,方便开发者进行开发和调试。 ### 回答2: stm32f407 hal库dma模块可以实现不定长数据传输。通过设置DMA的通道、传输方向、传输数据的起始地址和传输的数据长度等参数,可以实现DMA的不定长数据传输功能。 在使用DMA进行不定长数据传输时,需要注意以下几点: 1.传输方向:DMA可以实现单向传输和双向传输。在进行不定长数据传输时,需要根据实际情况选择传输方向。 2.传输数据的起始地址:应根据具体的传输数据类型和存储方式设置传输数据的起始地址。例如,对于存储在内存中的数据,可以设置传输数据的起始地址为该数据内存中的地址;对于存储在外设中的数据,可以设置传输数据的起始地址为外设对应的寄存器或存储空间地址。 3.传输数据的长度:可以根据实际需求设置传输数据的长度。在进行不定长数据传输时,可以通过软件控制传输数据的长度,也可以通过硬件自动控制传输数据的长度。在进行动态数据传输时,需要在达到一定条件时及时停止或重新启动传输。 总的来说,利用stm32f407 hal库dma模块进行不定长数据传输,需要合理设置参数并且充分考虑传输数据的类型和存储方式,以实现更加高效和可靠的数据传输。 ### 回答3: STM32F407 HAL库DMA不定长数据传输需要使用DMA的循环模式。在循环模式下,DMA会自动根据数据长度进行数据传输,不需要预先设置数据长度。 具体操作步骤如下: 1. 在DMA配置文件中,设置DMA的循环模式为循环模式。 2. 开启DMA传输中断,用于判断DMA传输是否完成。 3. 在程序中,设置DMA传输的缓存地址和数据长度,并启动DMA传输。 4. 等待DMA传输完成中断触发,即可完成数据传输。 需要注意的是,在不定长数据传输过程中,需要保证DMA传输的缓存区足够大,以确保数据不会溢出。同时,由于数据长度不定,需要在程序中进行数据长度的动态分配和释放。 总之,使用STM32F407 HAL库DMA不定长数据传输需要掌握DMA循环模式的配置方法,以及合理的数据缓存管理策略。这将有助于减少程序出错的可能性,提高数据传输的效率和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值