Режим ШИМ с коррекцией фазы

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

Поскольку изменение значения регистра TCNTn происходит не пилообразно, а то в сторону увеличения, то в сторону уменьшения, это даёт в результате вдвое больший период максимально-возможной частоты сигнала. Но для управления электродвигателями именно этот режим предпочтительнее, чем режим быстрого ШИМ.

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

Флаг прерывания TOVn в этом режиме устанавливается, когда регистр TCNTn равен 0.

Вывод OCnx переключается при совпадении регистров TCNTn и OCRnx. Когда значение регистра TCNTn увеличивается, состояние вывода OCnx переключается из логического нуля в единицу, и наоборот, когда значение регистра уменьшается. Он также может работать как в нормальном режиме вывода, так и в инверсном.

Если регистр OCRnx имеет значение 255 (65535) или 0, то вывод OCnx постоянно пребывает либо в состоянии логической единицы, либо в состоянии логического нуля.

В начале второго периода на диаграмме изображено переключение состояния вывода, хотя совпадения регистров TCNTn и OCRnx не происходит. Это переключение происходит для того, чтобы обеспечить корректность фазы относительно нуля. Такое переключение происходит в режиме ШИМ с коррекцией фазы в двух случаях:

  • Регистр OCRnx изменяет значение с 255 (65535) на меньшее. Чтобы обеспечить симметрию относительно 0 при обновлении OCRnx таймер переключает состояние вывода.

  • При запуске таймера-счётчика регистр TCNTn имеет значение, большее, чем OCRnx.

Частота ШИМ для этого режима может быть рассчитана по формуле

Fpwm = Fclk / (N*510),

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

При чтении документации лично я сделал вывод, что если в качестве верхней границы в этом режиме используется значение регистра OCRnx, то переключение вывода OCnx будет происходить, только если его каждый раз менять во время очередного периода. Поскольку если значение регистра равно верхней границе, которая в данном случае задаётся значением OCRnx, то на выводе будет постоянно высокий или низкий уровень, в зависимости от режима вывода нормального либо инверсного.

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

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

Я задал тактирование таймера-счётчика 2 с предделителем /64, что даёт на выводе OC2A частоты от 244,86 Гц при значении регистра OCR2A, равном 255, до 124,92 кГц при значении, равном 0.

Скетч использует библиотеку VEduino.

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

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


void setup()

{

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

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

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

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

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

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

}


void loop()

{

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

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

delay(100);

}