2017-03-08 02:54 AM
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 offwhile (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 enableADC_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 valueADC_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); } }Solved! Go to Solution.
2017-03-13 12:31 AM
Hi. found the problem, Was using this code in conjunction with SP1ML firmware. Turns out the firmware overwrites some of the interrupts.
2017-03-13 12:31 AM
Hi. found the problem, Was using this code in conjunction with SP1ML firmware. Turns out the firmware overwrites some of the interrupts.