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