cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C8T6 ADC DMA Strage Readings

e-zeki
Associate III

Hello everyone,

I have a circuit that measures 6 adc inputs from various voltage readings.

I've got 3x4 pcs 7 segment displays and 4 buttons on the circuit.

Tim1 is working on 100uS to generate a 100us tick and display scans.

the thing is when I left ADC Pins floating, readings are extremely noisy (+- 100 ADC counts),

also when timer works these jumps widens.

I've changed capacitors, resistors, added voltage divider circuits, changed ADC frequency, nothing helps. I simply coulndt get a stable reading at any circumstances.

I've built same sort of circuit with my stm32f4 discovery kit, same results as well.

do you know any particular reason for this behavior?

Project created via CubeMX, Stm32f103c8t6

Runs at 72Mhz ,ADC Runs at 12Mhz

ADC:

  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 6;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
*
*
*
Six same specs channels.
 
 
//DMA
 
    hdma_adc1.Instance = DMA1_Channel1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);

RCC:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

8 REPLIES 8
TDK
Guru

> the thing is when I left ADC Pins floating, readings are extremely noisy (+- 100 ADC counts), also when timer works these jumps widens.

I wouldn't expect a particularly stable reading when ADC pins are floating. Why would you measure a floating voltage?

If you feel a post has answered your question, please click "Accept as Solution".
Romych
Associate

I you have divider on ADC input, it is already not floating.​ In other cases, ADC input will be always pulled up or down. Working of other noisy consumers can affect on ADC measurement. For minimisation this effects analogue power will be separated from digital power. You can do it with separated power source or with simple LC filter, depends on conditions. Also, you can use MA filter in code.

Hello @Romych​ I have MA filter in the code but readings all jumpy it doesnt affect that good either.

Thanks though.

Ozone
Lead II

> the thing is when I left ADC Pins floating, readings are extremely noisy (+- 100 ADC counts),

> also when timer works these jumps widens.

As pointed out, you shall never leave the ADC inputs floating. What do you expect ?

That other peripherals have a measurable influence indicates that Vcc / Vref are not stable either.

e-zeki
Associate III

Hello @Ozone​ ,

Actually it was designed a plug'n measure circuit. so if there is none to be measured it has to become floating.

Also I've added a 1:1 voltage dividers afterwards starts with 10/10k upto 100/100k resistors. results are same, readings jumps.

for example when I try to measure some voltage lets say 2.3V and my Vcc is 3.3V I should read something around 2850 +/-5

But my readings are 2850 +/-100 that is my problem.

I constantly monitor my Vcc there isnt any notable noise at all.

Zeki,

Do you have another board to try? Same results if you max out the sample time?
If you feel a post has answered your question, please click "Accept as Solution".
e-zeki
Associate III

I've got an F4 Discovery board. I've tested floating condition on it it was same. But didnt tested with voltage dividers.

When I commented out the full code and left only DMA process it measures normal. as soon as I wrote a single line of code especially gpio set/reset readings starts to jump and form a band. I've tried all sample time options jumping doesnt changes. But strangly when I monitor with stmstudio, it draws almost a sinusoidal wave with the measurements. very small peak to peak but still visible waveform. period increases with sample time.

I still couldn't find any reasionable solution, or a cause of this problem

> I constantly monitor my Vcc there isnt any notable noise at all.

At the high clock rates of a modern MCU, supply voltage ripples can be very local. Thus the many buffer caps in most designs.

> Actually it was designed a plug'n measure circuit. so if there is none to be measured it has to become floating.

> Also I've added a 1:1 voltage dividers afterwards starts with 10/10k upto 100/100k resistors. results are same, readings jumps.

Take care to achieve a proper input impedance at the ADC inputs.

The input must be able to charge/discharge the S&H cap in teh specified sample time (basically a RC element at first approximation).

Mentioned 10k or 100k areprobably too much for your ADC applications (the 13,5 cycles sample time you have are quite short).