关于网站建设的名言,今天特大军事新闻事件,文创产品推广方案,免费数据源网站前言 本篇博客主要学习了解DMA的工作原理和部分寄存器解析#xff0c;针对ADC多通道来对代码部分#xff0c;应用部分作详细讲解#xff0c;掌握代码编程原理。本篇博客大部分是自己收集和整理#xff0c;如有侵权请联系我删除。
本次博客开发板使用的是正点原子精英版针对ADC多通道来对代码部分应用部分作详细讲解掌握代码编程原理。本篇博客大部分是自己收集和整理如有侵权请联系我删除。
本次博客开发板使用的是正点原子精英版芯片是STM32F103ZET6,需要资料可以我拿取。
交流群717237739
本博客内容原创创作不易转载请注明 ————————————————
一 . DMA的基本介绍
DMADirect Memory Access直接存储器存取DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输无须CPU干预节省了CPU的资源DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作传输动作本身是由DMA控制器来实现和完成的。DMA传输方式无需CPU直接控制传输也没有中断处理方式那样保留现场和恢复现场过程通过硬件为RAM和IO设备开辟一条直接传输数据的通道使得CPU的效率大大提高。
作用为CPU减负。
因此转移数据尤其是转移大量数据是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B只要给两种外设提供一条数据通路直接让数据由A拷贝到B 不经过CPU的处理 二 . DMA的特性
12个独立的可配置的通道(请求)DMA1有7个通道DMA2有5个通道 每个通道都直接连接专用的硬件DMA请求每个通道都同样支持软件触发。这些功能通过软件来配置。 在同一个DMA模块上多个请求间的优先权可以通过软件编程设置(共有四级很高、高、中等和低)优先权设置相等时由硬件决定(请求0优先于请求1依此类推) 。 在相等的优先级下DMA1通道2的优先级是 大于 DMA1通道4通道越低优先级越高。
独立数据源和目标数据区的 传输宽度(字节、半字、全字) 模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。 支持循环的缓冲器管理 每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错)这3个事件标志 逻辑或成为一个单独的中断请求。 存储器和存储器间的传输 外设和存储器、存储器和外设之间的传输 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。 可编程的数据传输数目最大为65535
三. 存储器映像 四 . DMA功能框图
1.功能描述 DMA控制器和Cortex™-M3核心共享系统数据总线执行直接存储器数据传输。 当CPU 和 DMA 同时访问相同的目标(RAM 或外设 ) 时 DMA 请求会暂停 CPU 访问系统总线达若干个周期总线仲裁器执行循环调度以保证CPU 至少可以得到一半的系统总线 ( 存储器或外设 ) 带宽。 1DMA2仅存在于大容量产品和互联型产品。 2SPI/I2S3、UART4、TIM5、TIM6、TIM7和DAC的DMA请求仅存在于大容量产品和互联型产品。 3ADC3、SDIO和TIM8的DMA请求仅存在于大容量产品。 2.DMA仲裁器 3.DMA通道
1.DMA1 控制器 从外设 (TIMx[x1 、 2 、 3 、 4] 、 ADC1 、 SPI1 、 SPI/I2S2 、 I2Cx[x1 、 2] 和 USARTx[x1 、 2 、 3]) 产生的 7 个请求通过逻辑或输入到 DMA1 控制器这意味着同时只能有一个请求有效。 外设的 DMA 请求可以通过设置相应外设寄存器中的控制位被独立地开启或关闭。 2.DMA 1 各通道一览 3.DMA 2 控制器 从外设 (TIMx[5 、 6 、 7 、 8] 、 ADC3 、 SPI/I2S3 、 UART4 、 DAC 通道 1 、 2 和 SDIO) 产生的 5 个请 求经逻辑或输入到 DMA2 控制器这意味着同时只能有一个请求有效。 4.DMA 2 各通道一览 5.DMA传输方式 DMA的作用就是实现数据的直接传输而去掉了传统数据传输需要CPU寄存器参与的环节主要涉及四种情况的数据传输但本质上是一样的都是从内存的某一区域传输到内存的另一区域外设的数据寄存器本质上就是内存的一个存储单元。四种情况的数据传输如下
外设到内存 内存到外设 内存到内存 外设到外设
6 .DMA传输参数 我们知道数据传输首先需要的是
1 数据的源地址
2 数据传输位置的目标地址
3 传递数据多少的数据传输量
4 进行多少次传输的传输模式 DMA所需要的核心参数 当用户将参数设置好主要涉及源地址、目标地址、传输数据量这三个DMA控制器就会启动数据传输当剩余传输数据量为0时 达到传输终点结束DMA传输 当然DMA 还有循环传输模式 当到达传输终点时会重新启动DMA传输。 也就是说只要剩余传输数据量不是0而且DMA是启动状态那么就会发生数据传输。
6. stm32中DMA的circle和normal模式的区别 在STM32系列微控制器上DMADirect Memory Access直接内存访问是一种用于高效数据传输的重要功能。DMA的Circle循环模式和Normal普通模式是两种常见的DMA传输模式它们在数据传输方面有一些区别。
Circle循环模式
在Circle模式下DMA传输可以循环执行即在完成一次传输后会自动重新开始下一次传输形成一个循环。这种模式适用于需要连续、循环传输数据的场景。在循环模式下DMA传输会持续不断地从源地址读取数据并将数据写入目标地址直到达到设定的传输长度或触发停止条件。循环模式下的DMA传输通常用于周期性的数据传输如音频、视频流等连续数据流的传输。
Normal普通模式
在Normal模式下DMA传输只会执行一次传输完毕后就会停止。这种模式适用于单次数据传输的场景。在普通模式下DMA传输会从源地址读取数据并将数据写入目标地址直到达到设定的传输长度或触发停止条件然后传输停止。普通模式下的DMA传输适用于需要一次性传输数据的情况如初始化数据、配置信息等。
需要注意的是循环模式和普通模式都可以设置传输长度、源地址和目标地址等参数区别主要在于传输的执行方式和传输结束后是否重新开始。
在使用DMA时需要根据具体的应用需求选择适合的模式。
如果需要连续、循环传输数据可以选择循环模式
如果只需进行单次传输可以选择普通模式。
同时还需要注意设置适当的传输长度和停止条件以确保传输的准确性和可靠性。
五 . DMA 的配置和应用
1.DMA运作过程图解
下面看有与没有DMA的情况下ADC采集的数据是怎样存放到SRAM中的
没有DMA
1.如果没有DMA,CPU传输数据还要以内核作为中转站比如要将ADC采集的数据转移到到SRAM中这个过程是这样的
内核通过DCode经过总线矩阵协调从获取AHB存储的外设ADC采集的数据
然后内核再通过DCode经过总线矩阵协调把数据存放到内存SRAM中。 参考博客链接https://blog.csdn.net/as480133937/article/details/104927922
2.DMA数据流仅存在于STM32F4 /M4 内核上了解即可
在设置了DMA的通道之后还要选择通道对应外设的数据流 3.指针增量
存储器到存储器源和目标的指针都需要设置为增量模式
存储器到外设 存储器地址设置为增量模式外设地址设置为非增量模式。
4.通道配置过程
0 .开启DMA时钟
1. 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时这个地址将是数据传输的源或目标。2. 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时传输的数据将从这个地址读出或写入这个地址。3. 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后这个数值递减。4. 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。5. 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度。 ---CCRX寄存器6. 设置DMA_CCRx寄存器的ENABLE位启动该通道。
5 .DMA中断 每个DMA通道都可以在DMA传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑通过设置寄存器的不同位来打开这些中断。 六. DMA配置过程
这个部分我们结合ADC来进行讲解使用
DMA配置参数包括通道地址、优先级、数据传输方向、存储器/外设数据宽度、存储器/外设地址是否增量、循环模式、数据传输量。 ADCDMA多通道框图
ADC详解在另一个博客ADC 讲解 配置初始化代码
#include stm32f10x.h // Device headeruint16_t AD_Value[4];void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure);//开启对应通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; //数据右对齐ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动ADC_InitStructure.ADC_ContinuousConvMode ENABLE; //模数转换工作在循环转换模式ADC_InitStructure.ADC_ScanConvMode ENABLE; //模数转换工作在多通道模式ADC_InitStructure.ADC_NbrOfChannel 4; //顺序进行规则转换的ADC通道的数目ADC_Init(ADC1, ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr (uint32_t)ADC1-DR; // ADC- DMA外设基地址DMA_InitStructure.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord; //半字传输数据宽度为16位DMA_InitStructure.DMA_PeripheralInc DMA_PeripheralInc_Disable; //外设地址不自增DMA_InitStructure.DMA_MemoryBaseAddr (uint32_t)AD_Value; //存储器数据存储地址 数组DMA_InitStructure.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; //半字传输数据宽度为16位DMA_InitStructure.DMA_MemoryInc DMA_MemoryInc_Enable; //存储器内存地址寄存器递增DMA_InitStructure.DMA_DIR DMA_DIR_PeripheralSRC; //数据传输方向从外设读取发送到存储器DMA_InitStructure.DMA_BufferSize 4; //扫描通道4个DMA_InitStructure.DMA_Mode DMA_Mode_Circular; //循环模式DMA_InitStructure.DMA_M2M DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输DMA_InitStructure.DMA_Priority DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_Init(DMA1_Channel1, DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMAADC_DMACmd(ADC1, ENABLE); //使能ADC_DMA传输ADC_Cmd(ADC1, ENABLE); //使能ADCADC_ResetCalibration(ADC1); //使能复位校准 while (ADC_GetResetCalibrationStatus(ADC1) SET); //等待复位校准结束ADC_StartCalibration(ADC1); //开启AD校准while (ADC_GetCalibrationStatus(ADC1) SET); //等待校准结束ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}库函数讲解摘自群友的笔记 总结 DMA的使用并不复杂搞清楚数据的方向还是是否自增就行了多使用多实践大家如果对我的博客有疑问或者错误可以我修改大家相互交流。
交流群717237739
如果觉得有用点赞关注收藏三连多谢支持 点赞收藏关注博主不定期分享单片机知识互相学习交流。 ————————————————