10 июня 2022 г.
13912

ATmega328 - Таймеры и настройка ШИМ

Вместо n ставится номер таймер 0, 1 или 2
Вместо x ставится A или B

Общая информация

    Каждый таймер имеет регистр сравнения OCRnx. Когда значение в счётном регистре таймера TCNTn достигнет значения, находящегося в регистре сравнения, то, в зависимости от настроек могут возникнуть следующие события:
  • Прерывание по совпадению (включается в регистре TIMSKn)
  • Изменение состояния вывода OCnx (настраивается в регистре TCCRnA)

Таким образом прерывание обрабатывается или программно или происходит вывод сигнала на ножку микроконтроллера.

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

Режимы работы

    В этом разделе будут представлены формулы для расчета частоты ШИМ, где:
  • Частота - частота срабатывания прерывания и соответственно частота работы ШИМ;
  • Частота_мк - частота работы микроконтроллера;
  • Предделитель - число на которое делится частота работы микроконтроллера при счете таймером, задается в регистре TCCRxB битами CSx0, CSx1, CSx2;
  • Верхний_предел - число, до которого считает счетчик таймера. Зависит от разрядности таймера, у таймеров 0 и 2 составляет 256, а у таймера 1 - 65535. А так же в некоторых режимах может быть указан в регистре OCRnx или ICR1.

Normal (Обычный режим работы)

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

Формулы расчета:
Частота = Частота_мк / (Предделитель * Верхний_предел)
Верхний_предел = Частота_мк / (Предделитель * Частота)

Fast PWM (Быстрый ШИМ)

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

Ширина импульса (скважность) изменяется в зависимости от значения, записанного в регистры сравнения OCRnx.
Когда значение в счетчике достигает значения регистра сравнения, то соответствующий ему вывод OCnx сбрасывается в ноль.
Для 8-битного таймера, к примеру, если записать в регистр сравнения число 10, состояние логической единицы на выходе совпадения будет 10 тактов из 256 (для не инверсного режима).

Формулы расчета:
Частота = Частота_мк / (Предделитель * Верхний_предел)
Верхний_предел = Частота_мк / (Предделитель * Частота)

Если смотреть в |datasheet|
Для Timer0 это режимы № 3,7 в таблице 19-9 на странице 140
Для Timer1 это режим № 5,6,7,14,15 в таблице 20-6 на странице 171
Для Timer2 это режим № 3,7 в таблице 22-9 на странице 205

Phase Correct PWM (ШИМ с коррекцией фазы)

Работает похоже на Fast PWM, но тут счетчик считает по другому. Сначала от ноля до верхнего предела, потом от верхнего предела до ноля. Частота прерываний в этом режиме вдвое меньше, чем у Fast PWM при одинаковых настройках, из-за большего периода.
Есть вариант, где частота задается с помощью значения в регистре сравнения OCRxA.

Ширина импульса (скважность) изменяется в зависимости от значения, записанного в регистры сравнения OCRnx.

Формулы расчета:
Частота = Частота_мк / (Предделитель * Верхний_предел * 2)
Верхний_предел = Частота_мк / (Предделитель * Частота * 2)

Если смотреть в |datasheet|
Для Timer0 это режим № 1,5 в таблице 19-9 на странице 140
Для Timer1 это режим № 1,2,3,10,11 в таблице 20-6 на странице 171
Для Timer2 это режим № 1,5 в таблице 22-9 на странице 205

Clear Timer On Compare (Сброс при совпадении)

Работа отличается от других режимов. Этот режим позволяет контролировать выходную частоту, то есть при изменении значения в регистре сравнения OCRnx меняется не скважность, а частота. При этом на выходе сигнал всегда одинаковой скважности, но разной частоты. Для вывода сигнала на ножку микроконтроллера нужно, чтоб COM0xn и COM0xn были выставлены во второй режим работы, то есть состояние должно меняться на противоположное при совпадении. Чаще всего этот режим применяется, когда нужно отсчитывать периоды или генерировать прерывания с заданным промежутком времени.

Формула расчета частоты
Частота = Частота_мк / (Предделитель * Верхний_предел)
Верхний_предел = Частота_мк / (Предделитель * Частота)
При этом верхний передел задается в регистре OCRnx

Например, чтобы прерывание выполнялось 1 раз в секунду, то есть с частотой 1 Гц. Тогда при частоте работы микроконтроллера 16 МГц пусть предделитель будет равен 1024, таким образом, получится, что в OCR1A нужно записать число 15625.

Если смотреть в |datasheet|
Для Timer0 это режим № 2 в таблице 19-9 на странице 140
Для Timer1 это режим № 4 в таблице 20-6 на странице 171
Для Timer2 это режим № 2 в таблице 22-9 на странице 205

Phase and Frequency Correct PWM (ШИМ с коррекцией фазы и частоты) (Только в Timer1)

Этот режим есть только в Timer1.
В этом режиме возможно менять не только скважность, но и частоту сигнала. В остальном аналогичен режиму Phase Correct PWM.

Частота задается значением в регистре ICR1. Чем выше значение в ICR1, тем ниже частота.

Скважность регулируется значением в регистре OCR1A, она зависит от значения в ICR1, таким образом, что максимальное значение OCR1A равно значению в ICR1.

Формула расчета частоты
Частота = Частота_мк / (Предделитель * Верхний_предел * 2)
Верхний_предел = Частота_мк / (Предделитель * Частота * 2)

Если смотреть в |datasheet| это режим № 8,9 в таблице 20-6 на странице 171

Регистры таймеров

    Настройка и управление таймерами осуществляется с помощью регистров:
  • TCNTn - счетный регистр таймера/счетчика;
  • OCRnA - регистр сравнения A;
  • OCRnB - регистр сравнения B;
  • TIMSKn - регистр маски прерываний для таймера/счетчика;
  • TIFRn - регистр флагов прерываний для таймера/счетчика;
  • TCCRnA - регистр управления таймера;
  • TCCRnB - регистр управления таймера.

Таймер 0

