ШИМ (PWM) — широтно-импульсная модуляция. Не нужно пугаться данного термина. Это всего навсего способ регулирования напряжения. Допустим подсветка монитора горит слишком ярко, вы меняете яркость. А что же происходит в этот момент на самом деле?
Представим себе, что подсветка монитора это несколько светодиодов. Питается все это дело от постоянного напряжения. Но вот нам понадобилось уменьшить яркость монитора. Логично ответить, что это можно сделать переменным резистором. На маленьких токах — возможно. Но на больших, резистор будет сильно греться. Сильно возрастут габариты, потери, энергопотребление.
Поэтому люди придумали схему на транзисторах, которая делает из постоянного напряжения пульсирующее. Оказывается, пульсирующее напряжение, в зависимости от заполнения периода будет эквивалентно постоянному напряжению. Т.е. если в течение периода напряжение 50% времени было включено, 50% выключено, то эквивалент постоянного напряжения будет равен 50% от номинального.
В цифрах это просто — было 5В постоянного напряжения прогнали через ШИМ — получили 2,5В. Если заполнение импульса равно 75%, то эквивалентное постоянное напряжение будет 3,75В. Думаю идея понятна.
Теперь приступим к практической реализации. Будем при помощи микроконтроллера изменять заполнение от 0 до 100%, потом от 100% до нуля. Конечный результат должен выглядеть так:
Чтобы было более наглядно, подключим светодиод. В результате у нас будет плавно включаться и отключаться светодиод.
Запускаем наш любимый CodeVision. Создаем проект при помощи мастера. В разделе таймеров (Timers), выбираем Timer 2 и выставляем настройки как на рисунке.
Если попробовать сгенерировать проект, то прога может ругнуться. Соглашаемся, ведь у нас нога 3 порта В должна быть настроена как выход.
Приводим код к следующему виду:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <mega8.h> void main(void) { PORTB=0x00; DDRB=0x08; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) { }; } |
Уделим внимание строке OCR2=0x00; Эта переменная как раз и отвечает за величину заполнения импульса. Изменяется данная величина от 0 до 255(0хFF), т.е. 255 соответствует 100% -му заполнению (постоянный ток). Следовательно, если нужно 30% заполнение (255/100)*30=77. Далее 77 переводим в шестнадцатеричную систему OCR2=0x4D;
TCCR2=0x6C; Изменяя данную величину мы можем регулировать частоту ШИМ. Величина частоты работы ШИМ кратна частоте, на которой работает микроконтроллер. В проекте использована частота микроконтроллера 8 МГц, частоту ШИМ использовали 125кГц, следовательно делитель равен 8/125=64
0x6C в двоичной системе счисления 1101100, открываем даташит на Atmega8 и видим описание регистра TCCR2, так вот 1101100 последние цифры 100 и отвечают за выбор частоты работы ШИМ
Приступим непосредственно к программе:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <mega8.h> #include <delay.h> void main(void) { PORTB=0x00; DDRB=0x08; ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) { while(OCR2<0xff) { OCR2=OCR2+0x01; delay_ms(5); } while(OCR2>0x00) { OCR2=OCR2-0x01; delay_ms(5); } }; } |
Код прост до безобразия: сначала в цикле увеличиваем заполнение от 0 до 255(ff), потом уменьшаем от 255 до 0.
И напоследок видосик, как это все должно работать. Успехов в изучении)
Просто я слышал про ЧИМ, и что вроде на мегах такое реализуемо.
могу вам порекомендовать взять специализированную микросхему AD9834, если хочется слепить «свое».
if((PINB.0==0)&&(OCR2<0xff))
{
OCR2=OCR2+0x01;
delay_ms(5);
}
Что обозначают эти 3 строчки?
если нажата кнопка, по увеличивать яркость
привет админ умне вапрос как получит atmega8 3фаз сдвинутых на 120 градусов
ni++;
switch (ni)
{
case 1:
PORTB.0 = 0;// COM1A1 = 0 faza a OF
PORTB.4 = 1;// COM1B1 = 1 faza b ON
PORTB.5 = 1; // COM21 c on
break;
case 2:
PORTB.0 = 1; //COM1A1 = 1 faza a ON
PORTB.4 = 0;// COM1B1 = 0 faza b OF
PORTB.5 = 1; // com21 faza c
break;
case 3:
PORTB.0 = 1; //COM1A1 = 1 faza a ON
PORTB.4 = 1;// COM1B1 = 0 faza b ON
PORTB.5 = 0; // com21 faza c of
break;
};
if(ni==3)
{
ni=0;
}
с помощью таймеров, считаете частоту, смещение, делители… 🙂
OCR1A=(SIN(2pi.x/128+2pi/3)+1).127
OCR1B=(SIN(2pi.x/128+2pi/3)+1).127
OCR1C=(SIN(2pi.x/128)+1).127
вот делаем три масива и три фазы готовы ка учил учител
ойбек on а частотник сделать сложнее.Я извеняюсь перед админом.Но я должен помочь брату по крови.
Можно сделать ЧИМ на STM32 но нужно что бы была аппаратно-программная задержка.Кстати я на AVR правда на atmega128a сделал 4 канальную ШИМ гирлянду на аппаратно-программной задержке.