DMA技术在STM32中优化UART、SPI和I2C通信性能的研究与实现

DMA(Direct Memory Access,直接存储器访问)技术可以在STM32微控制器上优化UART、SPI和I2C等通信性能。DMA可以实现数据的高速传输,减轻CPU的负担,提高系统性能。在本篇文章中,我将探讨DMA技术在STM32中优化这些通信协议的研究和实现。

一、DMA工作原理

DMA可以实现外设与存储器之间的直接数据传输,不需要CPU的干预。DMA控制器位于片内,独立于CPU,可以直接访问片外存储器,以及与UART、SPI和I2C等外设进行数据交换。

DMA工作的基本原理如下:
1. CPU配置DMA的控制寄存器,包括源地址、目的地址、传输长度和传输模式等。
2. 当满足触发条件时,DMA控制器开始进行数据传输。
3. DMA控制器从源地址读取数据,然后将数据传输到目的地址。
4. 数据传输完成后,DMA控制器产生中断或通知CPU。

通过使用DMA技术,外设与存储器之间的数据传输可以在不干扰CPU的情况下进行,从而提高系统性能。

二、DMA在STM32中的应用

1. UART通信中的DMA
在UART通信中,使用DMA技术可以高效地完成数据的发送和接收操作。

```c
#include "stm32f4xx.h"

void UART_DMA_Init() {
  // 使能UART时钟和DMA时钟
  RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
  
  // 配置UART和GPIO引脚
  
  // 配置UART的DMA模式和相关寄存器
  USART1->CR3 |= USART_CR3_DMAT | USART_CR3_DMAR; // 使能DMA发送和接收
  DMA2_Stream7->CR |= DMA_SxCR_DIR_0; // 设置DMA为内存到外设模式
  
  // 配置DMA传输相关寄存器和缓冲区
  DMA2_Stream7->PAR = (uint32_t)(&(USART1->DR)); // 外设地址为UART数据寄存器
  DMA2_Stream7->M0AR = (uint32_t)buffer; // 内存地址为数据缓冲区地址
  DMA2_Stream7->NDTR = sizeof(buffer); // 传输长度
  
  // 配置DMA传输模式、优先级等
  DMA2_Stream7->CR |= DMA_SxCR_MINC | DMA_SxCR_PINC; // 允许内存和外设地址自动增加
  DMA2_Stream7->CR |= DMA_SxCR_TCIE; // 使能传输完成中断
  
  // 使能DMA传输
  DMA2_Stream7->CR |= DMA_SxCR_EN;
}

void DMA2_Stream7_IRQHandler() {
  if (DMA2->HISR & DMA_HISR_TCIF7) {
    // 数据传输完成
    
    // 清除标志位
    DMA2->HIFCR |= DMA_HIFCR_CTCIF7;
  }
}

int main() {
  UART_DMA_Init();

  while (1) {
    // 向缓冲区写入数据
    // ...
    
    // 发起DMA传输
    DMA2_Stream7->CR |= DMA_SxCR_EN; // 手动启动DMA传输
  }
}
```

2. SPI通信中的DMA
在SPI通信中,DMA技术可以实现数据的高速传输、减少CPU的占用以及降低通信延迟。

```c
#include "stm32f4xx.h"

void SPI_DMA_Init() {
  // 使能SPI时钟和DMA时钟
  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
  
  // 配置SPI和GPIO引脚
  
  // 配置SPI的DMA模式和相关寄存器
  SPI1->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; // 使能DMA发送和接收
  DMA2_Stream3->CR |= DMA_SxCR_DIR_0; // 设置DMA为内存到外设模式
  
  // 配置DMA传输相关寄存器和缓冲区
  DMA2_Stream3->PAR = (uint32_t)(&(SPI1->DR)); // 外设地址为SPI数据寄存器
  DMA2_Stream3->M0AR = (uint32_t)txBuffer; // 内存地址为发送数据缓冲区地址
  DMA2_Stream3->NDTR = sizeof(txBuffer); // 传输长度
  
  DMA2_Stream2->PAR = (uint32_t)(&(SPI1->DR)); // 外设地址为SPI数据寄存器
  DMA2_Stream2->M0AR = (uint32_t)rxBuffer; // 内存地址为接收数据缓冲区地址
  DMA2_Stream2->NDTR = sizeof(rxBuffer); // 传输长度
  
  // 配置DMA传输模式、优先级等
  DMA2_Stream3->CR |= DMA_SxCR_MINC; // 允许内存地址自动增加
  DMA2_Stream2->CR |= DMA_SxCR_MINC | DMA_SxCR_PL_1; // 允许内存地址自动增加,设置高优先级
  
  // 使能DMA传输
  DMA2_Stream3->CR |= DMA_SxCR_EN;
  DMA2_Stream2->CR |= DMA_SxCR_EN;
}

void DMA2_Stream3_IRQHandler() {
  if (DMA2->LISR & DMA_LISR_TCIF3) {
    // 数据传输完成
    
    // 清除标志位
    DMA2->LIFCR |= DMA_LIFCR_CTCIF3;
  }
}

void DMA2_Stream2_IRQHandler() {
  if (DMA2->LISR & DMA_LISR_TCIF2) {
    // 数据传输完成
    
    // 清除标志位
    DMA2->LIFCR |= DMA_LIFCR_CTCIF2;
  }
}

int main() {
  SPI_DMA_Init();

  while (1) {
    // 向发送缓冲区写入数据
    // ...
    
    // 发起SPI的DMA发送
    DMA2_Stream3->CR |= DMA_SxCR_EN; // 手动启动DMA发送
  }
}
```

