stm32 dma 通道用多少个通道

后使用快捷导航没有帐号?
请完成以下验证码
查看: 4054|回复: 3
dma存储器到存储器模式,通道选几??
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
请教版主,dma
存储器到存储器模式
运行DMA_Init()函数,
里面的通道选几??
手册里可有说?
我做的实验是选几号通道都行!
&&&&&&&&&&
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
& & & & & & & & & & & & & & & &&&是的,DMA存储器到存储器模式不限定通道。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&谢谢斑竹回复,建议下一版手册补充上这条说明!
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&不需要补充这条说明,这是不言而喻的。
EEWORLD 官方微信
Powered by随笔 - 331&
文章 - 0&评论 - 18&trackbacks - 0
一、DMA简介
1、DMA简介
  DMA(Direct Memory Access:直接内存存取)是一种可以大大减轻CPU工作量的数据转移方式。
  CPU有转移数据、计算、控制程序转移等很多功能,但其实转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,再加上一些控制转移的部件就可以完成数据的拷贝。
  DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作--计算、控制等。
2、DMA的工作原理 
  DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。四种情况的数据传输如下:
外设到内存
内存到外设
内存到内存
外设到外设
  当用户将参数设置好,主要涉及源地址、目标地址、传输数据量这三个,DMA控制器就会启动数据传输,传输的终点就是剩余传输数据量为0(循环传输不是这样的)。换句话说只要剩余传输数据量不是0,而且DMA是启动状态,那么就会发生数据传输。  
3、DMA是否影响CPU的运行
  在X86架构系统中,当DMA运作时(假设我们从磁盘拷贝一个文件到U盘),DMA实际上会占用系统总线周期中的一部分时间。也就是说,在DMA未开启前,系统总线可能完全被CPU使用;当DMA开启后,系统总线要为DMA分配一定的时间,以保证DMA和CPU同时运作。那么显然,DMA会降低CPU的运行速度。
  在STM32控制器中,芯片采用Cortex-M3架构,总线结构有了很大的优化,DMA占用另外的总线,并不会与CPU的系统总线发生冲突。也就是说,DMA的使用不会影响CPU的运行速度。
