Stm32 H7 ADC Conversion time ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-11-30 11:00 PM
Hello
I m trying measure adc conversion time , I look datasheet , f_adc=37 Mhz(for fast channel)
with 12 bit resulation, 4.10 MSps , so ı use f_adc=32 Mhz(for fast channel) with 12 bit resulation, 3.54 MSps should be, but I m not measure 3.54 MSps,I measure 892 Ksps My measurement is as follows, when entering dma interrupt ,I toggle pin , then I set another pin At the end of the interrupt, I reset the pin again. the difference between the two times gives the adc conversion time.where is my fault project file and oscilloscope images are attached.
#include "main.h"
uint32_t cosa;
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
void adc2_config()
{
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_CLKP);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC12);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
LL_ADC_Init(ADC2, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE ;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE ;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE ;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
ADC_REG_InitStruct.DataTransferMode=LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
LL_ADC_REG_Init(ADC2, &ADC_REG_InitStruct);
LL_ADC_SetOverSamplingScope(ADC2, LL_ADC_OVS_DISABLE);
// LL_ADC_REG_SetTriggerEdge(ADC2, LL_ADC_REG_TRIG_EXT_RISING);
ADC_CommonInitStruct.CommonClock =LL_ADC_CLOCK_ASYNC_DIV2;
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC2), &ADC_CommonInitStruct);
LL_ADC_DisableDeepPowerDown(ADC2);
LL_ADC_EnableInternalRegulator(ADC2);
uint32_t wait_loop_index;
wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
while(wait_loop_index != 0)
{
wait_loop_index--;
}
LL_ADC_StartCalibration(ADC2,LL_ADC_CALIB_OFFSET , LL_ADC_SINGLE_ENDED);
while (LL_ADC_IsCalibrationOnGoing(ADC2) != 0);
LL_ADC_SetBoostMode(ADC2,LL_ADC_BOOST_MODE_50MHZ);
LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5);
LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_5,LL_ADC_SAMPLINGTIME_2CYCLES_5 );
LL_ADC_SetChannelSingleDiff(ADC2, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelPreSelection(ADC2, LL_ADC_CHANNEL_5);//PB1
LL_ADC_Enable(ADC2);
}
void adc2_dma_config()
{
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
LL_DMA_InitTypeDef DMA_InitStruct = {0};
NVIC_SetPriority(DMA2_Stream1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA2_Stream1_IRQn);
DMA_InitStruct.Direction=LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
DMA_InitStruct.FIFOMode=LL_DMA_FIFOMODE_DISABLE;
DMA_InitStruct.FIFOThreshold=LL_DMA_FIFOTHRESHOLD_FULL;
DMA_InitStruct.MemBurst=LL_DMA_MBURST_SINGLE;
DMA_InitStruct.MemoryOrM2MDstAddress= (uint32_t)&cosa;
DMA_InitStruct.MemoryOrM2MDstDataSize=LL_DMA_MDATAALIGN_WORD;
DMA_InitStruct.MemoryOrM2MDstIncMode=LL_DMA_MEMORY_INCREMENT;
DMA_InitStruct.Mode=LL_DMA_MODE_CIRCULAR ;
DMA_InitStruct.NbData=1;
DMA_InitStruct.PeriphBurst=LL_DMA_PBURST_SINGLE;
DMA_InitStruct.PeriphOrM2MSrcAddress=(uint32_t)&ADC2->DR;
DMA_InitStruct.PeriphOrM2MSrcDataSize=LL_DMA_PDATAALIGN_WORD ;
DMA_InitStruct.PeriphOrM2MSrcIncMode=LL_DMA_PERIPH_NOINCREMENT;
DMA_InitStruct.Priority=LL_DMA_PRIORITY_VERYHIGH ;
DMA_InitStruct.PeriphRequest= LL_DMAMUX1_REQ_ADC2;
LL_DMA_Init(DMA2, LL_DMA_STREAM_1, & DMA_InitStruct);
LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_1);
LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_1);
LL_DMA_EnableIT_TE(DMA2, LL_DMA_STREAM_1);
}
void DMA2_Stream1_IRQHandler(void)
{
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_0);// oscilloscope CH3
GPIOA->BSRR=0x00000001;//// oscilloscope CH4
if(LL_DMA_IsActiveFlag_TC1(DMA2))
{
LL_DMA_ClearFlag_TC1(DMA2);
LL_ADC_REG_StartConversion(ADC2);
GPIOA->BSRR=0x00010000;//// oscilloscope CH4
}
}
int main(void)
{
LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
SystemClock_Config();
/
MX_GPIO_Init();
adc2_dma_config();
adc2_config();
while (LL_ADC_IsActiveFlag_ADRDY(ADC2) == 0)
{
}
LL_ADC_REG_StartConversion(ADC2);
while (1)
{
}
}
void SystemClock_Config(void)
{
LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_3)
{
}
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
LL_RCC_HSI_Enable();
/* Wait till HSI is ready */
while(LL_RCC_HSI_IsReady() != 1)
{
}
LL_RCC_HSI_SetCalibTrimming(32);
LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV1);
LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
LL_RCC_PLL1P_Enable();
LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
LL_RCC_PLL1_SetM(4);
LL_RCC_PLL1_SetN(30);
LL_RCC_PLL1_SetP(1);
LL_RCC_PLL1_SetQ(2);
LL_RCC_PLL1_SetR(2);
LL_RCC_PLL1_Enable();
/* Wait till PLL is ready */
while(LL_RCC_PLL1_IsReady() != 1)
{
}
/* Intermediate AHB prescaler 2 when target frequency clock is higher than 80 MHz */
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
LL_Init1msTick(480000000);
LL_SetSystemCoreClock(480000000);
}
void PeriphCommonClock_Config(void)
{
LL_RCC_SetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE_HSI);
}
static void MX_GPIO_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
/**/
LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_0);
/**/
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
- Labels:
-
ADC
-
STM32H7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-11-30 11:21 PM
I m use stm32h723zg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-12-01 6:12 AM
Please don't PM me about threads.
You can't interrupt at the MHz rates, so instead of doing ONE sample, sample 10 or 100 and decimate the time to understand the sample rate. Use ping-pong buffers with the DMA HT/TC so you aren't working on active/changing data. Watch/manage cache coherency.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-12-01 6:53 AM
You cannot effectively measure the time for a single conversion. As I said in the other post you found, time 10000 conversions to reduce the overhead.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-12-01 9:39 PM
in other post, The person asking the question could not find a solution. so ı open new post because ı have same problem. I did what you said but the result did not change. time is still too long.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-12-01 9:42 PM
Can you explain this part-> "Use ping-pong buffers with the DMA HT/TC so you aren't working on active/changing data. Watch/manage cache coherency."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-01 8:35 PM
TDK, can you elaborate on "You cannot effectively measure the time for a single conversion"? Thanks.
-WQ
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-01 8:37 PM
Tesla, can you elaborate on "You can't interrupt at the MHz rates?
-WQ
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-01 9:29 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-01 9:59 PM
Well you'll saturate the MCU with a lot of context switching and all the burden you're carrying with the handlers, the HAL, and the callbacks.
The ceiling here is probably a lot lower than you think it is, and it scales very badly.
Up vote any posts that you find helpful, it shows what's working..
