alex1985 0 23 марта, 2011 Опубликовано 23 марта, 2011 · Жалоба Доброго всем времени суток! Задача следующая: требуется запустить одно АЦП-преобразование по событию канала 4 таймера 4. Делаю все как указано в Reference Manual, но преобразование стартует при совпадении с TIM4_CCR4 и продолжает выполняться пока счетчик (TIM4_CNT) не достигнет вершины (TIM4_ARR), при этом содержимое регистра ADC1_DR постоянно обновляется. А мне нужно получить только одно значение в момент совпадения счетчика с TIM4_CCR4. В Reference Manual написано: 11.3.4 Single conversion mode In Single conversion mode the ADC does one conversion. This mode is started either by setting the ADON bit in the ADC_CR2 register (for a regular channel only) or by external trigger (for a regular or injected channel), while the CONT bit is 0. Once the conversion of the selected channel is complete: ● If a regular channel was converted: –The converted data is stored in the 16-bit ADC_DR register –The EOC (End Of Conversion) flag is set –and an interrupt is generated if the EOCIE is set. ● If an injected channel was converted: –The converted data is stored in the 16-bit ADC_DRJ1 register –The JEOC (End Of Conversion Injected) flag is set –and an interrupt is generated if the JEOCIE bit is set. The ADC is then stopped. Т.е. если я правильно понимаю - после преобразования АЦП должен остановиться - но он не останавливается, а продолжает работать. Может быть я задаю не Single Mode? Контроллер stm32f103. Прикладываю скрины настроек АЦП и таймера. Заранее спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Поставлю вопрос по другому: эта задача имеет решение? Может ли АЦП без DMA один раз за период совершать однократное преобразование и сохранять значение в ADC1->DR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Может и однократное преобразование, и непрерывное. Нужно посмотреть инициализацию АЦП (битики SCAN и CONT) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Прошу прощения, что ввел в заблуждение участников форума - настройки АЦП указаны не совсем правильно, но это сути не меняет: Если я правильно понял - то биты SCAN и CONT здесь не причем. Первый используется для сканирования группы каналов, а второй для непрерывного АЦП преобразования, а мне нужно получить в ADC1->DR только одно значение при сравнении с TIM4_CCR4, т.е. использовать Single Mode, или я не прав? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Битики должны быть в нуле - Вы правы. Не обратил внимание на скрины из первого поста( Сейчас обратил - частота АЦП 36МГц. А это много) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Сейчас обратил - частота АЦП 36МГц. А это много) А сколько должно быть? Таймер работает на частоте 72МГц, вот процедура инициализации: void RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; // RCC system reset(for debug purpose) RCC_DeInit(); // Enable HSE RCC_HSEConfig(RCC_HSE_ON); // Wait till HSE is ready HSEStartUpStatus = RCC_WaitForHSEStartUp(); if (HSEStartUpStatus == SUCCESS) { // Enable Prefetch Buffer FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Flash 2 wait state FLASH_SetLatency(FLASH_Latency_2); // HCLK = SYSCLK RCC_HCLKConfig(RCC_SYSCLK_Div1); // PCLK2 = HCLK RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK1 = HCLK/2 RCC_PCLK1Config(RCC_HCLK_Div2); // PLLCLK = 8MHz * 9 = 72 MHz RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // Enable PLL RCC_PLLCmd(ENABLE); // Wait till PLL is ready while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} // Select PLL as system clock source RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Wait till PLL is used as system clock source while(RCC_GetSYSCLKSource() != 0x08){} } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_USART1| RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 марта, 2011 Опубликовано 24 марта, 2011 · Жалоба Из документации: "The ADC input clock is generated from the PCLK2 clock divided by a prescaler and it must not exceed 14 MHz, refer to Figure 8: Clock tree for low-, medium-, high- and XL-density devices, and to Figure 11: Clock tree for connectivity line devices." - т.е. не более 14МГц. Необходимо помнить, что преобразование занимает 12,5 тактов + настройки SMPn (в Вашем случае 1,5 такта). Т.е. на одно преобразование тратится минимум 14 тактов частоты АЦП, которая не может быть больше 14МГц. Если таймер пытается АЦеПировать с частотой большей 1МГц, то затея не работоспособная. С какой частотой Вы хотите получать выборки АЦП? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 24 марта, 2011 Опубликовано 24 марта, 2011 (изменено) · Жалоба Спасибо за дельное замечание, выставил частоту АЦП в 9МГц! Скрины прилагаются, только все равно не работает :( По достижению регистра сравнения АЦП преобразование запускается и молотит пока нога таймера выставлена в 1, постоянно обновляя регистр данных (ADC1->DR), а мне нужно получить одно значение. Вообще скорость АЦП хотелось бы максимальную, но 1,5 мкс. меня вполне устроит. Проблема пока не решена... Изменено 24 марта, 2011 пользователем Sprite Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться