1.DMA:data memory access //实际的内存存储
注:DMA干活的时候是不需要CPU干涉的
2.
①内存(定义的变量)---外设(寄存器);
②内存---内存
③外设---外设(一个外设的寄存器到另一个外设的寄存器)
3.
STM32有两个DMA控制器
如图:
4.举例说明:(内存到外设,串口1 TX DMA)
1 void USART1_DMA_Config(void) 2 { 3 DMA_InitTypeDef DMA_InitStructure; 4 5 /*Open the DMA clock*/ 6 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 7 8 /*Set the DMA source: serial port data register address*/ 9 DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; 10 11 /*Memory address,(A pointer to the variable transmission)*/ 12 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; 13 14 /*Direction:From memory to the peripherals*/ 15 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 16 17 /*Transmission size:DMA_BufferSize=SENDBUFF_SIZE*/ 18 DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; 19 20 /*It does not increase peripheral address*/ 21 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 22 23 /*Memory address since the increase*/ 24 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 25 26 /*A peripheral unit of data*/ 27 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 28 29 /*Memory data unit:8bit*/ 30 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 31 32 /*The DMA mode: cycle*/ 33 //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; 34 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 35 36 /*priority:medium*/ 37 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 38 39 /*Memory to memory transmission is prohibited*/ 40 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 41 42 /*Configuration of the channel 4*/ 43 DMA_Init(DMA1_Channel4, &DMA_InitStructure); 44 45 /*enable DMA1_Channel4*/ 46 DMA_Cmd (DMA1_Channel4,ENABLE); 47 //DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); //Configuration after completion of the DMA interrupt 48 }
①USART1_TX挂载在DMA1的通道4(每个DMA有7个通道,对应不同外设)如图:
②程序第九行source(源)
即:源头地址(外设地址)
1 #define USART1_DR_Base 0x40013804 // 0x40013800 + 0x04 = 0x40013804
怎么算出来的呢?
请来看:
基地址是什么呢?
故:串口1的数据寄存器地址:
// 0x40013800 + 0x04 = 0x40013804
③内存地址,自己定义的数组
④方向:内存到外设
⑤传输大小:5000个字节
⑥外设地址不增,内存地址自增,把5000个字节循环发完
⑦发送模式:有Normal:送完5000个字节工作就结束了,circular则是循环发送
⑧优先级:假如在一个程序里面有几个外设同时申请了DMA请求,则根据优先级不同来选择配置那个
⑨禁止内存到内存的传输
4.看看main函数
uint16_t i; /*Filling is going to send data*/ for(i=0;i<SENDBUFF_SIZE;i++) { SendBuff[i] = 'A'; } /* USART1向DMA发出TX请求*/ USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); /* 此时CPU是空闲的,可以来做别的事情*/ //LED At the same time scintillation for(;;) { LED1(ON); Delay(0xFFFFF); LED1(OFF); Delay(0xFFFFF); }
注:这样串口1不断向外发送数据,不影响CPU运行,CPU可以藤下时间做别的事情;(同事干两件事情)
M3里面的DMA只能软件触发,有的芯片可以外部的脉冲触发;
瘋子随记