Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запуск инжектированых каналов АЦП от события таймера
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
misyachniy
Мне нужно следить за состоянием двух аналоговых входов и при "резком" изменеии сигнала начать его обработку.

Частота опроса невысокая - пару сотен герц.
Я решил использовать инжектированые каналы, чтобы не программировать 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 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);    // приоритет
}
Сергей Борщ
Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строке
Цитата(misyachniy @ Oct 31 2014, 20:44) *
Код
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
}
надо написать _Enable
SSerge
Цитата(Сергей Борщ @ Nov 1 2014, 04:15) *
Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строкенадо написать _Enable

Подтверждаю, для запуска по CCx event должна быть включена и переключаться соответствующая нога.
Альтернативный вариант запуска - по событию TRGO event, оно происходит "внутри" таймера.
Сергей Борщ
Цитата(SSerge @ Nov 1 2014, 13:53) *
должна быть включена и переключаться соответствующая нога.
Нет, физическую ногу подключать через соответствующую альтернативную функцию не обязательно, но вот выход модуля Capture должен быть включен.
misyachniy
Цитата(Сергей Борщ @ Oct 31 2014, 23:15) *
Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строкенадо написать _Enable


Не помогло.
Выкрутился по другому.
Ulianov_Lenin
В коде настройки АЦП не вижу строки
ADC_ExternalTrigInjectedConvEdgeConfig(ADC1, ADC_ExternalTrigInjecConvEdge_RisingFalling);
- именно она с параметром отличным от ADC_ExternalTrigInjecConvEdge_None
включает срабатывание АЦП по внешнему триггеру и тогда на F446 АЦП по ADC_ExternalTrigInjecConv_T3_CC2 у меня работает.

А вот по ADC_ExternalTrigInjecConv_T1_CC4 - ни в какую. Хотя в дебуге видно что CC4IF меняется, да и прерывание по нему срабатывает, а вот АЦП не запускается.
Хотя если сделать
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
то один раз конверсия производилась.

Выкручиваться дополнительным таймером не хочется. Кто-нибудь с такой проблемой сталкивался?

Кстати да, по ADC_ExternalTrigInjecConv_T1_TRGO АЦП запускается. А оно всегда было по TIM_TRGOSource_Update, сейчас попробовал сделать TIM_TRGOSource_OC4Ref - тоже работает. Эффект как от ADC_ExternalTrigInjecConv_T1_CC4, но через TRGO. Странно что без TRGO не получается с первым таймером, а с третьим - получается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.