Регистр TCCR0A

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00

COM0A1, COM0A0 — определяют сигнал, который будет на выводе OC0A (12) при совпадении значения счетного регистра TCNT0 со значением регистра сравнения OCR0A (при совпадении с А).

WGM02, WGM01, WGM00 установлены в обычный режим или режим CTC (без ШИМ)
COM0A1 COM0A0 Описание
0 0 Нормальная работа порта, OC0A отключен
0 1 Состояние на выходе OC0A меняется на противоположное при совпадении
1 0 На выходе OC0A установится логический 0
1 1 На выходе OC0A установится логическая 1
WGM02, WGM01, WGM00 установлены в режим Fast PWM или Phase Correct PWM
COM0A1 COM0A0 Описание
0 0 Нормальная работа порта, OC0A отключен
0 1 Если WGM02 = 0 - Нормальная работа порта, OC0A отключен
Если WGM02 = 1 - Состояние на выходе OC0A меняется на противоположное при совпадении
1 0 Сброс OC0A при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка OC0A в 1 при совпадении (инверсный режим)

COM0B1, COM0B0 — определяют сигнал, который будет на выводе OC0B (11) при совпадении значения счетного регистра TCNT0 со значением регистра сравнения OCR0B (при совпадении с B)

WGM02, WGM01, WGM00 установлены в обычный режим или режим CTC (без ШИМ)
COM0B1 COM0B0 Описание
0 0 Нормальная работа порта, OC0B отключен
0 1 Состояние на выходе OC0B меняется на противоположное при совпадении
1 0 На выходе OC0B установится логический 0
1 1 На выходе OC0B установится логическая 1
WGM02, WGM01, WGM00 установлены в режим Fast PWM или Phase Correct PWM
COM0B1 COM0B0 Описание
0 0 Нормальная работа порта, OC0B отключен
0 1 -
1 0 Сброс OC0B при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка OC0B в 1 при совпадении (инверсный режим)

WGM00, WGM01 — Waveform Generation Mode (Режим генерации формы сигнала). В сочетании с битом WGM02, расположенным в регистре TCCR0B, эти биты управляют последовательностью подсчета счетчика, источником максимального (верхнего) значения счетчика и типом используемой формы сигнала.

В столбце Top указывается до какого верхнего значения считает таймер, при Top = 0xFF счет идет до 255, при Top = OCR0A счет идет до значения в OCR0A, которое не может быть больше 255.
В столбце TOV Flag Set on указывается при достижении какого значения устанавливается флаг прерывания.

MAX = 0xFF, BOTTOM = 0x00

WGM02 WGM01 WGM00 Режим TOP Update of OCR0x at TOV Flag Set on
0 0 0 0 Normal (Нормальный) 0xFF Immediate MAX
1 0 0 1 Phase Correct PWM (ШИМ с коррекцией фазы) 0xFF TOP BOTTOM
2 0 1 0 Clear Timer On Compare (Сброс по совпадению) OCR0A Immediate MAX
3 0 1 1 Fast PWM (Быстрый ШИМ) 0xFF BOTTOM MAX
4 1 0 0 - - - -
5 0 0 1 Phase Correct PWM (ШИМ с коррекцией фазы) OCR0A TOP BOTTOM
6 1 1 0 - - - -
7 0 0 1 Fast PWM (Быстрый ШИМ) OCR0A BOTTOM TOP

Регистр TCCR0B

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название FOC0A FOC0B - - WGM02 CS02 CS01 CS00
CS02, CS01, CS00 — устанавливают режим тактирования и предделителя тактовой частоты
CS02 CS01 CS00 Описание
0 0 0 Таймер выключен
0 0 1 Предделитель 1 (частота не делится)
0 1 0 Предделитель 8
0 1 1 Предделитель 64
1 0 0 Предделитель 256
1 0 1 Предделитель 1024
1 1 0 Внешний источник (pin T0) по спаду
1 1 1 Внешний источник (pin T0) по подъему

FOC0A, FOC0B — принудительно устанавливают значение на выводах OC0A и OC0B.

Регистр TIMSK0

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название - - - - - OCIE0B OCIE0A TOIE0

OCIE0B, OCIE0A — разрешают прерывания при совпадении с A и B. Если в эти биты записаны 1, то будут происходить прерывания, которые нужно обрабатывать функцией ISR, а если записаны 0, прерывания от таймера/счетчика будут запрещены и можно сделать только вывод ШИМ-сигнала на соответствующий вывод. Частота прерываний в два раза выше, чем частота ШИМ.

TOIE0 — разрешает прерывание по переполнению при установке 1.

Прерывания обрабатываются с помощью функций
ISR (TIMER0_COMPA_vect){
/*Тело функции*/}

ISR (TIMER0_COMPB_vect){
/*Тело функции*/}

Шаблон

    Для включения ШИМ сигнала нужно настроить
  • Порты на вывод
  • Режим вывода
  • Режим генерации сигнала
  • Предделитель
  • Скважность
Из каждой части нужно выбрать необходимое
cli(); //Отключение глобальных прерываний
//-----------------------Порты на вывод
DDRD |= (1 << PORTD6);  //OC0A (12)
DDRD |= (1 << PORTD5);  //OC0B (11)
//-----------------------Обнуление регистров
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
//-----------------------Режим вывода (только для ШИМ)
//OC0A
TCCR0A |= (1 << COM0A1);                 //Не инверсный режим OC0A (основной)
TCCR0A |= (1 << COM0A1) | (1 << COM0A0); //Инверсный режим OC0A
TCCR0A |= (1 << COM0A0);                 //Переключение состояния
//OC0B
TCCR0A |= (1 << COM0B1);                 //Не инверсный режим OC0B (основной)
TCCR0A |= (1 << COM0B1) | (1 << COM0B0); //Инверсный режим OC0B
TCCR0A |= (1 << COM0B0);                 //Переключение состояния
    
