Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запуск АЦП преобразования по таймеру
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Sprite
Доброго всем времени суток!

Задача следующая: требуется запустить одно АЦП-преобразование по событию канала 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.

Прикладываю скрины настроек АЦП и таймера.
Нажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файла
Заранее спасибо!
Sprite
Поставлю вопрос по другому: эта задача имеет решение?
Может ли АЦП без DMA один раз за период совершать однократное преобразование и сохранять значение в ADC1->DR?
adnega
Может и однократное преобразование, и непрерывное. Нужно посмотреть инициализацию АЦП (битики SCAN и CONT)
Sprite
Прошу прощения, что ввел в заблуждение участников форума - настройки АЦП указаны не совсем правильно, но это сути не меняет:
Нажмите для просмотра прикрепленного файла
Если я правильно понял - то биты SCAN и CONT здесь не причем. Первый используется для сканирования группы каналов, а второй для непрерывного АЦП преобразования, а мне нужно получить в ADC1->DR только одно значение при сравнении с TIM4_CCR4, т.е. использовать Single Mode, или я не прав?
adnega
Битики должны быть в нуле - Вы правы.
Не обратил внимание на скрины из первого поста(

Сейчас обратил - частота АЦП 36МГц. А это много)
Sprite
Цитата(adnega @ Mar 24 2011, 13:00) *
Сейчас обратил - частота АЦП 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
Из документации:
"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МГц, то затея не работоспособная.

С какой частотой Вы хотите получать выборки АЦП?
Sprite
Спасибо за дельное замечание, выставил частоту АЦП в 9МГц!
Скрины прилагаются, только все равно не работает sad.gif По достижению регистра сравнения АЦП преобразование запускается и молотит пока нога таймера выставлена в 1, постоянно обновляя регистр данных (ADC1->DR), а мне нужно получить одно значение.
Вообще скорость АЦП хотелось бы максимальную, но 1,5 мкс. меня вполне устроит.
Нажмите для просмотра прикрепленного файла

Проблема пока не решена...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.