#include <mega8.h>
#include <delay.h>
#asm                             //сообщаем куда подключен датчик 
        .equ __w1_port=0x15; PORTC 
        .equ __w1_bit=0 
#endasm                                
#include <1wire.h>         
#include <ds18b20.h>         
#include <stdio.h>
#include <m8_128.h>

#define digit1 PORTB.5      //4 анод индикатора                 
#define digit2 PORTB.4      //3 анод
#define digit3 PORTB.3      //2 анод
#define digit4 PORTB.2      //1 анод
  
flash char digits[] = {
0b01111110, //рисуем 0
0b00001100, //рисуем 1
0b10110110, //рисуем 2
0b10011110, //рисуем 3
0b11001100, //рисуем 4
0b11011010, //рисуем 5
0b11111010, //рисуем 6
0b01001110, //рисуем 7
0b11111110, //рисуем 8
0b11011110, //рисуем 9
0b11000110, //пишем знак градус...
0b01110010,    //пишем С
0b00000000,  // пустота
};

char digit_out[4], cur_dig ;
unsigned char sec=0;                   
unsigned char min=0;
unsigned char hour=0;
unsigned char al_min=0;
unsigned char al_hour=0;
unsigned char devices; 
int adr;        
int temp;
bit mig;     // "мигающая" переменная
bit col_h;   //переменная верхней точки двоеточия
bit col_l;   //переменная нижней точки двоеточия
bit hel=0;     // переменная "помошница"
bit alarm;   // пременная состояния будильника

 void time(void) {                       //функция вывода времени
 if (hour>9) {digit_out[1]=hour/10;}                                 
    else {digit_out[1]=12;};                  
 digit_out[2]=hour%10;     
 digit_out[3]=min/10;
 digit_out[0]=min%10; 
 } 
 
 void al_time(void) {                    //функция вывода времени будильника
 if (al_hour>9) {digit_out[1]=al_hour/10;}                                 
    else {digit_out[1]=12;};                  
 digit_out[2]=al_hour%10;     
 digit_out[3]=al_min/10;
 digit_out[0]=al_min%10; 
 } 

 
void but_time(void) {                      //функция установки времени
                if (!PINC.5){     //установщик минут
        
                   delay_ms (250);
                                min++;
                              if (min==60){
                                          min=0;
                                            
                                          };
                                          
                                    
                 
                  };
                if (!PINC.4){      //установщик часов
      
                    delay_ms (250);               
                               hour++;
                               if (hour==24){
                                            hour=0;
                                            };
                               
                                          
                  }; 
 }   

void but_altime(void) {                      //функция установки времени будильника
 
                if (!PINC.5){     //установщик минут
        
                   delay_ms (250);
                                al_min++;
                              if (al_min==60){
                                          al_min=0;
                                            
                                          };
                                          
                                    
                 
                  };
                if (!PINC.4){      //установщик часов
      
                    delay_ms (250);               
                               al_hour++;
                               if (al_hour==24){
                                            al_hour=0;
                                            };
                               
                                          
                  };
 }   


void EEPROM_hour(void)                 // запись времени будильника в нестрираемую память
                       {
                       while(EECR & (1<<EEWE));       // запись часов
                       EEAR = 100;
                       EEDR = al_hour;
                       EECR |= (1<<EEMWE);
                       EECR |= (1<<EEWE);
                        };
                       
void EEPROM_min(void)                 // запись времени будильника в нестрираемую память
                       {                       
                       while(EECR & (1<<EEWE));      // запись минут
                       EEAR = 200;
                       EEDR = al_min;
                       EECR |= (1<<EEMWE);
                       EECR |= (1<<EEWE);
                        }
                                
                        
unsigned char EEPROM_read(void)     //функция чтения из нестираемой памяти
{
while(EECR & (1<<EEWE));
EEAR = adr;
EECR |= (1<<EERE);
return EEDR;
}

                      
                        
interrupt [TIM0_OVF] void timer0_ovf_isr(void)     //функция вывода значений (динамическая индикация)
 {
  PORTB|=0x3C;
  PORTD=digits[digit_out[cur_dig]];
  switch (cur_dig){
  case 0:{digit4=0;PORTB.0=col_l;break;};  
  case 1:{digit1=0;break;};
  case 2:{digit2=0;break;};  
  case 3:{digit3=0;PORTB.0=col_h;break;};
  }    
  cur_dig++;                                     
  if (cur_dig==4) cur_dig=0; 
  }      