//----------------------Режим генерации сигнала
TCCR0A |= (1 << WGM00); 
    //Режим 1: Phase Correct PWM (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 3 режима
    //скважность регулируется OCR0A и OCR0B
    //частота регулируется предделителем
    //1 - 31,4 кГЦ, 8 - 3,9 кГЦ, 64 - 490 ГЦ, 256 - 122 ГЦ, 1024 - 30 ГЦ
    //доступны два канала: OC0A, OC0B

TCCR0A |= (1 << WGM01); 
    //Режим 2: Clear Timer On Compare (Сброс по совпадению)
    //вывод на ножку микроконтроллера осуществляется только когда Режим вывода настроен на переключение состояния при совпадении
    //то есть TCCR0A |= (1 << COM0B0);
    //в этом режиме на выходе всегда будет меандр, скважность не регулируется
    //частота регулируется предделителем и OCR0A
    //доступен один канал: OC0B
    //Частота рассчитывается по формуле: 
      //Частота = Частота_мк / (Предделитель * OCR0A * 2)
    //А значение в OCR0A, если известна необходимая частота - по формуле: 
      //OCR0A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR0A тем меньше частота

TCCR0A |= (1 << WGM00) | (1 << WGM01); 
    //Режим 3: Fast PWM (Быстрый ШИМ)
    //скважность регулируется OCR0A и OCR0B 
    //частота регулируется предделителем
    //1 - 62,5 кГЦ, 8 - 7,8 кГЦ, 64 - 976 ГЦ, 256 - 244 ГЦ, 1024 - 61 ГЦ
    //доступны два канала: OC0A, OC0B

TCCR0A |= (1 << WGM00); 
TCCR0B |= (1 << WGM02); 
    //Режим 5: Phase Correct PWM (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 7 режима
    //частота регулируется предделителем и OCR0A, в OCR0A записывается верхний предел
    //скважность регулируется OCR0B, при этом значение в OCR0B не может
    //быть больше значения в OCR0A, при OCR0A = OCR0B / 2 будет меандр
    //доступен один канал: OC0B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR0A * 2)
    //А значение в OCR0A, если известна необходимая частота - по формуле: 
        //OCR0A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR0A тем меньше частота

TCCR0A |= (1 << WGM00) | (1 << WGM01);
TCCR0B |= (1 << WGM02); 
    //Режим 7: Fast PWM (Быстрый ШИМ)
    //частота регулируется предделителем и OCR0A, в OCR0A записывается верхний предел
    //скважность регулируется OCR0B, при этом значение в OCR0B не может
    //быть больше значения в OCR0A, при OCR0A = OCR0B / 2 будет меандр
    //доступен один канал: OC0B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR0A)
    //А значение в OCR0A, если известна необходимая частота - по формуле: 
        //OCR0A = Частота_мк / (Предделитель * Частота)
    //Чем больше значение в OCR0A тем меньше частота

//----------------------Предделитель
TCCR0B |= (1 << CS00);              //1
TCCR0B |= (1 << CS01);              //8
TCCR0B |= (1 << CS01)|(1 << CS00);  //64
TCCR0B |= (1 << CS02);              //256
TCCR0B |= (1 << CS02)|(1 << CS00);  //1024 

//----------------------Прерывание по совпадению (только если нужна генерация прерывания)
//Частота прерываний в два раза выше, чем частота ШИМ
TIMSK0 |= (1 << OCIE0A);
TIMSK0 |= (1 << OCIE0B);

//----------------------Скважность
//Значение записываемое в регистр должно быть от 0 до верхнего предела
OCR0A = 128;
OCR0B = 128;

sei(); //Включение глобальных прерываний

//-----------------------Обработка прерываний (только если включены прерывания)
ISR (TIMER0_COMPA_vect){
  /*Тело функции*/}
  
ISR (TIMER0_COMPB_vect){
  /*Тело функции*/}

Таймер 2

Регистр TCCR2A

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название COM2A1 COM2A0 COM2B1 COM2B0 - - WGM21 WGM20

COM2A1, COM2A0 — определяют сигнал, который будет на выводе OC2A (17) при совпадении значения счетного регистра TCNT2 со значением регистра сравнения OCR2A (при совпадении с А).

WGM22, WGM21, WGM20 установлены в обычный режим или режим CTC (без ШИМ)
COM2A1 COM2A0 Описание
0 0 Нормальная работа порта, OC2A отключен
0 1 Состояние на выходе OC2A меняется на противоположное при совпадении
1 0 На выходе OC2A установится логический 0
1 1 На выходе OC2A установится логическая 1
WGM21, WGM20 установлены в режим Fast PWM или Phase Correct PWM
COM2A1 COM2A0 Описание
0 0 Нормальная работа порта, OC2A отключен
0 1 WGM22 = 0 - Нормальная работа порта, OC2A отключен
WGM22 = 1 - Состояние на выходе OC2A меняется на противоположное при совпадении
1 0 Сброс вывода OC2A в 0 при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка вывода OC2A в 1 при совпадении (инверсный режим)

COM2B1, COM2B0 — определяют сигнал, который будет на выводе OC2B (5) при совпадении значения счетного регистра TCNT2 со значением регистра сравнения OCR2B (при совпадении с B)

WGM22, WGM21, WGM20 установлены в обычный режим или режим CTC (без ШИМ)
COM2B1 COM2B0 Описание
0 0 Нормальная работа порта, OC2B отключен
0 1 Состояние на выходе OC2B меняется на противоположное при совпадении
1 0 На выходе OC2B установится логический 0
1 1 На выходе OC2B установится логическая 1
WGM21, WGM20 установлены в режим Fast PWM или Phase Correct PWM
COM2B1 COM2B0 Описание
0 0 Нормальная работа порта, OC2B отключен
0 1 -
1 0 Сброс вывода OC2B в 0 при совпадении (не инверсный режим) (используется чаще всего)
1 1 установка вывода OC2B в 1 при совпадении (инверсный режим)

WGM20, WGM21 — Waveform Generation Mode (Режим Генерации формы Сигнала) В сочетании с битом WGM22, расположенным в регистре TCCR2B, эти биты управляют последовательностью подсчета счетчика, источником максимального (верхнего) значения счетчика и типом используемой формы сигнала.