二、STM32的DMA结构
1、DMA的主要特性
● 12个 独立的可配置的通道(请求)DMA1有7个通道,DMA2 有5个通道 ● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。 ● 在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如在相等优先权时由硬件决定(请求0优先于请求1,依此类推)
。 ● 独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。 ● 支持循环的缓冲器管理 ● 每个通道都有3个事件标志(DMA
半传输,DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。 ● 存储器和存储器间的传输 ● 外设和存储器,存储器和外设的传输 ● 闪存、SRAM 、外设的SRAM 、APB1 APB2和AHB外设均可作为访问的源和目标。 ● 可编程的数据传输数目:最大为65536
下面为功能框图:
2、两个DMA控制器结构
① DMA1 controller
② DMA2 controller
3、DMA寄存器列表
DMA_ISR:   DMA中断状态寄存器
DMA_IFCR:  DMA中断标志位清除寄存器
说明:  DMA1、DMA2分别有一组寄存器。
② 控制传输类
DMA_CCRx:   DMA通道x配置寄存器 
DMA_CNDTRx:  DMA通道x数据数量寄存器
DMA_CPARx:  &DMA通道x外设地址寄存器
DMA_CMARx:  DMA通道x内存地址寄存器
说明: & &
1& 每一个通道都有一组寄存器。
2& DMA_CPARx、DMA_CMARx是没有差别的,它们都可以存放外设的地址、内存的地址。DMA_CPARx、DMA_CMARx只不过起得名字有差别而已。
4、STM32的DMA工作特点
① DMA进行数据传输的必要条件
剩余传输数据量大于0
DMA通道传输使能
通道上DMA数据传输有事件请求
 &前两者都好理解,对于第三点确实需要详细的解释,请看下边的三条。
② 外设到XX方向的传输
  假设是ADC到存储器的数据传输,显然ADC的DMA传输的源地址是ADC的数据寄存器。并不是说只要DMA通道传输使能后,就立即进行数据传输。只有当一次ADC转化完成,ADC的DMA通道的传输事件有效,DMA才会从ADC的数据寄存器读出数据,写入目的地址。当DMA在读取ADC的数据寄存器时,同时使ADC的DMA通道传输事件无效。显然,要等到下一次ADC转换完成后,才能启动再一次的数据传输。
③存储器对XX的DMA传输
  因为数据是准备好的,不像ADC还需要等待数据到位。所以,不需要对应通道的事件。只要使能DMA数据传输就一直传输,直到达到设定的传输量。
1.内存到内存
  DMA传输请求一直有效
2.内存到串口&
  DMA传输请求一直有效
一种解释:
  存储器对存储器的置位,就相当于相应通道的事件有效。&对应通道的事件有效和存储器对存储器的置位,就是传输的触发位。每次传输的事件置位一次,完成一次传输。如果是由外设引发的DMA传输,则传输完成后,相应传输事件会置为无效,而存储器对存储器的传输,则一次传输完成后,相应事件一直有效,直至完成设定的传输量。 &              摘自:
④外设以DMA方式工作时,能否再以软件方式进行操作?
  有一点是肯定的,当外设以DMA方式正在数据传输时,不可能再相应CPU的软件控制命令,否则这不符合逻辑。
  但是,倘若外设仅仅配置成DMA工作方式,但是DMA请求并未产生,数据传输并没有进行。此时,软件控制命令仍然能够对外设进行控制。这是笔者在串口以DMA方式发送数据情形下,所得到的测试结论。&
三、STM32的DMA软件编程
1、&内存到内存&模式传输
①&初始化配置
uint8_t SendBuff[SENDBUFF_SIZE];
uint8_t ReceiveBuff[RXBUFF_SIZE];
USART1 TX DMA 配置,内存到内存
* @retval 无
void DMA_Mem2Mem_Config(void)
DMA_InitTypeDef DMA_InitS
/*开启DMA时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/*设置DMA源地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SendB
/*设置DMA目的地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr =
(uint32_t)ReceiveB
/*方向:从内存SendBuff到内存ReceiveBuff*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
/*传输大小DMA_BufferSize=SENDBUFF_SIZE*/
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
/*ReceiveBuff地址自增*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_E
/*SENDBUFF_SIZE地址自增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E
/*ReceiveBuff数据单位*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_B
/*SENDBUFF_SIZE数据单位*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_B
/*DMA模式:正常模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_N
/*优先级:中*/
DMA_InitStructure.DMA_Priority = DMA_Priority_M
/*使能内存到内存的传输
DMA_InitStructure.DMA_M2M = DMA_M2M_E
/*配置DMA1的4通道*/
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
/*失能DMA1的4通道,一旦使能就开始传输*/
DMA_Cmd (DMA1_Channel4,DISABLE);
②&DMA中断配置
DMA 中断配置
* @retval 无
void DMA_NVIC_Configuration(void)
NVIC_InitTypeDef NVIC_InitS
/* 配置中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 配置DMA发送完成后产生中断 */
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
③启动传输
DMA_Cmd (DMA1_Channel4,ENABLE);
2、利用DMA实现循环传输
方法1:单次传输模式
  当传输结束时,触发DMA中断,在中断程序中首先失能DMA通道,然后修改该通道的传输数据量。最后重新使能DMA通道,注意只有失能的DMA通道才能成功修改传输数据量。
方法2:循环传输模式
  当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。
四、再谈STM32的DMA传输是否影响CPU的运行速度
  声明:经过笔者测试,当DMA工作在内存到外设的传输和内存到内存的传输时,都不会影响CPU的运行速度。为了给这种现象一个合理的解释,笔者做以下猜测:
1、S3C2440的DMA传输
  S3C2440的SDRAM是外置的,并且SDRAM的数据线、地址线、控制线总共只有一组。假设DMA传输的方向是内存到外设,当DMA运作时,需要占用SDRAM的三类线才才能实现传输;而与此同时CPU也需要通过这三类线来访问SDRAM来读取程序、读写数据。
  显然,DMA的运行与CPU的运行有交叉点,DMA就会影响到CPU的运行。
2、STM32的DMA传输
  STM32与S3C2440的区别是很大的,S3C2440是微处理器,RAM外置且空间很大;STM32是微控制器,RAM片内集成且空间较小。此时,ST公司就有可能提升DMA的运作效率,使DMA的工作不影响到CPU的运行。
  外设与外设之间的DMA传输,因为与CPU的运行没有交叉点(CPU的数据流注意是在Flash、内存、寄存器中传输),所以不会影响CPU的运行速度。唯一有可能影响的是外设与内存或者内存与内存之间的DMA传输。
  倘若ST公司的SRAM是一个双口RAM,也就是同时可以由两组接口对RAM进行访问,就可以很好的解决速度影响问题。倘若CPU恒定占有一组接口,而另一组接口留给DMA控制器。那么当外设与内存或者内存与内存之间的DMA传输时,由于不与CPU的访问SRAM接口冲突,所以可以解决速度影响问题。
  但其实偶尔还是会影响的,当CPU访问SRAM的空间和DMA访问SRAM的空间相同时,SRAM势必会对这种情况进行仲裁,这可能会影响到CPU的访问SRAM的速度。其实,这种情况的概率也是很小的,所以即使影响CPU的运行速度,也不会很大。
参考资料:《STM32参考手册》
阅读(...) 评论()同一个DMA的不同通道之间的数据会有冲突? - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 871|回复: 4
同一个DMA的不同通道之间的数据会有冲突?
在线时间6 小时
主题帖子好友
初级会员, 积分 77, 距离下一级还需 123 积分
初级会员, 积分 77, 距离下一级还需 123 积分
问题是:单独用STM32F373 的DMA2_CH3由内存向DAC1_CH1传数据,生成约13KHz正弦信号,没有问题。另外单独用DMA2_CH4将SDADC2转换结果通过DMA2_CH4送到内存,50KHz采样速率。也没有问题。上述两项工作同时做,DAC1_CH1出来的几乎是杂波。尝试将DAC1_CH1生成的正弦信号频率降低至2.5KHz,同时将SDADC2采样速率降低至12.5KHz,无济于事。
在线时间120 小时
主题帖子好友
金牌会员, 积分 1528, 距离下一级还需 3472 积分
金牌会员, 积分 1528, 距离下一级还需 3472 积分
应该不会吧& &&&
在线时间197 小时
ST金币2004
主题帖子好友
金牌会员, 积分 3743, 距离下一级还需 1257 积分
金牌会员, 积分 3743, 距离下一级还需 1257 积分
程序有问题吧。。。
在线时间6 小时
主题帖子好友
初级会员, 积分 77, 距离下一级还需 123 积分
初级会员, 积分 77, 距离下一级还需 123 积分
程序有问题吧。。。
确实是程序的问题,程序中开启了DMA2_CH4传输完成中断,中断中释放了执行FFT信号量,执行了FFT后紧跟着执行了求模函数arm_cmplx_mag_f32,已经查明就是由于执行了这个求模函数导致生成正弦信号失效。求模函数中执行了大量的乘法及开平方计算。估计由于计算量比较大,占用了系统总线带宽。
在线时间6 小时
主题帖子好友
初级会员, 积分 77, 距离下一级还需 123 积分
初级会员, 积分 77, 距离下一级还需 123 积分
又发现执行FFT运算(arm_cfft_radix4_f32函数)会导致DMA2_CH4数据传输错误。
DMA传输时要让出一半的系统总线带宽给CPU( Cortex-M4 with FPU core),但是也不对啊。SDADC以50KHz速率采样,占用的带宽不会超过1MHz。100点的正弦序列生成13KHz的正弦信号也就占用1.3MHz带宽。系统总线带宽有72MHz,系统总线是32位宽。怎么算这两个DMA通道都不会占用一半的系统总线带宽。
(43.23 KB, 下载次数: 0)
17:59 上传
(39.98 KB, 下载次数: 0)
17:59 上传
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered bystm32 DMA通道外设基地址的配置
单片机&嵌入式
单片机应用
嵌入式操作系统
学习工具&教程
学习和开发单片机的必备工具
(有问必答)
(带你轻松入门)
电子元件&电路模块
当前位置: >>
>> 浏览文章
stm32 DMA通道外设基地址的配置
看了许多资料都没有讲如何配置DMA通道外设基地址
ADC 规则数据寄存器(ADC_DR)的地址偏移:4Ch
#define ADC1_DR_Address&&& ((u32)0x4001244C)
就是ADC1的外设基地址(0x)加上ADC数据寄存器(ADC_DR)的偏移地址(0x4c)计算得到的。
/************************************************************************************
&* 文件名& :main.c
&* 描述&&& :串口1(USART1)向电脑发送当前ADC1的转换电压值&&&&&&&&
&* 库版本& :ST3.5.0
**********************************************************************************/
#include &stm32f10x.h&
#include &usart1.h&
#include &adc.h&
// ADC1转换的电压值通过DMA方式传到SRAM
extern __IO uint16_t ADC_ConvertedV
// 局部变量,用于保存转换计算后的电压值
float ADC_ConvertedValueL&&&&&&&
& * @brief& Main program.
& * @param& None
& * @retval : None
int main(void)
&&& /* USART1 config */
&&& USART1_Config();
&&& /* enable adc1 and config adc1 to dma mode */
&&& ADC1_Init();
&&& while (1)
&&&&&&& ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/; // 读取转换的AD值
&&&&&&& printf(&\r\n The current AD value = 0x%04X \r\n&, ADC_ConvertedValue);
&&&&&&& printf(&\r\n The current AD value = %f V \r\n&,ADC_ConvertedValueLocal);
/*************************************************************************************************/
/************************************************************************************
&* 文件名& :adc.c
***********************************************************************************/
#include &adc.h&
#define ADC1_DR_Address&&& ((u32)0xx4c)
__IO uint16_t ADC_ConvertedV
&* 函数名:ADC1_GPIO_Config
&* 描述& :使能ADC1和DMA1的时钟,初始化PC.01
&* 输入& : 无
&* 输出& :无
&* 调用& :内部调用
static void ADC1_GPIO_Config(void)
&&& GPIO_InitTypeDef GPIO_InitS
&&& /* Enable DMA clock */
&&& RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
&&& /* Enable ADC1 and GPIOC clock */
&&& RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
&&& /* Configure PC.01& as analog input */
&&& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
&&& GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
&&& GPIO_Init(GPIOC, &GPIO_InitStructure);&&&&&&&&&&&&&&&&&&& // PC1,输入时不用设置速率
/* 函数名:ADC1_Mode_Config
&* 描述& :配置ADC1的工作模式为MDA模式
&* 输入& : 无
&* 输出& :无
&* 调用& :内部调用
static void ADC1_Mode_Config(void)
&&& DMA_InitTypeDef DMA_InitS
&&& ADC_InitTypeDef ADC_InitS
&&& /* DMA channel1 configuration */
&&& DMA_DeInit(DMA1_Channel1);
&&& DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_A&&&&&&&&&&&&&& //ADC地址
&&& DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedV&&& //内存地址
&&& DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
&&& DMA_InitStructure.DMA_BufferSize = 1;
&&& DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D&&&&&&&&&&&&& //外设地址固定
&&& DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_D&&&&&&&&&&&&&&&&&&&&& //内存地址固定
&&& DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW//半字
&&& DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW
&&& DMA_InitStructure.DMA_Mode = DMA_Mode_C&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //循环传输
&&& DMA_InitStructure.DMA_Priority = DMA_Priority_H
&&& DMA_InitStructure.DMA_M2M = DMA_M2M_D
&&& DMA_Init(DMA1_Channel1, &DMA_InitStructure);
&&& /* Enable DMA channel1 */
&&& DMA_Cmd(DMA1_Channel1, ENABLE);
&&& /* ADC1 configuration */
&&& ADC_InitStructure.ADC_Mode = ADC_Mode_I&&&&&&&&&&&&&&&&&&&&&&& //独立ADC模式
&&& ADC_InitStructure.ADC_ScanConvMode = DISABLE ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //禁止扫描模式,扫描模式用于多通道采集
&&& ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;&&&&&&&&&&&&&&&&&&&&&&& //开启连续转换模式,即不停地进行ADC转换
&&& ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_N//不使用外部触发转换
&&& ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_R&&&&&&&&&&&&&&&&&&&&& //采集数据右对齐
&&& ADC_InitStructure.ADC_NbrOfChannel = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //要转换的通道数目1
&&& ADC_Init(ADC1, &ADC_InitStructure);
&&& /*配置ADC时钟,为PCLK2的8分频,即9Hz*/
&&& RCC_ADCCLKConfig(RCC_PCLK2_Div8);
&&& /*配置ADC1的通道11为55.5个采样周期,序列为1 */
&&& ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
&&& /* Enable ADC1 DMA */
&&& ADC_DMACmd(ADC1, ENABLE);
&&& /* Enable ADC1 */
&&& ADC_Cmd(ADC1, ENABLE);
&&& /*复位校准寄存器 */&&
&&& ADC_ResetCalibration(ADC1);
&&& /*等待校准寄存器复位完成 */
&&& while(ADC_GetResetCalibrationStatus(ADC1));
&&& /* ADC校准 */
&&& ADC_StartCalibration(ADC1);
&&& /* 等待校准完成*/
&&& while(ADC_GetCalibrationStatus(ADC1));
&&& /* 由于没有采用外部触发,所以使用软件触发ADC转换 */
&&& ADC_SoftwareStartConvCmd(ADC1, ENABLE);
&* 函数名:ADC1_Init
&* 描述& :无
&* 输入& :无
&* 输出& :无
&* 调用& :外部调用
void ADC1_Init(void)
&&& ADC1_GPIO_Config();//配置IO
&&& ADC1_Mode_Config();//配置DMA和ADC
DMA自动将ADC外设的数据寄存器(ADC_DR_Adress)的数据转移到内存中的变量ADC_ConvertedValue中。
【】【】【】【】
上一篇:下一篇:
CopyRight @
单片机教程网
, All Rights Reserved求大神之指导STM32
DMA多通道传输的问题啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 3823|回复: 5
求大神之指导STM32
DMA多通道传输的问题啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在线时间2 小时
主题帖子好友
初级会员, 积分 79, 距离下一级还需 121 积分
初级会员, 积分 79, 距离下一级还需 121 积分
废话不说了,直接上代码:
我的思路是这样的:AD采集的值通过DMA方式传输到内存,然后再请求使用DMA方式将数据直接打印到串口!
下面是DMA的配置!!!
u16 ADC_RegularConvertedValueTab[RECEVE_SIZE];
u16 SendBuff[SENDBUFF_SIZE];
void DMA_Configuration(void)
//DMA方式发送
DMA_InitTypeDef DMA_InitS
& & & & NVIC_InitTypeDef NVIC_InitS
& & & & RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
& & & & NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
& & & & NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
& & & & NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& & & & NVIC_Init(&NVIC_InitStructure);
//DMA设置:
//设置DMA源:内存地址&ADC1数据寄存器地址
//方向:外设--&内存
//每次传输位:16bit
//传输大小DMA_BufferSize=RECEVE_SIZE
//地址自增模式:外设地址不增,内存地址自增1
//DMA模式:循环
//优先级:很高
DMA_DeInit(DMA1_Channel1);//ADC1的DMA传输通道是通道1
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_B
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_RegularConvertedValueT
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设作为DMA数据传输的来源
DMA_InitStructure.DMA_BufferSize = RECEVE_SIZE;//传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D//外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E//内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW
DMA_InitStructure.DMA_Mode = DMA_Mode_N
//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryH//(DMA传送优先级很高)
DMA_InitStructure.DMA_M2M = DMA_M2M_D
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
& & & & DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
//中断方式吧
& & & & //开始一次DMA传输!
& & & & DMA_Cmd(DMA1_Channel1, ENABLE);
& & & & //DMA设置:
//设置DMA源:内存地址&串口数据寄存器地址
//方向:内存--&外设
//每次传输位:8bit
//传输大小DMA_BufferSize=SENDBUFF_SIZE
//地址自增模式:外设地址不增,内存地址自增1
//DMA模式:一次传输,非循环
//优先级:中
DMA_DeInit(DMA1_Channel4);//串口1的DMA传输通道是通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_B
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueT
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外设作为DMA的目的端
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D//外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E//内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_B
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW
DMA_InitStructure.DMA_Mode = DMA_Mode_N
//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_M//(DMA传送优先级为中等)
DMA_InitStructure.DMA_M2M = DMA_M2M_D
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
主函数简单!!!如下
int main(void)
& & & & delay_init(72);
& & & & USART_Configuration();
& & & & Beep_Init();
& & & & ADC1_Configuration();
& & & & DMA_Configuration();
& & & & while (1)
& & & & & & & & while(Flag_Uart_Send);
& & & & & & & & USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
& & & & & & & & DMA_SetCurrDataCounter(DMA1_Channel4,RECEVE_SIZE);
& & & & & & & & //开始一次DMA传输!
& & & & & & & & DMA_Cmd(DMA1_Channel4, ENABLE);
& & & & & & & & while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
& & & & & & & & {
& & & & & & & & & & & & beep_on();
& & & & & & & & & & & & delay_ms(50);
& & & & & & & & & & & & beep_off();
& & & & & & & & & & & & delay_ms(50);
& & & & & & & & Flag_Uart_Send=1;
其中DMA通道1采用了中断的方式!!!
extern u8 Flag_Uart_S
//串口1DMA方式发送中断
void DMA1_Channel1_IRQHandler(void)
& & & & //清除标志位
DMA_ClearFlag(DMA1_FLAG_TC1);
DMA_Cmd(DMA1_Channel4,DISABLE);
//允许再次发送
Flag_Uart_Send = 0;
经过调试发现,逻辑上应该是没有问题的,可是串口打印出来的数据是乱码,求大神指导啊!!!!
还有一个问题就是:DMA传输时外设地址自增这个一直不明白是什么意思!是不是就是多个外设采用DMA方式的时候的通道切换???求大神指导啊111
在线时间2 小时
主题帖子好友
初级会员, 积分 79, 距离下一级还需 121 积分
初级会员, 积分 79, 距离下一级还需 121 积分
回复:求大神之指导STM32
DMA多通道传输的问题啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
先顶为快!!!
在线时间2 小时
主题帖子好友
初级会员, 积分 79, 距离下一级还需 121 积分
初级会员, 积分 79, 距离下一级还需 121 积分
回复:求大神之指导STM32
DMA多通道传输的问题啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
哦,貌似是对的!!!我串口上看的时候以字符形式看的,这样就是乱码了、、、
在线时间2 小时
主题帖子好友
初级会员, 积分 79, 距离下一级还需 121 积分
初级会员, 积分 79, 距离下一级还需 121 积分
回复:求大神之指导STM32
DMA多通道传输的问题啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
DMA传输时外设地址自增这个一直不明白是什么意思!是不是就是多个外设采用DMA方式的时候的通道切换???求大神指导啊111
在线时间66 小时
主题帖子好友
高级会员, 积分 924, 距离下一级还需 76 积分
高级会员, 积分 924, 距离下一级还需 76 积分
在线时间78 小时
主题帖子好友
金牌会员, 积分 1124, 距离下一级还需 3876 积分
金牌会员, 积分 1124, 距离下一级还需 3876 积分
解决了吗?我马上也要做类似的实践。
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered by}

我要回帖

更多关于 stm32 adc dma 多通道 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信