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

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

[复制链接]
sailor.wu 发布时间:2015-11-2 22:08
双重 ADC 模式:
在 ADC1 或 ADC2 转换事件结束时:
● 会生成一个 32 位 DMA 传输请求(如果 ADC_CCR 寄存器中的 DMA[1:0] 位等于
0b10)。此请求会将存储在 ADC_CDR 32 位寄存器高位半字中的 ADC2 转换数据传输
到 SRAM,然后将存储在 ADC_CCR 低位半字中的 ADC1 转换数据传输到 SRAM。
● 当 ADC1/ADC2 的规则通道全部完成转换后,会生成一个 EOC 中断(如果已在两个 ADC
接口中的一个接口上使能)。

转换示意图:

转换示意图

转换示意图


配置代码:

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


void Init_ADC12(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_InitTypeDef       ADC_InitStructure;
   
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  
  //先初始化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_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;       //数据传输方向选择为内存->外设
    DMA_InitStructure.DMA_BufferSize = 2;                      //传输数据大小为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, ENABLE); //使能ADC1时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟

  ADC_DeInit();
  //初始化ADC Common
  ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化
   
  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_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(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_15Cycles);   
  ADC_RegularChannelConfig(ADC2, ADC_Channel_1 , 1, ADC_SampleTime_15Cycles);
  
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  
   
    /* Enable DMA request after last transfer (Multi-ADC mode)  */
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
  
  
  ADC_Cmd(ADC1, ENABLE);//开启AD1转换器   
  ADC_Cmd(ADC2, ENABLE);//开启AD2转换器   

转换示意图

转换示意图
收藏 4 评论12 发布时间:2015-11-2 22:08

举报

12个回答
disheng4688 回答时间:2015-11-3 08:36:56
谢谢分享         
dear祝子 回答时间:2015-11-3 08:50:24
给你32个赞!!!
me浩 回答时间:2015-11-3 09:03:20
谢谢分享啊
我是你的e 回答时间:2015-11-3 09:05:58
感觉你的头像很酷,内容也不错!所以给你一个赞
钊钊 回答时间:2015-11-3 09:28:38
看了下,楼主的思路还行,但是我不明白这么做的目的,或者说要实现的是什么,恕我看不懂呢,能稍微解释下吗?
sailor.wu 回答时间:2015-11-18 18:31:49
电机FOC控制,需要采两相电流,ADC采样时间短的话,调制度就可以放大。
wz002 回答时间:2015-11-20 15:55:16
:)
ataudio 回答时间:2015-11-20 17:01:41
与ADC 相关的都要关注。
‪931581159 回答时间:2017-4-7 13:43:17
本帖最后由 ‪931581159 于 2017-4-7 13:44 编辑

内存地址自增不允许,因为只存取一个数
这句注释错了吧,明明你设置的是DMA_MemoryInc_Enable
虽然我也不知道到底是注释错了还是代码错了
……
多看了几段,为什么注释和代码都是自相矛盾?
alisa123 回答时间:2018-12-16 23:51:18
楼主, 我看  你分享的代码中,把关于DAM的中断的部分注释掉了, 请问这一块开DMA中断的代码是OK的吗?你有测试过在DAM中断中收数据吗?
panze 回答时间:2018-12-25 16:33:07
谢谢分享啊
lxl8511 回答时间:2019-1-10 16:30:29
谢谢分享谢谢分享谢谢分享谢谢分享谢谢分享谢谢分享

所属标签

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