Schetchiksg.ru

Счетчик СГ
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Таймер счетчик для atmega32

Таймер счетчик для atmega32

В этой статье будет рассмотрено использование таймеров в МК и способ подсоединения кнопок к нему.Сначала немного теории.

В МК ATMega16 есть три таймера/счетчика – два 8-битных (Timer/Counter0, Timer/Counter2) и один 16-битный (Timer/Counter1). Каждый из них содержит специальные регистры, одним из которых является счетный регистр TCNTn (n – это число 0, 1 или 2). Каждый раз, когда процессор выполняет одну команду, содержимое этого регистра увеличивается на единицу (либо каждые 8, 64, 256 или 1024 тактов). Потому он и называется счетным. Помимо него, есть еще и регистр сравнения OCRn (Output Compare Register), в который мы можем сами записать какое-либо число. У 8-битного счетчика эти регистры 8-битные. По мере выполнения программы содержимое TCNTn растет и в какой-то момент оно совпадет с содержимым OCRn. Тогда (если заданы специальные параметры) в регистре флагов прерываний TIFR (Timer/Counter Interrupt Flag Register) один из битов становится равен единице и процессор, видя запрос на прерывание, сразу же отрывается от выполнения бесконечного цикла и идет обслуживать прерывание таймера. После этого процесс повторяется.

Ниже представлена временная диаграмма режима CTC (Clear Timer on Compare). В этом режиме счетный регистр очищается в момент совпадения содержимого TCNTn и OCRn, соответственно меняется и период вызова прерывания.

Это далеко не единственных режим работы таймера/счетчика. Можно не очищать счетный регистр в момент совпадения, тогда это будет режим генерации широтно-импульсной модуляции, который мы рассмотрим в следующей статье. Можно менять направление счета, т. е. содержимое счетного регистра будет уменьшаться по мере выполнения программы. Также возможно производить счет не по количеству выполненных процессором команд, а по количеству изменений уровня напряжения на «ножке» T0 или T1 (режим счетчика), можно автоматически, без участия процессора, менять состояние ножек OCn в зависимости от состояния таймера. Таймер/Счетчик1 умеет производить сравнение сразу по двум каналам – А или В.

Далее представлена функциональная схема таймера/счетчика0:

Для запуска таймера нужно выставить соответствующие биты в регистре управления таймером TCCRn (Timer/Counter Control Register), после чего он сразу же начинает свою работу.

Мы рассмотрим лишь некоторые режимы работы таймера. Если вам потребуется работа в другом режиме, то читайте Datasheet к ATMega16 – там все подробнейше по-английски написано, даны даже примеры программ на С и ассемблере (недаром же он занимает 357 страниц печатного текста!).

Теперь займемся кнопками.

Если мы собираемся использовать небольшое количество кнопок (до 9 штук), то подключать их следует между «землей» и выводами какого-либо порта микроконтроллера. При этом следует сделать эти выводы входами, для чего установить соответствующие биты в регистре DDRx и включить внутренний подтягивающий резистор установкой битов в регистре PORTx. При этом на данных «ножках» окажется напряжение 5 В. При нажатии кнопки вход МК замыкается на GND и напряжение на нем падает до нуля (а может быть и наоборот – вывод МК замкнут на землю в отжатом состоянии). При этом меняется регистр PINx, в котором хранится текущее состояние порта (в отличие от PORTx, в котором установлено состояние порта при отсутствии нагрузки, т. е. до нажатия каких-либо кнопок). Считывая периодически состояние PINx, можно определить, что нажата кнопка.

Читайте так же:
Ссылка счетчик до нового года

ВНИМАНИЕ! Если соответствующий бит в регистре DDRx будет установлен в 1 для вашей кнопки, то хорошее нажатие на кнопку может привести к небольшому пиротехническому эффекту – возникновению дыма вокруг МК. Естественно, МК после этого придется отправить в мусорное ведро…

Перейдем к практической части. Создайте в IAR новое рабочее пространство и новый проект с именем, например, TimerButton. Установите опции проекта так, как это описано в предыдущей статье. А теперь наберем следующий небольшой код.

