【STM32 CubeMX】串口编程DMA+IDLE中断

2024-02-17 12:44

本文主要是介绍【STM32 CubeMX】串口编程DMA+IDLE中断,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、为什么要引入IDLE中断
  • 二、IDLE中断使用方式
    • 2.1 接收的三种情况
    • 2.2 函数的使用
      • 查询方式
      • 中断方式
      • DMA方式
      • 分析一个问题
  • 总结


前言

在嵌入式系统中,串口通信是一项关键的任务,而使用DMA(直接内存访问)结合IDLE中断进行串口编程,尤其是在STM32 CubeMX环境中,能够提高系统的效率和性能。STM32 CubeMX为STM32微控制器提供了图形化的配置工具,可以简化初始化代码的生成过程,使得串口编程变得更加容易。通过结合DMA和IDLE中断,我们可以实现高效的异步串口通信,确保数据传输的可靠性,同时减轻CPU的负担。


一、为什么要引入IDLE中断

比如我们的stm32接了一个wifi模块esp8266,esp8266会发来数据,假设我现在想去读数据,我使用DMA方式读数据,我不知道esp8266给我发多少数据,但是肯定不超过1024字节吧,然后我调用函数去读,读1024字节,如果他给我发了刚好1024字节,欸,那么就读成功了。如果他发1000数据,而且这1000数据是完整的了,但DMA的中断并不会调用,DMA中断只会在接收到一半或者全部接收完才会调用。

我们如何知道他的发的这些东西已经完整了呢?
我们知道,当串口发送数据的时候,他必定有一个起始位,如果接收方在这一节数据之后,发现这个引脚一直没有开始信号,在10bit的时间里发现对方都没有数据,他就认为数据发送完了,这时就会产生IDLE空闲中断。

比如说对方发了1bit的数据,由于一些原因卡壳了,过了10bit的数据时间,这时就会调用IDLE中断,可是数据并不完整啊。所以对于这种情况,IDLE中断是无意义的。

注意:IDLE中断用来传输大量数据的时候才有意义。

二、IDLE中断使用方式

2.1 接收的三种情况

当我们使用IDLE中断来接收数据的时候,他完成会有三种情况

  1. 第一种就是确实接收到了指定数据,调用的完成的回调函数(HAL_UART_RxCpltCallback被调用)
  2. 第二种就是IDLE中断调用了(HAL_UARTEx_RxEventCallback被调用)
  3. 第三种就是有错误发生导致中断(HAL_UART_ErrorCallback被调用)

2.2 函数的使用

查询方式

我们可以使用下面这个函数进行IDLE中断的查询方式进行查询:

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,uint32_t Timeout);

UART_HandleTypeDef *huart:
作用: 传递一个指向UART_HandleTypeDef结构体的指针,该结构体包含了UART的配置和状态信息。
解释: 这个参数用于标识特定的UART外设,通过该参数,函数知道应该对哪个UART进行操作。

uint8_t *pData:
作用: 指向要接收数据的缓冲区的指针。
解释: 这个参数指定了存储接收数据的缓冲区。当函数接收到指定数量的字节或达到超时条件时,接收到的数据将存储在该缓冲区中。

uint16_t Size:
作用: 要接收的数据字节数。
解释: 它定义了期望接收的字节数目。当接收的字节数达到这个值时,函数将数据接收到空闲状态(IDLE)。

uint16_t *RxLen:
作用: 指向用于存储实际接收到的数据字节数的指针。
解释: 当函数成功接收到数据时,它将更新此指针指向的变量,以反映实际接收到的字节数。这对于知道接收了多少数据很有用。

uint32_t Timeout:
作用: 接收数据的超时时间。
解释: 定义了等待接收数据的最大时间。如果在超时时间内未接收到指定数量的字节,函数将返回适当的错误代码。

如果有IDLE状态,他放回HAL_OK

中断方式

我们可以使用下面这种方式进行IDLE中断的接收:

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

这个函数就是去使能接收中断和IDLE中断。
如果发生了IDLE中断他会怎么做?
在串口1这里,IDLE中断也属于串口中断
在这里插入图片描述
下面就是如果有IDLE中断发生的代码:如果发现了IDLE中断,他会分两种情况处理
在这里插入图片描述
如果你使用DMA:
取消DMA,调用下面这个:
在这里插入图片描述
传入你收到了几个字符。

如果你使用中断:
禁止接收中断,调用下面这个:
在这里插入图片描述

传入你收到了几个字符。

当有IDLE中断时,调用HAL_UARTEx_RxEventCallback表示有IDLE中断了

DMA方式

我们可以使用下面这个函数进行DMA+IDLE接收:

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

当他产生IDLE中断后,他会调用HAL_UARTEx_RxEventCallback回调函数

分析一个问题

UART 的 IDLE 中断何时发生?RxD 引脚一开始就是空闲的啊,难道 IDLE 中断一直产生?
不是的。当我们使能 IDLE 中断后,它并不会立刻产生,而是:至少收到 1 个数据后,发现
在一个字节的时间里,都没有接收到新数据,才会产生 IDLE 中断。


总结

串口编程对于嵌入式系统至关重要,而在STM32 CubeMX环境中,利用DMA和IDLE中断的组合可以使串口通信更为高效。DMA允许数据在内存和外设之间直接传输,减轻了CPU的负担,提高了系统的响应速度。IDLE中断则使得在没有数据传输时,系统能够进入低功耗状态,进一步降低功耗。通过这样的串口编程方式,我们能够在保证性能的同时,实现更加节能和可靠的嵌入式系统。在STM32 CubeMX的支持下,配置串口通信变得更加简单,为嵌入式开发者提供了更高的开发效率。

这篇关于【STM32 CubeMX】串口编程DMA+IDLE中断的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717797

相关文章

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal