黑皮男 发表于 2018-3-23 18:21:24

STM32F3 ADC外部触发采样达不到7.2MSPS

本帖最后由 黑皮男 于 2018-3-27 11:11 编辑

STM32F3的ADC在8bit模式理论可以达到7.2M的采样频率,但是在外部信号触发的情况下,采样速率一直不太理想。目前最多达到5M。下面是我的代码,求大神指点。以下代码都是经过测试的,只是外部触发信号的触发频率不能超过5Mhz,外部触发信号为EXTI_LINE_11。超过5Mhz,缓冲区的数据就会出错,6M的话,数据基本都为0xFFADC初始化部分
    LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_SYNC_PCLK_DIV1);
    LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_8B);
    LL_ADC_SetDataAlignment(ADC1, LL_ADC_DATA_ALIGN_RIGHT);
    LL_ADC_SetLowPowerMode(ADC1, LL_ADC_LP_MODE_NONE);
    //LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_TEMPSENSOR);
    //LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE);
    LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_EXT_EXTI_LINE11);
   
    LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_RISING);
    //LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_FALLING);
   
    LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_SINGLE);
   
    //LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_1RANK);
   
    LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_LIMITED);
   
    LL_ADC_REG_SetOverrun(ADC1, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
   
    //LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS);
    LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);
   
    //LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_TEMPSENSOR);
   
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_3);
/*    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_7, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_8, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_9, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_10, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_11, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_12, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_13, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_14, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_15, LL_ADC_CHANNEL_3);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_16, LL_ADC_CHANNEL_3);
    */
   
    LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_1CYCLE_5);
    LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SINGLE_ENDED);
   
    LL_ADC_Enable(ADC1);

    while(LL_ADC_IsActiveFlag_ADRDY(ADC1)==0)
    {
      
    }

DMA初始化部分
    NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),6, 0));
    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
   
    LL_DMA_ConfigTransfer(DMA1,
                            LL_DMA_CHANNEL_1,
                            LL_DMA_DIRECTION_PERIPH_TO_MEMORY|
                            LL_DMA_PERIPH_NOINCREMENT       |
                            LL_DMA_MEMORY_INCREMENT         |
                            LL_DMA_PDATAALIGN_BYTE               |
                            LL_DMA_MDATAALIGN_HALFWORD      |
                            LL_DMA_PRIORITY_VERYHIGH            );
                           
    LL_DMA_ConfigAddresses(DMA1,
                            LL_DMA_CHANNEL_1,
                            LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
                            0,
                            LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
    LL_DMA_SetDataLength(DMA1,
                        LL_DMA_CHANNEL_1,
                        0);
    LL_DMA_EnableIT_TC(DMA1,
                        LL_DMA_CHANNEL_1);
    LL_DMA_DisableChannel(DMA1,
                        LL_DMA_CHANNEL_1);触发信号初始化    LL_EXTI_DisableEvent_0_31(EXTI_LINE);
    LL_EXTI_EnableRisingTrig_0_31(EXTI_LINE);

时钟初始化
    LL_RCC_SetADCClockSource(LL_RCC_ADC1_CLKSRC_HCLK);
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC1);
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);启动转换
    LL_EXTI_DisableEvent_0_31(EXTI_LINE);
    LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_ADC_ClearFlag_EOC(ADC1);
    LL_ADC_ClearFlag_EOS(ADC1);
    LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, addr);//addr为缓冲区地址
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, nSize);//nSize为缓冲区大小
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_EXTI_EnableEvent_0_31(EXTI_LINE);
    LL_ADC_REG_StartConversion(ADC1);


黑皮男 发表于 2018-3-27 11:09:22

在使能前需要把voltage regulator打开,参考手册中有说,但是不知道voltage regulator的具体作用,有哪位大神指点一下

MrJiu 发表于 2018-3-24 09:57:06

LL库啊。。。。。现在搞得是HAL库。。。打不达到要求还不简单。。。。首先看看ADC的时钟频率,然后算一下,先从理论上来说是否达到这个速度。。。这些就需要看参考手册了。。。还有,搞设计或者量产的东西,一般都不会直接使用到官方给的最大值。。。个人建议,对了顺带问一下,你使用LL库的FLASH和RAM占用情况咋样,如果可以的话,可否贴个map文件。。。:L:L:L

黑皮男 发表于 2018-3-24 10:44:41

本帖最后由 黑皮男 于 2018-3-24 10:47 编辑

MrJiu 发表于 2018-3-24 09:57
LL库啊。。。。。现在搞得是HAL库。。。打不达到要求还不简单。。。。首先看看ADC的时钟频率,然后算一下, ...
资源有限,64K的片子,跑了个FreeRTOS, 之前用公司的平台,资源扛不住,就一切从简了,选了LL库。8bit模式理论值是7.2MSPS, 虽然不要求达到7.2M,但也要尽量接近,5M的速度是差的有点远。整个的文件无法贴出,文件中的命令会有点敏感,毕竟是公司的东西。目前基本框架完成,优化等级选用了最高。
28 334 bytes of readonlycode memory
   1 339 bytes of readonlydata memory
15 156 bytes of readwrite data memory

ssht428 发表于 2018-9-22 13:29:10

给后面的人参考:
外部触发的确是不能最高速。
要使用“ContinuousMode"+DMA才可以。
比如:
LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS);

然后其他的相应修改。。。。。

mvvm 发表于 2019-11-8 23:15:32

楼主你好,采样率这么高你得数据是怎么样处理的呢?我现在也要做高速采样,采样率设置为1M,采出来的波形就不对了。
页: [1]
查看完整版本: STM32F3 ADC外部触发采样达不到7.2MSPS