笔记11:STM32—— DMA简介和结构介绍

一. DMA简介

  1. DMA,即为 Direct Memory Access,直接存储器访问。实现数据高速在外设寄存器与存储器之间或者存储器与存储器之间传输提供了高效的方法。之所以称之为高效,是因为 DMA 传输实现高速数据移动过程无需任何 CPU 操作控制。这里的外设一般指外设的数据寄存器,比如 ADC、 SPI、 I2C、 DCMI 等等外设的数据寄存器,存储器一般是指片内 SRAM、外部存储器、片内 Flash 等等。
    作用:为CPU减负
  2. STM32F4有两个DMA控制器,每个 DMA 控制器有 8 个数据流,每个数据流有多达 8 个通道(或称请求)
    在这里插入图片描述
    DMA1:只能实现外设寄存器与存储器之间的数据传输
    外设–>SRAM SRAM–>外设

    在这里插入图片描述
    DMA2 :不仅能实现外设寄存器到存储器之间的数据搬运,还可以实现存储器到存储器之间的数据传输
    外设–>SRAM SRAM–>外设
    内部的FLASH(在这里可以看作外设)–>SRAM

二.DMA 结构框图
在这里插入图片描述
2.1 8通道+8数据流
流:即使数据走的道路,每个DMA控制器有8个独立的数据流,每一趟传输数据量最大为65535,如果数据单位为字的话,每次能够传输256KB。这里应该如何理解了?举个例子:如果这一次总的任务是传输完256KB,但是可以分多趟传过去,一趟可以传输1KB,也可以是其他值,但是这一次传输完成之后必须把256KB传输完。
通道:每个数据流有8个通道选择。每个通道对应不同的DMA请求。见上图。
在数据流和通道的配置上,如果是外设和存储器之间的访问,通过查阅上面的表格就可以了,但是如果你在使用DMA2中的存储器到存储器时,对数据流和通道就可以任意配置了。
在这里插入图片描述
上图是DMA相关寄存器,详见STM32F4XX中文参考手册。
2.2 仲裁器(解决多个DMA请求一起来的情况)
2.2.1 软件阶段:通过程序确定优先级,分为四个等级:非常高,高,中,低。
在这里插入图片描述
2.2.2 硬件阶段:若软件优先级是一样的,数据流编号小的优先级高。
但是注意的是:通一个数据流只能使用一个通道,同一个DMA控制器可以使用多个数据流。
2.3 FIFO(first in first out ,先进先出原则。源和目标之间的一个中转站)
每个数据流都独立拥有四级(1/4、 1/2、 3/4和满) 32 位 FIFO(先进先出存储器缓冲区),总共FIFO的存储容量是4*32=128位。
DMA 传输具有 FIFO模式和直接模式。这两种模式的数据都要经过FIFO这个中转站。
直接模式下,数据进了FIFO后就直接出去,不做停留。进一个出去一个。
FIFO模式下,数据进了FIFO后要停留,待数据到达了阈值后,再根据配置选择一次出去多少个数据。
两种模式配置和FIFO阈值配置
FIFO模式下数据出去个方式选择
这张图片中便是这是FIFO模式下数据出去的方式,当设置成单次传输时,和直接模式没有什么区别。图中节拍可以理解为数据传输的单位,比如我一次传输1个字节,那么4个节拍就说的是我传输完4个字节后在根据突发次数选择数据送出去。但是需要注意的是,一旦FIFO突发传输模式开始传输数据后,CPU是没办法中断的,它仍然会把数据传输完成。
FIFO 对于要求源地址和目标地址数据宽度不同时非常有用,比如源数据是源源不断的字节数据,而目标地址要求输出字宽度的数据,即在实现数据传输时同时把原来 4 个 8 位字节的数据拼凑成一个 32 位字数据。此时使用 FIFO 功能先把数据缓存起来,分别根据需要输出数据。
FIFO 另外一个作用使用于突发(burst)传输。
FIFO模式和突发模式时一起使用的:
在这里插入图片描述
途中的SIZE就是节拍的含义,数据一次传输的单位
后面三列就是数据出去的方式。举个例子来说:当我们数据传输以字节为单位时,FIFO级别设置为1/2,即每一级都是2个字节,FIFO总共就要容纳8个字节,那么FIFO中的数据到达8个字节以后,你可以选择4个字节(节拍)的2次突发传输,那么一次就传4个字节。如果你选择8个字节(节拍)的1次突发传输,那么一次就把8个字节送出去了。
FIFO框图中的4(存储器端口),5(外设端口),6(编程端口)部分不涉及到程序。
三. DMA 初始化结构体

