历史上的今天
返回首页

历史上的今天

今天是:2025年01月04日(星期六)

2019年01月04日 | STM32 DMA buffersize理解

2019-01-04 来源:eefocus

DMA

参考野火《STM32库开发实战》 P195-P215 “DMA—直接存储区访问 ”章节讲解。


DMA FIFO

每个数据流都独立拥有四级32位FIFO。DMA传输具有FIFO模式和直接传输模式。 

FIFO用于源数据传输到目标地址之间临时存储这些数据。


DMA传输模式

DMA2 支持全部三种传输模式,而 DMA1 只有外设到存储器和存储器到外设两种模式。 

DMA1 的存储区端口相比 DMA2 的要减少 AHB2 外设的访问权,同时 DMA1 外设端口是没有连接至总线矩阵的,只有连接到 APB1 外设,所以 DMA1 不能实现存储器到存储器传输。


DMA 流控制器

流控制器主要涉及到一个控制 DMA 传输停止问题。 DMA 传输在 DMA_SxCR 寄存器的 EN 位被置 1 后就进入准备传输状态,如果有外设请求 DMA 传输就可以进行数据传输。 


很多情况下,我们明确知道传输数据的数目,比如要传 1000 个或者 2000 个数据,这样我们就可以在传输之前设置 DMA_SxNDTR 寄存器为要传输数目值, DMA 控制器在传输完 这么多数目数据后就可以控制 DMA 停止传输。 


DMA 数据流 x 数据项数 DMA_SxNDTR(x 为 0~7)寄存器用来记录当前仍需要传输数目,它是一个 16 位数据有效寄存器,即最大值为 65535,这个值在程序设计是非常有用也是需要注意的地方。我们在编程时一般都会明确指定一个传输数量,在完成一次数目传输 

后 DMA_SxNDTR 计数值就会自减,当达到零时就说明传输完成。


如果某些情况下在传输之前我们无法确定数据的数目,那 DMA 就无法自动控制传输停止了,此时需要外设通过硬件通信向 DMA 控制器发送停止传输信号。这里有一个大前提就是外设必须是可以发出这个停止传输信号,只有 SDIO 才有这个功能,其他外设不具备此功能。


理解1 

看库函数中 

DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; 

而CNDTR即数据传输数量 (Number of data to transfer) 


数据传输数量为0至65535。这个寄存器只能在通道不工作(DMA_CCRx的EN=0)时写入。通道开启后该寄存器变为只读,指示剩余的待传输字节数目。寄存器内容在每次DMA传输后递减。 


数据传输结束后,寄存器的内容或者变为0;或者当该通道配置为自动重加载模式时,寄存器的内容将被自动重新加载为之前配置时的数值。 


当寄存器的内容为0时,无论通道是否开启,都不会发生任何数据传输。


理解2 

这个DMA_BufferSize 就是要传输的次数。 

这个并不是指buf的字节大小,而是指DMA的传输次数,一次传输可以是:1字节,2字节,4字节。


理解3 

那为啥取名叫buffer 呢,我猜是为了和DMA_MemoryInc_Enable配合。虽然传输计数是减少的,但是内存地址是增长的。在声明DMA_MemoryBaseAddr时候,其实DMA的就指向(是指向,不是开辟!)一个大小为DMA_BufferSize的数组,数组的开始地址为DMA_MemoryBaseAddr。这个数组就是缓冲区。


每次ADC采样后,就通过DMA把数据放在内存中, 从DMA_MemoryBaseAddr+0地址开始放, 直到DMA_MemoryBaseAddr+DMA_BufferSize-1,此时CNDTR变成0,传输结束。


理解4 

如果你有32字节数据: 

datasize=1 ==> buffersize = 32 

datasize=2 ==> buffersize = 16 

datasize=4 ==> buffersize = 8 

这个理解,说明了buffer_size设置时需要注意的事项, 

1. 外设数据宽度、内存数据宽度 

2. 我们设置了外部存储区的大小


**外设:DCMI_DR_ADDRESS 

内存:FSMC_LCD_ADDRESS #液晶屏地址或数组首地址**


  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;   #外设数据宽度为32位

  

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  #内存数据宽度为16位


上述此情况下,假设传输2个字节,则buffer_size = 16/32 = 0.5 假设传输32个字节,则buffer_size = 32/2*0.5=8


DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;   #外设数据宽度为16位


DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;  #内存数据宽度为32位


上述此情况下,假设传输4个字节,则buffer_size = 32/16= 2 

假设传输32个字节,则buffer_size = 32/4*2=16


  DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;   #外设数据宽度为16

 

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  #内存数据宽度为16位


上述此情况下,假设传输2个字节,则buffer_size = 16/16= 1 

假设传输32个字节,则buffer_size = 32/2*1=16


传输类型

DMA传输类型有单次(single)传输和突发(Burst)传输。


burst: 

dma实际上是一次一次的申请总线,把要传的数据总量分成一个一个小的数据块。比如要传64个字节,那么dma内部可能分为2次,一次传 64/2=32个字节,这个2(a)次呢,就叫做burst。这个burst是可以设置的。这32个字节又可以分为32位 * 8或者16位*16来传输。


突发传输与 FIFO 密切相关,突发传输需要结合 FIFO 使用,具体要求 FIFO 阈值一定要是内存突发传输数据量的整数倍。 FIFO 阈值选择和存储器突发大小必须配合使用, 


这里写图片描述


直接模式


默认情况下, DMA 工作在直接模式,不使能 FIFO 阈值级别。 