3. I2C通信中的DMA
在I2C通信中,DMA技术可以实现数据的高速传输、减少CPU的占用以及提高通信的稳定性。

```c
#include "stm32f4xx.h"

void I2C_DMA_Init() {
  // 使能I2C时钟和DMA时钟
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
  
  // 配置I2C和GPIO引脚
  
  // 配置I2C的DMA模式和相关寄存器
  I2C1->CR2 |= I2C_CR2_DMAEN; // 使能DMA
  DMA1_Stream6->CR |= DMA_SxCR_DIR_1; // 设置DMA为外设到内存模式
  
  // 配置DMA传输相关寄存器和缓冲区
  DMA1_Stream6->PAR = (uint32_t)(&(I2C1->DR)); // 外设地址为I2C数据寄存器
  DMA1_Stream6->M0AR = (uint32_t)rxBuffer; // 内存地址为接收数据缓冲区地址
  DMA1_Stream6->NDTR = sizeof(rxBuffer); // 传输长度
  
  // 配置DMA传输模式、优先级等
  DMA1_Stream6->CR |= DMA_SxCR_MINC | DMA_SxCR_PL_1; // 允许内存地址自动增加,设置高优先级
  
  // 使能DMA传输
  DMA1_Stream6->CR |= DMA_SxCR_EN;
}

void DMA1_Stream6_IRQHandler() {
  if (DMA1->HISR & DMA_HISR_TCIF6) {
    // 数据传输完成
    
    // 清除标志位
    DMA1->HIFCR |= DMA_HIFCR_CTCIF6;
  }
}

int main() {
  I2C_DMA_Init();

  while (1) {
    // 向I2C发送数据
    // ...
    
    // 发起I2C的DMA发送
    DMA1_Stream6->CR |= DMA_SxCR_EN; // 手动启动DMA发送
  }
}
```

三、总结
DMA技术在STM32上的应用可以显著提高UART、SPI和I2C等通信协议的性能和效率,减轻CPU的负担,提高系统的稳定性。
通过上述代码示例,可以实现UART、SPI和I2C的DMA传输。在实际应用中,需要根据具体需求和外设功能进行配置,以实现最佳的性能和稳定性。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

代码获取、问题探讨及文章转载可私信。

 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/334607.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL之存储引擎

存储引擎简介 存储引擎就是存储数据,建立索引、更新/查询数据等技术的实现方式。存储引擎基于表,而不是基于库的,所以存储引擎也可被称为表类型。 查询建表语句: show create table 表名; 查询当前数据库支持的存储引擎&#…

redis未授权访问全漏洞复现

