// ATtiny2313
// Регулирование частоты ШИМ изменением верхней границы счета таймера
// Для ШИМ спользован 8-разрядный таймер0, выход - D5 (OC0B)
// Период ШИМ меняется туда-сюда между значениями c_Tmin и c_Tmax.
// Изменение происходит в прерывании по совпаденю таймера1.
// Для простоты ширина импульса постоянна.

#include <avr/io.h>
#include <avr/interrupt.h>


#define c_TMax 255		
#define c_TMin 25
#define c_impulse 20
#define c_TMax 255
uint8_t dir;

ISR (TIMER1_COMPA_vect)
{
	uint16_t pwm=OCR0A;
	if (dir==0)//Вверх
	{
		if (pwm==c_TMax)
		{
			dir=1;
		}
		else
			pwm++;
	}
	else//Вниз
	{
		if (pwm==c_TMin)
		{
			dir=0;
		}
		else
			pwm--;
	}
	OCR0A = pwm;
}

void ioinit (void)
{
	TCCR0A = (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
	TCCR0B = (1<<WGM02)|1;  //запуск Т0 с к=1, режим FastPWM, TOP=OCR0A
	OCR0A = c_TMax; 		//максимальный период ШИМ
	OCR0B = c_impulse;		//в регистр сравнения грузим период импульса
	TIMSK = (1<<OCIE1A);	//разрешаем прерывания по совпадению таймера1 (канал А)
	OCR1A = 256;			//регистр совпадения 
	TCCR1B = (1<<WGM12)|2;	//запуск Т1 с к=1/8, режим обнуления по совпадению
		
    sei ();
}


int main (void)
{	
	/* Вывод на пятую ногу порта D, она же является OC0B */
    DDRD = _BV (PD5);
	
	dir=0;//Задаём "направление"

	//Запускаем таймеры
	ioinit ();
	
	//Бесконечный цикл
	for (;;)
	{
	}

  return(0);
}
