STM32()——DMA存储器

一、DMA存储器存取功能

1.1  DMA简介


二、DMA数据转运&AD多通道+DMA

2.1  DMA相关函数介绍

//将DMA恢复成缺省配置
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);

//DMA初始化函数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

//将DMA初始化函数中的结构体参数初始化
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);
——————————————————————————————————————————————————————————————————————————————————————
//DMA使能
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);

//用于开启DMA的中断输出
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);

//给DMA中的传输计数器赋值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); 

//获取DMA中的传输计数器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);
——————————————————————————————————————————————————————————————————————————————————————
//获取标志位状态
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);

//清除标志位状态
void DMA_ClearFlag(uint32_t DMAy_FLAG);

//获取中断状态
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);

//清除中断挂起标志位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);

2.2  DMA数据转运

MyDMA.c

#include "stm32f10x.h"          //Device header

uint16_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{
	MyDMA_Size = Size;  //用于存储转运次数

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_BufferSize = Size;  //转运次数
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //选择外设站点是源端还是目的地
	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;  //选择硬件触发还是软件触发
    //存储器站点
	DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址是否自增

	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //设置是否开启重装计数器(重装计数器和软件触发不可同时开启)
    //外设站点
	DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //地址是否自增

	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  //设置通道优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStructure); //DMA初始化函数

	DMA_Cmd(DMA1_Channel1 ,DISABLE);
}


//设置转运计数器时先关闭DMA
void MyDMA_Transfer(void)
{
	DMA_Cmd(DMA1_Channel1 ,DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);
	DMA_Cmd(DMA1_Channel1 ,ENABLE);
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待转运完成
	DMA_ClearFlag(DMA1_FLAG_TC1);
}

 main.c

#include "stm32f10x.h"  // Device header
#include "Delay.h"
#include "MyDMA.h"
#include "OLED.h"

uint8_t DataA[] = {0x01,0x02,0x03,0x04};  //数组名就是首地址
uint8_t DataB[] = {0,0,0,0};

int main(void)
{
	OLED_Init();
	
	MyDMA_Init((uint32_t)DataA, (uint32_t)DataB, 4);
	
	OLED_ShowString(1, 1, "DataA");
	OLED_ShowString(3, 1, "DataB");
	OLED_ShowHexNum(1, 8, (uint32_t)DataA, 8);  //显示数组A的首地址
	OLED_ShowHexNum(3, 8, (uint32_t)DataB, 8);  //显示数组B的首地址
	
	OLED_ShowHexNum(2, 1, DataA[0], 2);
	OLED_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);
	OLED_ShowHexNum(4, 4, DataB[1], 2);
	OLED_ShowHexNum(4, 7, DataB[2], 2);
	OLED_ShowHexNum(4, 10, DataB[3], 2);
	while(1)
	{
		DataA[0]++;
		DataA[1]++;
		DataA[2]++;
		DataA[3]++;
		
        //转运前的数组A、B
		OLED_ShowHexNum(2, 1, DataA[0], 2);
		OLED_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);
		OLED_ShowHexNum(4, 4, DataB[1], 2);
		OLED_ShowHexNum(4, 7, DataB[2], 2);
		OLED_ShowHexNum(4, 10, DataB[3], 2);
		
		Delay_ms(1000);
		
		MyDMA_Transfer();
		
        //转运后的数组A、B
		OLED_ShowHexNum(2, 1, DataA[0], 2);
		OLED_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);
		OLED_ShowHexNum(4, 4, DataB[1], 2);
		OLED_ShowHexNum(4, 7, DataB[2], 2);
		OLED_ShowHexNum(4, 10, DataB[3], 2);
		
		Delay_ms(1000);
	}
}

2.3  AD多通道+DMA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值