关于DMA的学习
来源:互联网 发布:斑马410网络打印设置 编辑:程序博客网 时间:2024/06/05 10:46
在之前做飞思卡尔智能车比赛时接触过K60的DMA,用DMA可以采集图像,也可以用DMA来测速。
概念相信大家都清楚:所谓 DMA就是直接内存取( Direct Memory Access ),是计算机科学中的一种内存访问技术。
书上说,DMA模块可以不占用CPU自行传输数据,能够减轻CPU的负担,然而具体原理是怎样的呢?为什么DMA能够不需要CPU的介入呢?我查阅了相关资料,大概地了解了些。
在STM32中,DMA单元和Cortex CPU之间对总线使用一种交叉存取的机制。DMA传输遵循相应的传输流程。其中,在数据从内存传输到内存的情况下,每传输一个字要消耗5个时钟周期:1个读周期,1个写周期,插入3个空闲周期供CPU使用。所以,每个DMA通道都只是在总线存取周期才会占用总线,即使传输大量数据,DMA单元最大也只会消耗40%的数据总线带宽。
所以说,STM32中的DMA与CPU对总线的使用方式是交叉式的。
在K60中,DMA是通过DMA控制器接管接管数据和地址总线。如果CPU正在执行指令,DMA控制利用空闲的地址和数据总线完成数据传送,某种程度上说,CPU运算和数据传送是在并行进行的。K60的DMA数据的传送分为主循环(major loop)和副循环(minor loop)。major loop循环一次,可能需要minor loop循环多次。每个minor loop循环都需要DMA源发来请求或者通过软件请求。每个minor loop传送完毕,对应的DMA通道就进入空闲模式,等待下一次DMA请求。当所有DMA传送完毕,即置DONE标志,并且可以通过设置选择传送完毕是否触发中断。此外,可以通过相关寄存器设置,使用Kinetis的DMA模块的主/副循环链接功能、散/聚模式、副循环映射。
对DMA模块的相应的寄存器进行初始化后,便可开启DMA功能。例如(K60例程):
以智能车摄像头组图采集应用为例。使GPIO口 D0~D7采集数字摄像头OV7620的 8位灰度输出,使用引脚 位灰度输出,使用引脚 A19输入像素同步脉冲pclk4分频后的信号,上升沿触发 分频后的信号,上升沿触发DMA 请求。 每行采集点数为 V,通过 DMA传送到到 video 数组 。一行采集完成后关闭 DMA 硬件请求,进 入 DMA中断,使用 DMA 通道 0:
void DMA0_Init(void){SIM_SCGC6|=SIM_SCGC6_DMAMUX_MASK;//打开DMA多路复用时钟SIM_SCGC7|=SIM_SCGC7_DMA_MASK;//打开DMA模块时钟DMAMUX_CHCFG0=DMAMUX_CHCFG_SOURCE(49);//DMA通道0对应49号DMA请求,即PORTADMA_TCD0_CITER_ELINKNO=DMA_CITER_ELINKNO_CITER(V);//当前主循环次数,采集点数DMA_TCD0_BITER_ELINKNO=DMA_BITER_ELINKNO_BITER(V);//起始主循环次数,采集点数DMA_TCD0_SADDR=(uint32)&GPIOD_PDIR;//设置源地址GPIO口,PORTDDMA_TCD0_SOFF=0;//每次传送源地址不变DMA_TCD0_NBYTES_MLNO=DMA_NBYTES_MLNO_NBYTES(1);//每次读取一字节DMA_TCD0_SLAST=0;//主循环结束后源地址不变DMA_TCD0_DLASTSGA=0;//主循环结束后目的地址不调整,自动指向下一行数组第一个元素DMA_TCD0_DADDR=(uint32)video;//设置目的地址,video数组第一个元素DMA_TCD0_DOFF=1;//每次写目的地址加1DMA_TCD0_ATTR=DMA_ATTR_SSIZE(0)+DMA_ATTR_DSIZE(0);//源数据8bit,目的数据8bitDMA_TCD0_CSR=DMA_CSR_DREQ_MASK;//通道0主循环结束后停止硬件请求DMA_TCD0_CSR|=DMA_CSR_INTMAJOR_MASK;//使能DMA0中断DMAMUX_CHCFG0|=DMAMUX_CHCFG_ENBL_MASK;//DMA通道0使能 }DMA的中断服务函数中可登记采集的行数:
void DMA_CH0_ISR(void){DMA_INT|=DMA_INT_INT0_MASK;//清除通道0中断row_F[imagerow]=1;//采集完成标志imagerow++; }
顺便提一句,用DMA测速,就是把编码器或者光电马盘的脉冲当做DMA请求信号,在周期中断中读相应寄存器的值,再考虑上是否溢出,经过简单计算((DMA_MAX_NUM - DMA_BASE_PTR->TCD[DMA_CH0].CITER_ELINKNO)+ DMA_MAX_NUM*ch0_over_cnt),便可得出一定时间内的脉冲数,便可用于测速。
- 关于DMA的学习
- 关于DMA的配置
- DMA控制器的学习
- 基于stm32f103zet6的DMA学习
- 关于DMA
- 关于IDE DMA的简单说明.
- 关于YL2410 DMA 与SPI 的问题
- 关于DMA和它的仇家
- 关于STM32的I2C硬件DMA实现
- 关于DMA传输外设地址的说明
- 关于DMA和它的仇家
- 关于DMA的两个小知识点
- DMA学习
- 对DMA传输机制的学习
- stm32上DMA的学习笔记
- 关于DMA基础知识
- 近期关于“WINCE驱动开发之DMA的使用”讨论
- 关于NIOS II的DMA controller
- 网址批量缩短工具
- uva 10420 List of Conquests
- ch05 Servlet技术
- 29.栈的push、pop 序列
- Direct UI
- 关于DMA的学习
- 简单工厂模式,工厂方法模式及抽象工厂模式比较
- 深入理解php原理之变量分离/引用
- Boost 1.46.1编译成VS2008版本
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 关于如何把canvas中的内容转换为图片上传到服务器的操作过程
- 精选实用正则表达式
- 深刻理解php之变量分离/引用
- zb的生日 nyist325