Режим быстрого ШИМ

В этом режиме таймер-счётчик на каждом такте увеличивает на единицу значение регистра TCNTn от 0 до верхней границы регистра (255 для 8-битных таймеров или 65535 для 16-битного). При переполнении, как и в нормальном режиме, устанавливается флаг переполнения TOVn, а также обновляется значение совпадения из регистра OCRnx (двойная буферизация).

Вывод OCnx в этом режиме может работать как нормальном режиме, так и в инверсном. В нормальном режиме он устанавливается в высокий уровень при TCNTn равном 0, и в низкий уровень при совпадении значений регистров TCNTn и OCRnx. В инверсном режиме - наоборот.

Временная диаграмма работы таймера-счётчика в режиме быстрого ШИМ:

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

Для расчёта Частоты ШИМ можно применить формулу

Fpwm = Fclk / (N*256),

где Fclk равен тактовой частоте таймера-счётчика, а N равен коэффициенту предделителя (например, 1, 8, 32, 64, ...).

Если записать в регистр OCRnx значение половины верхней границы (127 для 8-битных счётчиков или 32767 для 16-битного), то логический уровень на выводе OCnx будет переключаться с половиной тактовой частоты таймера, так же, как и режиме CTC, но при этом можно использовать двойную буферизацию регистра OCRnx.

Значения, близкие к верхней и нижней границам TCNTn - это особый случай. Если записать в регистр OCRnx ноль, то напряжение на выводе OCnx в нормальном режиме будет изменяться краткими импульсами каждые 256 или 65536 тактов. А если записать 255 или 65535, то оно постоянно равно логической единице в нормальном режиме или нулю - в инверсном.

Пример использования таймера-счётчика в режиме быстрого ШИМ

В данном примере я с помощью потенциометра, подключенного ко входу Analog 0, буду управлять шириной импульсов на выводе OC2A.

Если соединить резистором 10К вывод Digital 11 (OC2A) платы Arduino UNO с выводом Digital 13, то можно будет управлять яркостью свечения встроенного светодиода.

В скетче используется библиотека VEduino.

Код скетча (скачать):

#include <ve_avr.h> // Используется библиотека VEduino


void setup()

{

setModeOutput(DEV_TIMER2_OCA); // Пин OC2A в режим вывода

DEV_TIMER2.setClockSelect(Prescaler2::Prescaler_8); // 16МГц / 8 = 2 МГц. Таймер-счётчик 2 будет

// увеличивать значение регистра TCNT2 на единицу

// каждые 100 наносекунд.

DEV_TIMER2.setWaveGenMode(Timer2::FastPWM); // Режим быстрого ШИМ таймера-счётчика

DEV_TIMER2.setCompOutModeA(Timer2::Clear); // Сбрасывать вывод OC2A при TCNT2 == OCR2A

}


void loop()

{

int potValue = analogRead(0); // Считать значение ширины импульса, заданное потенциометром

OCR2A = map(potValue, 0, 1023, 0, 255); // Задать значение регистра OCR2A

delay(100);

}

Пример использования таймера-счётчика в режиме быстрого ШИМ с вершиной в OCRnA

В данном примере я с помощью потенциометра, подключенного ко входу Ananlog 0, буду управлять частотой импульсов на выходе OC2A (пин 11 платы Arduino UNO).

Я задал тактирование таймера-счётчика 2 с предделителем /1024, что даёт частоты от 30,5 Гц при значении регистра OCR2A, равном 255, до 7812 Гц при значении, равном 0.

В скетче используется библиотека VEduino.

Код скетча (скачать):

#include <ve_avr.h> // Используется библиотека VEduino


void setup()

{

setModeOutput(DEV_TIMER2_OCA); // Пин OC2A в режим вывода

DEV_TIMER2.setClockSelect(Prescaler2::Prescaler_1024); // 16МГц / 1024 = 15625 Гц. Таймер-счётчик 2 будет

// увеличивать значение регистра TCNT2 на единицу

// каждые 64 микросекунды.

DEV_TIMER2.setWaveGenMode(Timer2::FastPWM_OCRA); // Режим быстрого ШИМ с вершиной OCR2A таймера-счётчика

DEV_TIMER2.setCompOutModeA(Timer2::Toggle); // Переключать вывод OC2A при TCNT2 == OCR2A

}


void loop()

{

int potValue = analogRead(0); // Считать значение частоты, заданное потенциометром

OCR2A = map(potValue, 0, 1023, 255, 0); // Задать значение регистра OCR2A

delay(100);

}