单片机学习小组
直播中

hxjq

12年用户 810经验值
私信 关注

如何对两路ADC的数据实现同时采集呢

ADC的多重模式是什么意思?
如何对两路ADC的数据实现同时采集呢?

回帖(1)

杜喜喜

2022-1-25 14:46:06
*** STM32F429HAL库

对于单片机来说我个人觉得最难的部分就是定时器和ADC的运用以及结合了,最近结束了一个项目,刚从学习出来算是四处碰壁了,以前接触的都是一个ADC多路采集数据也就是轮询采集,对于ADC的轮询采集相对于ADC的多重使用更简单一点,反正它只涉及一个ADC,但是不能实现两路ADC的“同时采集”,所有ADC知识在数据手册上都做了详细说明,奈何自己花了很长时间才算相对了解一点
所谓多重ADC就是ADC的主从模式,在宏观上有一种多个ADC同时工作的感觉,ADC1作为主ADC其他作为从。当ADC1启动转换且结束后就会触发从ADC的转换,这样循坏就实现了多路ADC的同时采样
多路ADC用的最多的就是在射频方向上的器件,因为很多都涉及到IQ两路或者差分信号等,ADC的多重模式在芯片手册的讲解如下:

在这里我只讲解规则模式下的多重ADC
在多重ADC下数据是存放在ADC_CDR寄存器当中,这是一个32为的寄存器,也就意味着每次采集完数据最多只能存放两路的ADC数据
我的项目刚好也只需要两路,介于需求是对两路ADC的数据实现同时采集,采用了DMA模式2的双重交替模式
具体的可自行查看芯片手册相应章节
从手册不难看出当两路ADC都采集完成时,ADC2的数据放在ADC_CDR寄存器的高16位,ADC1放在低16位

当两路ADC传输完成后会生成一个DMA请求,此时去读取数据即可,注意在读取的时候将数据分离
下面是多路ADC的基本配置: 本配置采用定时器触发ADC1从而触发从ADC用DMA方式读取数据

     
        ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6;   //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    ADC1_Handler.Init.ScanConvMode=DISABLE;                      //非扫描模式
    ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    ADC1_Handler.Init.ContinuousConvMode=DISABLE;                //连续转换
    ADC1_Handler.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_CC1;       //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING;//使用软件触发
    ADC1_Handler.Init.DMAContinuousRequests=ENABLE;             //开启DMA请求
   
    ADC_MultiMode.Mode = ADC_DUALMODE_REGSIMULT;                // 规则同步模式
    ADC_MultiMode.DMAAccessMode = ADC_DMAACCESSMODE_2;                        //DMA模式2
    ADC_MultiMode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;  // 规则同步模式 不影响
    HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handler,&ADC_MultiMode);
   
    ADC_ChanConf.Channel=ADC_CHANNEL_13;                       //通道11
    ADC_ChanConf.Rank=1;                                       //第1个序列,序列1
    ADC_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;          //采样时间
    ADC_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC_ChanConf);        //通道配置
   
   
   
    ADC2_Handler.Instance=ADC2;
    ADC2_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV6;   //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ
    ADC2_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    ADC2_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    ADC2_Handler.Init.ScanConvMode=DISABLE;                      //非扫描模式
    ADC2_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    ADC2_Handler.Init.ContinuousConvMode=DISABLE;                //连续转换
    ADC2_Handler.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1
    ADC2_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    ADC2_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    ADC2_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_CC1;       //软件触发
    ADC2_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING;//使用软件触发
    ADC2_Handler.Init.DMAContinuousRequests=ENABLE;             //开启DMA请求
   
    ADC_MultiMode.Mode = ADC_DUALMODE_REGSIMULT;                // 规则同步模式
    ADC_MultiMode.DMAAccessMode = ADC_DMAACCESSMODE_2;
    ADC_MultiMode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;  // 规则同步模式 不影响
    HAL_ADCEx_MultiModeConfigChannel(&ADC2_Handler,&ADC_MultiMode);
   
   
    ADC_ChanConf.Channel=ADC_CHANNEL_3;                        //通道13
    ADC_ChanConf.Rank=1;                                       //第1个序列,序列1
    ADC_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;          //采样时间
    ADC_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC_ChanConf);        //通道配置
    HAL_ADCEx_MultiModeConfigChannel(&ADC2_Handler,&ADC_MultiMode);
   
    __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,DMA_InitStructure);    //将DMA与ADC1联系起来
   
   
   
   
    HAL_ADC_Init(&ADC1_Handler);                             //初始化ADC1
    HAL_ADC_Init(&ADC2_Handler);                             //初始化ADC2
            
举报

更多回帖

发帖
×
20
完善资料,
赚取积分