Давайте посмотрим, как это работает. В функциях init_timern задаются биты в регистрах TCCRn, OCRn и TIMSK, причем такой способ может кому-нибудь показаться странным или незнакомым. Придется объяснить сначала, что означает запись «(1 © KERNELCHIP 2006 — 2021

Введение

Таймер-счетчик является одним из самых ходовых ресурсов AVR микроконтроллера. Его основное назначение — отсчитывать заданные временные интервалы. Кроме того, таймеры-счетчики могут выполнять ряд дополнительных функций, как то — формирование ШИМ сигналов, подсчет длительности и количества входящих импульсов. Для этого существуют специальные режимы работы таймера-счетчика.

В зависимости от модели микроконтроллера количество таймеров и набор их функций может отличаться. Например, у микроконтроллера Atmega16 три таймера-счетчика — два 8-ми разрядных таймера-счетчика Т0 и Т2, и один 16-ти разрядный — Т1. В этой статье, на примере ATmega16, мы разберем как использовать таймер-счетчик Т0.

Используемые выводы

Таймер-счетчик Т0 использует два вывода микроконтроллера ATmega16. Вывод T0 (PB0) — это вход внешнего тактового сигнала. Он может применяться, например, для подсчета импульсов. Вывод OC0 (PB3) — это выход схемы сравнения таймера-счетчика. На этом выводе с помощью таймера может формировать меандр или ШИМ сигнал. Также он может просто менять свое состояние при срабатывании схемы сравнения, но об этом поговорим позже.

Выводы T0 и OC0 задействуются только при соответствующих настройках таймера, в обычном состоянии это выводы общего назначения.

Регистры таймера-счетчика Т0

Хоть это и скучно, но регистры — это то, без чего невозможно программировать микроконтроллеры, конечно, если вы не сидите плотно на Arduino. Так вот, таймер Т0 имеет в своем составе три регистра:

Читайте так же:
Завод изготовитель счетчиков каскад

— счетный регистр TCNT0,
— регистр сравнения OCR0,
— конфигурационный регистр TCCR0.

Кроме того, есть еще три регистра, относящиеся ко всем трем таймерам ATmega16:

— конфигурационный регистр TIMSK,
— статусный регистр TIFR.
— регистр специальных функций SFIOR

Начнем с самого простого.

Это 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) в единицу.

Заключение

Нудная часть закончена. Далее разберем как настроить таймер на определенную частоту, как таймер ведет себя в разных режимах, как генерировать ШИМ сигнал.

Таймеры-счетчики в микроконтроллерах AVR

Микроконтроллеры AVR семейства Mega имеют в своем составе от 2 до 4 таймеров/счетчиков.

Микроконтроллеры ATmega32 оснащены тремя таймерами/счетчиками общего назначения — двумя 8-разрядными (0 и 2) и одним 16-разрядным (1).

Таймер/счетчик может работать с тактовой частотой микроконтроллера или через предделитель. Предварительный делитель таймеров/счетчиков содержит четыре ступени деления: СК/8, СК/64, СК/256 и СК/1024, где СК — входной тактовый сигнал. Кроме того, в качестве источников тактовых сигналов могут быть использованы сигналы от внешних источников, тактовый сигнал СК и дополнительный кварцевый генератор (в зависимости от номера таймера).

Читайте так же:
Счетчик банкнот с детекцией кассида

Регистры управления таймером/счетчиком 0:

OCR0 – регистр сравнения

TCNT0 – регистр счета

TCCR0 – настройка режима работы таймера/счетчика

FOC0 – принудительное изменение состояния вывода (при записи лог. 1) в соответствие с режимом COM01:COM00. Прерывание не генерируется.

COM01:COM00 – настройка вывода OC0

0:0 – нормальная работа порта ввода/вывода

0:1 – изменение состояния вывода при совпадении

1:0 – лог. 0 при совпадении

1:1 – лог. 1 при совпадении

Назначение регистров управления таймером/счетчиком 2 аналогично таймеру/счетчику 0. Кроме этого регистр ASSR настраивает асинхронный режим работы.

Регистры управления таймером/счетчиком 1:

OCR1А и OCR1B – регистры сравнения

TCNT1 – регистр счета

TCCR1A и TCCR1АB – настройка режимов работы таймера/счетчика

ICR1 – регистр захвата

ICNC1 – управление схемой подавления помех блока захвата (1 включена)

ICES1 – выбор фронта захвата (0 – спад, 1 — нарастание)

COM1A1:COM1A0 – настройка вывода OC1A

COM1B1:COM1B0 – настройка вывода OC1B

Режимы аналогичны таймеру/счетчику 0

