*** 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
*** 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
举报