Частота опроса невысокая - пару сотен герц.
Я решил использовать инжектированые каналы, чтобы не программировать DMA.
Запуск АЦП по прерыванию таймера (переполенение) работает.
Решил запуск АЦП производить без участия процессора используя событие
"ADC_ExternalTrigInjecConv_T1_CC4"
Прерывание по окончанию обработки инжектированых каналдо не происходит.
Код настройки АЦП:
Код
// Настроить АЦП для штатного съема данных с инжектирваными каналами
// Этот АЦП будет следить за входными сигналами с синхронного детектора
void start_work_sample(unsigned short target_freq)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
// ADC configuration
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 4;
ADC_Init(ADC3, &ADC_InitStructure);
ADC_InjectedSequencerLengthConfig(ADC3, 2);
ADC_InjectedChannelConfig(ADC3, ADC_X, 1, DEFAULT_ADC_SAMPLE_TIME);
ADC_InjectedChannelConfig(ADC3, ADC_Y, 2, DEFAULT_ADC_SAMPLE_TIME);
// калибровка
ADC_Cmd(ADC3, ENABLE);
ADC_ResetCalibration(ADC3);
while(ADC_GetResetCalibrationStatus(ADC3));
ADC_StartCalibration(ADC3);
while(ADC_GetCalibrationStatus(ADC3));
//Выключаем триггер.
ADC_ExternalTrigInjectedConvConfig(ADC3, ADC_ExternalTrigInjecConv_T1_CC4);
// Enable automatic injected conversion start after regular one
ADC_AutoInjectedConvCmd(ADC1, ENABLE);
//Включили прерывания с инжекторного канала по окончании преобразования.
ADC_ITConfig(ADC3, ADC_IT_JEOC, ENABLE);
// вычисляем коэффициенты для частоты оцифровки запускаем таймер
unsigned short presc_value, half_period_value;
calc_presc(target_freq, &presc_value, &half_period_value);
main_met_det_timer_init(presc_value, half_period_value);
}
// Этот АЦП будет следить за входными сигналами с синхронного детектора
void start_work_sample(unsigned short target_freq)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
// ADC configuration
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 4;
ADC_Init(ADC3, &ADC_InitStructure);
ADC_InjectedSequencerLengthConfig(ADC3, 2);
ADC_InjectedChannelConfig(ADC3, ADC_X, 1, DEFAULT_ADC_SAMPLE_TIME);
ADC_InjectedChannelConfig(ADC3, ADC_Y, 2, DEFAULT_ADC_SAMPLE_TIME);
// калибровка
ADC_Cmd(ADC3, ENABLE);
ADC_ResetCalibration(ADC3);
while(ADC_GetResetCalibrationStatus(ADC3));
ADC_StartCalibration(ADC3);
while(ADC_GetCalibrationStatus(ADC3));
//Выключаем триггер.
ADC_ExternalTrigInjectedConvConfig(ADC3, ADC_ExternalTrigInjecConv_T1_CC4);
// Enable automatic injected conversion start after regular one
ADC_AutoInjectedConvCmd(ADC1, ENABLE);
//Включили прерывания с инжекторного канала по окончании преобразования.
ADC_ITConfig(ADC3, ADC_IT_JEOC, ENABLE);
// вычисляем коэффициенты для частоты оцифровки запускаем таймер
unsigned short presc_value, half_period_value;
calc_presc(target_freq, &presc_value, &half_period_value);
main_met_det_timer_init(presc_value, half_period_value);
}
Код настройки таймера:
Код
// Инициализация таймера управления АЦП для реальной работы детектора
void main_met_det_timer_init(int prescaller, int period)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Enable Timer1 clock and release reset
RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);
TIM_InternalClockConfig(TIM1);
// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = prescaller;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = period*2 -1; // 0xFF; // 8 bit resolution
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse = period;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC4Init(TIM1,&TIM_OCInitStructure);
// Double buffered
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM1->CCR4 = period;
// TIM counter enable
TIM_Cmd(TIM1, ENABLE);
// TIM2->DIER |= TIM_DIER_UIE; // прерывание по обновлению
// NVIC_EnableIRQ(TIM2_IRQn); // прерывание по таймеру2
// NVIC_SetPriority(TIM2_IRQn, 1); // приоритет
}
void main_met_det_timer_init(int prescaller, int period)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Enable Timer1 clock and release reset
RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);
TIM_InternalClockConfig(TIM1);
// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = prescaller;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = period*2 -1; // 0xFF; // 8 bit resolution
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse = period;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC4Init(TIM1,&TIM_OCInitStructure);
// Double buffered
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM1->CCR4 = period;
// TIM counter enable
TIM_Cmd(TIM1, ENABLE);
// TIM2->DIER |= TIM_DIER_UIE; // прерывание по обновлению
// NVIC_EnableIRQ(TIM2_IRQn); // прерывание по таймеру2
// NVIC_SetPriority(TIM2_IRQn, 1); // приоритет
}