interrupt [TIM2_OVF] void timer2_ovf_isr(void)    //функция счета времени
{
 sec++;
  mig++;

                   if (sec==60){
                                min++;
                                if (min==60){
                                            hour++;
                                            if (hour==24){
                                                         hour=0; 
                                                         }; 
                                            min=0;
                                             };              
                                sec=0;             
                                };

}




void main(void)
{

// Port B initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In 
// State7=T State6=T State5=1 State4=1 State3=1 State2=1 State1=P State0=P 
PORTB=0x3F;
DDRB=0x3F;

// Port C initialization
// Func6=In Func5=кнопка Min Func4=кнопка Hour Func3=кнопка Alarm Func2=кнопка Time Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x3E;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=T State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1 
PORTD=0x00;
DDRD=0xFF;

               //таймер 0 запущен
TCCR0=0x02;
TCNT0=0x00;


// Timer/Counter 2 initialization
// Clock source: TOSC1 pin
// Clock value: PCK2/128
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x41;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

                            //записываем прошлое значение времени будильника в рабочие переменные
adr = 100;                  //адрес " пальцем в небо"
al_hour = EEPROM_read();
adr = 200;                  //адрес " пальцем в небо"
al_min = EEPROM_read();


// Global enable interrupts
#asm("sei")


while (1)
      { 
      
      while (!PINC.2){             // нажата кнопка Time
      
       if (!hel){                 // выполняем это только в 1ю прокрутку цикла
                TIMSK=0x01;                // отключаем счет времени
                sec=0;                     //обнуляем секунды....
                col_h=0;
                col_l=1;                   // зажигаем нижнюю точку двоеточия
                hel++;
                };
               
       but_time ();      // переходим в обработчик счета-установки     
       time ();          //выводим информацию на дисплей     
                     };
                  
      TIMSK=0x41;
      hel=0;            
      
      while (!PINC.3){             // нажата кнопка Alarm
      
       if (!hel){           // выполняем это только в 1ю прокрутку цикла
                hel++;
                alarm++;    //обращаем состояние будульника
                col_h=1;           // зажигаем верхнюю точку двоеточия
                col_l=0;
                };
                  
       but_altime ();   // переходим в обработчик счета-установки                
       al_time ();      //выводим информацию на дисплей
                    };
                    
       if (hel){              // сохраняем время будильника сразу после окончания его установки
               TIMSK=0x00;
               EEPROM_hour();
               EEPROM_min();
               TIMSK=0x41; 
               hel=0; 
               };              
                    
                     
      
      if (alarm) {col_h=1;} // если будильник включен, то не разрешаем моргать верхней точке
      else {col_h=mig;};          
      col_l=mig;              
      time ();               //выводим информацию на дисплей
                            
      if (alarm) {                                       // проверяем будильник, если он включен
                 while ((hour==al_hour)&(min==al_min)&alarm){ 
                 PORTB.1=0;
                 col_h=1;           
                 col_l=1;                              //сработал будильник... 
                 al_time();                
                 delay_ms (500);
                 digit_out[1]=12;
                 digit_out[2]=12;                        //мигаем временем будильника
                 digit_out[3]=12;
                 digit_out[0]=12;
                 delay_ms (500); 
                 if ((!PINC.3)&(!hel)){ alarm++; hel++;};
                 };
                       PORTB.1=1;
                       hel=0;
                       delay_ms (1000);};
                                               
      
      

   while(sec==25){        //обработчик термометра
         
         TIMSK=0x40;
         PORTB=0x3F;
         
      devices=w1_init();               
      if(devices>0)                 
          { 
          temp=ds18b20_temperature(0);  
          if (temp>1000){               
             temp=4096-temp;         
             temp=-temp;          
          } 

      
      
          };
           
       TIMSK=0x41;   
          
      while(sec<40){                  //вывод температуры...
           
       if (temp>9) {digit_out[1]=temp/10;}                                 
        else {digit_out[1]=12;};                             
      digit_out[2]=temp%10;             
      digit_out[3]=10;    
      digit_out[0]=11;
      col_h=0;
      col_l=0;        //выводим информацию на дисплей
          
         };
      
      
         };   
             
      };
          
}