В столбце Top указывается до какого значения считает таймер, при Top = 0xFF счет идет до 255, при Top = OCR2A счет идет до значения в OCR2A
В столбце TOV Flag Set on указывается при достижении какого значения устанавливается флаг прерывания.

MAX = 0xFF, BOTTOM = 0x00

WGM22 WGM21 WGM20 Режим TOP Update of OCR0x at TOV Flag Set on
0 0 0 0 Normal (Нормальный) 0xFF Immediate MAX
1 0 0 1 Phase Correct PWM (ШИМ с коррекцией фазы) 0xFF TOP BOTTOM
2 0 1 0 Clear Timer On Compare (Сброс по совпадению) OCR2A Immediate MAX
3 0 1 1 Fast PWM (Быстрый ШИМ) 0xFF BOTTOM MAX
4 1 0 0 - - - -
5 0 0 1 Phase Correct PWM (ШИМ с коррекцией фазы) OCR2A TOP BOTTOM
6 1 1 0 - - - -
7 0 0 1 Fast PWM (Быстрый ШИМ) OCR2A BOTTOM TOP

Регистр TCCR2B

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название FOC2A FOC2B - - WGM22 CS22 CS21 CS20
CS22, CS21, CS20 — устанавливают режим тактирования и предделителя тактовой частоты
CS22 CS21 CS20 Описание
0 0 0 Таймер выключен
0 0 1 Предделитель 1 (частота не делится)
0 1 0 Предделитель 8
0 1 1 Предделитель 32
1 0 0 Предделитель 64
1 0 1 Предделитель 128
1 1 0 Предделитель 256
1 1 1 Предделитель 1024

FOC2A, FOC2B — принудительно устанавливают значение на выводах OC2A и OC2B.

Регистр TIMSK2

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название - - - - - OCIE2B OCIE2A TOIE2

OCIE2B, OCIE2A — разрешают прерывания при совпадении с A и B. Если в эти биты записаны 1, то будут происходить прерывания, которые нужно обрабатывать функцией ISR, а если записаны 0, прерывания от таймера/счетчика будут запрещены и можно сделать только вывод ШИМ-сигнала на соответствующий вывод. Частота прерываний в два раза выше, чем частота ШИМ.

TOIE2 — разрешает прерывание по переполнению при установке 1.

Прерывания обрабатываются с помощью функций
ISR (TIMER2_COMPA_vect){
/*Тело функции*/}

ISR (TIMER2_COMPB_vect){
/*Тело функции*/}

Шаблон

    Для включения ШИМ сигнала нужно настроить
  • Порты на вывод
  • Режим вывода
  • Режим генерации сигнала
  • Предделитель
  • Скважность
Из каждой части нужно выбрать необходимое
cli(); //Отключение глобальных прерываний
//-----------------------Порты на вывод
DDRB |= (1 << PORTB3);  //OC2A (17)
DDRD |= (1 << PORTD3);  //OC2B (5)
//-----------------------Обнуление регистров
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
//-----------------------Режим вывода (только для ШИМ)
//OC2A
TCCR2A |= (1 << COM2A1);                 //Не инверсный режим OC2A (основной)
TCCR2A |= (1 << COM2A1) | (1 << COM2A0); //Инверсный режим OC2A
TCCR2A |= (1 << COM2A0);                 //Переключение состояния
//OC2B
TCCR2A |= (1 << COM2B1);                 //Не инверсный режим OC2B (основной)
TCCR2A |= (1 << COM2B1) | (1 << COM2B0); //Инверсный режим OC2B
TCCR2A |= (1 << COM2B0);                 //Переключение состояния
    
//----------------------Режим генерации сигнала
TCCR2A |= (1 << WGM20); 
    //Режим 1: Phase Correct PWM (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 3 режима
    //скважность регулируется OCR0A и OCR0B
    //частота регулируется предделителем
    //1 - 31,4 кГЦ, 8 - 3,9 кГЦ, 64 - 490 ГЦ, 256 - 122 ГЦ, 1024 - 30 ГЦ
    //доступны два канала: OC0A, OC0B

TCCR2A |= (1 << WGM21); 
    //Режим 2: Clear Timer On Compare (Сброс по совпадению)
    //вывод на ножку микроконтроллера осуществляется только когда Режим вывода настроен на переключение состояния при совпадении
    //то есть TCCR2A |= (1 << COM2B0);
    //в этом режиме на выходе всегда будет меандр, скважность не регулируется
    //частоту можно регулировать изменяя значение в OCR2A
    //доступен один канал: OC2B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR2A * 2)
    //А значение в OCR2A, если известна необходимая частота - по формуле: 
        //OCR2A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR2A тем меньше частота

TCCR2A |= (1 << WGM20) | (1 << WGM21); 	
    //Режим 3: Fast PWM (Быстрый ШИМ) 
    //скважность регулируется OCR2A и OCR0B 
    //а частота регулируется предделителем
    //1 - 62,5 кГЦ, 8 - 7,8 кГЦ, 64 - 976 ГЦ, 256 - 244 ГЦ, 1024 - 61 ГЦ
    //доступны два канала: OC2A, OC2B

TCCR2A |= (1 << WGM20); 
TCCR2B |= (1 << WGM22); 
    //Режим 5: Phase Correct PWM (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 7 режима
    //частота регулируется предделителем и OCR2A, в OCR2A записывается верхний предел
    //скважность регулируется OCR2B, при этом значение в OCR2B не может
    //быть больше значения в OCR2A, при OCR2A = OCR2B / 2 будет меандр
    //доступен один канал: OC2B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR2A * 2)
    //А значение в OCR2A, если известна необходимая частота - по формуле: 
        //OCR2A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR2A тем меньше частота

