当前位置:首页 > 单片机 > 单片机
[导读]一、为什么要用DMA?DMA全称:Direct MemoryAccess 就是可以直接内存存取;正是它可以直接操作内存所以具备以下优点:而无需经过CPU去操作内存的存取,这样可以解放CPU出来干其他的事情;因为他可以进行存储器时间的数

一、为什么要用DMA?

DMA全称:Direct MemoryAccess 就是可以直接内存存取;

正是它可以直接操作内存所以具备以下优点:

而无需经过CPU去操作内存的存取,这样可以解放CPU出来干其他的事情;

因为他可以进行存储器时间的数据传输,而不需经过cpu,所以大大加快了数据传输速度—是一种高速的数据传输;


二.DMA有几种传输数据方式:

(1)内存到 内存之间的;即:SRAM?à SRAM

(2)内存到 外设之间的; (例如:串口收到的数据 从数据寄存器 à 内存)

(3) 外设到内存之间的;


三.传输的数据宽度是怎样的,数据是什么样的形式传输?DMA 能传输多大的数据量?

A. 数据源地址到数据目的地址 传输宽度或者说传输数据的形式,有几种:1)字节;2)半字;3)全字 [1字节=8bit 1半字=2字节=16位 1全字=2半字=4字节=32位]

B.传输的最大数据量是65536


我们来看一下stm32f103ve的数据手册第九章DMA 大概的了解一下DMA的特性:

四、怎样配置软件来使用DMA

/****************************************************************/

函数名称: Dma_Init *功能描述: 利用DMA 把内存的数据 传输到flash 达到高速传输的目的

* *输入参数:无 *返回值 :无 *其他说明:无 *当前版本:v1.0

*作者 :尹宣 *完成时间:2013年12月1日*

*----------------------------------------------------------------- * ******************************************************************/

void Dma_Init(void)

{

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA channel6 configuration */

DMA_DeInit(DMA1_Channel1);

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Const_Buffer; //外设地址

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer; //内存地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为DMA的源端

DMA_DIR_PeripheralDST; //外设作为目的地址

DMA_InitStructure.DMA_BufferSize = BufferSize; //传输大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外设地址增加

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增使能

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //内存存储方式:字节

DMA_MemoryDataSize_Word;//字(32位)

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA_Mode_Normal 正常模式,只传送一次;DMA_Mode_Circular:循环模式,不停的传送; DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;

DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA Channel1 Transfer Complete interrupt */

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); /* Get Current Data Counter value before transfer begins */

CurrDataCounter= DMA_GetCurrDataCounter(DMA1_Channel1); /* Enable DMA Channel6 transfer */ DMA_Cmd(DMA1_Channel1, ENABLE);

}

2.设置DMA优先级

?

12345678910111213141516171819202122232425262728/******************************************************************函数名称: NVIC_Config*功能描述: 配置DMA的中断优先级**输入参数:无*返回值 :无*其他说明:无*当前版本:v1.0*作者 :尹宣*完成时间:2013年12月1日*修改日期 版本号 修改人 修改内容*-----------------------------------------------------------------*******************************************************************/voidNVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;/* Configure one bit for preemption priority -------------------------------- */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/* Enable DMA channel1 IRQ Channel */NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}


3.在stm3210x_it.c 文件中添加 DMA中断处理函数

?

1234567891011121314151617181920/******************************************************************************** Function Name : DMAChannel1_IRQHandler* Description : This function handles DMA Stream 1 interrupt request.* Input : None* Output : None* Return : None*******************************************************************************/voidDMA1_Channel1_IRQHandler(void){/* Test on DMA Channel1 Transfer Complete interrupt */if(DMA_GetITStatus(DMA1_IT_TC1))//DMA1_IT_TC1:通道1传输完成中断{/* Get Current Data Counter value after complete transfer */CurrDataCounter= DMA_GetCurrDataCounter(DMA1_Channel1); //返回当前DMA通道1 剩余的待传输的数据数目/* Clear DMA Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits */DMA_ClearITPendingBit(DMA1_IT_GL1);//清中断1全局中断}}


4主函数部分:


?

12345678910111213141516171819202122intmain(void){intcount;NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x00);// NVIC_VectTab_FLASH=0x08000000// RCC_Config();SysTick_Init();GPIO_Config();USART1_Init(19200);NVIC_Config();Dma_Init();/* Get Current Data Counter value before transfer begins */CurrDataCounter= DMA_GetCurrDataCounter(DMA1_Channel1); //·μ??μ±?°DMAí¨μàx, ê£óà′y′?ê?êy?Yêy??while( CurrDataCounter!=0) ;Delay_ms(1);}



关键问题

问1:

使用内存窗口观测SRC_Const_Buffer和DST_Buffer所在的位置,可以发现SRC_Const_Buffer

地址为0x08001384,,即Flash中;DST_Buffer地址为0x20000030,即RAM中;


答1:

不能改变其值得变量(包括全局和局部)都是存储在FLASH中的,能改变的都储存在SRAM中

SRC_Const_Buffer 的定义:uc32 SRC_Const_Buffert

搜索了一下uc32的出处----

typedef const uint32_tuc32; /*!< Read Only */


DST_Buffer 的定义:u32DST_Buffer[BufferSize];

搜索了一下u32的出处----

Typedef uint32_t u32;


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

中国北京(2025年9月10日)—— 业界领先的半导体器件供应商兆易创新GigaDevice(股票代码 603986)亮相于深圳国际会展中心举办的第26届中国国际光电博览会(展位号:12C12),全面展示GD25 SPI...

关键字: 光通信 MCU Flash

在嵌入式系统中,Flash存储器因其非易失性、高密度和低成本特性,成为代码存储和关键数据保存的核心组件。然而,MCU驱动Flash读写时,开发者常因对硬件特性理解不足或操作流程疏忽,陷入性能下降、数据损坏甚至硬件损坏的陷...

关键字: MCU驱动 Flash

在嵌入式开发中,STM32的时钟系统因其灵活性和复杂性成为开发者关注的焦点。然而,看似简单的时钟配置背后,隐藏着诸多易被忽视的陷阱,轻则导致系统不稳定,重则引发硬件损坏。本文从时钟源选择、PLL配置、总线时钟分配等关键环...

关键字: STM32 时钟系统

在嵌入式系统开发中,STM32系列微控制器的内部温度传感器因其低成本、高集成度特性,广泛应用于设备自检、环境监测等场景。然而,受芯片工艺差异和电源噪声影响,其原始数据存在±1.5℃的固有误差。本文从硬件配置、校准算法、软...

关键字: STM32 温度传感器

在能源效率与智能化需求双重驱动下,AC-DC转换器的数字控制技术正经历从传统模拟方案向全数字架构的深刻变革。基于STM32微控制器的PFM(脉冲频率调制)+PWM(脉冲宽度调制)混合调制策略,结合动态电压调整(Dynam...

关键字: AC-DC STM32

当前智能家居产品需求不断增长 ,在这一背景下 ,对现有浇花装置缺陷进行了改进 ,设计出基于STM32单片机的全 自动家用浇花机器人。该设计主要由机械结构和控制系统构成 ,机械结构通过麦克纳姆轮底盘与喷洒装置的结合实现机器...

关键字: STM32 麦克纳姆轮 安全可靠 通过性强

用c++编程似乎是让你的Arduino项目起步的障碍吗?您想要一种更直观的微控制器编程方式吗?那你需要了解一下Visuino!这个图形化编程平台将复杂电子项目的创建变成了拖动和连接块的简单任务。在本文中,我们将带您完成使...

关键字: Visuino Arduino ESP32 STM32
关闭