首页 > 其他分享 >DMA传输数据

DMA传输数据

时间:2023-12-04 18:47:44浏览次数:43  
标签:DMA DataB DMA2 传输数据 InitStructure printf 外设

前言

  DMA即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。本篇文章以STM32F4为例,不同型号可能略有不同。

一.DMA特性简介

  STM32F4有两个DMA控制器,一个控制器有8个数据流,一个数据流有8个通道(请求)
  值得注意的是,DMA1仅支持外设P->M,M->P,而不支持M->M,而DMA2全都支持。这是因为DMA1的存储区端口相比DMA2的要减少AHB2外设的访问权,同时DMA1外设端口是没有连接至总线矩阵的,只有连接到 APB1 外设,所以DMA1不能实现存储器到存储器传输。
image

二.代码配置

这里仅实现简单的M->M,传输一次即可,并将结果通过串口打印。代码如下
首先是初始化DMA:

//DMA_Streamx设置DMA控制器和数据流,如DMA2_Stream0
//chx设置通道
//par设置发送地址
//mar设置接收地址
//ndtr设置数据传输量
void MYDMA_Init(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{
    DMA_InitTypeDef  DMA_InitStructure;

    if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
    {
       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 
    }else
    {
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能 
    }
      DMA_DeInit(DMA_Streamx); 
      while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待 DMA 可配置

    /* 配置 DMA Stream */
    DMA_InitStructure.DMA_Channel = chx;  //通道选择
    DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址,其实就是传输起始地址
    DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址,数据接收地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;//存储器到外设模式
    DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量 
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable ;//外设增量模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式,一次传输,存储器到存储器只能一次模式 
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不用FIFO        
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
    DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream,初始化数据流
		
    DMA_Cmd(DMA_Streamx, ENABLE); //开启 DMA 传输
	
}

主函数代码如下

uint8_t DataA[] = {0x01, 0x02, 0x03, 0x04};
uint8_t DataB[] = {0, 0, 0, 0};

int main(void)
{
    uart_init(115200);
    delay_init(84);
    //delay_ms(500);
    printf("t:%d\r\n",DataB[0]);
    printf("t:%d\r\n",DataB[1]);
    printf("t:%d\r\n",DataB[2]);
    printf("t:%d\r\n",DataB[3]);
    MYDMA_Init(DMA2_Stream0,DMA_Channel_4,(uint32_t) DataA,(uint32_t) DataB,4);
    delay_ms(500);
    printf("t:%d\r\n",DataB[0]);
    printf("t:%d\r\n",DataB[1]);
    printf("t:%d\r\n",DataB[2]);
    printf("t:%d\r\n",DataB[3]);
  while(1){
	}
}

三.实验结果

通过串口查看数组B在DMA传输前后的数据,结果如下:
image
可知数据搬运成功。

标签:DMA,DataB,DMA2,传输数据,InitStructure,printf,外设
From: https://www.cnblogs.com/manchestercity/p/17875635.html

相关文章

  • avdmanager 返回了非零退出代码: 1。
    最近做了一次系统还原,很多功能都出现了异常重装了VisualStudio之后创建安卓仿真器的时候遇到问题,说“avdmanager返回了非零退出代码:1。”解决思路1搜索问题使用Google搜索,前两条是开发者社区,点进去看看2.看帖子详情不要看到问题关闭就划走,看看下面都说了什么3.......
  • HAL_RS485发送接收_DMA:编码器
    RS485编码器使用RS485读取多个编码器接收数据:空闲中断+DMA发送数据:DMA配置串口:基本与串口通信一致,增加接收和发送DMA,正常模式,另外增加485使能IO      接收数据:使能空闲中断        __HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);        _......
  • STM32使用SDIO模式和DMA实现SD卡的读写及擦除操作
    对于STM32操作SD卡来说,最重要的就算初始化、写操作、读操作、擦除这几个操作了。对于初始化部分上一篇文章已经分析,本篇就主要分析写、读、擦除操作。本篇函数来自于STM32提供的例程。参考野火的程序进行了解释,与野火函数有些不同。这几种函数完成之后,就是开始实现对SD卡进行操作了......
  • podman容器无法从外部连接
    启动容器时添加--nethost参数即可podmanrun-d-p80:80--rm--network=host--namenginxnginx如果有防火墙可以尝试放行端口#放行ufwallow80#关闭ufwdeny80......
  • Docker开始收费了,开始转学podman【第一篇podman容器的安装和基本操作】
    podman什么是Podman?Podman是无守护程序容器引擎,用于在Linux系统上开发,管理和运行OCI容器。容器可以以root用户或无根模式运行。简而言之:`aliasdocker=podman`。Podman(PodManager)是一个功能齐全的容器引擎,它是一个简单的无守护工具。Podman提供了一个类似Docker-CLI的命令......
  • 第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DM
     这个是我们初学RTOS面临的最直接问题,很多时候,简单的RTOS机制明白了,API也会调用了,就是添加到RTOS后,总感觉那里不对劲,怎么使用才是正确姿势。针对这些问题,本期视频教程,我们ThreadX内核教程穿插一期实战应用。使用RTOS要充分发挥其高效的多任务管理机制和实时性,这样也是我们采用RTOS......
  • STM32 HAL 使用串口IDLE中断+DMA实现收发
    STM32HAL使用串口IDLE中断+DMA实现收发cubeMX配置mx配置如下(省去系统时钟,烧录口,工程属性配置)注意:这里关闭ForceDMAchannelsInterrupts然后按下面配置即可(TX和RX的DMA都是normal模式)代码部分uart_com.h:#ifndef__UART_COM_H__#define__UART_COM_H__#include"......
  • 使用 AJAX、PHP 和服务器发送事件从 OpenAI 的 API 流式传输数据
    如何使用服务器发送事件(SSE)将数据从上述API流式传输到使用JavaScript和PHP的浏览器客户端?我已经研究这个问题好几个小时了,但我似乎无法弄清楚出了什么问题。作为参考,我尝试在这里调整解决方案:StreamDATAFromopenaiGPT-3APIusingPHP我的代码的其余部分或多或少与上......
  • podman 容器管理 docker替代,进阶版本?
    简介Docker的一个缺点是它有一个中央守护进程,它以root用户的身份运行,这对安全有影响。但这正是Podman的用武之地。padman完全兼容docker命令和镜像。Podman是一个无守护进程容器引擎,用于开发、管理和在你的Linux系统上以root或无root模式运行OCI容器。安装安......
  • Map---SortedMap&NavigableMap&TreeMap
    SortedMap概述A{@linkMap}thatfurtherprovidesa<em>totalordering</em>onitskeys.Themapisorderedaccordingtothe{@linkplainComparablenaturalordering}ofitskeys,orbya{@linkComparator}typicallyprovidedatsortedmapcreati......