TCCR2A |= (1 << WGM20) | (1 << WGM21);
TCCR2B |= (1 << WGM22);
  //Режим 7: Fast PWM (Быстрый ШИМ)
  //частота регулируется предделителем и OCR2A, в OCR2A записывается верхний предел
  //скважность регулируется OCR2B, при этом значение в OCR2B не может
  //быть больше значения в OCR2A, при OCR2A = OCR2B / 2 будет меандр
  //доступен один канал: OC2B
  //Частота рассчитывается по формуле: 
      //Частота = Частота_мк / (Предделитель * OCR2A)
  //А значение в OCR2A, если известна необходимая частота - по формуле: 
      //OCR2A = Частота_мк / (Предделитель * Частота)
  //Чем больше значение в OCR2A тем меньше частота

//----------------------Предделитель
TCCR2B |= (1 << CS20);              //1
TCCR2B |= (1 << CS21);              //8
TCCR2B |= (1 << CS21)|(1 << CS20);  //32
TCCR2B |= (1 << CS22);              //64
TCCR2B |= (1 << CS22)|(1 << CS20);  //128
TCCR2B |= (1 << CS22)|(1 << CS21);  //256
TCCR2B |= (1 << CS22)|(1 << CS21)|(1 << CS20);  //1024

//----------------------Прерывание по совпадению (только если нужна генерация прерывания)
//Частота прерываний в два раза выше, чем частота ШИМ
TIMSK2 |= (1 << OCIE2A);
TIMSK2 |= (1 << OCIE2B);

//----------------------Скважность
//Значение записываемое в регистр должно быть от 0 до верхнего предела
OCR2A = 128;
OCR2B = 128;

sei(); //Включение глобальных прерываний

//-----------------------Обработка прерываний (только если включены прерывания)
ISR (TIMER2_COMPA_vect){
  /*Тело функции*/}
  
ISR (TIMER2_COMPB_vect){
  /*Тело функции*/}

Таймер 1

Регистр TCCR1A

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название COM1A1 COM1A0 COM1B1 COM1B0 - - WGM11 WGM10

COM1A1, COM1A0 — определяют сигнал, который будет на выводе OC1A (15) при совпадении значения счетного регистра TCNT1 со значением регистра сравнения OCR1A (при совпадении с А).

WGM13, WGM12, WGM11, WGM10 установлены в обычный режим или режим CTC (без ШИМ)
COM1A1 COM1A0 Описание
0 0 Нормальная работа порта, OC1A отключен
0 1 Состояние на выходе OC1A меняется на противоположное при совпадении
1 0 На выходе OC1A установится логический 0
1 1 На выходе OC1A установится логическая 1
WGM13, WGM12, WGM11, WGM10 установлены в режим Fast PWM
COM1A1 COM1A0 Описание
0 0 Нормальная работа порта, OC1A отключен
0 1 При режиме 14 или 15 состояние на выходе OC1A меняется на противоположное при совпадении
При остальных режимах OC1A отключен
1 0 Сброс OC1A при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка вывода OC1A в 1 при совпадении (инверсный режим)
WGM13, WGM12, WGM11, WGM10 установлены в режим Phase Correct PWM или Phase and Frequency Correct PWM
COM1A1 COM1A0 Описание
0 0 Нормальная работа порта, OC1A отключен
0 1 При режиме 9 или 11 состояние на выходе OC1A меняется на противоположное при совпадении
При остальных режимах OC1A отключен
1 0 Сброс OC1A при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка OC1A в 1 при совпадении (инверсный режим)

COM1B1, COM1B0 — определяют сигнал, который будет на выводе OC1B (16) при совпадении значения счетного регистра TCNT1 со значением регистра сравнения OCR1B (при совпадении с B).

WGM13, WGM12, WGM11, WGM10 установлены в обычный режим или режим CTC (без ШИМ)
COM1B1 COM1B0 Описание
0 0 Нормальная работа порта, OC1B отключен
0 1 Состояние на выходе OC1B меняется на противоположное при совпадении
1 0 На выходе OC1B установится логический 0
1 1 На выходе OC1B установится логическая 1
WGM13, WGM12, WGM11, WGM10 установлены в режим Fast PWM или Phase Correct PWM или Phase and Frequency Correct PWM
COM1B1 COM1B0 Описание
0 0 Нормальная работа порта, OC1B отключен
0 1 Нормальная работа порта, OC1B отключен
1 0 Сброс OC1B при совпадении (не инверсный режим) (используется чаще всего)
1 1 Установка OC1B в 1 при совпадении (инверсный режим)

WGM10, WGM11 — Waveform Generation Mode (Режим Генерации формы Сигнала). В сочетании с битами WGM12 и WGM13, расположенными в регистре TCCR1B, эти биты управляют последовательностью подсчета счетчика, источником максимального (верхнего) значения счетчика и типом используемой формы сигнала.

    В столбце Top указывается до какого значения считает таймер:
  • при Top = 0xFF счет идет до 255
  • при Top = 0x01FF счет идет до 511
  • при Top = 0x03FF счет идет до 1023
  • при Top = 0xFFFF счет идет до 65535
  • при Top = OCR1A счет идет до значения в OCR1A
  • при Top = ICR1 счет идет до значения в ICR1

В столбце TOV Flag Set on указывается при достижении какого значения устанавливается флаг прерывания.

