stm32 DMA

DMA:直接存储器存取

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

12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道)

每个通道都支持软件触发(存储器到存储器)和特定的硬件触发(外设到存储器)

uint16_t aa=0x66;

OLED_ShowHexNum( 1,  5 , aa ,8);
OLED_ShowHexNum( 2,  5 , (uint32_t)&aa ,8);

//00000066
//20000040

const uint16_t  aa=0x66;

OLED_ShowHexNum( 1,  5 , aa ,8);
OLED_ShowHexNum( 2,  5 , (uint32_t)&aa ,8);

//00000066
//08000990

aa在运行内存SRAM区, const 的aa 在Flash区

ROM只读存储器,掉电不丢失

RAM随机存储器,掉电丢失

Flash,ROM只读存储器的一种,无论是CPU,DMA,只读,不能写入

SRAM运行内存

DMA基本结构图

       

不能从SRAM到Flash

 传输计数器:转运一次传输计数器会减一,减到0之后,自增的地址也会恢复到起始地址的位置

自动重装器:使用后,循环模式重装给传输寄存器

软件触发:早日把传输计数器清0,相当于循环模式,不能与自动重装器一起用

硬件触发:使用硬件触发一般与外设有关,需要时机,比如ADC转换完成,串口收到的数据

条件: 第一,开关控制,DMA_Cmd必须使能

          第二,传输计数器必须大于0

          第三,必须有触发源

       

如果使用ADC1,会有库函数ADC_DMACmd,必须使用这个库函数才有效 

数据转运

DMA:直接存储器访问

主要功能是可以把数据从一个地方搬到另外的地方,不占用CPU

DMA1:有7个通道

DMA_PeripheralBaseAddr //外设地址
DMA_MemoryBaseAddr //存储器地址
#include "dma.h"

uint32_t count;

void dma_config(uint32_t arrA,uint32_t arrB,uint32_t Size)
{
	count=Size;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr=arrA;
	DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
	DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Enable;
	
	DMA_InitStruct.DMA_MemoryBaseAddr=arrB;
	DMA_InitStruct.DMA_MemoryDataSize=DMA_PeripheralDataSize_Byte;
	DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
	
	DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;
	DMA_InitStruct.DMA_BufferSize=Size;	
	DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;
	DMA_InitStruct.DMA_M2M=DMA_M2M_Enable;
	DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;
	
	DMA_Init( DMA1_Channel1,&DMA_InitStruct);
	
	DMA_Cmd(DMA1_Channel1,ENABLE );
}

void dma_remake()
{
	DMA_Cmd(DMA1_Channel1,DISABLE );
	DMA_SetCurrDataCounter( DMA1_Channel1,count ); 
	DMA_Cmd(DMA1_Channel1,ENABLE );
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
	DMA_ClearFlag( DMA1_FLAG_TC1);
}
#include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
#include "bsp_led.h"
#include "KEY.h"
#include "OLED.h"
#include "beep.h"
#include "sysclock.h"
#include "exit.h"
#include "CountSensor.h"
#include "uart.h"
#include "timer.h"
#include "stdio.h"
#include "pwm.h"
#include "dma.h"
// 来到这里的时候,系统的时钟已经被配置成72M。
volatile uint32_t time = 0;
const uint16_t aa=0x66;
 uint32_t num;
 
uint8_t DataA[]={0x01,0x02,0x03,0x04};
uint8_t DataB[]={0,0,0,0};

int main(void)
{
	
	OLED_Init();
	OLED_ShowHexNum( 1,  1 , DataA[0] ,2);
	OLED_ShowHexNum( 1,  4 , DataA[1] ,2);
	OLED_ShowHexNum( 1,  7 , DataA[2] ,2);
	OLED_ShowHexNum( 1,  10 , DataA[3] ,2);
	
	OLED_ShowHexNum( 2	,  1 , DataB[0] ,2);
	OLED_ShowHexNum( 2	,  4 , DataB[1] ,2);
	OLED_ShowHexNum( 2	,  7 , DataB[2] ,2);
	OLED_ShowHexNum( 2	,  10 , DataB[3] ,2);
	
	dma_config((uint32_t)DataA,(uint32_t)DataB, 4);
	
	OLED_ShowHexNum( 3,  1 , DataA[0] ,2);
	OLED_ShowHexNum( 3,  4 , DataA[1] ,2);
	OLED_ShowHexNum( 3,  7 , DataA[2] ,2);
	OLED_ShowHexNum( 3,  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)
	{
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值