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);
在使能前需要把voltage regulator打开,参考手册中有说,但是不知道voltage regulator的具体作用,有哪位大神指点一下
LL库啊。。。。。现在搞得是HAL库。。。打不达到要求还不简单。。。。首先看看ADC的时钟频率,然后算一下,先从理论上来说是否达到这个速度。。。这些就需要看参考手册了。。。还有,搞设计或者量产的东西,一般都不会直接使用到官方给的最大值。。。个人建议,对了顺带问一下,你使用LL库的FLASH和RAM占用情况咋样,如果可以的话,可否贴个map文件。。。:L:L:L 本帖最后由 黑皮男 于 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
给后面的人参考:
外部触发的确是不能最高速。
要使用“ContinuousMode"+DMA才可以。
比如:
LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS);
然后其他的相应修改。。。。。 楼主你好,采样率这么高你得数据是怎么样处理的呢?我现在也要做高速采样,采样率设置为1M,采出来的波形就不对了。
页:
[1]