通过修改HAL_UART_Transmit_DMA()函数,解决串口发送DMA只能发送一次的问题

这篇具有很好参考价值的文章主要介绍了通过修改HAL_UART_Transmit_DMA()函数,解决串口发送DMA只能发送一次的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考文章:1. http://t.csdn.cn/FT6Mg

                  2. http://t.csdn.cn/ejFIQ

今天用STM32F1的HAL库开发遇到一个奇怪的问题,在主函数循环调用中用串口1的DMA请求,将内存中的数据发送给串口,无论延迟Delay开了多大,始终只能发送一次DMA数据。后来在网上查阅大佬的资料终于有了思路。

废话不多说,先上代码:

在 stm32f1xx_hal_uart.c 文件中找到HAL_UART_Transmit_DMA()函数实现,在解锁操作__HAL_UNLOCK;后添加代码:huart -> gState = HAL_UART_STATE_READY;  编译以后运行完美解决。而且在低延迟的高速while循环中反复调用串口DMA请求,都可以运行。

HAL_UART_Transmit_DMA()函数实现修改:(也就多加了一行代码而已[doge])

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  uint32_t *tmp;

  /* Check that a Tx process is not already ongoing */
  if (huart->gState == HAL_UART_STATE_READY)     
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;   //修改串口的工作状态为Busy

    /* Set the UART DMA transfer complete callback */
    huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;

    /* Set the UART DMA Half transfer complete callback */
    huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;

    /* Set the DMA error callback */
    huart->hdmatx->XferErrorCallback = UART_DMAError;

    /* Set the DMA abort callback */
    huart->hdmatx->XferAbortCallback = NULL;

    /* Enable the UART transmit DMA channel */
    tmp = (uint32_t *)&pData;
    HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);

    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

    /* Process Unlocked */
    __HAL_UNLOCK(huart);
		huart -> gState = HAL_UART_STATE_READY;    //这一句官方好像给落下了???

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

简要分析:每当调用一次HAL_UART_Transmit_DMA()都会先进行一次串口状态的判断:if (huart->gState == HAL_UART_STATE_READY) 如果串口处于READY状态,则开始本次的DMA传输,否则会返回一个BUSY状态:

else
  {
    return HAL_BUSY;
  }

当第一次调用HAL_UART_Transmit_DMA()时,串口处于READY状态,于是进行DMA传输,注意,在DMA传输过程中,会将串口从READY状态改为发送BUSY状态(软件修改):huart->gState = HAL_UART_STATE_BUSY_TX;但是在DMA完成本次传输工作以后,并没有将串口从发送BUSY状态改回READY状态,一开始我认为可能硬件自动修改该标志,但是不确定,还没有翻参考手册,如果有知道的大佬烦请指教!因此这里我索性添加一句代码软件修改该状态:huart -> gState = HAL_UART_STATE_READY;

这样就能保证每次调用完HAL_UART_Transmit_DMA()函数后,串口的状态均为READY,为下一次的串口发送DMA请求做准备。文章来源地址https://www.toymoban.com/news/detail-536708.html