WGM13 WGM12 WGM11 WGM10 Режим TOP Update of OCR0x at TOV Flag Set on
0 0 0 0 0 Normal (Нормальный) 0xFFFF Immediate MAX
1 0 0 0 1 Phase Correct PWM 8-bit (ШИМ с коррекцией фазы) 0x00FF TOP BOTTOM
2 0 0 1 0 Phase Correct PWM 9-bit (ШИМ с коррекцией фазы) 0x01FF TOP BOTTOM
3 0 0 1 1 Phase Correct PWM 10-bit (ШИМ с коррекцией фазы) 0x03FF TOP BOTTOM
4 0 1 0 0 Clear Timer On Compare (Сброс по совпадению) OCR1A Immediate MAX
5 0 1 0 1 Fast PWM 8-bit (Быстрый ШИМ) 0x00FF BOTTOM TOP
6 0 1 1 0 Fast PWM 9-bit (Быстрый ШИМ) 0x01FF BOTTOM TOP
7 0 1 1 1 Fast PWM 10-bit (Быстрый ШИМ) 0x03FF BOTTOM TOP
8 1 0 0 0 Phase and Frequency Correct PWM (ШИМ с коррекцией фазы и частоты) ICR1 BOTTOM BOTTOM
9 1 0 0 1 Phase and Frequency Correct PWM (ШИМ с коррекцией фазы и частоты) OCR1A BOTTOM BOTTOM
10 1 0 1 0 Phase Correct PWM (ШИМ с коррекцией фазы) ICR1 TOP BOTTOM
11 1 0 1 1 Phase Correct PWM (ШИМ с коррекцией фазы) OCR1A TOP BOTTOM
12 1 1 0 0 Clear Timer On Compare (Сброс по совпадению) ICR1 Immediate MAX
13 1 1 0 1 - - - -
14 1 1 1 0 Fast PWM (Быстрый ШИМ) ICR1 BOTTOM TOP
15 1 1 1 1 Fast PWM (Быстрый ШИМ) OCR1A BOTTOM TOP

Регистр TCCR1B

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
CS12, CS11, CS10 — устанавливают режим тактирования и предделителя тактовой частоты
CS12 CS11 CS10 Описание
0 0 0 Таймер выключен
0 0 1 Предделитель 1 (частота не делится)
0 1 0 Предделитель 8
0 1 1 Предделитель 64
1 0 0 Предделитель 256
1 0 1 Предделитель 1024
1 1 0 Внешний источник (pin T1) по спаду
1 1 1 Внешний источник (pin T1) по подъему

Регистр TCCR1C

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название FOC1A FOC1B - - - - - -

FOC1A, FOC1B — принудительно устанавливают значение на выводах OC1A и OC1B.

Регистр TIMSK1

Включает в себя следующее
Номер бита 7 6 5 4 3 2 1 0
Название - - ICIE - - OCIE1B OCIE1A TOIE1

OCIE1B, OCIE1A — разрешают прерывания при совпадении с A и B. Если в эти биты записаны 1, то будут происходить прерывания, которые нужно обрабатывать функцией ISR, а если записаны 0, прерывания от таймера/счетчика будут запрещены и можно сделать только вывод ШИМ-сигнала на соответствующий вывод. Частота прерываний в два раза выше, чем частота ШИМ.

TOIE1 — разрешает прерывание по переполнению при установке 1

Прерывания обрабатываются с помощью функций
ISR (TIMER1_COMPA_vect){
/*Тело функции*/}

ISR (TIMER1_COMPB_vect){
/*Тело функции*/}

Шаблон

    Для включения ШИМ сигнала нужно настроить
  • Порты на вывод
  • Режим вывода
  • Режим генерации сигнала
  • Предделитель
  • Скважность
Из каждой части нужно выбрать необходимое
cli(); //Отключение глобальных прерываний
//-----------------------Порты на вывод
DDRB |= (1 << PORTB1);  //OC1A (15)
DDRB |= (1 << PORTB2);  //OC1B (16)
//-----------------------Обнуление регистров
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
//-----------------------Режим вывода (только для ШИМ)
//OC1A
TCCR1A |= (1 << COM1A1);                 //Не инверсный режим OC1A (основной)
TCCR1A |= (1 << COM1A1) | (1 << COM1A0); //Инверсный режим OC1A
TCCR1A |= (1 << COM1A0);                 //Переключение состояния
//OC1B
TCCR1A |= (1 << COM1B1);                 //Не инверсный режим OC1B (основной)
TCCR1A |= (1 << COM1B1) | (1 << COM1B0); //Инверсный режим OC1B
TCCR1A |= (1 << COM1B0);                 //Переключение состояния
    
//----------------------Режим генерации сигнала
TCCR1A |= (1 << WGM10); 
    //Режим 1: TOP = 0xFF (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 5 режима
    //скважность регулируется OCR1A и OCR1B
    //частота регулируется предделителем
    //1 - 31,4 кГЦ, 8 - 3,9 кГЦ, 64 - 490 ГЦ, 256 - 122 ГЦ, 1024 - 30 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1A |= (1 << WGM11); 
    //Режим 2: Phase Correct PWM, TOP = 0x01FF (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 6 режима
    //скважность регулируется OCR1A и OCR1B
    //частота регулируется предделителем
    //1 - 15,6 кГЦ, 8 - 977 кГЦ, 64 - 244 ГЦ, 256 - 61 ГЦ, 1024 - 15 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1A |= (1 << WGM11) | (1 << WGM10); 
    //Режим 3: Phase Correct PWM, TOP = 0x03FF (ШИМ с коррекцией фазы)
    //частота в 2 раза ниже чем у 7 режима
    //скважность регулируется OCR1A и OCR1B
    //частота регулируется предделителем
    //1 - 7,8 кГЦ, 8 - 1,9 кГЦ, 64 - 122 ГЦ, 256 - 30 ГЦ, 1024 - 7 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1B |= (1 << WGM12);
    //Режим 4: Clear Timer On Compare (Сброс по совпадению)
    //вывод на ножку микроконтроллера осуществляется только когда режим вывода настроен на переключение состояния при совпадении
    //то есть TCCR1A |= (1 << COM1B0);
    //в этом режиме на выходе всегда будет меандр, скважность не регулируется
    //частота регулируется предделителем и OCR1A
    //доступен один канал: OC1B
    //Частота рассчитывается по формуле: 
      //Частота = Частота_мк / (Предделитель * OCR1A * 2)
    //А значение в OCR1A, если известна необходимая частота - по формуле: 
      //OCR1A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR1A тем меньше частота
    //Например при предделителе 8, значении OCR1A = 100 получится частота 10 кГц

