你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f405/407的三重 ADC同步触发模式+DMA 配置

[复制链接]
sailor.wu 发布时间:2015-11-2 21:41
本帖最后由 sailor.wu 于 2015-11-2 21:54 编辑

在成功实现stm32f405/407的两重 ADC同步触发 模式+DMA 配置的情况下,想实现stm32f405/407的三重 ADC同步触发模式+DMA 配置,但是怎么改配置都只有ADC1和ADC2有数据出来,纠结了很久,最后决定静下心来看参考手册和数据手册。最后终于发现是ADC3的端口配置错了。

ADC1~ADC3 的引脚与通道对应关系

ADC1~ADC3 的引脚与通道对应关系

我用ADC3去采PA4数据,哎。。。浪费生命啊!!!!!!!!


我换成ADC1去采PA4的数据。下面附上我的程序,给大家做参考。
【注]
1.用软件触发一下,ADC_SoftwareStartConv(ADC1),就同时完成三路的ADC采集。在ADC都给到最大频率36M时,采样时间设为ADC_SampleTime_3Cycles时,实测需要730ns时间,没有理论的(3+12)/36=0.4166us,不知道是什么原因,有知道的小伙伴告诉我一下。
2.实测ADC给到最大频率36M,采样时间配置为ADC_SampleTime_3Cycles的数据并不是很稳定,改成ADC_SampleTime_15Cycles后,有很大改善。

#define ADC_CDR_ADDRESS    ((uint32_t)0x40012308) //适用于双重和三重模式的 ADC 通用规则数据寄存器( ADC_CDR)

inline void Init_ADC123(void)
{
   
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  
  
  GPIO_InitTypeDef  GPIO_InitStructure;
  //先初始化ADC1通道 IO口
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  
  
  
  
  /*****************************************************************
  *************************** DMA Configuration  ******************
  *******************************************************************/
  
  
  
    DMA_InitTypeDef DMA_InitStructure;
    /*首先开DMA2时钟,由407参考手册-RM0090-Reference manual
     *165页可知,ADC与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
   
    DMA_DeInit(DMA2_Stream0);
    DMA_StructInit( &DMA_InitStructure);
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;                     //选择Channel_0
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; //数据传输的外设首地址,详解见上
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&adc_result;   //自己定义待发送数组的首地址,要强制转换为32位
                                                                                                        //记得改成你需要DMA放置数据的地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;       //数据传输方向选择为内存->外设
    DMA_InitStructure.DMA_BufferSize = 3;                      //传输数据大小为16,单位由以下确定,大小要配合定义的数组类型和外设数据类型
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //内存地址自增不允许,因为只存取一个数
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设的数据大小
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;     //这里也选Byte
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;       //DMA传输模式为Normal,如果为Circular,将会循环传输
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;   //优先级为VeryHigh
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
   

//    NVIC_InitTypeDef NVIC_InitStructure;
//    /* DMA中断配置 */
//    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;      //嵌套通道为DMA2_Stream0_IRQn
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为 1
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //响应优先级为 0
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //通道中断使能
//    NVIC_Init(&NVIC_InitStructure);
   
   
   
    //使能DMA2_Stream0通道
    DMA_Cmd(DMA2_Stream0, ENABLE);
   

//    /* DMA中断开 */
//    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
   
   
  /*****************************************************************
  *************************** ADC Configuration  ******************
  *******************************************************************/
  
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2|RCC_APB2Periph_ADC3, ENABLE); //使能ADC123时钟


  ADC_DeInit();
  //初始化ADC Common
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频2分频。ADCCLK=PCLK2/2=72/2=36Mhz,ADC时钟最好不要超过36Mhz
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化
   
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式   
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐   
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
  
  ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
  ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 1, ADC_SampleTime_3Cycles);   
  
  
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式   
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐   
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
  
  ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化
  ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);
  
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式   
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐   
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
  
  ADC_Init(ADC3, &ADC_InitStructure);//ADC初始化
  ADC_RegularChannelConfig(ADC3,ADC_Channel_1 , 1, ADC_SampleTime_3Cycles);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

   
      /* Enable DMA request after last transfer (Multi-ADC mode)  */
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
   
  /*可通过将 ADC_CR2 寄存器中的 ADON 位置 1 来为 ADC 供电。首次将 ADON 位置 1 时, 会将 ADC 从掉电模式中唤醒。*/
  ADC_Cmd(ADC1, ENABLE);//开启AD1转换器   
  ADC_Cmd(ADC2, ENABLE);//开启AD2转换器   
  ADC_Cmd(ADC3, ENABLE);//开启AD3转换器
   
}

收藏 5 评论16 发布时间:2015-11-2 21:41

举报

16个回答
dz6666 回答时间:2020-5-30 17:19:59
三重adc都存在adc_cdr寄存器中吗,adc的分辨率是12,三个需要36位,adc_cdr寄存器不够啊
CarverZhang 回答时间:2018-8-31 22:38:36
假定 ADC为 3个通道,ADC2为 3个通道,而ADC3 为4个或5个通道,能采用同时模式采集吗?
webberz 回答时间:2016-12-15 21:48:18
楼主大大,请问只要开启ADC1的DMA就可以吗?ADC2和ADC3的是不是也需要开启?
sailor.wu 回答时间:2015-11-2 21:52:10
自己顶一个,哈哈哈!!!!!!
钊钊 回答时间:2015-11-3 00:25:16
多看手册必定有用·哈哈
沐紫 回答时间:2015-11-3 08:38:41
谢谢楼主
me浩 回答时间:2015-11-3 09:03:39
心下大喜
我是你的e 回答时间:2015-11-3 09:06:28
学习ing.............
dear祝子 回答时间:2015-11-3 09:11:35
给你32个赞!!!
niexiaohui 回答时间:2015-11-3 22:39:33
wz002 回答时间:2015-12-11 17:06:42
五哥1 回答时间:2016-12-29 02:50:22
辛苦了,学习了
zbber 回答时间:2016-12-29 09:11:39
楼主加油,我们都看好你哦
5265325 回答时间:2016-12-29 09:50:01
黑皮男 回答时间:2016-12-29 12:28:08
赞一个
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版