到了这里,关于通过修改HAL_UART_Transmit_DMA()函数,解决串口发送DMA只能发送一次的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 HAL库的HAL_UART_Transmit_IT使用方法

    是STM32 HAL库中非阻塞的串口发送函数。 用法:1. 调用HAL_UART_Transmit_IT()发送数据            2. 在HAL_UART_TxCpltCallback()里写上发送完成后的处理 注意: HAL_UART_Transmit_IT()要等待上次发送完成后再发送,否则返回HAL_BUSY。用huart-gState == HAL_UART_STATE_READY判断上次是否发送完成。 官方

    2024年02月16日
    浏览(32)
  • STM32-UART-DMA HAL库缓冲收发

    1.1、注意事项: HAL库的DMA底层基本都会默认开启中断使能,如果在STM32CubeMx禁用了中断相关的功能,程序可能会进入空中断回调出不来。 切记使用STM32-HAL库的DMA发送时需要开启USART中断和DMA中断。 在一般时间要求不是很高很高的场合,使用HAL库自带的函数就可以,并不会很频

    2024年01月18日
    浏览(37)
  • (stm32之HAL库)UART工作在DMA模式要打开串口中断吗?

    最近学习了stm32(F4xx)的串口在DMA模式下的使用,期间以ST官方提供的例程进行参考学习,发现其初始化过程中是打开了UART的中断的,而且HAL库中stm32f4xx_hal_uart.c文件中的DMA模式使用说明里也有这么一句话: 即在非循环模式下(也就是发完一次数据就停止的常用模式)需要配置

    2024年02月12日
    浏览(30)
  • stm32 hal库uart使用 DMA中断只能发送一次的问题

    1.stm32 uart使用DMA,无论发送还是接收都各自有一个数据流中断。这个数据流中断是框架代码不必过多关心。 2.使用了DMA后,uart的global中断是否要使用?标准做法是在cubemx上要勾选的,不然,就会产生只能发送一次的问题。 问题的原因? 我相信这是hal库的问题,理论上讲有一

    2024年02月11日
    浏览(34)
  • 【STM32+HAL库+CubeMX】UART轮询收发、中断收发、DMA收发方法及空闲中断详解

    Author: DrinkCat(szt@drinkcat.com) Copyright © 2023 DrinkCat Original link: DrinkCat’s Blog UART是一种异步串行通信接口,常用于通过串口与外部设备进行通信。它通过发送和接收数据帧来实现数据传输,使用起来相对简单。UART通常包含发送器(Transmitter)和接收器(Receiver),通过两根信号线

    2024年02月10日
    浏览(34)
  • STM32 HAL库函数——HAL_UART_RxCpltCallback()详解

    HAL_UART_RxCpltCallback 是一个回调函数,用于在使用 HAL 库进行串口接收时处理接收完成事件。当使用 HAL_UART_Receive_IT 函数启动串口接收并且接收到指定数量的数据后,HAL 库会自动调用 HAL_UART_RxCpltCallback 函数。 回调函数是一种特殊的函数,它在特定事件发生时由系统或库调用,

    2024年02月13日
    浏览(30)
  • STM32 HAL库函数——HAL_UART_Receive_IT()详解

    huart :UART句柄,指向要使用的UART外设。 pData :指向数据缓冲区的指针,用于存储接收到的数据。 Size :要接收的数据元素(u8或u16)的数量。 返回值类型为 HAL_StatusTypeDef ,表示函数执行的状态。可能的返回值有: HAL_OK :函数执行成功。 HAL_ERROR :函数执行过程中发生错误

    2024年02月08日
    浏览(35)
  • STM32CubeMX-HAL库-UART串口接收中断回调函数代码分析

            CubeMx中HAL库函数的调用不同于库函数调用,在学习CubeMx串口通信时,不理解HAL库中的回调函数是怎么被调用的,于是查看每个的定义,参考其他人写的博客,总算弄明白了HAL库中断调用与库函数不同之处。写下这篇博客一是加深自己的理解,二是希望对不理解HA

    2024年02月02日
    浏览(44)
  • A11 STM32_HAL库函数 之 DMA通用驱动所有函数的介绍及使用

    序号 函数名 描述 1 HAL_DMA_Init() 初始化DMA通道。 2 HAL_DMA_DeInit() 反初始化DMA通道。 3 HAL_DMA_Start() 启动DMA传输。 4 HAL_DMA_Start_IT() 启动DMA传输并使用中断处理传输完成。 5 HAL_DMA_Abort() 中止DMA传输。 6 HAL_DMA_Abort_IT() 中止DMA传输并使用中断处理中止完成。 7 HAL_DMA_PollForTransfer() 轮询

    2024年04月12日
    浏览(25)
  • CubeMX生成的中断函数HAL_UART_IRQHandler(*huart1)如何使用。

    串口发送/接收函数 HAL_UART_Transmit();串口发送数据,使用超时管理机制  HAL_UART_Receive();串口接收数据,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送   HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收 串口中断函

    2024年02月15日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包