TCCR1A |= (1 << WGM10);
TCCR1B |= (1 << WGM12);
    //Режим 5: Fast PWM, TOP = 0xFF (Быстрый ШИМ)
    //скважность регулируется OCR1A и OCR1B 
    //частота регулируется предделителем
    //1 - 62,5 кГЦ, 8 - 7,8 кГЦ, 64 - 976 ГЦ, 256 - 244 ГЦ, 1024 - 30 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12);
    //Режим 6: Fast PWM, TOP = 0x01FF (Быстрый ШИМ)
    //скважность регулируется OCR1A и OCR1B 
    //частота регулируется предделителем
    //1 - 31,4 кГЦ, 8 - 3,9 кГЦ, 64 - 490 ГЦ, 256 - 122 ГЦ, 1024 - 30 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1A |= (1 << WGM11) | (1 << WGM10);
TCCR1B |= (1 << WGM12);
    //Режим 7: Fast PWM, TOP = 0x03FF (Быстрый ШИМ)
    //скважность регулируется OCR1A и OCR1B 
    //частота регулируется предделителем
    //1 - 15,6 кГЦ, 8 - 977 кГЦ, 64 - 244 ГЦ, 256 - 61 ГЦ, 1024 - 15 ГЦ
    //доступны два канала: OC1A, OC1B

TCCR1B |= (1 << WGM13);
    //Режим 8: Phase and Frequency Correct PWM (ШИМ с коррекцией фазы и частоты)
    //частота регулируется предделителем и ICR1, в ICR1 записывается верхний предел
    //скважность регулируется OCR1A и OCR1B, при этом значение в OCR1A и OCR1B не может
    //быть больше значения в ICR1, при OCR1A = ICR1 / 2 будет меандр
    //доступны два канала: OC1A, OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * ICR1 * 2)
    //А значение в ICR1, если известна необходимая частота - по формуле: 
        //ICR1 = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в ICR1 тем меньше частота
    //Например при предделителе 8, значении ICR1 = 100 получится частота 10 кГц,
    //при этом значение OCR1A и OCR1B должно быть в пределах от 0 до 100

TCCR1A |= (1 << WGM10);
TCCR1B |= (1 << WGM13);
    //Режим 9: Phase and Frequency Correct PWM (ШИМ с коррекцией фазы и частоты)
    //частота регулируется предделителем и OCR1A, в OCR1A записывается верхний предел
    //скважность регулируется OCR1B, при этом значение в OCR1B не может
    //быть больше значения в OCR1A, при OCR1B = OCR1A / 2 будет меандр
    //доступен один канал: OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR1A * 2)
    //А значение в OCR1A, если известна необходимая частота - по формуле: 
        //OCR1A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR1A тем меньше частота
    //Например при предделителе 8, значении OCR1A = 100 получится частота 10 кГц,
    //при этом значение OCR1B должно быть в пределах от 0 до 100

TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM13);
    //Режим 10: Phase Correct PWM (ШИМ с коррекцией фазы), по сути тоже самое, что и 8 режим
    //частота регулируется предделителем и ICR1, в ICR1 записывается верхний предел
    //скважность регулируется OCR1A и OCR1B, при этом значение в OCR1A и OCR1B не может
    //быть больше значения в ICR1, при OCR1A = ICR1 / 2 будет меандр
    //доступны два канала: OC1A, OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * ICR1 * 2)
    //А значение в ICR1, если известна необходимая частота - по формуле: 
        //ICR1 = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в ICR1 тем меньше частота
    //Например при предделителе 8, значении ICR1 = 100 получится частота 10 кГц,
    //при этом значение OCR1A и OCR1B должно быть в пределах от 0 до 100

TCCR1A |= (1 << WGM10) | (1 << WGM11);
TCCR1B |= (1 << WGM13);
    //Режим 11: Phase Correct PWM (ШИМ с коррекцией фазы), по сути тоже самое, что и 9 режим
    //частота регулируется предделителем и OCR1A, в OCR1A записывается верхний предел
    //скважность регулируется OCR1B, при этом значение в OCR1B не может
    //быть больше значения в OCR1A, при OCR1B = OCR1A / 2 будет меандр
    //доступен один канал: OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR1A * 2)
    //А значение в OCR1A, если известна необходимая частота - по формуле: 
        //OCR1A = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в OCR1A тем меньше частота
    //Например при предделителе 8, значении OCR1A = 100 получится частота 10 кГц,
    //при этом значение OCR1B должно быть в пределах от 0 до 100

TCCR1B |= (1 << WGM12) | (1 << WGM13);
    //Режим 12: Clear Timer On Compare (Сброс по совпадению)
    //вывод на ножку микроконтроллера осуществляется только когда Режим вывода настроен на переключение состояния при совпадении
    //то есть TCCR1A |= (1 << COM1A0) | (1 << COM0B0);
    //в этом режиме на выходе всегда будет меандр, скважность не регулируется
    //частота регулируется предделителем и ICR1
    //доступны два канала: OC1A, OC1B
    //Частота рассчитывается по формуле: 
      //Частота = Частота_мк / (Предделитель * ICR1 * 2)
    //А значение в ICR1, если известна необходимая частота - по формуле: 
      //ICR1 = Частота_мк / (Предделитель * Частота * 2)
    //Чем больше значение в ICR1 тем меньше частота
    //Например при предделителе 8, значении ICR1 = 100 получится частота 10 кГц

TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12) | (1 << WGM13);
    //Режим 14: Fast PWM (Быстрый ШИМ)
    //частота регулируется предделителем и ICR1, в ICR1 записывается верхний предел
    //скважность регулируется OCR1A и OCR1B, при этом значение в OCR1A и OCR1B не может
    //быть больше значения в ICR1, при OCR1A = ICR1 / 2 будет меандр
    //доступны два канала: OC1A, OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * ICR1)
    //А значение в ICR1, если известна необходимая частота - по формуле: 
        //ICR1 = Частота_мк / (Предделитель * Частота)
    //Чем больше значение в ICR1 тем меньше частота
    //Например при предделителе 8, значении ICR1 = 100 получится частота 20 кГц,
    //при этом значение OCR1A и OCR1B должно быть в пределах от 0 до 100

