cancel
Showing results for 
Search instead for 
Did you mean: 

ADC1 Interrupt on EOC stopping after one conversion

david239955_stm1
Associate
Posted on January 27, 2014 at 11:22

Hi,

Basically I have an issue with the ADC1 interrupt on EOC. It fires once in continuous mode but then after reading the value (thus resetting the EOC) it never fires again. Im stumped as to why this happens. Any advice much appreciated:


#include <
stdio.h
> 

#include ''serial.h'' 

#include <
stm32f4xx.h
> 

#include <
stm32f4_discovery.h
> 

#include <
stm32f4xx_adc.h
> 

#include <
stm32f4xx_rcc.h
> 


void init_ADC(void){ 


ADC_InitTypeDef ADC_init1; // ADC structure to configure an ADC 

GPIO_InitTypeDef GPIO_init1; // Configures the gpio that the adc is coming in on 


// Sets up the parameters for the 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Enables ADC1s clock 

RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN, ENABLE); // Enables the GPIO clock for the pin that the cable in plugged into 


/* Configure the GPIO to take analogue voltages in */ 

GPIO_init1.GPIO_Pin = GPIO_Pin_2; // Use PC2 for the ADC input 

GPIO_init1.GPIO_Mode = GPIO_Mode_AN; // Analogue input 

GPIO_init1.GPIO_PuPd = GPIO_PuPd_NOPULL; 

GPIO_Init(GPIOC, &GPIO_init1); 


/* Configures the ADC */ 

ADC_init1.ADC_DataAlign = ADC_DataAlign_Right; 

ADC_init1.ADC_Resolution = ADC_Resolution_12b; 

ADC_init1.ADC_ContinuousConvMode = ENABLE; 

ADC_init1.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; 

ADC_init1.ADC_NbrOfConversion = 1; 

ADC_init1.ADC_ScanConvMode = DISABLE; 

ADC_Init(ADC1, &ADC_init1); 


// Enables interrupts 

ADC1->CR1 |= ADC_CR1_EOCIE; 


NVIC_EnableIRQ(ADC_IRQn); //Enable IRQ for ADC complete. 


ADC_Cmd(ADC1,ENABLE); // Turn on ADC1 

} 


int main(void) { 

serial_init(); 


printf(''System Test\r\n''); 

printf(''0123456789ABCDEF\r\n''); 


init_ADC(); 


ADC1->CR2 |= ADC_CR2_SWSTART; // Starts the ADC 

/* Infinite loop: embedded software must never end */ 

while(1) { 

} 

} 


void ADC_IRQHandler (void) { 

float step = 3.3 / 4096; 

float voltage; 

int convertedValue; 

convertedValue = ADC1->DR; // Gets the converted value. Should also reset the EOC flag 

voltage = (float)convertedValue * (float)step; 

printf(''Converted Value is: %.5fV\r\n'', voltage); 

} 

#interrupts #adc
3 REPLIES 3
Posted on January 27, 2014 at 13:19

The initialization is a bit of a mess, neglects to set up the channel being used, and I'm not sure of the wisdom of trying to print from within the interrupt, which is going to take much longer than the conversion time. Does the ADC indicate it's overflowed?

Also not clear on the project/ide here, you shouldn't need to explicitly include all the files, but rather use the stm32f4xx_conf.h to do that via stm32f4xx.h and USE_STDPERIPH_DRIVER
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
david239955_stm1
Associate
Posted on January 27, 2014 at 13:38

Thanks Clive,

Setting up the channel worked, not sure how I missed that!
Posted on January 27, 2014 at 14:12

// STM32F4-Discovery ADC1 PC2 EOC - sourcer32@gmail.com
// define USE_STDPERIPH_LIBRARY
#include ''stm32f4_discovery.h''
//******************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Configure ADC1 Channel12 pin as analog input PC2 *****************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
//******************************************************************************
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the ADC1 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//******************************************************************************
void ADC1_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable peripheral clocks *************************************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // Single Channel
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Keep Sampling
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel configuration ***************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_480Cycles); // PC2
/* Enable ADC1 EOC interrupt ************************************************/
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
/* Enable ADC1 **************************************************************/
ADC_Cmd(ADC1, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
}
//******************************************************************************
volatile uint16_t CurrentSample;
void ADC_IRQHandler(void)
{
static int i = 0;
if (ADC_GetITStatus(ADC1, ADC_IT_EOC))
{
CurrentSample = ADC1->DR; /* Clear EOC */
if ((i++ % 10000) == 0)
STM_EVAL_LEDToggle(LED4); /* Toggle Green LED: signaling the EOC functions, a lot */
}
}
//******************************************************************************
int main(void)
{
GPIO_Configuration();
STM_EVAL_LEDInit(LED4);
STM_EVAL_LEDOn(LED4);
NVIC_Configuration();
ADC1_Configuration();
while(1); /* Infinite loop */
}
/**************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
while (1)
{}
}
#endif

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