КИПиА ЯМАЛ
Электронная библиотека учебной документации КИПиА
6-й разряд · МДК.01.02 · Билет № 6 · Вопрос 2

Управление таймерами микроконтроллеров AVR c помощью программ, написанных на языке С (Си).

Ответ

Ответ на вопрос

Управление таймерами микроконтроллеров AVR с помощью программ на языке C (Си)

Таймеры/счётчики AVR — аппаратные модули микроконтроллера, предназначенные для отсчёта времени, подсчёта импульсов, формирования периодических событий и ШИМ-сигналов.

Главное преимущество таймера — он работает аппаратно и не требует постоянного выполнения задержек программой.


1. Для чего используются таймеры AVR

С помощью таймеров можно:

  • создавать точные временные интервалы;

  • формировать задержки;

  • генерировать периодические прерывания;

  • подсчитывать внешние импульсы;

  • измерять длительность сигналов;

  • формировать ШИМ;

  • управлять яркостью светодиодов;

  • регулировать скорость двигателя;

  • формировать звуковые сигналы;

  • измерять частоту и период.


2. Основные регистры таймера

Конкретные названия зависят от модели AVR, но обычно используются следующие группы регистров.

Счётный регистр

Например:

TCNT0 TCNT1

В нём находится текущее значение таймера.

Таймер получает тактовые импульсы и изменяет содержимое этого регистра:

0 → 1 → 2 → 3 → ... → максимальное значение

Регистры управления

Например:

TCCR0A TCCR0B TCCR1A TCCR1B

Через них задаются:

  • режим работы;

  • источник тактирования;

  • коэффициент деления частоты;

  • режим ШИМ.


Регистры сравнения

Например:

OCR0A OCR0B OCR1A OCR1B

В них задаётся значение, с которым сравнивается содержимое таймера.

Если:

TCNT=OCRTCNT = OCR

может произойти:

  • установка флага;

  • вызов прерывания;

  • изменение состояния аппаратного выхода.


3. Предделитель частоты

Тактовая частота микроконтроллера обычно слишком велика для непосредственного формирования длинных интервалов.

Поэтому применяется предделитель — prescaler.

Например:

1 8 64 256 1024

Если микроконтроллер работает с частотой:

FCPU=16 МГцF_{CPU}=16\text{ МГц}

а предделитель равен 64:

Ftimer=1600000064=250000 ГцF_{timer}=\frac{16\,000\,000}{64}=250\,000\text{ Гц}

Период одного отсчёта:

T=1250000=4 мксT=\frac{1}{250000}=4\text{ мкс}

То есть таймер изменяется один раз каждые 4 мкс.


4. Основные режимы работы

Normal — обычный режим

Таймер считает от нуля до максимального значения.

Для 8-разрядного таймера:

0 → 1 → 2 → ... → 255 → 0

При переполнении может возникнуть прерывание.


CTC — сброс при совпадении

CTC — Clear Timer on Compare Match.

Таймер считает до значения, записанного в регистре сравнения, например OCR0A.

0 → 1 → 2 → ... → OCR0A → 0

Этот режим очень удобен для получения точных периодических прерываний.


PWM — широтно-импульсная модуляция

Таймер может автоматически формировать ШИМ-сигнал.

Изменяя значение регистра сравнения, можно изменять коэффициент заполнения импульсов.

Например:

25 % ──┐ ┌── └──────┘ 50 % ────┐ ┌──── └────┘ 75 % ──────┐ ┌────── └──┘

ШИМ применяется для управления:

  • яркостью светодиодов;

  • скоростью двигателя;

  • нагревателями;

  • силовыми ключами.


5. Прерывания таймера

Таймер способен вызвать прерывание:

  • при переполнении;

  • при совпадении со значением сравнения;

  • при захвате входного сигнала.

Для разрешения прерываний используются специальные регистры, например:

TIMSK0 TIMSK1

Глобальное разрешение прерываний:

sei();

Для этого обычно подключается:

#include <avr/interrupt.h>
6. Пример таймера AVR на языке C

Рассмотрим пример для AVR с Timer0, работающим в режиме CTC.

