2013-06-30 08:27 AM
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 #timers2013-07-03 10:19 AM
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?2013-07-07 05:45 AM
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!2013-07-09 04:58 AM
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!
2013-07-09 07:32 AM
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?2013-07-09 09:16 AM
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 */
}
2013-07-09 09:27 AM
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!
2013-07-09 09:43 AM
Ok, thanks.
But is T1_TRGO a valid trigger for ADC1/2?2013-07-09 10:45 PM
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!!