This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32F3 analog-digital converter

Hello.
I am using a STM32F303 development board and i am trying to use the 4 ADCs that incorporates.My first question is it's possible to use the 4 ADCs in the same time?. I want to measure four voltages variating from 0 to 3.6v on one analog input of each ADC.If anyone has an idea about how to do, i will be very grateful.
Best Regards

Parents Reply Children
  • I don´t know an answer directly as well. What u could try is taking a look at the FirmWare library. For the discovery Board stm32f3 are existing Example Projects, even if due to murphy´s law with a different F3 type than your´s. AFAIK there is no example that fits directly to your issue. The librarys are controlled by using predefined Statments an filling them into init-Structures. May be if u understand the structure where and how to find the DEFINES you could set your needed init. But never the less you have to look closely to the Usermanual. I know how that pains since the f3 are widly more complex than the the f1´s...

  • Ok thanks. Otherwise, i took the ADC firmware of STM32F3 but i can't get the expected values.

    When i put 1.5V for example in my input channel i got 1.6 after conversion.
    Below the code i used, someone have an idea why ?

    #include "main.h"

    /* Private variables ---------------------------------------------------------*/

    __IO uint16_t ADC1ConvertedValue = 0; //Stores the calculated ADC value
    __IO uint16_t ADC1ConvertedVoltage = 0; // Used to store the actual voltage calculated by ADC for the 1st channel
    __IO uint16_t calibration_value = 0; // Used to store the value of the calibartion
    __IO uint32_t TimingDelay = 0;
    __IO uint32_t tabVal[512];

    // PRIVATE Variables as float
    __IO uint32_t ADC1ConvertedVoltage1 = 0; // Used to store the actual voltage calculated by ADC for the 1st channel
    __IO float tabVal1[512]; // GPIO Structure to use the GPIO functionnalities
    GPIO_InitTypeDef GPIO_InitStructure; // Declare a structure to use ADC Init structure definition
    ADC_InitTypeDef ADC_InitStructure; // we can define the mode of conversion (continuous or single, resolution, number of channels to be convertrted // Declare a structure to use ADC InitType structure definition
    ADC_CommonInitTypeDef ADC_CommonInitStructure;// define the mode ( independant or multimode)

    /* Private define ------------------------------------------------------------*/
    /** * @brief Main program. * @param None * @retval None */

    int main(void)
    { int i=0; tabVal[i]=0; /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */

    /* Configure the ADC clock */ //RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2); RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);// added by me to bring 72Mhz/6=12 Mhz

    /* Enable ADC1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

    /* Setup SysTick Timer for 1 µsec interrupts */ if (SysTick_Config(SystemCoreClock / 1000000)) { /* Capture error */ while (1) {} }

    /* ADC Channel configuration */ /* GPIOC Periph clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    /* Configure ADC Channel7 as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure);

    ADC_StructInit(&ADC_InitStructure);

    /* Calibration procedure */ ADC_VoltageRegulatorCmd(ADC1, ENABLE);

    /* Insert delay equal to 10 µs */ //Delay(10); // doesn't work, stuck in debug mode, so i replaced it by nop __nop(); __nop(); __nop(); __nop(); __nop();

    ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single); ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1) != RESET ); calibration_value = ADC_GetCalibrationValue(ADC1);

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot; ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0; ADC_CommonInit(ADC1, &ADC_CommonInitStructure);

    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable; //ADC_ContinuousConvMode_Enable; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0; ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable; ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable; ADC_InitStructure.ADC_NbrOfRegChannel = 1; ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 regular channel7 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_1Cycles5);

    /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE);

    /* wait for ADRDY */ while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));

    /* Start ADC1 Software Conversion */ ADC_StartConversion(ADC1);

    /* Infinite loop */ while (1) {

    /* Test EOC flag */ while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // wait for the conversion to be end

    /* Get ADC1 converted data */ ADC1ConvertedValue =ADC_GetConversionValue(ADC1);

    /* Compute the voltage */ ADC1ConvertedVoltage = (ADC1ConvertedValue *3300)/0xFFF; // FFF=4095 because we have 12 bits of resolution //ADC1ConvertedVoltage=(ADC1ConvertedValue *3300/0xFFF); tabVal[i]=ADC1ConvertedVoltage; i++; if(i>511) i=0;

    }

    }
    /** * @brief Inserts a delay time. * @param nTime: specifies the delay time length, in milliseconds. * @retval None */
    /*void Delay(__IO uint32_t nTime)
    { TimingDelay = nTime;

    while(TimingDelay != 0);
    }*/

  • Hey,

    may be the problem is more in the value´s calculating part than in the init of the adc.
    I assume you have a Vref = 3,3V(?).
    You may have an overrun issue in your equation
    (ADC1ConvertedValue *3300)/0xFFF.

    with an inputvoltage = 1.5V the ADC1ConvertedValue would be
    1.) (1.5/3.3) * ((2^12)-1) = 1861
    2.) 1861 * 3300 = 6141300

    I don´t know enough about what the compiler is doing with the (1861 * 3300) operation. If it is performed on the ADC1ConvertedValue variable and the result is stored there you´d have an overrun problem. I don´t know if the compiler handles that by it´s own.
    So in first run try to change the ADC1ConvertedValue variable to an uint32_t and cast it back to uint16_t AFTER dividing it by 4096.

  • Hey,

    For the Vref, i don't know its value. In STM32F302xx/STM32F303xx electrical characteristics, i have noticed that Vref is connected to Vdda, so i measured with millimeter its value on stm32f3-discovery and found 3V. Then, i changed this line(ADC1ConvertedValue *3300)/0xFFF by (ADC1ConvertedValue *3000)/0xFFF. So the problem was resolved.

    I don't know if my way to proceed is correct or no...

    Otherwise, i don't understand your point 1) and 2).

  • I have a question about the ADC clock of STM32F3. In fact in the examlples given by ST configure this clock like this:

    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1); //that's mean that the ADC is derived from the PLL Clock (72Mhz in this case). In the same time ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
    So based on the data sheet, with this configuration has the advantage to reach the maximum of the ADC clock but it's not synchronized with the AHB clock. if i want to use timer to trigger the conversion of ADC, we have to use the AHB clock to drive the ADC clock.

    For that purpose i have configured my ADC clock like this :

    /* Configures the AHB clock (HCLK) ***/

    RCC_HCLKConfig(RCC_SYSCLK_Div1); // RCC_AHB_Clock_Source( 72MHz in this case ). Then :
    ADC_CommonInitStructure.ADC_Clock = ADC_Clock_SynClkModeDiv4; // this gives us 18 MHz

    Do you thank this configuration is correct or no ? Thank in advance of your help.