STM32使用DMA传输UART空闲中断中接收的数据遇到的问题以及解决方法

这篇具有很好参考价值的文章主要介绍了STM32使用DMA传输UART空闲中断中接收的数据遇到的问题以及解决方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32使用DMA传输UART空闲中断中接收的数据遇到的问题以及解决方法

CubeMX配置
  • 串口配置:使用默认配置(传输数据长度为8 Bit,奇偶检验无,停止位为1 Bit, 接收和发送都使能),因为我的是LIN项目所以使用的时串口的LIN模式,一般就是异步通信

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 打开DMA传输

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 打开串口接收中断

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 生成工程

  • 在mian.c中添加如下代码

    //添加方法定义
    void Util_Receive_IT(UART_HandleTypeDef *huart);
    
    //USER CODE BEGIN 4之间实现Util_Receive_IT方法
    /**
     * 重写接收中断函数
     */
    void Util_Receive_IT(UART_HandleTypeDef *huart)
    {
        if(huart == &huart2)
        {
            //开启DMA传输UART空闲中断中接收的数据,并在接收到UART空闲中断后停止传输
            //判断DMA接收是否正常启动
            if(HAL_UARTEx_ReceiveToIdle_DMA(huart, pLINRxBuff, LIN_RX_MAXSIZE) != HAL_OK)
            {
                //如果有错误的话,清空缓冲,置位一些标志
                HAL_UART_AbortReceive(huart);
                //重启DMA接收,pLINRxBuff是接收缓冲数组,接收的字节数,我这里LIN_RX_MAXSIZE是12
                HAL_UARTEx_ReceiveToIdle_DMA(huart, pLINRxBuff, LIN_RX_MAXSIZE);
            }
        }
    }
    
    //USER CODE BEGIN 2中添加如下代码
    //开启中断接收
    Util_Receive_IT(&huart2);
    
    //USER CODE BEGIN 4之间增加中断回调函数和错误回调函数的实现
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
        //LIN协议
        if (huart == &huart2)
        {
            //具体的数据处理函数
        }
        //重启DMA接收
        Util_Receive_IT(huart);
    }
    /**
     * 重写UART错误中断处理程序,重新开启中断
     *
     * @brief UART error callback.
     * @param huart UART handle.
     * @retval None
     */
    void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
    {
        /* Prevent unused argument(s) compilation warning */
        //解决串口溢出,导致不断进入串口中断函数,使MCU过载的问题
        if(HAL_UART_GetError(huart) & HAL_UART_ERROR_ORE)
        {
            //清除ORE标志位
            __HAL_UART_FLUSH_DRREGISTER(huart);
            Util_Receive_IT(huart);
            huart->ErrorCode = HAL_UART_ERROR_NONE;
        }
    }
    
  • 存在的问题:

    • LIN_RX_MAXSIZE是12,所以程序最多可以接收12个字节的数据,但是因为HAL_UARTEx_RxEventCallback回调函数会处理半满中断,全满中断和串口空闲中断,所以接收6个字节(包括6个字节)的数据中断回调函数中Size参数得到的值是正确的,并且保存到接收缓冲数组中的数据也是正确的。当接收超过6个字节的数据,中断回调函数中Size参数得到的值是LIN_RX_MAXSIZE一半,也就是6,只要字节数在7-12之间,参数Size的值永远是6,数据是可以正常接收的。
    • 原因可能开启了DMA通道的中断,然后HAL_UARTEx_RxEventCallback中断回调函数会处理半满中断、全满中断和串口空闲中断这三种情况,半满中断先执行导致Size会变成接收字节数的一半。
解决方法
  • 取消DMA通道的中断

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 在串口页面查看中断,可以发现DMA通道的中断已经取消了

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 代码不需要修改

  • 存在的问题:

    • 接收1-11个字节的数据是没有问题的,只要接收12个字节的数据,在串口调试过程中,点击串口的发送按钮,需要发送两次12个字节的数据,才会进入到中断回调函数的断点中,并且中断回调函数的Size参数得到的值是不正确的,接收缓存中保存的数据也是不正确的
    • 还有一个问题,当进入中断回调函数的断点中,再次用串口调式助手发送一次数据,当前的中断回调函数执行完后,再次使用串口调试助手发送12字节的数据,中断回调函数只会接收到一个字节的数据
    • 目前没有找到原因
再次开启DMA通道中断
  • 开启DMA通道中断,虽然Size会有错误,但是接收的数据是正确的,只要全满中断和串口空闲中断就可以了,不需要半满中断

  • 通过网上查阅资料,可以使用__HAL_DMA_DISABLE_IT()宏来禁用半满中断

  • stm32g0xx_hal_dma.h定义了全满中断、半满中断和错误中断

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

  • 修改代码

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

    空闲中断加dma数据错位,stm32,单片机,嵌入式硬件

    //开启中断接收
    Util_Receive_IT(&huart2);
    //禁用DMA半满接收中断
    __HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
    
    
    /**
     * 重写接收中断函数
     */
    void Util_Receive_IT(UART_HandleTypeDef *huart)
    {
        if(huart == &huart2)
        {
            //开启DMA传输UART空闲中断中接收的数据,并在接收到UART空闲中断后停止传输
            //判断DMA接收是否正常启动
            if(HAL_UARTEx_ReceiveToIdle_DMA(huart, pLINRxBuff, LIN_RX_MAXSIZE) != HAL_OK)
            {
                //如果有错误的话,清空缓冲,置位一些标志
                HAL_UART_AbortReceive(huart);
                //重启DMA接收
                HAL_UARTEx_ReceiveToIdle_DMA(huart, pLINRxBuff, LIN_RX_MAXSIZE);
            }
            //禁用DMA半满接收中断
            __HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
        }
    }
    
  • 每次开启DMA接收时,都要禁用DMA半满接收中断

  • 至此,可以正常接收数据,并且中断回调函数中的Size得到的值也是正确的文章来源地址https://www.toymoban.com/news/detail-752008.html

