Учебный курс AVR. Таймер – счетчик Т0. Регистры. Ч1
Это 8-ми разрядный счетный регистр. Когда таймер работает, по каждому импульсу тактового сигнала значение TCNT0 изменяется на единицу. В зависимости от режима работы таймера, счетный регистр может или увеличиваться, или уменьшаться.
Регистр TCNT0 можно как читать, так и записывать. Последнее используется когда требуется задать его начальное значение. Когда таймер работает, изменять его содержимое TCNT0 не рекомендуется, так как это блокирует схему сравнения на один такт.
OCR0
Это 8-ми разрядный регистр сравнения. Его значение постоянно сравнивается со счетным регистром TCNT0, и в случае совпадения таймер может выполнять какие-то действия – вызывать прерывание, менять состояние вывода OC0 и т.д. в зависимости от режима работы.
Значение OCR0 можно как читать, так и записывать.
TCCR0 (Timer/Counter Control Register)
Это конфигурационный регистр таймера-счетчика Т0, он определяет источник тактирования таймера, коэффициент предделителя, режим работы таймера-счетчика Т0 и поведение вывода OC0. По сути, самый важный регистр.
Биты CS02, CS01, CS00 (Clock Select) – определяют источник тактовой частоты для таймера Т0 и задают коэффициент предделителя. Все возможные состояния описаны в таблице ниже.
Как видите, таймер-счетчик может быть остановлен, может тактироваться от внутренней частоты и также может тактироваться от сигнала на выводе Т0.
Биты WGM10, WGM00 (Wave Generator Mode) – определяют режим работы таймера-счетчика Т0. Всего их может быть четыре – нормальный режим (normal), сброс таймера при совпадении (CTC), и два режима широтно-импульсной модуляции (FastPWM и Phase Correct PWM). Все возможные значения описаны в таблице ниже.
Более подробно будем разбирать режимы в коде. Сейчас все нюансы все равно не запомнятся.
Биты COM01, COM00 (Compare Match Output Mode) – определяют поведение вывода OC0. Если хоть один из этих битов установлен в 1, то вывод OC0 перестает функционировать как обычный вывод общего назначения и подключается к схеме сравнения таймера счетчика Т0. Однако при этом он должен быть еще настроен как выход.
Поведение вывода OC0 зависит от режима работы таймера-счетчика Т0. В режимах normal и СTC вывод OC0 ведет себя одинаково, а вот в режимах широтно-импульсной модуляции его поведение отличается. Не будем сейчас забивать себе голову всеми этими вариантами и разбирать таблицы для каждого режима, оставим это на практическую часть.
И последний бит регистра TCCR0 – это бит FOC0 (Force Output Compare).Этот бит предназначен для принудительного изменения состояния вывода OC0. Он работает только для режимов Normal и CTC. При установки бита FOC0 в единицу состояние вывода меняется соответственно значениям битов COM01, COM00. FOC0 бит не вызывает прерывания и не сбрасывает таймер в CTC режиме.
TIMSK (Timer/Counter Interrupt Mask Register)
Общий регистр для всех трех таймеров ATmega16, он содержит флаги разрешения прерываний. Таймер Т0 может вызывать прерывания при переполнении счетного регистра TCNT0 и при совпадении счетного регистра с регистром сравнения OCR0. Соответственно для таймера Т0 в регистре TIMSK зарезервированы два бита – это TOIE0 и OCIE0. Остальные биты относятся к другим таймерам.TOIE0 – 0-е значение бита запрещает прерывание по событию переполнение, 1 – разрешает.
OCIE0 – 0-е значение запрещает прерывания по событию совпадение, а 1 разрешает. Естественно прерывания будут вызываться, только если установлен бит глобального разрешения прерываний – бит I регистра SREG.TIFR (Timer/Counter0 Interrupt Flag Register)
Общий для всех трех таймеров-счетчиков регистр. Содержит статусные флаги, которые устанавливаются при возникновении событий. Для таймера Т0 – это переполнение счетного регистра TCNT0 и совпадение счетного регистра с регистром сравнения OCR0.
Если в эти моменты в регистре TIMSK разрешены прерывания и установлен бит I, то микроконтроллер вызовет соответствующий обработчик. Флаги автоматически очищаются при запуске обработчика прерывания. Также это можно сделать программно, записав 1 в соответствующий флаг.
TOV0 – устанавливается в 1 при переполнении счетного регистра.
OCF0 – устанавливается в 1 при совпадении счетного регистра с регистром сравнения
SFIOR (Special Function IO Register)
Начинающему про этот регистр в принципе можно и не знать, один из его разрядов сбросывает 10-ти разрядный двоичный счетчик, который делит входную частоту для таймера Т0 и таймера Т1. Сброс осуществляется при установке бита PSR10 (Prescaler Reset Timer/Counter1 и Timer/Counter0) в единицу.
Заключение
Нудная часть закончена. Далее разберем как настроить таймер на определенную частоту, как таймер ведет себя в разных режимах, как генерировать ШИМ сигнал.
У вас недостаточно прав для комментирования.
Источник: http://chipenable.ru/index.php/programming-avr/item/171
Программирование микроконтроллеров: таймер — drive2
Для самых маленьких познавателей микроконтроллеров.Поговорим про таймеры-счетчики микроконтроллеров AVR и конкретно ATTiny13A.
Начинающим очень сложно порой понять, как работают таймеры, в даташите столько написано про таймеры и так непонятно, что жуть. Да ещё и по-английски.
Обычно описание работы начинают как в даташите сверху вниз, а я начну снизу вверх, так более понятно начинающим.
Работа таймера-счетчика очень похожа на работу механического колесика одометра в панели приборов автомобиля. Вот и с ним будем сравнивать.
Долее по даташиту:
TCNT0 Timer/Counter Register. Это регистр таймера счетчика. Это колесико одометра. Если этому колесику придать вращение от какого нибудь сигнала, то он начнет крутиться. У колесика 255 положений, а не от нуля до девяти, как у одометра авто.
Крутится он по кругу, то есть 0,1,2,3…254,255,0,1,2,3… Этот регистр открыт для чтения и записи, то есть можно считывать его значение и писать свое.
простой пример: колесико должно крутится до 127, а потом сразу сбрасываться в ноль и считать дальше:
if(TCNT0==127) {TCNT0=0};
По-русски:
Если значение счетчика равно 127 if(TCNT0==127)
То сбрасываем этот же счетчик в ноль (присваиваем регистру нулевое значение ) {TCNT0=0}
В этом примере есть и чтение регистра TCNT0 и запись в этот же регистр.
Теперь выше по даташиту: как и чем и отчего заставить крутится это колесико одометра?
Для этого есть два способа:
1.- От тактового генератора микроконтроллера.
2. — От состояние входа( ножки) Т0
От тактового генератора:
Счетчик крутится от тактового генератора, “скорость” вращения колесика можно выбирать делителем. Отвечает за делитель регистр TCCR0B
Пример расчета “скорости”: тактовый генератор лопатит на 1,2МГц:
TCCR0B=0x00 счетчик выключен.
Можно использовать это значение как выключалку таймера-счетчика
TCCR0B=0x01 счетчик лопатит на 1,2МГц: деление на единицу типа)
TCCR0B=0x02 счетчик лопатит на 150кГц: деление на 8
TCCR0B=0x03 счетчик лопатит на 18,75кГц: деление на 64
TCCR0B=0x04 счетчик лопатит на 4,688кГц: деление на 256
TCCR0B=0x05 счетчик лопатит на 1,172кГц: деление на 1024
От состоянии на входной ножке Т0 (это 7 ножка порт РВ2)
TCCR0B=0x06 по спаду сигнала
TCCR0B=0x07 по фронту сигнала
Например: на входе Т0 логический ноль. В регистре TCCR0B=0x06 стоит по спаду сигнала. Счетчик стоит. Появилась единица на входе. Счетчик почуял это и приготовился, ибо по спаду. Пропала единица — стал ноль на входе Т0 — регистр таймера счетчика TCNT0 прибавил себе единичку и опять следит за состоянием по входу Т0
Колесико то крутится, но в холостую. Надо теперь сделать так, чтоб оно делало полезную работу. А вот тут уже много возможностей.
Есть несколько основных выводов полезной работы счетчика-таймера.
Делать работу, можно если значение счетчика (колесико TCNT0) сравняется с регистром сравнения-совпадения OCR0х. Это ещё составная часть таймера счетчика, состоящая из двух равнозначных регистра OCR0A и OCR0B.
OCR0A и OCR0B — это как колесики на кодовом навесном замке. Если уж совсем так сравнивать, то это два отдельных кодовых навесных замка с одним колесиком:
Ну как то так, только не на десять положений, а на 255
То есть можно выставлять свое значение колесика замка OCR0A или OCR0B, затем крутить колесико таймера одометра TCNT0, при совпадении значений замок открывается и происходит какое либо событие.
Описание этого события зависит от того, в каком режиме работы находится таймер-счетчик. От этого режима зависит алгоритм работы и взаимодействия этих регистров.
Режимы можно посмотреть в мастере CodeVisionAVR:
Далее простым детским языком уже достаточно сложно объяснять, поэтому резко взрослеем, и начинаем понимать, что такое прерывание, что такое Широтно Импульсная Модуляция и что такое прерывание по переполнению таймера и как эти слова можно использовать к нашему таймеру счетчику, чтоб получить полезное действие.
Теперь примеры, созданные для среды разработки CodeVisionAVR:
значение фьюзов по умолчанию, поэтому тактовая частота равна 1.2МГц. Значения настройки портов и т.п. не указано, только мясо:
TCCR0B=0x03; //Запускаем таймер в обычном счетном режиме на 18,750 kHz
OCR0A=0xF0; // Указываем значение регистра сравнения равное 0хF0
TIMSK0=0x04;//Разрешаем выполнение прерываний по совпадению в OCR0A
#asm(“sei”) // Разрешаем сами глобальные прерывания
interrupt [TIM0_COMPA] void timer0_compa_isr(void){// Здесь малюем кодTCNT0=0x00;
}
Скриншот мастера:
Описание:
Таймер-счетчик прибавляет единичку 18750 раз в секунду (то самое колесико одометра TCNT0), значение OCR0A=0xF0; как и так понятно равно F0, в десятичной системе это равно числу 240. Если колесико одометра насчитает 240 “тиков”, то сработает прерывание: основной цикл программы останавливается, и начинается выполнения кода “здесь малюем код”:
interrupt [TIM0_COMPA] void timer0_compa_isr(void){// Здесь малюем кодTCNT0=0x00;
}
Внутри фигурных скобок есть сброс колесика одометра в ноль: TCNT0=0x00;, то есть после выполнения кода счетчик сбрасывается и начинается счет с нуля. И так циклично.
Этот код применяется, если необходимо производить какое либо действо через определенный точно заданный промежуток времени: делать опрос какого либо устройства, мерять температуру, сканировать состояние энкодера да еще много что можно. Ну или например, если настроить вызов прерывания ровно раз в секунду, то можно сделать секундомер. Конкретно данный пример срабатывает 18750/240=78,125 раза в секунду.
Теперь интереснее: запускаем ШИМ:
TCCR0A=0x81;//запускаем ШИМ с фазовой коррекцией и назначаем выход ножки PB0(OC0A) на выход импульсов ШИМа
TCCR0B=0x02;//частота работы таймера 150 кГц
TIMSK0=0x02;//разрешаем прерывания по переполнению таймера
#asm(“sei”)// Разрешаем сами глобальные прерывания
interrupt [TIM0_OVF] void timer0_ovf_isr(void){// Малюем код}
Ну а здесь описание совсем короткое: на выходе PB0 микроконтроллера (ножка 5) будет присутствовать ШИМ сигнал (если будет правильно сконфигурирован этот порт на выход), с заполнением пропорционально значению регистра OCR0AПримеры:OCR0A=0; — ШИМа небудет, ноль на выходеOCR0A=127; — на выходе ровный меандр с заполнением 50/50
OCR0A=255; — на выходе единица, ШИМа нет
Так как включено прерывание по переполнению таймера, то когда счетчик насчитает максимальное значение, то будет срабатывать прерывание (выполняться код “Малюем код”)Скриншот мастера:
Теперь, освоив и поняв принцип работы таймера, несложно понять, как работает таймер в других режимах, чем отличается ШИМ с фазовой коррекцией от обычного Fast PWM и так далее и тому подобное. Но это вы уже сами.
Источник: https://www.drive2.ru/b/768372/
AVR130: настройка и использование таймеров AVR
Источник: http://AVRproject.ru/publ/capture_timer1_avr/1-1-0-24
Adblockdetector