0
\$\begingroup\$

I found this code online claiming to do single mode conversion for ADC :


#include "stm32f4xx_hal.h"

void Configure_GPIO(void);
void configure_ADC2_Channel_0(void);
void Delay_ms(volatile int time_ms);

uint32_t Adc_value;
ADC_HandleTypeDef myADC2Handle;
int main(void)
{
    Configure_GPIO(); // initialize PA0 pin 
    configure_ADC2_Channel_0(); // configure ADC2
    while(1)
    {
     HAL_ADC_Start(&myADC2Handle); // start A/D conversion
        if(HAL_ADC_PollForConversion(&myADC2Handle, 5) == HAL_OK) //check if conversion is completed
        {
        Adc_value  = HAL_ADC_GetValue(&myADC2Handle); // read digital value and save it inside uint32_t variable
        }
        HAL_ADC_Stop(&myADC2Handle); // stop conversion 
        Delay_ms(200);
    }
}

/* Configure and initialize PA0 pin as analog input pin for A/D conversion */
void Configure_GPIO(void)
{
     __HAL_RCC_GPIOA_CLK_ENABLE(); // enable clock to GPIOA
    GPIO_InitTypeDef ADCpin; //create an instance of GPIO_InitTypeDef C struct
    ADCpin.Pin = GPIO_PIN_0; // Select pin PA0
    ADCpin.Mode = GPIO_MODE_ANALOG; // Select Analog Mode
    ADCpin.Pull = GPIO_NOPULL; // Disable internal pull-up or pull-down resistor
    HAL_GPIO_Init(GPIOA, &ADCpin); // initialize PA0 as analog input pin
}
void configure_ADC2_Channel_0(void)
{
__HAL_RCC_ADC2_CLK_ENABLE(); // enable clock to ADC2 module
    myADC2Handle.Instance = ADC2; // create an instance of ADC2
    myADC2Handle.Init.Resolution = ADC_RESOLUTION_12B; // select 12-bit resolution 
    myADC2Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //select  single conversion as a end of conversion event
    myADC2Handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; // set digital output data right justified
    myADC2Handle.Init.ClockPrescaler =ADC_CLOCK_SYNC_PCLK_DIV8; 
    HAL_ADC_Init(&myADC2Handle); // initialize AD2 with myADC2Handle configuration settings
    
  /*select ADC2 channel */
    ADC_ChannelConfTypeDef Channel_AN0; // create an instance of ADC_ChannelConfTypeDef
    Channel_AN0.Channel = ADC_CHANNEL_0; // select analog channel 0
    Channel_AN0.Rank = 1; // set rank to 1
    Channel_AN0.SamplingTime = ADC_SAMPLETIME_15CYCLES; // set sampling time to 15 clock cycles
    HAL_ADC_ConfigChannel(&myADC2Handle, &Channel_AN0); // select channel_0 for ADC2 module. 
}

But if the conversion is single mode (it's only reading ADC value when asked) then what is this line of code doing :

Channel_AN0.SamplingTime = ADC_SAMPLETIME_15CYCLES; // set sampling time to 15 clock cycles

Is the code doing single mode conversion, if so then what is the sampling time being referred to in the above code ? I would like to set the ADC sampling rate using delay in the main loop but I'm not sure this will get me there.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Sampling time is the duration of charging the ADC internal capacitor, it is used in every mode - single or not . See here for some good answers. \$\endgroup\$
    – Flexz
    Commented Feb 5, 2023 at 9:20

1 Answer 1

1
\$\begingroup\$

The time it takes the ADC to perform a sample for a channel consists of two portions. The first portion is called the sampling time. This is how long the ADC allows the input signal to settle after switching to the input channel. The sampling time is selectable in the ADC configuration. The second portion of a channel’s sample is called the conversion time. This is how long it takes the ADC to convert the analog signal level into the 12 bit digital sample. The conversion time is determined by the ADC clock rate and the resolution (i.e., number of sample bits).

You can use a delay in the main loop to trigger a single conversion at your desired sample rate. However, the sample period (1/rate) should be greater than the time it takes to perform the sample (i.e., ADC sample time plus the conversion time.)

A delay loop can introduce jitter between samples if the main loop can be interrupted. Consider using a hardware timer to trigger the ADC sample to get a more consistent sample period.

\$\endgroup\$
1
  • \$\begingroup\$ I'm trying to run an FIR filter so the calculation and delays will be even if i run the delays in the main loop . Do you think the above code gives me single mode conversion ADC? I tested it on an oscope with a function generator sending a 1khz sine with a +ve DC offset on the ADC and tried reproducing the same value/wave with DAC. I got pretty weird results, I don't think the ADC sampled at all then. \$\endgroup\$
    – Vrisk
    Commented Feb 5, 2023 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.