Опубликовано 2010-04-25 15:30:54 автором Ruslan

Широтно-Импульсная Модуляция (ШИМ, PWM). Урок AVR 8


Наверное, вы не раз задавались вопросом, как можно регулировать мощность потребителя, например управлять яркостью светодиода или регулировать обороты двигателя. Самый простой способ - последовательно нагрузке, например светодиоду, включить резистор, но ведь он будет греться и забирать драгоценную энергию, и чем мощней светодиод, тем сильней будет греться наш резистор, такой вариант не для нас. А что если светодиод очень быстро включать и выключать, при этом меняя длительность включений при константной частоте? Например, включать светодиод на 0,2 милисекунди каждую милисекунду, то светодиод засветится, но не на полную яркость. Аналогично с двигателем - включать движок на 30 секунд каждую минуту - тогда двигатель раскрутится, но не на полную скорость — относительно большой вес ротора сгладит рывки от включающегося двигателя, а сопротивление от трения будет его притормаживать. Таким образом, двигатель будет крутится на половину своей мощности.

Широтно-импульсная модуляция

- приближение желаемого сигнала (многоуровневого или непрерывного) к действительным бинарным сигналам (с двумя уровнями - вкл / выкл), так, что, в среднем, за некоторый отрезок времени, их значения равны.

Основной причиной внедрения ШИМ является сложность обеспечения произвольным напряжением. Есть какое-то базовое постоянное напряжение питания (сети, от аккумуляторов и пр.). И на его основе нужно получить более низкую и уже им питать электродвигатели или иное оборудование. Самый простой вариант - делитель напряжения, но он имеет пониженное КПД, повышенное выделением тепла и расходом энергии. Другой вариант - транзисторная схема. Она позволяет регулировать напряжение без использования механики. Основное преимущество ШИП - высокий КПД его усилителей мощности, который достигается за счет использования исключительно в ключевом режиме. Это значительно уменьшает выделение мощности на силовом преобразователе (СП).Діаграми скважності

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

схема ШИМ регулятор яркости светодиода

Самое главное находится в прошивке:

void main(void)
{ PORTB=0x00; //Выставляем все выходы порта B на 0 DDRB=0xFF; //Делаем порт B как выход, чтобы мы могли менять лог уровень на ножках (устанавливать или 0 или 1) while (1) //Организовываем бесконечный цикл { PORTB.1=1; //Включаем светодиод на 1 выходе порта B delay_us(5); //разрешаем светодиоду посветится 5 микросекунд PORTB.1=0; //Выключаем светодиод на 1 выходе порта B delay_us(5); //Делаем задержку на 5 микросекунд }; }

Компилим и закидываем в мк, светодиод должен светится на половину яркости. Но вы, наверное, уже успели заметить, что наша программа только то и делает, что устанавливает лог-уровни на выводе мк. Чтобы освободить главный цикл от этой рутинной работы, мы воспользуемся таймером.

Апаратный ШИМ
Таймер может генерировать ШИМ в нескольких режимах:

  • Phase Correct PWM (симметричный ШИМ)

    режим Phase Correct PWM

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

    Вывод OCxx при первом совпадении с регистром сравнения сбрасывается, при втором устанавливается.

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

    режым Phase Correct PWM

    В этом режиме таймер работает так:

    • увеличивает переменную TCNTX от 0 до top, при переполнении TCNTX она сбрасывается в 0, и счет начинается снова.
    • при каждом увеличении TCNTX проверяет, не равен ли он регистру сравнения OCRXA/OCRXB, если равен, то соответствующий ему вывод ОСхх сбрасываeтся в ноль. При обнулении счетчика этот вывод устанавливается в 1

  • СТС (сброс при совпадении)

    режим Phase Correct PWM

    Таймер тикает от 0 до регистра сравнения, при совпадении с регистром сравнения сбрасывается в 0. Этот режим хорошо подходит для регулировки частоты, или когда нужно отсчитывать периоды.

Итак, для наших нужд (регулировка яркости светодиода) подходит режим Fast PWM. Запускаем CodeWizard AVR, переходим на вкладку timers->timer1, выставляем все, как показано на скриншоте

режим Fast PWM timer1

здесь:

  • Clock Source - выбор источника тактирования таймера, выбираем System Clock - таймер тактируeтся частотой, на которой работает микроконтроллер
  • Clock Value - выбор частоты работы таймера, здесь мы установили 1000000 hz, это значит, что переменная TCNT1 будет переполнятся с частотой 1000000/255 = 3921 hz, частота ШИМ будет 3921 khz
  • out A (вывод А) определяет состояния ножки OC1A при совпадении счетного регистра и регистра сравнения
  • Comp. A значение регистра сравнения
Кликаем File->Generate and save.
#include  <mega8.h>

void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x02;

// Timer/Counter 1 initialization
TCCR1A=0x81;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x64;// число 100 в шестнадцатеричном виде
OCR1BH=0x00;
OCR1BL=0x00;

while (1)
      {
      };
}

Компилим и закидаем в мк, теперь наш светодиод должен светиться примерно на половину яркости.

Давайте теперь попробуем что-нибудь пропищать с помощью таймера:
Схема подключения динамика к мк:

подключения динамика к мк

Таймер мы установим в режим Fast PWM и будем плавно менять частоту от 0 - 4 khz.
Код такой программы выглядит следующим образом:

  #include <mega8.h>
  #include <delay.h>
void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x02;

// Timer/Counter 1 initialization
TCCR1A=0x40;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x64;
OCR1BH=0x00;
OCR1BL=0x00;

while (1)
      { 
        OCR1AL++; // увеличиваем регистр сравнения на  1, чтобы изменилась частота
        delay_ms(100);
      };
}

Комментарии - (0)

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

Для отправки комментария вы должны авторизоваться.