Пусть:

FCPU=16 МГцF_{CPU}=16\text{ МГц}

предделитель:

6464

и требуется прерывание примерно каждые 1 мс.

Частота таймера:

1600000064=250000 Гц\frac{16\,000\,000}{64}=250\,000\text{ Гц}

За 1 мс требуется:

2500000,001=250250\,000 \cdot 0{,}001=250

отсчётов.

Поэтому:

OCR0A = 249;

Программа:

#include <avr/io.h> #include <avr/interrupt.h> volatile unsigned int ms = 0; int main(void) { // Режим CTC TCCR0A |= (1 << WGM01); // Значение сравнения OCR0A = 249; // Разрешить прерывание по совпадению TIMSK0 |= (1 << OCIE0A); // Предделитель 64 TCCR0B |= (1 << CS01) | (1 << CS00); // Разрешить глобальные прерывания sei(); while (1) { // Основная программа } } ISR(TIMER0_COMPA_vect) { ms++; }

Прерывание вызывается примерно один раз в миллисекунду.


7. Пример мигания светодиодом без _delay_ms()

Можно использовать таймер вместо программной задержки:

#include <avr/io.h> #include <avr/interrupt.h> volatile uint16_t counter = 0; ISR(TIMER0_COMPA_vect) { counter++; if (counter >= 500) { PORTB ^= (1 << PB0); counter = 0; } } int main(void) { DDRB |= (1 << PB0); TCCR0A |= (1 << WGM01); OCR0A = 249; TCCR0B |= (1 << CS01) | (1 << CS00); TIMSK0 |= (1 << OCIE0A); sei(); while (1) { // Здесь могут выполняться другие задачи } }

Светодиод меняет состояние примерно каждые 500 мс, а микроконтроллер в это время может выполнять другие функции.


8. Формирование ШИМ

Для генерации ШИМ таймер переводится в режим PWM.

Упрощённый пример:

DDRB |= (1 << PB1); TCCR1A |= (1 << COM1A1); TCCR1A |= (1 << WGM10); TCCR1B |= (1 << WGM12); TCCR1B |= (1 << CS11); OCR1A = 128;

Значение OCR1A определяет длительность импульса.

При изменении OCR1A изменяется коэффициент заполнения ШИМ.


9. 8-разрядные и 16-разрядные таймеры

AVR могут иметь таймеры различной разрядности.

8-разрядный

Диапазон счёта:

0...2550...255

То есть:

28=2562^8=256

состояний.

16-разрядный

Диапазон:

0...655350...65535

То есть:

216=655362^{16}=65536

состояний.

16-разрядный таймер позволяет получать более длительные интервалы и большую точность задания периода.


10. Счёт внешних импульсов

Таймер может работать не только от внутренней тактовой частоты.

На специальный вход можно подавать внешние импульсы:

Датчик → вход таймера → TCNT

Каждый импульс увеличивает счётчик.

Так можно измерять:

  • число оборотов;

  • количество изделий;

  • импульсы расходомера;

  • частоту внешнего сигнала.


Основной принцип настройки таймера

Обычно программа выполняет следующие действия:

  1. выбирает таймер;

  2. задаёт режим его работы;

  3. выбирает предделитель;

  4. записывает начальное значение или значение сравнения;

  5. при необходимости разрешает прерывание;

  6. запускает таймер;

  7. обрабатывает событие в основной программе или обработчике прерывания.

Кратко для ответа по билету

Управление таймерами AVR на языке C выполняется через специальные регистры TCNT, TCCR, OCR и TIMSK. Таймер подсчитывает внутренние или внешние импульсы и может работать в режимах Normal, CTC и PWM. С помощью предделителя задаётся частота его работы.

Таймеры применяются для формирования временных интервалов, прерываний, подсчёта импульсов, измерения сигналов и генерации ШИМ. Например, в режиме CTC значение TCNT сравнивается с OCR, после совпадения таймер может обнулиться и вызвать прерывание. Это позволяет выполнять точные периодические операции без применения программных задержек.

Этот вопрос используется в билетах