cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 ADC Timer Triggered conversion hangs

rwa
Associate
Posted on November 03, 2016 at 15:41

Hello

I am trying to use TIM3 update event to trigger ADC to convert one channel 1000 times @ 50kHz resulting in about 20ms. This is for filtering out net interference. The problem is when I configure the timer with a frequency of > 10kHz, after several conversions the ADC hangs waiting for EOC bit to be set. sampleADC() is called every 250ms. I disabled interrupts when converting to be sure its not an IRQ related problem. My uC runs at 8MHz,

/* ADC INIT FUNCTION */
void
RWA_ADC_Init(uint16_t Gpio_Pins, uint8_t TimerTrigger){
GPIO_InitTypeDef GPIO_InitStruct;
/* peripheral clock enable */
RCC->AHBENR |= (RCC_AHBENR_GPIOAEN);
/*Configure GPIO pins*/
GPIO_InitStruct.Pin = Gpio_Pins;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN);
ADC1->CR |= ADC_CR_ADEN; 
// enable adc
ADC1->CFGR1 |= ADC_CFGR1_DISCEN;
// | ADC_CFGR1_WAIT;
if
(TimerTrigger)
ADC1->CFGR1 |= ADC_CFGR1_EXTEN_0 | ADC_CFGR1_EXTSEL_0 | ADC_CFGR1_EXTSEL_1 | ADC_CFGR1_OVRMOD;
ADC1->SMPR = ADC_SMPR1_SMPR_0 | ADC_SMPR1_SMPR_2;
ADC1->CR |= ADC_CR_ADDIS; 
//disable adc
while
(ADC1->CR & ADC_CR_ADEN);
RWA_ADC_Calibrate();
}
/* TIM3 INIT FUNCTION */
void
RWA_ADC_TIM_Init(uint16_t Period, uint8_t Prescaler){
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim3.Instance = TIM3;
htim3.Init.Prescaler = Prescaler;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = Period-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim3);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
HAL_TIM_Base_Start(&htim3);
}
/* ADC CONVERT FUNCTION*/
uint16_t samplecount;
uint16_t SampleADC(uint16_t SampleCount, uint32_t ADC_Channel)
{
uint32_t Value =0;
samplecount= SampleCount;
__disable_irq();
ADC1->CR = 0;
ADC1->CR |= ADC_CR_ADEN; 
// ADC enable
ADC1->CR &= ~ADC_CR_ADSTART;
ADC1->CHSELR = ADC_Channel; 
// select adc channel
ADC1->CR|=ADC_CR_ADSTART; 
// start conversion
while
(SampleCount){
GPIOF->ODR |= GPIO_PIN_0;
while
(!(ADC1->ISR&ADC_ISR_ADRDY)); 
// wachten tot de ADC klaar is
//ADC1->CR|=ADC_CR_ADSTART; // start conversion
//wacht tot conversie is voltooid
while
((ADC1->ISR & ADC_ISR_EOC)!=ADC_ISR_EOC);
Value += ADC1->DR; 
// haal analoge waarde op
SampleCount--;
GPIOF->ODR &= ~GPIO_PIN_0;
}
Value /= samplecount; 
// gemiddelde nemen
ADC1->CR |= ADC_CR_ADDIS; 
//disable adc
__enable_irq();
return
Value&0xFFFF;
}

#!stm32-!adc
2 REPLIES 2
Jeroen3
Senior
Posted on November 03, 2016 at 16:25

I'm confused. You're using external trigger AND software start&poll?

Posted on November 03, 2016 at 16:48

Why wouldn't one use DMA for this, and process the buffer with all the data at the 50Hz / 20ms interval ? Or at least decimate, so as not to grind in loops sucking power.

At some point your current code is going to saturate.

Suggest you look at the other ADC flags, probably overrunning

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