当前位置: 首页 > java >正文

STM32标准库-DMA直接存储器存取

文章目录

  • 一、DMA
    • 1.1简介
    • 1.2存储器映像
    • 1.3DMA框图
    • 1.4DMA基本结构
    • 1.5DMA请求
    • 1.6数据宽度与对齐
    • 1.7数据转运+DMA
    • 1.8ADC扫描模式+DMA
  • 二、数据转运+DMA
    • 2.1接线图
    • 2.2代码
    • 2.3相关API

一、DMA

1.1简介

  • DMA(Direct Memory Access)直接存储器存取

  • DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源

  • 12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)每个通道都支持软件触发和特定的硬件触发

  • STM32F103C8T6 DMA资源:DMA1(7个通道)

1.2存储器映像

在这里插入图片描述

1.3DMA框图

在这里插入图片描述

1.4DMA基本结构

在这里插入图片描述

1.5DMA请求

在这里插入图片描述

1.6数据宽度与对齐

在这里插入图片描述

1.7数据转运+DMA

在这里插入图片描述

1.8ADC扫描模式+DMA

在这里插入图片描述

二、数据转运+DMA

2.1接线图

在这里插入图片描述

2.2代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyDMA.h"uint8_t DataA[] = {0x01, 0x02, 0x03, 0x04};				//定义测试数组DataA,为数据源
uint8_t DataB[] = {0, 0, 0, 0};							//定义测试数组DataB,为数据目的地int main(void)
{/*模块初始化*/OLED_Init();				//OLED初始化MyDMA_Init((uint32_t)DataA, (uint32_t)DataB, 4);	//DMA初始化,把源数组和目的数组的地址传入/*显示静态字符串*/OLED_ShowString(1, 1, "DataA");OLED_ShowString(3, 1, "DataB");/*显示数组的首地址*/OLED_ShowHexNum(1, 8, (uint32_t)DataA, 8);OLED_ShowHexNum(3, 8, (uint32_t)DataB, 8);while (1){DataA[0] ++;		//变换测试数据DataA[1] ++;DataA[2] ++;DataA[3] ++;OLED_ShowHexNum(2, 1, DataA[0], 2);		//显示数组DataAOLED_ShowHexNum(2, 4, DataA[1], 2);OLED_ShowHexNum(2, 7, DataA[2], 2);OLED_ShowHexNum(2, 10, DataA[3], 2);OLED_ShowHexNum(4, 1, DataB[0], 2);		//显示数组DataBOLED_ShowHexNum(4, 4, DataB[1], 2);OLED_ShowHexNum(4, 7, DataB[2], 2);OLED_ShowHexNum(4, 10, DataB[3], 2);Delay_ms(1000);		//延时1s,观察转运前的现象MyDMA_Transfer();	//使用DMA转运数组,从DataA转运到DataBOLED_ShowHexNum(2, 1, DataA[0], 2);		//显示数组DataAOLED_ShowHexNum(2, 4, DataA[1], 2);OLED_ShowHexNum(2, 7, DataA[2], 2);OLED_ShowHexNum(2, 10, DataA[3], 2);OLED_ShowHexNum(4, 1, DataB[0], 2);		//显示数组DataBOLED_ShowHexNum(4, 4, DataB[1], 2);OLED_ShowHexNum(4, 7, DataB[2], 2);OLED_ShowHexNum(4, 10, DataB[3], 2);Delay_ms(1000);		//延时1s,观察转运后的现象}
}

MyDMA.c

#include "stm32f10x.h"                  // Device headeruint16_t MyDMA_Size;					//定义全局变量,用于记住Init函数的Size,供Transfer函数使用/*** 函    数:DMA初始化* 参    数:AddrA 原数组的首地址* 参    数:AddrB 目的数组的首地址* 参    数:Size 转运的数据大小(转运次数)* 返 回 值:无*/
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{MyDMA_Size = Size;					//将Size写入到全局变量,记住参数Size/*开启时钟*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);						//开启DMA的时钟/*DMA初始化*/DMA_InitTypeDef DMA_InitStructure;										//定义结构体变量DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;						//外设基地址,给定形参AddrADMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//外设数据宽度,选择字节DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;			//外设地址自增,选择使能DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;							//存储器基地址,给定形参AddrBDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;			//存储器数据宽度,选择字节DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;					//存储器地址自增,选择使能DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;						//数据传输方向,选择由外设到存储器DMA_InitStructure.DMA_BufferSize = Size;								//转运的数据大小(转运次数)DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;							//模式,选择正常模式DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;								//存储器到存储器,选择使能DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;					//优先级,选择中等DMA_Init(DMA1_Channel1, &DMA_InitStructure);							//将结构体变量交给DMA_Init,配置DMA1的通道1/*DMA使能*/DMA_Cmd(DMA1_Channel1, DISABLE);	//这里先不给使能,初始化后不会立刻工作,等后续调用Transfer后,再开始
}/*** 函    数:启动DMA数据转运* 参    数:无* 返 回 值:无*/
void MyDMA_Transfer(void)
{DMA_Cmd(DMA1_Channel1, DISABLE);					//DMA失能,在写入传输计数器之前,需要DMA暂停工作DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);	//写入传输计数器,指定将要转运的次数DMA_Cmd(DMA1_Channel1, ENABLE);						//DMA使能,开始工作while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);	//等待DMA工作完成DMA_ClearFlag(DMA1_FLAG_TC1);						//清除工作完成标志位
}

MyDMA.h

#ifndef __MYDMA_H
#define __MYDMA_Hvoid MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size);
void MyDMA_Transfer(void);#endif

2.3相关API

http://www.xdnf.cn/news/13218.html

相关文章:

  • 服务器数据恢复—ocfs2文件系统被误格式化为Ext4文件系统的数据恢复案例
  • OS12.【Linux】gcc和g++以及动静态链接
  • RNN做中文分词
  • Linux动态库与静态库详解:从入门到精通
  • Redis高可用与扩展性:构建稳定高效的缓存系统
  • AR珠宝佩戴与传统的珠宝购物有哪些区别?​
  • 3.3.1_1 检错编码(奇偶校验码)
  • eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
  • 破界协同:解锁电商平台混合云架构的双引擎效能
  • 深入浅出掌握 Axios(持续更新)
  • day50python打卡
  • 论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(四)
  • Flutter:弹窗UI,不带背景色,自定义图片的弹窗
  • Linux向文件每行结尾追加指定内容的方法
  • PyArk飘云阁出品的ARK工具
  • MVVM 模式,以及 Angular、React、Vue 和 jQuery 的区别与关系
  • STL 3算法
  • srs linux
  • 立足数字人文,深化历史叙事|科学智能赋能人文社科领域研究
  • 用 LoRA 对 Qwen2.5-VL 模型进行SFT - 训练哪些层
  • 为什么选择物理服务器租用?
  • 混合动力无人机设计与运行要点分析
  • 大模型原理、架构与落地
  • LeetCode - 394. 字符串解码
  • 广告系统中后链路数据为什么要使用流批一体技术?流批一体技术是什么?
  • LLM不按预期格式输出?提示词工程远远不够。
  • Log4Net Demo
  • 高防CDN可以防御什么类型的攻击?—— 解析高防CDN的防御能力与应用场景
  • 第十章 基本定时器
  • Gartner企业技术参考架构学习心得