历史上的今天
返回首页

历史上的今天

今天是:2025年08月05日(星期二)

正在发生

2021年08月05日 | STM32中DMA的使用入门

2021-08-05 来源:eefocus

今天刚看了一个ADC采集的程序,和之前用其他单片机写的程序还是有比较大的差别,这个差别主要就在DMA。这里面总结一下,有一部分是转载别人的。

 

什么是STM32的DMA?其全称是:Direct Memory Access;根据ST公司提供的相关信息,DMA是STM32中一个独立与Cortex-M3内核的模块,有点类似与ADC、PWM、TIMER等模块;主要功能是通信“桥梁”的作用,可以将所有外设映射的寄存器“连接”起来,这样就可以高速问各寄存器,其传输不受CPU的支配,传输还是双向的;例如,从“表面”上看,它可以将flash中的数据与储存器中变量建立通讯,还可以将一外设的积存器或缓冲器与另外设的寄存器或缓冲器建立双向通讯,有点像把外设硬件之间用“导线”连接在一起了。其间的通讯不占CPU资源,访问速度高,对于实时性强的应用将是一个很好的选择;当然,对于实时性非常强的,建议还是采用专用的DSP芯片。


怎样启用DMA?首先,众所周知的是初始化,任何设备启用前都要对其进行初始化,要对模块初始化,还要先了解该模块相应的结构及其函数,以便正确的设置;由于DMA较为复杂,我就只谈谈DMA的基本结构和和常用函数,这些都是ST公司提供在库函数中的。


1、下面代码是一个标准DMA设置,当然实际应用中可根据实际情况进行裁减:

 

DMA_DeInit(DMA_Channel1);


上面这句是给DMA配置通道,根据ST提供的资料,STM3210Fx中DMA包含7个通道(CH1~CH7),这里需要选择一个传输通道

 

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;


上面语句中的DMA_InitStructure是一个DMA结构体,在库中有声明了,当然使用时就要先定义了;DMA_PeripheralBaseAddr是该结构体中一个数据成员,给DMA一个起始地址,好比是一个buffer起始地址,数据流程是:外设寄存器à DMA_PeripheralBaseAddàmemory中变量空间(或flash中数据空间等),ADC1_DR_Address是ADC1的地址,既然是桥梁,肯定要连接两个端点,这里需要明白所需要连接的外设的地址;

 

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;


上面这句很显然是DMA要连接在Memory中变量的地址,ADC_ConvertedValue是我自己在memory中定义的一个变量;

 

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;


上面的这句是设置DMA的传输方向,就如前面我所说的,DMA可以双向传输,也可以单向传输,这里设置的是单向传输,如果需要双向传输:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。

 

DMA_InitStructure.DMA_BufferSize = 2;


上面的这句是设置DMA在传输时缓冲区的长度,前面有定义过了buffer的起始地址:ADC1_DR_Address ,为了安全性和可靠性,一般需要给buffer定义一个储存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的2个half-word(见下面的设置);32位的MCU中1个half-word占16 bits。

 

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;


上面的这句是设置DMA的外设递增模式,如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;我的例子里DMA只与ADC1建立了联系,所以选用DMA_PeripheralInc_Disable

 

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;


上面的这句是设置DMA的内存递增模式,DMA访问多个内存参数时,需要使用DMA_MemoryInc_Enable,当DMA只访问一个内存参数时,可设置成:DMA_MemoryInc_Disable。

 

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;


上面的这句是设置DMA在访问时每次操作的数据长度。有三种数据长度类型,前面已经讲过了,这里不在叙述。

 

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

与上面雷同。在此不再说明。

 

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;


上面的这句是设置DMA的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal

 

DMA_InitStructure.DMA_Priority = DMA_Priority_High;


上面的这句是设置DMA的优先级别:可以分为4级:VeryHigh,High,Medium,Low.

 

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;


上面的这句是设置DMA的2个memory中的变量互相访问的

 

DMA_Init(DMA_Channel1,&DMA_InitStructure);


前面那些都是对DMA结构体成员的设置,在次再统一对DMA整个模块做一次初始化,使得DMA各成员与上面的参数一致。

 

/*DMA Enable*/

DMA_Cmd(DMA_Channel1,ENABLE);

使能此通道。

当然更多的还需要看固件库函数的说明。

 

这里面知识DMA的一个简单应用,后面做很多设计在数据传输上需要做这种转变,特别是像我这样从单片机学过来的,现在里面有了更好的方式要学会去运用,不能固守原来单片机的设计思路。这个相信也是后面学习中很重要的一部分。

推荐阅读

史海拾趣

Cramer公司的发展小趣事

随着5G技术的普及,Cramer公司紧跟时代潮流,开始研发5G通信设备。他们与多家通信巨头合作,共同推进5G技术的发展。经过不懈的努力,Cramer公司成功研发出了一款高性能的5G路由器。这款产品的推出,使得Cramer公司在5G市场上取得了先机,并为其带来了丰厚的回报。

