misyachniy 0 31 октября, 2014 Опубликовано 31 октября, 2014 (изменено) · Жалоба Мне нужно следить за состоянием двух аналоговых входов и при "резком" изменеии сигнала начать его обработку. Частота опроса невысокая - пару сотен герц. Я решил использовать инжектированые каналы, чтобы не программировать 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); // приоритет } Изменено 21 ноября, 2022 пользователем haker_fox Уточнил название темы, добавил теги, переместил в нужный раздел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 31 октября, 2014 Опубликовано 31 октября, 2014 · Жалоба Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строке TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; } надо написать _Enable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 1 ноября, 2014 Опубликовано 1 ноября, 2014 · Жалоба Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строкенадо написать _Enable Подтверждаю, для запуска по CCx event должна быть включена и переключаться соответствующая нога. Альтернативный вариант запуска - по событию TRGO event, оно происходит "внутри" таймера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 117 1 ноября, 2014 Опубликовано 1 ноября, 2014 · Жалоба должна быть включена и переключаться соответствующая нога.Нет, физическую ногу подключать через соответствующую альтернативную функцию не обязательно, но вот выход модуля Capture должен быть включен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 4 ноября, 2014 Опубликовано 4 ноября, 2014 · Жалоба Я не знаю этих библиотек, но насколько смог убедиться по F100 - должен быть включен выход таймера. То есть предположу, что в этой строкенадо написать _Enable Не помогло. Выкрутился по другому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ulianov_Lenin 0 25 июня, 2017 Опубликовано 25 июня, 2017 · Жалоба В коде настройки АЦП не вижу строки 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 не получается с первым таймером, а с третьим - получается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться