cancel
Showing results for 
Search instead for 
Did you mean: 

ADC on STM32L15xx

amiller
Associate
Posted on July 08, 2013 at 19:59

Hello,

I am currently stuck on a problem where I believe I have acquired the proper examples and tried to follow form, but I cannot get a value out of my ADC. On my device there is only 1 ADC (ADC1 on APB2). Below is some code I run from IAR debugging with a ST-Link. One problem right off the bat is that 'result' is consistently ''unavailable'', except when I make it static, then its filled with some unchanging gibberish. I don't know the significance of channels, and I realize that may be the issue, but I tried to iterate through all of the available channels to see if I can get anything, and I seem to hang around channel 5, where I'm stuck on the End of Conversion flag check. Please help!

void Enable_ADC(void)    {

  

      

      ADC_CommonInitTypeDef CommonInitStruct;

      ADC_InitTypeDef ADC_InitStructure;

      /*Get a Fresh Start*/

      ADC_DeInit(ADC1);

  

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

      /*Enable APB2 Clock for ADC1*/

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

      

      /*Set up Prescaler*/

      CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4;

      ADC_CommonInit(&CommonInitStruct);

      

      /*Initialize ADC*/

      ADC_StructInit(&ADC_InitStructure);   

      ADC_Init(ADC1,&ADC_InitStructure);

      

      /*Enable ADC*/

      ADC_Cmd(ADC1,ENABLE);

    }

(snippet from InitGPIO)

...

/*Battery Measurment pins*/

  /*                                             PA1(ADC)                       */

  /*                                     R13       ||      R12                  */

  /*     PB15(OpenDrain)BatMeas   <<----/\/\/--->BatMon---/\/\/<++++++Vbat      */

  /*                                                                            */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_ResetBits(GPIOB,GPIO_Pin_15);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

...

int readADC1(uint8_t channel) { 

  

  ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_9Cycles); 

  // Start the conversion 

  ADC_SoftwareStartConv(ADC1); 

  // Wait until conversion completion 

  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); 

  // Get the conversion value 

  return ADC_GetConversionValue(ADC1); 

}

int main(void)

{

   

    

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);

    

    RCC_Configuration();

    

    /* Init I/O ports */

    Init_GPIOs ();

    

    Enable_ADC();

    int result = 0;

    int k = 0;

    while(1){

      

     

     result = readADC1(k);

      k++;

        if(k>25) k = 0;

    }

}

#stm32l1-adc
4 REPLIES 4
Posted on July 08, 2013 at 20:09

You should perhaps make sure that the HSI is enabled and running.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 08, 2013 at 20:15

0690X00000604FkQAI.png
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
amiller
Associate
Posted on July 08, 2013 at 20:35

Hello Clive,

Thank you for the quick reply!

I made the following changes to ensure HSI is enabled:

  if(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){

      // Enable HSI Clock and wait until it's ready

      RCC_HSICmd(ENABLE);

      while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);

  }

still same old problems. Thank you for taking the time to help me out. I'm not sure what other information would be helpful to solve this problem, but I wonder if it has to do with calibration? I read on another forum that this may be done automatically though, so perhaps my problem is sampling rate, or something stupid like type mismatching. IAR still says that 'result' is unavailable, and never gets set, not even to 0.

Posted on July 08, 2013 at 22:12

Test this on an STM32L-Discovery, verified with PA1 attached to VDD and then GND and observed full scale measurements. Attempted to recreate your configuration using code from my own trees.

// sourcer32@gmail.com - STM32L15x ADC Demo (PA.1 Channel 1)
// Built in Keil against STM32L1xx_StdPeriph_Lib_V1.1.1
#include ''stm32l1xx.h''
#include <
stdio.h
>
//******************************************************************************
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32l1xx_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32l1xx.c file
*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_15); // PB15 Low
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable The HSI (16Mhz) */
RCC_HSICmd(ENABLE);
/* Check that HSI oscillator is ready */
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
/* ADC1 Configuration ------------------------------------------------------*/
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* Deinitialize ADC */
ADC_DeInit(ADC1);
ADC_CommonStructInit(&ADC_CommonInitStructure);
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC Configuration */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // Single channel
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Continuously back-to-back
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1,&ADC_InitStructure);
/* ADC1 regular channel 1 for PA1 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_192Cycles);
/* Enable ADC1 Power Down during Delay */
ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Wait until ADC1 ON status */
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
/* Infinite loop */
while(1)
{
/* Wait until ADC Channel end of conversion */
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
printf(''%04
X'', ADC_GetConversionValue(ADC1)); // STDIO via SWD/SWV code redacted
}
}
//******************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..