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

Этот режим доступен для 16-битного таймера-счётчика 1 и только для вывода OC1A. В этом режиме таймер-счётчик также как и в режиме ШИМ с коррекцией фазы увеличивает значение регистра TCNTn на единицу на каждом такте до достижения верхней границы, а затем уменьшает до нуля, и т.д. Верхней границей также может быть 65535 либо значение OCR1A.

Отличие от режима ШИМ с коррекцией фазы состоит в том, что в этом режиме значение регистра OCR1A обновляется из буферного регистра не при TCNT1, равном верхней границе, а при TCNT1 равном 0.

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

Из диаграммы видно, что этот режим также отличается от режима ШИМ с коррекцией фазы тем, что в точке 0 вывод OC1A находится в нормальном режиме вывода в состоянии логической единицы, а не нуля. При совпадении значений регистров TCNT1 и OCR1A cостояние вывода OC1A переключается из логической единицы в ноль, когда значение регистра TCNT1 увеличивается, и из логического нуля в единицу, когда значение регистра TCNT1 уменьшается.

Частота ШИМ в этом режиме задаётся значением либо регистра OCR1А, либо регистра ICR1 (при использовании модуля захвата ввода). Минимальное разрешение составляет 2 бита, таким образом минимальное значение для этих регистров равно 3. Максимальное разрешение составляет 16 бит.

Разрешение ШИМ в битах может быть рассчитано по формуле

Rpwm = log(TOP+1) / log(2),

где TOP равен верхней границе ШИМ.

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

Fpwm = F clk/ (2*N*TOP),

где TOP равен верхней границе таймера, а N равен коэффициенту предделителя (то есть 1, 8, 64, 256 или 1024).

Регистр TCNT1 принимает значение верхней или нижней границы на 1 такт.

При изменении значения верхней границы, новое значение должно быть больше значений сравниваемых регистров, в противном случае совпадения между TCNT1A и OCR1A не произойдёт.

На диаграмме видно, что сигнал на выводе симметричен во всех периодах. Таким образом, импульсы в этом режиме фазово и частотно корректны.

Использование регистра ICR1 для задания верхней границы вполне применимо, если граница фиксирована. Если же она должна часто изменяться, то регистр OCR1A для этих целей предпочтительнее, поскольку его значение буферизировано.

Значение верхней границы и нуля в качестве значения регистра OCR1A - это особые случаи в этом режиме. При OCR1A равном верхней границе, вывод OC1A находится в состоянии высокого уровня в нормальном режиме вывода. При OCR1A равном нулю на выводе OC1A логический ноль. В инверсном режиме вывода - наоборот.

Если регистр OCR1A используется для задания верхней границы, на выводе OC1A генерируется ШИМ с 50%-ным циклом заполнения.

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

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

Поскольку таймер-счётчик 1 -- 16-битный, то я задал значение предделителя /1 (самое быстрое), что даёт частоты от 61 Гц при значении регистра OCR1A, равном 65535, до 4 МГц -- при значении, равном 1. При значении 0 на выводе OC1A будет просто высокий логический уровень.

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

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

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


void setup()

{

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

DEV_TIMER1.setClockSelect(TimerW::Prescaler_1); // 16МГц / 1 = 16 МГц. Таймер-счётчик 1 будет

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

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

DEV_TIMER1.setWaveGenMode(TimerW::PhaseFreqCorrect_OCRA); // Режим ШИМ с коррекцией фазы и частоты с вершиной OCR1A таймера-счётчика

DEV_TIMER1.setCompOutModeA(TimerW::Toggle); // Переключать вывод OC1A при TCNT1 == OCR1A

}


void loop()

{

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

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

delay(100);

}