Hitron公司的发展小趣事

随着可穿戴设备的兴起,Cramer公司迅速捕捉到了市场机遇。他们推出了一款智能手表,该手表不仅具备基本的时间显示功能,还集成了健康监测、运动追踪等多项实用功能。为了提升产品的竞争力,Cramer公司与多家科技公司合作,共同研发新技术。这款智能手表在市场上获得了广泛认可,进一步提升了Cramer公司的品牌知名度和市场份额。

ETEQ Microsystems Inc公司的发展小趣事

ETEQ Microsystems Inc一直将品质管理作为公司的核心竞争力之一。公司建立了严格的质量管理体系,从原材料采购到产品生产、测试、包装等各个环节都严格把控。同时,公司还鼓励员工积极参与品质改进活动,通过持续改进不断提升产品质量和客户满意度。

Feller US公司的发展小趣事

在经历了多年的发展后,菲斯克逐渐意识到品牌的重要性。为了进一步提升品牌价值和市场影响力,公司决定进行品牌重塑。通过重新设计品牌形象、加强品牌宣传以及推出更具吸引力的产品和服务,菲斯克成功吸引了更多消费者的关注和喜爱。同时,公司还积极拓展市场渠道和合作伙伴网络,通过多元化的营销策略和灵活的渠道策略,成功打开了多个新的市场领域。这些努力不仅提升了公司的市场份额和盈利能力,还为公司的长期发展奠定了坚实的基础。

请注意,以上故事均基于虚构的情境和假设,旨在解释和描述菲斯克(FSR.US)公司可能的发展情况。实际的发展过程可能因各种因素而有所不同。

ddm hopt + schuler GmbH & Co KG公司的发展小趣事

随着全球对环境保护意识的增强,ddm hopt + schuler公司开始关注绿色制造和可持续发展。公司投入大量资源进行绿色生产技术的研发,成功开发出一系列节能、环保的电子生产设备。这些设备在保障生产效率和产品质量的同时,显著降低了能源消耗和废弃物排放。这一举措不仅提升了公司的品牌形象,也赢得了客户和市场的广泛赞誉。

ADLINK公司的发展小趣事

为了保持技术领先地位和市场竞争力,ddm hopt + schuler公司积极开展跨界合作和创新发展。公司与多所知名高校和研究机构建立了产学研合作关系,共同研发新技术、新产品。此外,公司还积极参与国际交流与合作,引进国际先进技术和管理经验。这些合作不仅为公司带来了更多的创新资源,也提升了公司的国际影响力和竞争力。

问答坊 | AI 解惑

word表格制作

本帖最后由 paulhyde 于 2014-9-15 09:42 编辑 word表格制作 希望对大家有用 [ 本帖最后由 yushiqian 于 2009-8-15 23:34 编辑 ]  …

查看全部问答>

这个比较好玩,美研制出双腿直立行走机器人~

直立行走机器人Petman Petman可以像真人一样直立行走 在试验人员用力侧推之后,Petman能自我保持平衡 据美国媒体报道,曾研制出大狗机器人的波士顿动力公司近日又有新发明,他们研制出一种像真人一样四处活动的机器人。该公司正在制造Petm ...…

查看全部问答>

ARM编译器中预定义的宏

***************************************************** ARM编译器中预定义的宏 ***************************************************** ARM编译器预定义了一些宏,这些预定义宏对应一定的数值,有些预定义宏没有对应数值,见下表: _arm  ...…

查看全部问答>

传入ImeToAsciiEx的虚拟键值内容是什么?

如题。 UINT WINAPI ImeToAsciiEx(        UINT    uVirtKey,        UINT    uScanCode,        CONST   LPBYTE lpbKeyState,    &nb ...…

查看全部问答>

关于ActivateDevice的问题

各位大侠,我第一次用ActivateDevice去加载一个驱动,但是加载的时候总是返回0,用getlasterror()时,得到1610的错误值,请问一下是什么问题呀?各位有没有什么例子让我参考一下呀?多谢了。…

查看全部问答>

windows 底层驱动招聘

帮我解决一个问题 ,一次性给钱。 价格面谈,地点:成都。 及时联系。qq16839505…

查看全部问答>

PPP连接的问题

我使用串口进行PPP拨号连接,LCP、PAP都过去了,到了IPCP时,已经可以分配IP地址,进入数据通信打开状态,为什么服务器端还给我发服务器(网关)的IP地址请求包啊?这个包在NCP配置阶段已经发过了,并且我发过ack包过去了。 有哪位仁兄遇见过类似 ...…

查看全部问答>

STR9定时器0捕获功能问题

                                 我现在用STR912的定时器0作外部上升延捕获,仿真时已确定TIM0计数正常,捕获管脚定义为P4.0,(具体该怎么配置为该 ...…

查看全部问答>

4.5分频

module Div_45(                input clk,                output div_clk   &nbs ...…

查看全部问答>