直接模式在每个外设请求都立即启动对存储器传输的单次传输。直接模式要求源地址和目标地址的数据宽度必须一致,所以只有 PSIZE 控制,而 MSIZE 值被忽略。突发传输是基于 FIFO 的所以直接模式不被支持。另外直接模式不能用于存储器到存储器传输。 


在直接模式下,如果 DMA 配置为存储器到外设传输那 DMA 会见一个数据存放在FIFO 内,如果外设启动 DMA 传输请求就可以马上将数据传输过去

推荐阅读

史海拾趣

Evans Capacitor Company公司的发展小趣事

面对数字化浪潮的冲击,ECC决定进行数字化转型以提升竞争力。公司引入了先进的生产设备和管理系统,实现了生产过程的自动化和智能化。同时,ECC还建立了大数据分析平台,对市场需求、客户需求等数据进行深入分析,为公司的决策提供有力支持。数字化转型使得ECC在市场竞争中更加灵活和高效。

AverLogic公司的发展小趣事

AverLogic公司深知人才是企业发展的核心竞争力。因此,公司一直致力于人才培养和团队建设。通过定期的培训和学习,公司不断提升员工的技能和素质,打造了一支高效、专业的团队。这支团队在产品研发、市场拓展等方面都发挥了重要作用,为公司的持续发展提供了有力的保障。

Cortina Systems Inc公司的发展小趣事

随着电子行业的不断发展,市场竞争也日益激烈。面对行业的变革和挑战,AverLogic公司及时调整战略,加大在研发和创新方面的投入,以适应市场的变化。同时,公司还积极开拓新的应用领域,如智能家居、自动驾驶等,以寻求新的增长点。这些战略调整不仅帮助公司应对了市场的挑战,也为其未来的发展奠定了坚实的基础。

Adafruit公司的发展小趣事

AverLogic公司在电子行业中以其技术创新和产品突破而崭露头角。在早期的发展阶段,公司专注于研发高质量的视频处理芯片,以满足市场对于更高清晰度和更流畅视频播放的需求。经过多次实验和迭代,公司成功推出了一款具有革命性的转换器产品——AL110,这款产品能够将PC和Macintosh的VGA信号转换为高品质的NTSC或PAL信号,从而极大地提升了视频信号的处理效率和输出品质。这一创新不仅为公司赢得了市场的认可,也为公司在电子行业中奠定了坚实的基础。

Astema公司的发展小趣事

随着业务的迅速增长,Astema意识到供应链管理的重要性。公司开始优化供应链管理流程,提高生产效率和产品质量。同时,Astema还与供应商建立了紧密的合作关系,确保原材料供应的稳定性和可靠性。这些举措使得Astema在激烈的市场竞争中保持了稳定的运营。

AVAGO公司的发展小趣事

随着公司规模的扩大和技术的不断积累,AVAGO公司开始寻求多元化的发展道路。除了继续深耕半导体领域外,公司还积极拓展其他相关领域,如传感器、无线通信等。同时,公司还与其他行业的领军企业建立了紧密的战略合作关系,共同推动技术创新和市场拓展。

问答坊 | AI 解惑

Schneider变频器通讯的代码

Schneider变频器通讯的代码…

查看全部问答>

RAMDISK: Couldn't find valid RAM disk image starting at 0.

环境:AT91RM9200 利用u-boot启动内核并加载RAMDISK UBOOT> bootm 1001c000 100a0000 输出信息如下: .... RAMDISK: Couldn\'t find valid RAM disk image starting at 0. Freeing initrd memory: 3072K Kernel panic: VFS: Unable to mount ro ...…

查看全部问答>

请教一下STM32怎么避免各个中断互相打架啊?

我用3.1.2的lib写了以SysTick来产生准确Delay的程式还有再LCD上显示时钟.另外在512K Flash里放了一个48KHz采样220Hz Sine值的阵列用来让DAC产生一个220Hz的波.我把喇叭直接接到DAC的PIN上来确认产生的声音.听到的纯音虽然正确不过不知道为什么 ...…

查看全部问答>

Arduino能给我们带来什么?

Arduino,是一块基于开放源代码的USB接口Simple i/o接口板(包括12通道数字GPIO,4通道PWM输出,6-8通道10bit ADC输入通道),并且具有使用类似Java,C语言的IDE集成开发环境。关键部分为:Arduino开发IDE接口基于开放源代码,可以免费下载使用。但 ...…

查看全部问答>

自己整理的ADI的dsp学习资料,从今天开始连载大家一起学习

学习ADIdsp已经有一段时间了,把学习的一些心得整理了一下,陆陆续续发上来,大家一起学习进步…

查看全部问答>

关于硬件I2C的,用的是I2C1

/*---------------------------------------------------------------------------------------------------------*********************************************************************************************************** 文件名称 :&nbs ...…

查看全部问答>

【项目外包】飞思卡尔32位Power Pc架构MPC5XXX芯片驱动开发

飞思卡尔32位Power Pc架构MPC5XXX芯片驱动开发 项目预算:¥ 1,~100,000 开发周期: 60 天 项目分类: 嵌入式 竞标要求: 项目标签: ...…

查看全部问答>

学习Sitara AM335x之思路篇

本人专业是电路与系统,结合自己学习ARM9的情况,我想谈谈学习这款芯片的思路,希望大家一起讨论一起研究。我觉得最初应该先把Sitara当单片机使更合适些,因为电子相关的专业的同学大部分还是希望往驱动固件开发方向发展(这个方向工资也不错,将来 ...…

查看全部问答>