Таймер/счетчик в режиме CTC

Тема в разделе "Микроконтроллеры AVR", создана пользователем Андрей Хохлов, 11 фев 2016.

  1. Правильно ли я понимаю логику работы таймера в режиме CTC?

    Для определенности Timer0, при каждом импульсе выполняются действия,
    соответствующие приведенному псевдокоду:

    Код (C++):

    if (TCNT0 == OCR0A)
    {
      TCNT0 = 0;
    }
    else
    {
      TCNT0 = (TCNT0 + 1) % 256;
    }
     
    Спасибо
     
  2. Onkel

    Onkel Гуру

    может кто и поймет, мне непонятно. Что за импульсы ?
     
  3. ИгорьК

    ИгорьК Гуру

    Там все выглядит следующим образом.
    Как только таймер досчитывает до значения регистра(регистров) сравнения - происходит прерывание и сброс в ноль. Или не происходит сброса в ноль - только прерывание (как настроено), а счет идет дальше.
    Соответственно, источником счета могут быть как внутренний генератор, да с предделителями, так и внешние импульсы - в зависимости от настроек.
    А теперь, пожалуйста, объясните вот это:
    Код (C++):
    else
    {
      TCNT0 = (TCNT0 + 1) % 256;
    }
     
    Что это, по-вашему, значит?
     
  4. DrProg

    DrProg Вечный нерд

    Если счетчик таймера остановить битами CS02, CS01 и CS00, установив их в 0, то придется увеличивать его вручную как в примере. )

    А вообще счетчик таймера увеличивается автоматически каждый такт генератора импульсов. Или каждый 8, 64, 256, 1024 такт, смотря как задано в настройках.
     
    ИгорьК нравится это.
  5. ИгорьК

    ИгорьК Гуру

    Пора опять плюсовать...
    Это о чем? Отсюда по-подробнее...
     
  6. DrProg

    DrProg Вечный нерд

    Поправьте меня.
     
    ИгорьК нравится это.
  7. В даташите написано буквально следующее: "In CTC mode the counter is cleared to zero when the counter value (TCNT0) matches the OCR0A". Неясно, что происхолит раньше - инкремент или сравнениею

    Я подключил внешний генератор (примерно 1Гц) ко входу 4 Arduino (T0), инициализировал счетчик так:
    Код (C++):

    TCNT0   = 253;
    TCCR0A  = 1 << WGM01;
    TCCR0B  = 1 << CS02 | 1 << CS01 | 1 << CS00;
    OCR0A   = 3;
     
    И в цикле вывожу значение TCNT0 на индикатор. Показывает он следующее:
    Код (Text):
    253->254->255->0->1->2->3->0->...
    Значение 3 отображается примерно в течение 1 сек
     
  8. ИгорьК

    ИгорьК Гуру

    Вы мой кумир! Это не я Вас исправлять должен а Вы меня! Спасибо, уважаемый!
     
  9. ИгорьК

    ИгорьК Гуру

    Инкремент. Иначе с чем сравнивать? Досчитали до 3 - 3 уже есть. Сравнили, что 3, сбросились. Это же и в вашем примере видно - там цифра 3 есть. Иначе бы ее не было.
     
  10. Допустим TCNT0=2 и на вход T0 поступает импульс. Если бы при этом выполнялся инкремент и сразу следом сравнение (и сброс), число 3 было бы в TCNT0 очень недолго (один такт?).
     
  11. ИгорьК

    ИгорьК Гуру

    Сравнение происходит в начале следующего такта. Это же видно.
    Но если этот вопрос предельно важен - даташит... Не так ли?
    У нас только Доктор не ошибается, все остальные грешны :)
     
  12. Осталось еще включить прерывание и посмотреть, когда оно происходит...
     
  13. ИгорьК

    ИгорьК Гуру

    Для верности - добавьте Герцев :)
     
  14. Прерывание по совпадению с OCR0A (TIMER0_COMPA_vect) происходит при переходе 3->0. Т.е. при сбросе счетчика, а не при совпадении.