cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152 ADC with TIMER reads only once

melt brink
Associate III
Posted on March 08, 2017 at 11:54

Im trying to read a battery voltage with a  STM32L152, using timer 2 to trigger the ADC. I can see Timer 2 running (by toggling a LED in the TMR2 interrupt routine) but my ADC only reads once (when the circuit initially switch on) . I have trawled the internet for solutions but still cant find what i'm missing or where i'm going wrong. If I debug, my program never enters the ADC IRQ  function. I presume a flag is not being cleared. Any assistance will be greatly appreciated.

Below is relevant code.

int main(void)

{

RCC_Configuration();  // call clock setup

NVIC_Configuration();  // call interrupt setup

GPIO_Configuration();  // gpio config

TIM2_Configuration();  // tim2 setup

ADC_Configuration(); // adc setup

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

gpio_config(GPIO0_PORT, GPIO0_PIN, GPIO_PP); // setup GPIO0 as output

gpio_config(GPIO1_PORT, GPIO1_PIN, GPIO_PP); // setup GPIO1 as output

gpio_config(GPIO3_PORT, GPIO3_PIN, GPIO_PP); // setup GPIO3 as output

gpio_set_state(GPIO3_PORT, GPIO3_PIN, SET);// set led high, turn led off

while (1) // check battery voltage here at TMR2 interrupt

{

AD_value=ADC_GetConversionValue(ADC1);

if (AD_value<=0xE00)

   {  gpio_set_state(GPIO3_PORT, GPIO3_PIN, RESET);     } // turn led on

         

          else gpio_set_state(GPIO3_PORT, GPIO3_PIN, SET);// turn led off

}

}

Void RCC_Configuration(void)

{

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_HSICmd(ENABLE); /* Enable the HSI */

while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); /* Wait until HSI oscillator is ready */

}

void GPIO_Configuration(void) // setup pin 12 for ADC

{

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void ADC_Configuration(void) // setup ADC to t start on TMR2 interrupt

{

ADC_CommonInitTypeDef ADC_CommonInitStructure;

ADC_InitTypeDef ADC_InitStructure;

/* ADC Common Init */

ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInit(&ADC_CommonInitStructure);

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 1 Channel

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversions Triggered

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfConversion = 1;

ADC_Init(ADC1, &ADC_InitStructure);

ADC_TempSensorVrefintCmd(ENABLE); // reference enable

ADC_RegularChannelConfig(ADC1, ADC_Channel_18, 1, ADC_SampleTime_16Cycles); // PORT B12 is ADC_IN18

ADC_ITConfig(ADC1 , ADC_IT_EOC , ENABLE);

ADC_Cmd(ADC1, ENABLE);

}

void TIM2_Configuration(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 500;

TIM_TimeBaseStructure.TIM_Prescaler = 5000;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM2 TRGO selection */

TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); // ADC_ExternalTrigConv_T2_TRGO

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);/* TIM IT enable */

TIM_Cmd(TIM2, ENABLE);/* TIM2 enable counter */

}

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void ADC1_IRQHandler(void)

{

if(ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET)

AD_value=ADC_GetConversionValue(ADC1); // Store ADC value

ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); // Clear ADC1 EOC pending interrupt bit 

}

void TIM2_IRQHandler()

{

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

{

GPIO_ToggleBits(GPIO0_PORT,GPIO0_PIN); // toggle led to show timer running

AD_value=ADC_GetConversionValue(ADC1); // store ADC value

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}

}
1 ACCEPTED SOLUTION

Accepted Solutions
melt brink
Associate III
Posted on March 13, 2017 at 08:31

Hi. found the problem, Was using this code in conjunction with SP1ML firmware. Turns out the firmware overwrites some of the interrupts.

View solution in original post

1 REPLY 1
melt brink
Associate III
Posted on March 13, 2017 at 08:31

Hi. found the problem, Was using this code in conjunction with SP1ML firmware. Turns out the firmware overwrites some of the interrupts.