Проблема с ШИМ на atmega32
- Войдите на сайт для отправки комментариев
Вс, 16/10/2016 - 16:27
Всем добрый день! Делаю одно устройство на atmega32 и у меня возникли проблемы с ШИМ. На выводах OC1A, OC1B и OC2 ШИМ формируется без проблем, а вот на выводе OC0 ШИМ не регулируется. Точнее он либо в "0" либо "1" либо шим с частотой примерно 125. На регулировку не реагирует. Скетч:
volatile int pa = 3; // основной выход с ШИМ volatile int ledR = 12; // зеленый и синий светодиоды для индикации volatile int ledG = 13; // красный светодиод для индикации volatile int butcount = 0; // переменная для "антидребезга" кнопок volatile int PWMledG = 100; // ШИМ-ы: volatile int PWMledR = 125; volatile int PWMpa = 255; volatile int PWMledB = 0; volatile byte mode = 0; // режим работы void setup() { pinMode(pa, OUTPUT); // основной выход с ШИМ pinMode(ledR, OUTPUT); //Светодиоды pinMode(ledG, OUTPUT); //pinMode(ledB, OUTPUT); pinMode(4, INPUT); // кнопки pinMode(7, INPUT); PORTB |=(1<<PB4)|(1<<PB7); // подтягивающие резисторы analogWrite(pa, PWMpa); // записть начальных значений analogWrite(ledR, PWMledR); analogWrite(ledG, PWMledG); } void loop() { switch (mode) { case 0: be_work(); break; case 1: //be_sleep(); break; } } void be_work()// режим работы. реакция на кнопки. { if (!(PINB & (1<<PINB7))) //если кнопка нажата { if (butcount < 5) { butcount++; } else { PWMpa = PWMpa + 10; if (PWMpa > 255) { PWMpa=255; } analogWrite(pa, PWMpa); delay (200); } } else if (!(PINB & (1<<PINB4))) //если кнопка нажата { if (butcount < 5) { butcount++; } else { if (PWMpa > 10) { PWMpa = PWMpa - 10; analogWrite(pa, PWMpa); delay (200); } } } else { if (butcount > 0) { butcount--; } } }
Если кнопками регулировать лютой другой ШИМ-канал, то все без проблем, а OC0 не регулируется. Как стартанет вместе с программой так и работает. На управление нет реакции. В чем проблема? Для меги использую библиотеку ATmega32-Arduino-master. Где скачивал - не помню.
Хоть подскажите в какую сторону копать...
Копай в сторону таймера 0, за одно узнаешь чем он занят.
добавил настройку:
TCCR0|=(1<<COM01)|(1<<WGM00);
сбился счетчик для DELAY - но это не проблема. Возникла проблема: ШИМ получается инверсным. То есть если я записываю 50, то получаю длинный высокий уровень и короткий низкий. Если записать 200 то все наоборот. не могу найти где сделать инверсию для ШИМ.
forfrends, ну если вы ШИМмите через функцию дуни, то очевидно - analogWrite(~PWMpa);
Ну, это очевидный способ :) Хотя я сам до него не додумался. Я думал в даташите найти какой-то регистр который просто настроит ШИМ.
Но можно и так :)
Еще вопрос: а можно ли на один и тот же таймер вешать и ШИМ и прерывание?
forfrends, можно сделать правильную инверсию битами регистра таймера, ссылку на книжку я вам уже давал )
-можно, если это не системный таймер.