Суть программки - В основном цикле таймер остановлен. При нажатии на кнопку (лог.0), срабатывает внешнее прерывании INT0 и в нем запускается плавно ШИМ от нуля до определенной величины. При отпускании кнопки - уходим опять в вечный цикл. Вроде все работает, но скважность ШИМ постоянно увеличивается и потом уменьшается. И так беcконечно, пока не отпустить кнопку. Как можно исправить этот момент? Подскажите пожалуйста.
Code: Select all
#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int i=0;
void init_pwm()
{
TCCR0A |=(1<<WGM00); // Режим Phase correct PWM, в этом режиме счет идет до 255, а потом обратно до 0
TCCR0A |=(1<<COM0A1) | (0<<COM0A0); // 0 при 1-м равенстве регистров TCNT0 и OCROA и 1 при 2-м равенстве. (инвертированный ШИМ-сигнал)
TCCR0B |= (1<<CS01); // делитель 8
OCR0A =0;// регистр сравнения
}
//--------------------------------------------------------------------------
void start_pwm()
{
while(i<95)
{
i=i+1;
OCR0A=i;
_delay_ms(25);
}
}
//--------------------------------------------------------------------------
void stop_pwm()
{
TCCR0B= 0x00;
TCCR0A= 0x00;
}
//------------------------------------------------------------------------------
ISR (INT0_vect) /* Объявление функции прерывания INT0 (порт PB1) */
{
init_pwm();
start_pwm();
asm("sei"); // глобальное разрешение прерываний//
}
//------------------------------------------------------------------------------
int main(void)
{
DDRB|=(0<<PB1)|(1<<PB0)|(0<<PB4)|(1<<PB2);
PORTB=0b00010010;
MCUCR |= (0<<ISC01)|(0<<ISC00); // Низкий уровень на INT0 генерирует запрос прерывание//
GIMSK |= (1<<INT0); //Разрешение работы прерывания INT0 на выводе PB1//
GIFR= 0x00; // Флаг прерываний//
TIMSK0|=(1<<OCIE0B);
init_pwm();
asm("sei"); //глобальное разрешение прерываний//
while(1)
{
stop_pwm();
}
}