FOC1A – принудительное изменение состояния вывода OC1A (при записи лог. 1) в соответствие с режимом. Прерывание не генерируется.

FOC1B – принудительное изменение состояния вывода OC1B (при записи лог. 1) в соответствие с режимом. Прерывание не генерируется.

Регистр настройки прерываний таймеров/счетчиков TIMSK

Регистр флагов прерываний таймеров/счетчиков TIFR

ATmega32 C++ объект в прерывании таймера

Есть ли возможность вызвать функцию-член, скажем, выход над UART, который будет вызван прерыванием? Обычно я бы использовал TIMER0_COMP vect, но, похоже, не могу заставить его работать с объектами.

2 ответа

  • ATmega32 UART связь

Я пытаюсь сделать последовательную связь в ATMEGA32 и у меня есть вопрос: В асинхронной последовательной связи оба регистра UBRRH и UCSRC имеют одинаковое расположение. Я не знаю, при каких условиях это место будет действовать как UBRRH , а при каких-как UCSRC . Мне нужны разные значения для.

Я хочу использовать ADXL345 в прерывании таймера с Arduino mega. Но это не может не сработать. Вот мой код : #include #define Register_ID 0 #define Register_2D 0x2D #define Register_X0 0x32 #define Register_X1 0x33 #define Register_Y0 0x34 #define Register_Y1 0x35 #define.

Невозможно, чтобы вектор прерывания указывал на функцию-член конкретного объекта . Это связано с тем, что невозможно напрямую передать указатель *this на ISR.

Вектор прерывания может указывать на функцию-член определенного класса , при условии, что это статическая функция, которая возвращает void и не имеет параметров. Однако, поскольку это статическая функция, она не имеет доступа к нестатическим элементам данных любого отдельного объекта.

Читайте так же:
Счетчик для вышивки крестом

Вот пример для компилятора IAR и вектора прерывания таймера из AVR:

Опять же, ограничения этого подхода заключаются в том, что ISR может получить доступ только к статическим данным для класса.

Если вы хотите, чтобы прерывание было связано с конкретным объектом, вам понадобится что-то вроде того, что рекомендует H2C03, а именно, чтобы ISR знал о конкретном объекте, а затем вызывал член этого объекта в самом ISR.

Это то, что вы ищете?

Похожие вопросы:

Как объект таймера C# определяет, когда произошло истекшее количество времени? Я задаюсь вопросом, является ли он просто циклом или более разумным, чем это. Кроме того, было бы неплохо знать, где.

Итак, я использую System.Timers.Timer в .Net 4 с C#. У меня есть свой объект таймера вот так: var timer = new Timer ; У меня есть обработчик событий Timer Elapsed, указывающий на.

Каковы преимущества использования ATmega32 по сравнению с другими микроконтроллерами? Это лучше , чем PIC , ARM и 8051 ?

Я пытаюсь сделать последовательную связь в ATMEGA32 и у меня есть вопрос: В асинхронной последовательной связи оба регистра UBRRH и UCSRC имеют одинаковое расположение. Я не знаю, при каких условиях.

Я хочу использовать ADXL345 в прерывании таймера с Arduino mega. Но это не может не сработать. Вот мой код : #include #define Register_ID 0 #define Register_2D 0x2D #define.

Я читал, что постскаляр таймера определяет, сколько раз счетчик должен переполниться, чтобы получить прерывание. Но у меня есть сомнения. Итак, я понимаю, что если я поставлю 0x55 и начну таймер с.

В настоящее время я работаю в проекте синусоидального инвертора, и мне нужно сгенерировать PWM с помощью microcontroller, для этой цели я выбрал atmega32, может ли кто-нибудь подсказать мне, с чего.

Когда мы используем kernel таймеров, kernel таймер запускается в программном прерывании, поэтому функция kernel таймера выполняется в контексте прерывания таймера. void timer_func(unsigned long arg).

Мне нужен пример таймера для использования. В конце концов, это должен быть объект, которому я передам длительность (X МС) и указатель на функцию, которая должна быть вызвана по истечении таймера.

Является ли ATmega32 8-битным или 16-битным microcontroller? При чтении книги мазиди AVR было указано, что RAMEND в ATmega32 находится на 0x085f , что является 16-битным адресом. Выдержка из Книги.

голоса
Рейтинг статьи
Ссылка на основную публикацию