typedef struct
{
uint32_t DMA_Channel;  //DMA数据流对应的通道
uint32_t DMA_PeripheralBaseAddr;//外设基地址
uint32_t DMA_Memory0BaseAddr;//存储器基地址
uint32_t DMA_DIR;//传输方向,是存储器到外设还是存储器到存储器
uint32_t DMA_BufferSize;//一次传输的数据量大小
uint32_t DMA_PeripheralInc;//外设地址是否增量
uint32_t DMA_MemoryInc;//存储器地址是否增量
uint32_t DMA_PeripheralDataSize;//外设传输单位,字节还是字还是半字等等
uint32_t DMA_MemoryDataSize;//存储器传输单位,节拍定义
uint32_t DMA_Mode;//是否循环采集
uint32_t DMA_Priority;//DMA优先级别,是较高,高,中还是低
uint32_t DMA_FIFOMode;//FIFO模式是否开启
uint32_t DMA_FIFOThreshold; //FIFO模式阈值
uint32_t DMA_MemoryBurst;//用来配置存储器是几个单位数据的突发传输
uint32_t DMA_PeripheralBurst;//用来配置外设是几个单位数据的突发传输
}DMA_InitTypeDef;


本文是观看野火视频学习总结性文章

### STM32 SPI DMA与lwIP集成 #### 一、概述 在嵌入式开发中,STM32微控制器支持多种通信接口,其中包括SPI(串行外设接口)。为了提高数据传输效率并减轻CPU负担,可以利用DMA(直接存储器访问)技术。当涉及到网络应用时,通常会结合轻量级的TCP/IP协议栈——lwIP来处理复杂的网络事务。 对于STM32互联型单片机而言,其以太网DMA可以在不依赖于CPU的情况下完成内存以太网外设间的数据交换[^1]。这意味着,在设计基于SPI总线与其他设备通讯的同时,也可以借助DMA机制优化整个系统的性能表现,并且能够有效地管理来自不同源的数据流,比如通过以太网接收到的信息可以直接由DMA搬运至指定缓冲区等待进一步处理。 #### 二、硬件配置 确保所使用的STM32型号具备足够的资源用于同时运行SPI、DMA以及lwIP库函数。这可能意味着需要评估目标板载有的RAM大小能否满足程序需求,特别是考虑到TCP/IP协议本身较为庞大而MCU内部可用空间有限的情况[^2]。 #### 三、软件设置 ##### 初始化SPI模块 ```c // 设置SPI参数... void MX_SPI_Init(void){ hspi.Instance = SPIx; hspi.Init.Mode = SPI_MODE_MASTER; // 或者其他模式 HAL_SPI_Init(&hspi); } ``` ##### 启动DMA通道并与SPI关联 ```c static void MX_DMA_Init(void){ __HAL_RCC_DMA_CLK_ENABLE(); hdma_spi_tx.Instance = DMAt_Channel; hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE; hal_dma_init(&hdma_spi_tx); __HAL_LINKDMA(&hspi, hdmatx, hdma_spi_tx); } int main(){ ... MX_DMA_Init(); MX_SPI_Init(); ... } ``` ##### 结合lwIP进行网络编程 由于lwIP是一个独立运作的组件,它并不直接参与到SPI或DMA的操作当中。但是可以通过回调函数等方式让两者协同工作。例如,在接收到来自远端主机的消息之后触发一次完整的读写周期: ```c err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err){ static uint8_t buffer[BUFFER_SIZE]; struct pbuf *p; while(1){ /* 接收数据 */ p = tcp_recvmbox_fetch(newpcb->recvmbox, NULL); if(p != NULL){ memcpy(buffer, p->payload, p->len); // 将buffer中的内容经由SPI发送出去... HAL_SPI_Transmit_DMA(&hspi, (uint8_t*)buffer, p->len); pbuf_free(p); } } return ERR_OK; } ``` 上述代码片段展示了如何在一个简单的TCP服务器模型里调用`HAL_SPI_Transmit_DMA()`方法向外部器件传递信息。需要注意的是实际项目可能会更加复杂一些,因此建议开发者仔细阅读官方文档并参照具体应用场景调整相应逻辑。 #### 四、注意事项 - 在编写应用程序之前,请务必查阅最新的STMicroelectronics提供的参考手册技术笔记。 - 对于特定版本的固件库支持工具链也要保持更新状态以便获得最佳兼容性稳定性。 - 考虑到实时性的要求,合理规划任务优先级服务时间窗口是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值