2013-07-08 10:59 AM
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-adc2013-07-08 11:09 AM
You should perhaps make sure that the HSI is enabled and running.
2013-07-08 11:15 AM
2013-07-08 11:35 AM
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.2013-07-08 01:12 PM
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
}
}
//******************************************************************************