STM32多重ADC+DMA+定时器浅讲

***

STM32F429HAL库

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

ADC多重模式

在这里我只讲解规则模式下的多重ADC
在多重ADC下数据是存放在ADC_CDR寄存器当中,这是一个32为的寄存器,也就意味着每次采集完数据最多只能存放两路的ADC数据
我的项目刚好也只需要两路,介于需求是对两路ADC的数据实现同时采集,采用了DMA模式2的双重交替模式DMA描述
具体的可自行查看芯片手册相应章节
从手册不难看出当两路ADC都采集完成时,ADC2的数据放在ADC_CDR寄存器的高16位,ADC1放在低16位
DMA
当两路ADC传输完成后会生成一个DMA请求,此时去读取数据即可,注意在读取的时候将数据分离
下面是多路ADC的基本配置: 本配置采用定时器触发ADC1从而触发从ADC用DMA方式读取数据
关于DMA配置和定时器配置由于篇幅原因,如有需要可转(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
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值