#include <mega8.h>

// Задаём константы для отсчёта времени
// интервалы могут быть любыми
#define LOAD1_ON_TIME 1800 // 30 минут 
#define LOAD1_OFF_TIME 1800 // 30 минут 
#define LOAD2_ON_TIME  2700 // 45 минут 
#define LOAD2_OFF_TIME 900 // 15 минут
// и вообще, нагрузок может быть несколько

// задаём порты через которые включается нагрузка
#define LOAD1_PORT PORTD.0
#define LOAD2_PORT PORTD.1 

// объявляем наши счетчики как глобальные переменные
volatile unsigned int load1_on_time;
volatile unsigned int load1_off_time;
volatile unsigned int load2_on_time;
volatile unsigned int load2_off_time;

// Timer 1 output compare A interrupt service routine
// это тот самый обработчик прерывания
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
// сюда попадаем каждую секунду
// если счётчики времени не равны нулю, то уменьшаем их на единицу
if(load1_on_time)
    load1_on_time--;
if(load2_on_time)
    load2_on_time--;
if(load1_off_time)
    load1_off_time--;
if(load2_off_time)
    load2_off_time--;
}


void main(void)
{
// Declare your local variables here
// статус нагрузки. 1 - включена, 0 - выключена
unsigned char load1_status = 0;
unsigned char load2_status = 0;


// Port D initialization
// порты PD0, PD1 на вывод, остальные PD2 - PD6 на ввод
PORTD=0x00;
DDRD=0x03;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x3D;
OCR1AL=0x09;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;


// Global enable interrupts
#asm("sei")

// включаем нагрузку 1 и загружаем значения счётчиков
LOAD1_PORT = 1;
load1_status = 1;
load1_on_time = LOAD1_ON_TIME;

// включаем нагрузку 2 и загружаем значения счётчиков
LOAD2_PORT = 1;
load2_status = 1;
load2_on_time = LOAD2_ON_TIME;


while (1)
    {
    // проверяем состояние нагрузки 1 
    if(load1_status == 1)
    {
        // нагрузка включена, проверяем, вышло ли время
        if(load1_on_time == 0)
        {
            // время вышло
            LOAD1_PORT = 0; // выключаем нагрузку
            load1_status = 0; // изменяем статус на "выключено"
            load1_off_time = LOAD1_OFF_TIME; // задаём время паузы
        }
    }
    else
    {
        // нагрузка выключена, проверяем, вышло ли время паузы
        if(load1_off_time == 0)
        {
            // время паузы вышло
            LOAD1_PORT = 1; // включаем нагрузку
            load1_status = 1; // изменяем статус на "включено"
            load1_on_time = LOAD1_ON_TIME; // задаём время включения
        }
    }      

    // аналогично проверяем состояние нагрузки 2 
    if(load2_status == 1)
    {
        if(load2_on_time == 0)
        {
            LOAD2_PORT = 0;
            load2_status = 0;
            load2_off_time = LOAD2_OFF_TIME;
        }
     }
    else
    {
        if(load2_off_time == 0)
        {
            LOAD2_PORT = 1;
            load2_status = 1;
            load2_on_time = LOAD2_ON_TIME;
        }
    }
    // и таких нагрузок может быть несколько...
    
    }; // конец главного цикла
}// конец главной программы.


