历史上的今天
今天是:2025年03月28日(星期五)
2020年03月28日 | stm32---DMA基础
2020-03-28 来源:eefocus
DMA,意思为直接存储器访问。
DMA 可 用于实现外设与存储器之间或者存储器与存储器之间数据高效传输。
因为 DMA 传输数据移动过程无需 CPU 直接操作,这样节省的 CPU 资 源就可供其它操作使用。
从硬件层面来理解,DMA 就好像是 RAM 与 I/O 设备间数 据传输的通路,外设与存储器之间或者存储器与存储器之间可以直接在这条通路 上进行数据传输。
这里说的外设一般指外设的数据寄存器,比如 ADC、SPI、I2C、 DCMI 等外设的数据寄存器,存储器一般是指片内 SRAM、外部存储器、片内 Flash 等。
STM32F1 最多有 2 个 DMA 控制器,DMA1 有 7 个通道。 DMA2 有 5 个通道。每个通道专门用来管理来自于一个或多个外设 对存储器访问的请求。还有一个仲裁器来协调各个 DMA 请求的优先权。
DMA1通道对应外设请求
DMA2通道对应外设请求
DMA就像一个中转站一样,里面有源地址和目标地址,多通道并用可以配置优先级,
只要开启DMA就可以直接实现源地址里的内容传送给目标地址,不需要CPU来管理,它就像个通道一样,开启就传输。
dma.c
#include "dma.h"
/*******************************************************************************
* 函 数 名 : DMAx_Init
* 函数功能 : DMA初始化函数
* 输 入 :
DMAy_Channelx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
par:外设地址
mar:存储器地址
buff_size:数据传输量
* 输 出 : 无
*******************************************************************************/
void DMAx_Init(DMA_Channel_TypeDef* DMA1_Channelx,u32 par,u32 mar,u16 buff_size)
{
DMA_InitTypeDef DMA_InitStructure;
//1*开启相应时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//2*DMA结构体配置
DMA_InitStructure.DMA_PeripheralBaseAddr = par; //外设目标地址
DMA_InitStructure.DMA_MemoryBaseAddr = mar; //存储器源地址
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralDST ; //方向是DMA存储器到外设寄存器。方向还有外设到存储器,存储器到存储器
DMA_InitStructure.DMA_BufferSize = buff_size; //传输的字节数目
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设寄存器地址自递增,外设通常是一个不需要递增
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryInc_Enable; //传输数据多字节时需要地址自增,实现开启就全部传输完
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA传输模式,单次传输
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级配置,用于多通道时
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //存储器到存储器时打开
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度为1Byte,8位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设接收数据长度为必须要存储器发送数据长度一样
DMA_Init(DMA1_Channelx,&DMA_InitStructure);
}
/*******************************************************************************
* 函 数 名 : DMAx_Enable
* 函数功能 : 开启一次DMA传输
* 输 入 : DMAy_Channelx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
buff_size:数据传输量,传输时再赋值一遍防止出错
* 输 出 : 无
*******************************************************************************/
//3*开启DMA
void DMAx_ENABLE(DMA_Channel_TypeDef* DMA1_Channelx,u16 buff_size)
{
DMA_Cmd(DMA1_Channelx,DISABLE); //先关闭DMA使能来赋
DMA_SetCurrDataCounter(DMA1_Channelx,buff_size);
DMA_Cmd(DMA1_Channelx,ENABLE);
}
dma.h
#ifndef _dma_H
#define _dma_H
#include "system.h"
void DMAx_Init(DMA_Channel_TypeDef* DMA1_Channelx,u32 par,u32 mar,u16 buff_size);
void DMAx_ENABLE(DMA_Channel_TypeDef* DMA1_Channelx,u16 buff_size);
#endif
main.c
#include "systick.h"
#include "led.h"
#include "system.h"
#include "key.h"
#include "usart.h"
#include "dma.h"
#define data_size 5000
u8 data[data_size];
//数组赋值专用函数
void Data_zhuang(u8 *p)
{
u16 i;
for(i=0;i *p = '5'; p++; } } int main() { u8 i=0; u8 key; SysTick_Init(72); //系统时钟初始 LED_INIT(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); USART1_Init(9600); KEY_INIT(); Data_zhuang(data); //给数组赋值 DMAx_Init(DMA1_Channel4,(u32)&USART1->DR,(u32)data,data_size); //DMA初始化,(u32)&USART1->DR是串口1的数据寄存器,(u32)data是我们在内存中造的数组 while(1) { key = KEY_Scan(0); if(key==KEY_UP) { USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //是哪个外设就开启哪个的DMA功能 DMAx_ENABLE(DMA1_Channel4,data_size); //使能DMA while(1) { if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==1) //判断DMA1的通道4是否传输完成 { DMA_ClearFlag(DMA1_FLAG_TC4); //清除传输完成标志 break; } led2=!led2; delay_ms(300); } } i++; if(i%20==0) //200ms变换一次 { led1=!led1; } } }
上一篇:stm32---DS18b20
下一篇:stm32---DAC
史海拾趣
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:56 编辑 请教各位高手,什么型号的双栅管可以代替3SK318(能直接替换最好) 谢谢! … 查看全部问答> |
|
2440 读 温度芯片,总是无法触发中断,请教有什么方法呀? BSP包里通过应用层调用IIC文件夹不能正常工作,只好转入到bootloader层去做温度检测了,可是无论如何也不能触发中断,有经验的请指教,先谢谢了。… 查看全部问答> |
|
只要电路原理图和c源程序。小弟在这拜谢了! 或者谁能帮我改下这电压表的程序成电流表的程序: #include unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7, &nbs ...… 查看全部问答> |
|
刚做的东西给几个小MM去贴片,把101当103贴上去了,居然USB也可以联机。但操作偶尔有问题,手工复位一般可以解决掉。听小道消息说,101是阉割的103,就像奔腾的cache有瑕疵变成赛扬一样。… 查看全部问答> |
|
使能I/O口子程序,在CCS帮助文件中看到对该子程序 GPIO_Handle GPIO_open( int chaNum, Uint32 flags ); 的解释是: chaNum GPIO channel to open: lags & ...… 查看全部问答> |