redis未授权访问全漏洞复现 Redis 有关的漏洞具有明显的时间分段性,在15年11月之前,主要是未授权导致的数据泄露,获得一些账号密码。另外还可以 DoS(参考:Sangfor VMP redis unauthorized access vulnerability&#…

54 C++ 多线程 条件变量 condition_variable,wait(),notify_one()

一 前提:之前代码的缺陷 在前面我们使用两个线程 ,一个线程读,一个线程写来完成对于共享数据访问。 我们把这个代码 先放在这里,方便回忆,然后说明代码可能存在的问题,然后改动。 class Teacher174 { pri…

Producer源码解读

Producer源码解读 在 Kafka 中, 我们把产生消息的一方称为 Producer 即 生产者, 它是 Kafka 的核心组件之一, 也是消息的来源所在。它的主要功能是将客户端的请求打包封装发送到 kafka 集群的某个 Topic 的某个分区上。那么这些生产者产生的消息是怎么传到 Kafka 服务端的呢&a…

使用emby在Nas群晖搭建一个私人影院

1、安装Emby 打开套件中心搜索emby并安装 2、新增一个共享文件夹 设置好,无脑下一步到应用 给emby赋予这个文件夹的读写权限 保存 3、打开emby service 选择媒体库

chatgpt的实用技巧四temperature 格式

四、temperature 格式 GPT3.5 temperature 的范围为:0-0.7; GPT4.0 temperature 的范围为:0-1; 当 temperature 为 0 时候,结果可稳定。 当 temperature 为 0.7/1 时候,结果发散具备创力。 数值越大&a…

操作教程|JumpServer堡垒机结合Ansible进行批量系统初始化

运维人员常常需要对资产进行系统初始化的操作,而初始化服务器又是一项繁琐的工作,需要花费运维人员大量的时间和精力。为了提高效率,许多组织会使用自动化工具和脚本来简化这些任务。自动化工具的运用可以大幅降低运维人员的工作量&#xff0…

Elasticsearch 数据类型相关总结:快速参考指南【记录】

在Elasticsearch中,有多种数据类型可用于定义字段。 在开始了解数据类型之前,首先要知道,在Elasticsearch中,分词处理主要针对文本字段,而对于其他类型字段(如数值、日期、布尔等),通…

MCM备赛笔记——熵权法

Key Concept 熵权法是一种基于信息熵概念的权重确定方法,用于多指标决策分析中。信息熵是度量信息量的不确定性或混乱程度的指标,在熵权法中,它用来反映某个指标在评价过程中的分散程度,进而确定该指标的权重。指标的分散程度越高…

[C#]winform部署openvino调用padleocr模型

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR 【算法介绍】 OpenVINO和PaddleOCR都是用于计算机视觉应用的工具,但它们有不同的特点和用途。OpenVINO是一个由Intel开发的开源工具套件,主要用于加速深度学习推理,而PaddleOC…

Javaweb之SpringBootWeb案例员工管理之删除员工的详细解析

3.3 删除员工 查询员完成之后,我们继续开发新的功能:删除员工。 3.3.1 需求 当我们勾选列表前面的复选框,然后点击 "批量删除" 按钮,就可以将这一批次的员工信息删除掉了。也可以只勾选一个复选框,仅删除一…

【开源】基于JAVA语言的免税店商城管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.2 研究方法 三、系统展示四、核心代码4.1 查询免税种类4.2 查询物品档案4.3 新增顾客4.4 新增消费记录4.5 审核免税 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的免税店商城管理系…

代码之外:工程师的成长进阶秘籍

程序员只懂技术能行吗? 为什么说技术人员“说”和“写”总得擅长一个? 你以为的“关注结果”是真的结果吗? 从一线工程师跃升团队管理者一共分几步? 在不断变化的职场环境中,技术人如何保持竞争力并实现自我增值&a…

【消息队列】RocketMQ 生产和消费中的集群模式和广播模式

在消息队列系统中,生产者和消费者的模式通常包括集群模式和广播模式。这两种模式分别用于不同的场景,具有不同的特点和优势。 1. 集群模式(Cluster Mode): 在集群模式下,多个相同角色的实例组成一个集群&…

精品量化公式——“筹码动态”,筹码动态改进版,增加了三个买点信号标识

不多说,直接上效果如图: ► 日线表现 代码评估 技术指标代码评估: 散筹估算: 使用EMA(指数移动平均)方法计算(WINNER(C*1.1)-WINNER(C*0.9))*70的3日均线,用黄色粗线表示。这是用于估算市场中散户投资者的…

三维重建(3)--单视几何

目录 一、无穷远点、无穷远线、无穷远平面 1、2D平面上的无穷远问题 2、3D平面上的无穷远问题 二、影消点与影消线 1、2D平面上的无穷远点,无穷远线变换 2、影消点 3、影消线 三、单视重构 1、两平行线夹角与影消线关系 2、单视图标定 一、无穷远点、无…

Vue3 在 history 模式下通过 vite 打包部署白屏

Vue3 在 history 模式下通过 vite 打包部署后白屏; 起因 hash 模式 url 后面跟个 # 强迫症犯了改成了 history,就此一波拉锯战开始了 ... 期间 nigix 和 router 各种反复排查尝试最终一波三折后可算是成功了 ... Vue官方文档 具体配置可供参考如下: 先简要介绍下,当前项目打包…

【网站项目】331基于jsp的超市库存商品管理系统

🙊作者简介:多年一线开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

paramiko 、netmiko抛出 No existing session的解决方法。

写这篇文章,是因为我在H3C交换机上很正常的代码,可以ssh登录,但huawei交换机上失败,用CSDN上的文章关于allow_agentFalse,look_for_keysFalse 处理还是失败后,找相关的一些帖子总结的必须修改paramiko的源代码文章。 如…