Starting ADC1 by hardware trigger on STM32F103
Posted: Mon Sep 22, 2014 12:42 am
For a motor control application I need to do high speed (as fast as possible) ADC measurements that are exactly in sync with the PWM signal. I wanted to operate ADC1 in circular mode to get a continous stream with 1 MHz. Starting the ADC1 by software does not work because the ADC and the PWM is never in sync because of delay and jitter.
To do this I have the following idea:
The PWM-signal is generated by TIM1. Each time a commutation is detected, TIM3 shall be started at the next period of TIM1. Then TIM3 shall trigger the ADC1 after a fixed time which is always a few periods of TIM1. So TIM3 is the slave of TIM1 and the starter of the ADC1. The circular buffer of ADC1 is sized to be completely filled exactly after one PWM period. So, the PWM period is also set to be an integer multiple of 1 microsecond (here 500 -> 20KHz).
In the first step I wanted to make TIM3 triggering the ADC1 by hardware (which didnt succeed yet). This is the ADC config:
Then I tried to configure TIM3 and start ADC1:
The ADC-callback is never called and the controller hangs completely when adcStartConversion is called.
Do you have an idea whats wrong up to this point?
Cheers,
Jörg
To do this I have the following idea:
The PWM-signal is generated by TIM1. Each time a commutation is detected, TIM3 shall be started at the next period of TIM1. Then TIM3 shall trigger the ADC1 after a fixed time which is always a few periods of TIM1. So TIM3 is the slave of TIM1 and the starter of the ADC1. The circular buffer of ADC1 is sized to be completely filled exactly after one PWM period. So, the PWM period is also set to be an integer multiple of 1 microsecond (here 500 -> 20KHz).
In the first step I wanted to make TIM3 triggering the ADC1 by hardware (which didnt succeed yet). This is the ADC config:
Code: Select all
static const ADCConversionGroup adc_commutate_group = {
TRUE, // circular
ADC_COMMUTATE_NUM_CHANNELS, // 1
adc_commutate_cb, //adccatchcallback,
NULL, //adccatcherrorcallback,
0, // ADC_CR1
ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_2, // ADC_CR2: use ext event | select Timer3 TRGO event
0, // ADC_SMPR1
ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5), // ADC_SMPR2
ADC_SQR1_NUM_CH(ADC_COMMUTATE_NUM_CHANNELS), // ADC_SQR1
0, // ADC_SQR2
ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) // ADC_SQR3
};
Then I tried to configure TIM3 and start ADC1:
Code: Select all
TIM3->PSC = (STM32_TIMCLK1/200)-1; // prescaler to get Timer 1 period as clock cycle for one tick; STM32_TIMCLK1 is 2Mhz
TIM3->ARR = 100; // 100 periods
TIM3->CR2 = TIM_CR2_MMS_1; // TRGO event is timer update event, e.g. overflow
TIM3->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; // enable the timer / one pulse mode
adcStartConversion(&ADCD1, &adc_commutate_group, commutatesamples, ADC_COMMUTATE_BUF_DEPTH);// ADC_COMMUTATE_BUF_DEPTH=500
The ADC-callback is never called and the controller hangs completely when adcStartConversion is called.
Do you have an idea whats wrong up to this point?
Cheers,
Jörg