到了这里,关于STM32使用DMA传输UART空闲中断中接收的数据遇到的问题以及解决方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • stm32串口空闲中断+DMA传输接受不定长数据+letter shell 实现命令行

    空闲中断(IDLE),俗称帧中断,即第一帧数据接收完毕到第二帧数据开始接收期间存在一个空闲状态(每接收一帧数据后空闲标志位置1),检测到此空闲状态后即执行中断程序。 空闲中断的优点在于省去了帧头帧尾的检测 ,进入中断程序即意味着已经接收到一组完整数据,仅需

    2024年02月03日
    浏览(60)
  • 【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日
    浏览(40)
  • GD32实现串口空闲(IDLE)中断 + DMA机制接收数据

    前言 串口功能在单片机开发中,是比较常用的外设,熟练使用串口功能也是驱动开发必备的技能之一。 DMA 是一种CPU辅助手段,可以在CPU不参与的情况下,是做一些辅助CPU的事情,如通常的数据搬运。 在没有DMA之前,数据读取时,需要CPU的处理,在多任务处理时,增加资源紧

    2023年04月13日
    浏览(47)
  • 衔尾法解决当无法使用空闲中断以及DMA中断时配置DMA接收串口不定长数据

    问题:类似K线与蓝牙接收模块,要求由原来的接收串口中断改为DMA接收。据说要用到空闲中断与DMA中断,但是经仿真发现DMA每完成传输一个数据(比如1BYTE)就会进入空闲中断(k线发现这种情况),考虑到这样进入中断的频率和以前串口接收中断的频率差不多,所以放弃此方案,

    2024年02月09日
    浏览(56)
  • STM32_串口中断接收数据_空闲中断

    引言: 1、串口中断接收数据首先要保证完整性(设置串口中断优先级) 2、串口中断接收数据要保证实时性(打开串口空闲中断——空闲时间是2个字节的时间) 3、串口中断接收+DMA缓存,等到需要处理时候在进行处理数据 方法一:直接利用stm32的RXNE和IDLE中断进行接收不定字

    2024年02月13日
    浏览(51)
  • STM32 F4串口空闲中断 + DMA实现数据发送

    最近在做 STM32 + ROS车的项目,STM32与ROS之间通信由于数据量大,所以在 STM32端 使用 空闲中断 + DMA 的方案来减轻 CPU 的压力。 一、空闲中断 空闲中断 顾名思义为空了,闲了,没事了进的中断,在 没有数据流 的时候会进入进行读取。 在我们串口进行发送时实则为连续发送,两

    2024年02月16日
    浏览(64)
  • STM32 UART串口通信IDLE空闲中断的使用步骤

    参考了各路大神的资料,蒙蔽了半天,终于学会了,记录一下,以后忘了可以回来复习参考。 一、首先在stm32cube中配置打开对应uart串口的中断 二、工程main函数调用 __HAL_UART_ENABLE_IT(huart1,UART_IT_IDLE);//hal库宏定义,使能串口空闲中断     HAL_UART_Receive_DMA(huart1,data,sizeof(data));//使

    2024年02月12日
    浏览(43)
  • STM32实战(三):利用空闲中断从串口接收任意长数据

    “ 想起密码了,终于想起密码了(´・ω・`) ” 这次我们利用STM32F103的UART内部的空闲中断来实现对串口任意长数据的接收,通过简洁的手段解决了接收端在事前无法得知数据长度的问题。本次教程我们需要一块STM32核心板与一个USB转TTL工具。 STM32的异步串口接收寄存器可以存放

    2024年02月13日
    浏览(46)
  • 环形队列+DMA空闲中断+接收串口数据

    本次实验利用环形队列+DMA空闲中断+串口。。通过这个实验可以非常深入的理解队列,DMA,串口的知识。如果你能自己实现掌握这个实验,那么你应该基本掌握了队列,DMA,串口的知识。 本次使用的是用环形队列当缓冲器区接收串口数据。我们可以先区了解DMA的空闲中断。本次

    2024年02月13日
    浏览(44)
  • STM32使用三种方式(阻塞、中断、DMA)实现串口发送和接收数据

    记录下学习STM32开发板的心得的和遇见的问题。 板卡型号:STM32F405RGT6 软件:STM32CubeMX、IAR STM32串口外设提供了3种接收和发送方式:阻塞、中断、DMA,主要给大家分享中断方式接收不定长数据和DMA使用空闲中断接收不定长数据。 阻塞发送: 阻塞接收: 两个函数需要注意的就

    2024年02月03日
    浏览(51)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包