cancel
Showing results for 
Search instead for 
Did you mean: 

Timer triggers the ADC to work

sherif
Associate II
Posted on June 30, 2013 at 17:27

I'm using TIM1 to generate a PWM signal of period 1 sec and a varying pulse duty.

This pulse undergoes some signal conditioning and then entered to the ADC, worth to mention that nothing happens to the signal's period nor the pulse width.

How i make the ADC reads only this value? i want something like triggering the ADC to start the conversion.

#adc #stm32 #timers
17 REPLIES 17
Posted on July 03, 2013 at 19:19

If HSI was not running, none of the the code would be executing at all, a synchronous processor needs a clock, HSI is started at reset.

If the PLL lock testing loop doesn't exit what do you think that tells you about the PLL?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sherif
Associate II
Posted on July 07, 2013 at 14:45

Yes i know there should be something wrong, but i'm confused the clock is 24MHz after all!

I'm going to try your code...Thx for now!

sherif
Associate II
Posted on July 09, 2013 at 13:58

I've tried the code, the result is the same! I don't know why but i'm sure it's in the configuration of the ADC itself!

sherif
Associate II
Posted on July 09, 2013 at 16:32

Well i think i figured out the problem.

The ADC is reading the low edge so it always reads around zero. The question now, how i tell the ADC to read from the High edge?
Posted on July 09, 2013 at 18:16

This is how I'd demo this on a VLDiscovery, STM32F100 running at 24 MHz

// VL Discovery ADC1 1 KHz Sample PA.3 via TIM1, and EOC interrupt - sourcer32@gmail.com
#include ''STM32vldiscovery.h''
/******************************************************************************/
#define SAMPLES 100
vu16 ADC_RegularConvertedValueTab[SAMPLES];
/******************************************************************************/
void ADC1_IRQHandler(void) // ADC1_2_IRQHandler() for non F100
{
static int i = 0;
if (ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET) // Enters at 1 KHZ
{
ADC_RegularConvertedValueTab[i] = ADC_GetConversionValue(ADC1);
i = (i + 1) % SAMPLES;
STM32vldiscovery_LEDToggle(LED3); // Toggles at 500 Hz
if (i == 0) STM32vldiscovery_LEDToggle(LED4); // Toggles at 5 Hz for 100 samples
}
}
/******************************************************************************/
int main(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructInit;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t Period;
/* Initialise LEDs LD3&LD4, both off */
STM32vldiscovery_LEDInit(LED3);
STM32vldiscovery_LEDInit(LED4);
STM32vldiscovery_LEDOff(LED3);
STM32vldiscovery_LEDOff(LED4);
/* Enable ADC1, TIM1 and GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);
/* Configure PA.03 (ADC Channel3) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
 /* 

configure the NVIC */
NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn; // ADC1_2_IRQn for non F100
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // Single Channel
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Scan on Demand (Trigger)
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel3 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Enable ADC1 EOC interrupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); /* EOC = End Of Conversion */
Period = 24000; // 1 KHz from a 24 MHz system clock
TIM_TimeBaseStructInit.TIM_Period = Period - 1;
TIM_TimeBaseStructInit.TIM_Prescaler = 0;
TIM_TimeBaseStructInit.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructInit.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructInit.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructInit);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50 duty
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Enables the TIM1 counter */
TIM_Cmd(TIM1, ENABLE);
/* Enables the TIM1 peripheral Main Outputs */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* Enable ADC1 external trigger conversion */
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
while(1); /* does not exit - kind of important */
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sherif
Associate II
Posted on July 09, 2013 at 18:27

It has been just resolved by this API:

TIM_ForcedOC1Config(TIM1, TIM_ForcedAction_Active);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1Ref);

I came to write down my results as for anyone else might have the same problem when i found your reply. Thanks a lot Clive for your help!
Posted on July 09, 2013 at 18:43

Ok, thanks.

But is T1_TRGO a valid trigger for ADC1/2?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sherif
Associate II
Posted on July 10, 2013 at 07:45

This is for the injected channels? I'm using just regular ones.

But i found a very weird behavior!

Despite the ADC reads the signal very well, i cannot display the voltage of it on the scope anymore!

This has something to do with this API ''TIM_ForcedOC1Config'', still don't know how to fix this!!