DMA-STM32

DMA-STM32

DMA (Direct Memory Access) direct memory access
DMA can provide high-speed data transmission between peripherals and memory or memory and memory without CPU intervention, saving CPU resources
12 independently configurable channels: DMA1 (7 channels ), DMA2 (5 channels)
each channel supports software triggers and specific hardware triggers
STM32F103C8T6DMA resources: DMA1 (7 channels)
insert image description here

insert image description here
DMA bus used to access each memory
Multiple internal channels can perform independent data transfer
Arbiter, used to schedule each channel to prevent conflict
AHB slave device, used to configure DMA parameters
DMA request, used to trigger DMA by hardware If the data transfer
CPU or DMA directly accesses the Flash, it can only be read but not written. The
latter SRAM is the running memory, which can be read and written arbitrarily.
insert image description here
The left side is the peripheral register site,
and the right side is the memory site, including Flash and SRAM
insert image description here

If it is not enough, add 0, and if it exceeds, discard the high bit

example

insert image description here
insert image description here
insert image description here
The data transfer here is a kind of copy transfer, and the data of DataA will not disappear after the transfer is completed
insert image description here
insert image description here
insert image description here

insert image description here

In the first step, RCC turns on the DMA clock.

In the second step, you can directly call DMA Init to initialize each parameter here. Including the starting address, data width, and whether the address is self-incrementing of peripherals and memory sites. Direction, transfer counter, auto-reload required, select trigger source.

The software trigger is used, so the channel can be selected arbitrarily.

Finally: switch control, DMA_Cmd

#include "stm32f10x.h"                  // Device header

uint16_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{
	MyDMA_Size = Size;
	//¿ªÆôDMAʱÖÓ
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	//ÅäÖÃDMA½á¹¹Ìå
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;//Ô´µØÖ·
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//×Ö½ÚÀàÐÍ´«Êä(8λ)
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//ʹÄܵØÖ·×ÔÔö
	DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;//Ä¿±êµØÖ·
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//×Ö½ÚÀàÐÍ´«Êä(8λ)
	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_Cmd(DMA1_Channel1, DISABLE);
}

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);
}

#ifndef __MYDMA_H
#define __MYDMA_H

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size);
void MyDMA_Transfer(void);

#endif

Guess you like

Origin blog.csdn.net/qq_45159887/article/details/130696395