ATmega. Формирование ШИМ сигнала

Решил научиться управлять 4-х контактными кулерами, для этого необходим ШИМ с частотой 25 кГц. Разбираемся, реализуем требуемое.

Задача

Для управления скоростью вращения вентилятора при помощи МК ATmega 328P организовать 2-х канальный ШИМ, с частотой 25 кГц. Проверить, что при помощи настроенной схемы можно управлять вентиляторами.

Отступление

Не имею профильного образования по работе с МК, в данный момент самостоятельно изучаю данное направление. Например на изучение работы таймеров и закрепления материала в виде написания данной статьи потрачено ~ 10 часов. Как следствие решение может содержать некоторые не точности.

Решение

Как обычно расписывать много теории не буду, благо много информации в интернетах и есть документация от производителя(далее по тексту буду ссылаться на эту документацию с указанием номеров страниц и таблиц). Для облегчения жизни МК организуем ШИМ при помощи таймеров.

По условиям задачи необходимо реализовать 2 канала, в ATmega 328P можно реализовать двумя способами:

  1. Использовать два 8-ми битных таймера T0 и T2;
  2. Использовать один 16-ти битный таймер T1.

Свободные таймеры всегда пригодятся, потому будем использовать вариант с одном таймером, да и смотрится он красивее.

Расчет таймера

В документации есть раздел с описанием работы T1 стр. 149-185(в целом не мало), а на страницах 171-172 размещена таблица 20-6 с режимами работы таймера.

Как писал выше интересен вариант независимого управления двумя каналами на частоте 25 кГц, из прочитанного понял, что не подойдут следующие:

  1. Нормальный режим(Normal), счет происходит от нижнего до разрядности таймера. Даже с применением делителя, его не достаточно. Рассчитать можно по формуле:

    ШИМ = Тактовая частота / ( Делитель * Разрядность таймера )

    16 000 000 / ( 1 * 65 535 ) = 244,144 Гц

  2. Режим очистки по совпадению(Clear Timer on Compare Match, CTC), в которых переполнение в происходит при достижения установленного значения в регистре OCR1A — на выходе имеем только один канал;
  3. Режимы быстрого ШИМ(Fast PWM) и с коррекцией фазы(Phase Correct), с разрядностью 8, 9 , 10 бит смотри пункт 1.

Остаются режимы работы в которых переполнение в происходит при достижения установленного значения в регистре ICR1,

Режим Fast PWM

Режим 14 в таблице 20-6 на странице 172. В этом режиме счетчик считает до верхнего предела и сбрасывается, формула расчета следующая:

ШИМ = Тактовая частота / Делитель * ( 1 + Верхний предел )

16 000 000 / 1 * ( 1 + 639 ) = 25 000 Гц

Ну и напишу формулу, которой я получил верхний предел:

Верхний предел = ( Тактовая частота * Делитель  /  ШИМ ) — 1 

( 16 000 000 * 1 / 25 000 ) — 1 = 639

Полученное значение помещаем в регистр ICR1. Скважность сигнала будет регулироваться регистрами OCR1A  и  OCR1B. Предполагал, что диапазон должен быть от 0 до 639, но по работе вентилятора пришел к значениям от 320 до 640(при условии, что по документации вентилятор не меняет скорости, при скважности 0-30%). Попробую позже разобрать(TODO).

Остается воспользоваться таблицей выходного сигнала 20-4, параметрами режима 14 таблицы 20-6, таблицей делителей 20-7, и написать функцию инициализации:

void pwm_initial() {

    DDRB |= 1 << 1; // PB1 как выход, канал 1
    DDRB |= 1 << 2; // PB2 как выход, канал 2

    TCCR1A = 0; // Сброс данных регистра
    TCCR1B = 0; // Сброс данных регистра
    TCNT1  = 0; // Установка нижнего предела

    TCCR1B |= (1 << CS10); // Работа без делителя

    TCCR1A |= (1 << COM1A1) | (1 << COM1B1);  // Не инверсный режим работы
    ICR1    = 639;                            // 16 МГц / 1 * ( 1 + 639 ) = 25 кГц

    // Установка верхнего предела
    // значением в бите ICR1
    // Режим 14 из документации
    TCCR1A |= (1 << WGM11);
    TCCR1B |= (1 << WGM12) | (1 << WGM13);

    OCR1A = 416;  // Начальное значение уровня 30%
    OCR1B = 416;  // Начальное значение уровня 30%

}

Режим Phase Correct

Режим 10 в таблице 20-6 на странице 172. В этом режиме счетчик считает от 0 до верхнего предела, а потом обратно до 0,  формула расчета следующая:

ШИМ = Тактовая частота / 2* Делитель *  Верхний предел

16 000 000 / 2 * 1 * 320 = 25 000 Гц

Ну и напишу формулу, которой я получил верхний предел:

Верхний предел = Тактовая частота / ( 2 * Делитель  *  ШИМ )

16 000 000 / ( 2 * 1 * 25 000 ) = 320

Полученное значение помещаем в регистр ICR1. Скважность сигнала будет регулироваться регистрами OCR1A  и  OCR1B, по документации диапазон от 0 до 320.

Остается воспользоваться таблицей выходного сигнала 20-5, параметрами режима 10 таблицы 20-6, таблицей делителей 20-7, и написать функцию инициализации:

void pwm_initial() {

    DDRB |= 1 << 1; // PB1 как выход, канал 1
    DDRB |= 1 << 2; // PB2 как выход, канал 2

    TCCR1A = 0; // Сброс данных регистра
    TCCR1B = 0; // Сброс данных регистра
    TCNT1  = 0; // Установка нижнего предела

    TCCR1B |= (1 << CS10); // Работа без делителя

    TCCR1A |= (1 << COM1A1) | (1 << COM1B1);  // Не инверсный режим работы
    ICR1    = 320;                            // 16 МГц / 2 * 1 * 320 = 25 кГц

    // Установка верхнего предела
    // значением в бите ICR1
    // Режим 10 из документации
    TCCR1A |= (1 << WGM11);
    TCCR1B |= (1 << WGM13);

    OCR1A = 96;  // Начальное значение уровня 30%
    OCR1B = 96;  // Начальное значение уровня 30%

}

Режим Phase and Frequency Correct

Режим 8 в таблице 20-6 на странице 172. В этом режиме возможно менять не только скважность, но и частоту сигнала. В остальном аналогичен режиму Phase Correct PWM, в рамках данной статьи разбирать не буду.

Проверка работы

Теперь при остается вызвать описанную функцию при начале работы программы, и на ножках PB1 и PB2 будет работать ШИМ с частотой 25 кГц

Для проверки работы нам хватит одного вентилятора. К вентилятору производим подключение к контактам

  1. — 12 В и от Atmega;
  2. + 12 В;
  3. Не задействован;
  4. ШИМ сигнал  от порта PB1 или PB2.

После запуска вентилятор начнет вращаться с небольшой скоростью. Для управления скоростью необходимо менять значение битов OCR1A  и  OCR1B  для портов  PB1  и  PB2 соответственно.

Для проверки частоты можно воспользоваться осциллографом или написать небольшую программку на том же МК, об этом опубликована статья ATmega. Счетчик импульсов ШИМ.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *