0
\$\begingroup\$

I'm trying to enable an ADC converter. I'm using STM32F3 Discovery with SPL Library. I measure voltage on PA1 pin. I don't know why it doesn't work. What have I missed? The value of 'value' variable doesn't change and equals 0.

#include "stm32f30x.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_adc.h"
#include <stm32f30x_gpio.h>


uint16_t Read_ADC()
{
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_4Cycles5);
    ADC_StartConversion(ADC1);
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    return ADC_GetConversionValue(ADC1);
}

void delay_ms (int time)
{
    int i;
    for (i = 0; i < time * 4000; i++) {}
}

int main()
{

  uint16_t value = 0;

  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //PA1 ADC1_IN2
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);

  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Pin  = LED;
  GPIO_Init( GPIOE, &GPIO_InitStructure);
  uint32_t led = 0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_Cmd(ADC1, ENABLE);


  while(1)
      {
          value = Read_ADC();
      }
}
\$\endgroup\$
  • \$\begingroup\$ Put some dwell in your while loop, so any debugger has time to update. It's probably not your answer, but it's the right thing to do. \$\endgroup\$ – Scott Seidman Apr 14 '18 at 19:04
  • \$\begingroup\$ Previously I had code in the while loop responsible for turning led diodes and It didn't work as well \$\endgroup\$ – marek.m371 Apr 14 '18 at 19:12
  • \$\begingroup\$ Did you checke whether the clock to the SDC is enabled somewhere? It is probably off by default. \$\endgroup\$ – Wouter van Ooijen Apr 14 '18 at 19:16
  • \$\begingroup\$ @WoutervanOoijen -- there are RCC commands in the code (though without looking, I don't know if they're right!) \$\endgroup\$ – Scott Seidman Apr 14 '18 at 19:24
  • \$\begingroup\$ It looks like the GPIO clock is enabled, but not the ADC clock \$\endgroup\$ – Scott Seidman Apr 14 '18 at 20:02
0
\$\begingroup\$

You haven't enabled the ADC clock. Try

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

If that doesn't work, use your IDE to find the declaration of RCC_AHBPeriphClockCmd and read the source to see if I've gotten the name of the clock wrong.

The STM30xx library docs will probably be of help. Enabling the ADC clock is step 2 in Section 3.2.1 -- and I can't see anything else you missed. From that doc:

3.2.1 How to use this driver

  1. select the ADC clock using the function RCC_ADCCLKConfig()

  2. Enable the ADC interface clock using RCC_AHBPeriphClockCmd();

  3. ADC pins configuration  Enable the clock for the ADC GPIOs using the following function: RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOx, ENABLE);  Configure these ADC pins in analog mode using GPIO_Init();

  4. Configure the ADC conversion resolution, data alignment, external trigger and edge, sequencer lenght and Enable/Disable the continuous mode using the ADC_Init() function.

  5. Activate the ADC peripheral using ADC_Cmd() function. FWIW, when I have trouble, I usually go into the library declarations, as these functions tend to be very well self-documented.

FWIW, my SOP for library problems is to find the declaration in the library, as the libraries tend to be fairly well self-documented.

\$\endgroup\$
  • \$\begingroup\$ I have done it according to the manual but still doesn't work. I placed my fixed code above \$\endgroup\$ – marek.m371 Apr 15 '18 at 23:23
0
\$\begingroup\$

I got something like this

#include "stm32f30x.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_adc.h"
#include <stm32f30x_gpio.h>

#define LED (GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15)

uint16_t convertedValue= 0;

void delay_ms (int time)
{
    int i;
    for (i = 0; i < time * 4000; i++) {}
}

void Configure_ADC(void)
{
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12,ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    ADC_DeInit(ADC1);
    ADC_InitTypeDef ADC_InitStructure;
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_10b;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
    ADC_InitStructure.ADC_NbrOfRegChannel = 1;
    ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
    ADC_Init(ADC1,&ADC_InitStructure);
    ADC_Cmd(ADC1, ENABLE);
}

uint16_t Read_ADC()
{
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
    ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 1,    ADC_SampleTime_1Cycles5);
    ADC_StartConversion(ADC1);
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    return ADC_GetConversionValue(ADC1);
}

int main()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Pin  = LED;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    uint32_t led = 0;


    while(1)
      {

          convertedValue = Read_ADC();//Read the ADC converted value
          GPIO_SetBits(GPIOE, 1 << led); //turn on a diode
          delay_ms(150); // wait
          GPIO_ResetBits(GPIOE, 1 << led); //turn off a diode
          if (++led >= 16)
              {
                  led = 8;
              }
      }
}

I've configured according to manual. Program stops on Read_ADC function.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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