TCCR1A |= (1 << WGM10) | (1 << WGM11);
TCCR1B |= (1 << WGM12) | (1 << WGM13);
    //Режим 15: Fast PWM (Быстрый ШИМ)
    //частота регулируется предделителем и OCR1A, в OCR1A записывается верхний предел
    //скважность регулируется OCR1B, при этом значение в OCR1B не может
    //быть больше значения в OCR1A, при OCR1B = OCR1A / 2 будет меандр
    //доступен один канал: OC1B
    //Частота рассчитывается по формуле: 
        //Частота = Частота_мк / (Предделитель * OCR1A)
    //А значение в OCR1A, если известна необходимая частота - по формуле: 
        //OCR1A = Частота_мк / (Предделитель * Частота)
    //Чем больше значение в OCR1A тем меньше частота
    //Например при предделителе 8, значении OCR1A = 100 получится частота 20 кГц,
    //при этом значение OCR1A и OCR1B должно быть в пределах от 0 до 100

//----------------------Предделитель
TCCR1B |= (1 << CS10);              //1
TCCR1B |= (1 << CS11);              //8
TCCR1B |= (1 << CS11)|(1 << CS10);  //64
TCCR1B |= (1 << CS12);              //256
TCCR1B |= (1 << CS12)|(1 << CS10);  //1024

//----------------------Прерывание по совпадению (только если нужна генерация прерывания)
//Частота прерываний в два раза выше, чем частота ШИМ
TIMSK1 |= (1 << OCIE1A);
TIMSK1 |= (1 << OCIE1B);

//----------------------Скважность
//Значение записываемое в регистр должно быть от 0 до верхнего предела
OCR1A = 128;
OCR1B = 128;

sei(); //Включение глобальных прерываний

//-----------------------Обработка прерываний (только если включены прерывания)
ISR (TIMER1_COMPA_vect){
  /*Тело функции*/}
  
ISR (TIMER1_COMPB_vect){
  /*Тело функции*/}

Примеры

ШИМ Сигнал 20 КГц, со скважностью 70% на Timer0
#define F_CPU 16000000UL //частота работы микроконтроллера
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
  

void timer0_init(){
  DDRD |= (1 << PORTD6);  //OC0A (12)
  DDRD |= (1 << PORTD5);  //OC0B (11)

  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0 = 0;

  // Не инверсный режим работы и OC0B 
  TCCR0A |= (1 << COM0B1);

  //Режим 7: Fast PWM (Быстрый ШИМ), частота регулируется предделителем и OCR0A
  TCCR0A |= (1 << WGM00) | (1 << WGM01);
  TCCR0B |= (1 << WGM02); 

  //Предделитель - 8
  TCCR0B |= (1 << CS01);

  //С помощью значения в OCR0A определяется частота, но оно не должно быть больше 255
  //OCR0A = Частота_мк / (Предделитель * Частота)
  OCR0A = F_CPU / (8 * 20000); //100

  //С помощью значения в OCR0B определяется скважность, но оно не должно быть больше значения в OCR0A
  OCR0B = 70;
}

int main(void){

  cli();
  timer0_init(); //после инициализации на выводе OC0B (11) будет ШИМ сигнал 
  sei();

    while (1){
      //В основном цикле программы можно менять значение как частоты OCR0A, так и скважности OCR0B
      //Это можно делать как и просто присваивая значения, так и взяв их с АЦП
      OCR0B = 40;
    }

  return 0;
}
Генерация и обработка прерываний раз в секунду на Timer1
#define F_CPU 16000000UL //частота работы микроконтроллера
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
  

void timer1_init(){
  DDRD |= (1 << PORTD6);  //OC0A (12)
  DDRD |= (1 << PORTD5);  //OC0B (11)

  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0 = 0;

  //Режим 4: Clear Timer On Compare (Сброс по совпадению)
  TCCR1B |= (1 << WGM12);

  //Предделитель - 1024
  TCCR1B |= (1 << CS10)|(1 << CS12);

  //Частота прерываний
  //OCR1A = Частота_мк / (Предделитель * Частота)
  OCR1A = F_CPU / (1024 * 1);   //15625

  //Разрешить прерывание по совпадению A
  TIMSK1 |= (1 << OCIE1A);
}

int main(void){

  cli();
  timer1_init(); //после инициализации на выводе OC0B (11) будет ШИМ сигнал 
  sei();

  int second = 0;

    while (1){

    }
  return 0;
}

ISR (TIMER1_COMPA_vect){
  second++;
}
Трех-канальный ШИМ. 2 канала на timer0, 1 канал - на timer2
#define F_CPU 16000000UL //частота работы микроконтроллера
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

void timer0_init(){
  DDRD |= (1 << PORTD6);  //OC0A (12)
  DDRD |= (1 << PORTD5);  //OC0B (11)

  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0 = 0;
  
  //Не инверсный режим работы OC0A и OC0B 
  TCCR0A |= (1 << COM0A1);  
  TCCR0A |= (1 << COM0B1);

  //Режим 3: Fast PWM (Быстрый ШИМ), частота регулируется предделителем, скважность регулируется OCR0A и OCR0B
  TCCR0A |= (1 << WGM00) | (1 << WGM01); 	
  
  //Предделитель - 64 - 976 ГЦ
  TCCR0B |= (1 << CS01)|(1 << CS00);
  
  OCR0A = 200;
  OCR0B = 70;
}

void timer2_init(){
  DDRD |= (1 << PORTD3);  //OC2B (5)

  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  
  //Не инверсный режим работы OC2B
  TCCR2A |= (1 << COM2B1);
  
  //Режим 3: Fast PWM (Быстрый ШИМ), частота регулируется предделителем, скважность регулируется OCR0A и OCR0B
  TCCR2A |= (1 << WGM20) | (1 << WGM21); 

  //Предделитель - 64 - 976 ГЦ
  TCCR2B |= (1 << CS22);
  
  OCR2B = 50;
}

int main(void){
  
  cli();
  timer0_init();
  timer2_init();
  sei();
  
    while (1){

    }
  return 0;
}