/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.5 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Kitchen Clock
Version : 1.0
Date    : 10.02.2009
Author  : Anton Andreev
Company : uC Lab
Comments: 


Chip type           : ATmega8515L
Program type        : Application
Clock frequency     : 4,096000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 128
*****************************************************/

#include <mega8515.h>
#include <sleep.h>
#define _MCU_CLOCK_FREQUENCY_ 4096000L

#define KeysPort PINA
#define BUTTONMODE 1
#define BUTTONLONG 8
#define BUTTONLONGMODE (BUTTONMODE|BUTTONLONG)
#define BUTTONPLUS 2
#define BUTTONMINUS 4
#define KeyPressed() ((~KeysPort)&(BUTTONMODE|BUTTONPLUS|BUTTONMINUS))
// I2C Bus functions
#asm
   .equ __i2c_port=0x18 ;PORTB
   .equ __sda_bit=1
   .equ __scl_bit=2
#endasm
#include <i2c.h>
/*
void i2c_init(void);
unsigned char i2c_start(void);
void i2c_stop(void);
unsigned char i2c_read(unsigned char ack);
unsigned char i2c_write(unsigned char data);
*/

// LM75 Temperature Sensor functions
#include <lm75.h>
/*
void lm75_init(unsigned char chip,signed char thyst,signed char tos, unsigned char pol);
int lm75_temperature_10(unsigned char chip);
*/

// 1 Wire Bus functions
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=3
#endasm
#include <1wire.h>
/*
unsigned char w1_init(void);
unsigned char w1_read(void);
unsigned char w1_write(unsigned char data);
unsigned char w1_search(unsigned char cmd,void *p);
unsigned char w1_dow_crc8(void *p,unsigned char n);
*/

// DS1820 Temperature Sensor functions
#include <ds1820.h>
/*
unsigned char ds1820_select(unsigned char *addr);
unsigned char ds1820_read_spd(unsigned char *addr);
int ds1820_temperature_10(unsigned char *addr);
unsigned char ds1820_set_alarm(unsigned char *addr,signed char temp_low,signed char temp_high);

*/
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
/*
void _lcd_ready(void);
void _lcd_write_data(unsigned char data);
// write a byte to the LCD character generator or display RAM
void lcd_write_byte(unsigned char addr, unsigned char data);
// read a byte from the LCD character generator or display RAM
unsigned char lcd_read_byte(unsigned char addr);
// set the LCD display position  x=0..39 y=0..3
void lcd_gotoxy(unsigned char x, unsigned char y);
// clear the LCD
void lcd_clear(void);
void lcd_putchar(char c);
// write the string str located in SRAM to the LCD
void lcd_puts(char *str);
// write the string str located in FLASH to the LCD
void lcd_putsf(char flash *str);
// initialize the LCD controller
unsigned char lcd_init(unsigned char lcd_columns);

*/

unsigned char Sec, Min, Hour, Day, WDay, Month, Year;
char Temp, TempIn, TempOut;
unsigned char i, c, TimerMin, TimerSec, CounterT0, Button, ButCnt, ButLast, But, SetTimeout;
int StatSound; // Генерация прерывистого звука в течении StatSound/20 секунд,
               // StatSound=1 - выключить звук, StatSound=2 - один звуковой сигнал
               // StatSound==0 - показывает что звук выключен
int WY; 
bit StatLeap, StatDS, StatTimer, Stat220, HalfSec, IsHalfSec, Redraw, TimeOut, ClockRun, WasClock;       
static char rom_code[72];
const flash char DaysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
eeprom char DaysOfWeek[7][3]={{'B','C',0},{0xa8,'H',0},{'B','T',0},{'C','P',0},
{0xab,'T',0},{0xa8,'T',0},{'C',0xa0,0}};
eeprom char MonthNames[12][4]={{0xb1,0xbd,0xb3,0},{0xaa,'e',0xb3,0},"Map",{'A',0xbe,'p',0},
{'M','a',0xb9,0},{0xa5,0xc6,0xbd,0},{0xa5,0xc6,0xbb,0},{'A',0xb3,0xb4,0},{'C','e',0xbd,0},
{'O',0xba,0xbf,0},{'H','o',0xc7,0},{0xe0,'e',0xba,0}};
eeprom char WordHouse[5]={0xe0,'o',0xbc,':',0};                  // "Дом:"
eeprom char WordStreet[4]={0xa9,0xbb,':',0};                     // "Ул:"
eeprom char WordTimer[6]={'T','a',0xb9,0xbc,':',0};              // "Тайм:"
eeprom char WordSet[6]={0xa9,'c',0xbf,'.',' ',0};                 // "Уст. "
eeprom char WordClock[9]={0xb3,'p','e',0xbc,'e',0xbd,0xb8,':',0};// "времени:"
eeprom char WordDate[6]={0xe3,'a',0xbf,0xc3,':',0};              // "даты:"
eeprom char WordSetTimer[14]={0xbf,'a',0xb9,0xbc,'e','p','a',':',0};// "таймера:"
eeprom char WordMinutes[7]={' ','M',0xb8,0xbd,'y',0xbf,0};// " минут"

eeprom char Copyright[]="Kitchen Clock//Thermometer";
eeprom char Copyright2[]="(c) Anton Andreev 2009";

#define COUNTERT0 156 // 2000/(256-156)=20 раз в секунду

void ShowNumberF(char Num, char Sym)
{
   char t;
   t=Num/10;
   if((!t)&&Sym) lcd_putchar(Sym);
   if(t) lcd_putchar(t+'0');
   lcd_putchar(Num%10+'0');
} 

void ShowTemp(char Temp)
{
   if(Temp<0)
   { 
      lcd_putchar('-');
      Temp=(-Temp);
   }
   else if(Temp>0) lcd_putchar('+');
        else lcd_putchar(' ');
   ShowNumberF(Temp, 0);
}

void ShowStr(eeprom char *Text)
{
   i=0;
   while(c=Text[i++]) lcd_putchar(c);
}

inline void GetHomeTemp(void)
{
   TempIn=(char)(((lm75_temperature_10(0)-35)/10));
}

inline void GetStreetTemp(void)
{          
   TempOut=(ds1820_temperature_10(rom_code)/10);
}

void MyInit(void)
{      
   if(PIND.2) // Появилось 220
   {  
      Stat220=1;
      PORTB=0;
      Button=0;
      DDRB=1;
      PORTA=0x0F;
      DDRC=0;
      PORTC=0;
      i2c_init(); 
      w1_init();
#asm("sei") // разрешим прерывания чтобы часы не сбились пока проводим инициализацию
      
      // LM75 Temperature Sensor initialization
      // thyst: 75°C tos: 80°C O.S. polarity: 0
      lm75_init(0,75,80,0);
      
      // 1 Wire Bus initialization
      w1_search(0xf0,rom_code);

      
      // LCD module initialization
      lcd_init(16);
      CounterT0=COUNTERT0; 
      TCCR0=0x02; // запускаем таймер Т0 (обработка нажатий кнопок)
      UCSRB=0xD8; // включаем приемник USART
      Redraw=1;
   }
   else       // Пропало 220
   {            
      Stat220=0;  // Сброс флажков: есть 220
      StatTimer=0; // выключение таймера
      TimeOut=0;
      StatSound=1;
      DDRB=0;
      PORTB=0;     // порты в 3е состояние
      PORTA=0;
      TCCR0=0;
      UCSRB=0;    // выключаем приемник USART
      Redraw=0;
   }
}

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
  if(Stat220!=PIND.2)// Изменилось состояние датчика сетевого питания
  {
     MyInit();
  }
}

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
if(rx_counter==0) return 0xFF; // если буфер приема пуст, возврат 0xFF
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
   {
   --tx_counter;
   UDR=tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
   ++tx_counter;
   }
else
   UDR=c;
#asm("sei")
}
#pragma used-
#endif

// Standard Input/Output functions
//#include <stdio.h>

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
   if((!(++CounterT0))&&Stat220)
   { //Обработка кнопок и звуковой сигнал
     CounterT0=COUNTERT0; 
     if(StatSound)        // Управление звуковым сигналом
     {  
       StatSound--;                 // формирование прерывистого сигнала
       if(StatSound&1) TCCR0=0x12;  // включение сигнала 1000Гц на 1/20 сек
       else TCCR0=0x02;             // выключение сигнала на 1/20 сек
       if(!StatSound) PORTB.0=0; // Отключение динамика
     }
     But=KeyPressed();
     if(But)
     {
       if(But==ButLast) ButCnt++;
       else
       {
         ButLast=But;
         ButCnt=0;
       }          
       if(ButCnt>=20)
       {
          Button=But;
          if(But==BUTTONMODE)
          {
            Button|=BUTTONLONG;
            ButCnt=0;
          }
          else ButCnt=16;
       }
     }
     else
     {
        if(ButCnt>3) Button=ButLast;
        ButLast=0;
        ButCnt=0;
     }
   }
}

void CountTime(void)
{
// Часы реального времени пока без перехода на летнее время и обратно
   if(ClockRun) 
   {
   if((++Sec)>=60)
   {                 
      Sec=0;
      if(Stat220) Redraw=1; // каждую минуту обновляем показания индикатора
      if((++Min)>=60)
      {                
         Min=0;
         if((++Hour)>=24)
         {
            Hour=0;
            if((++WDay)>=7) WDay=0;
            Day++;
            if(Day>DaysInMonth[Month+((StatLeap)&&(Month==2))])
            {                                                     
               Day=1;
               if((++Month)>12)
               {
                  Year++;
                  if(!(Year&3)) StatLeap=1;
                  else StatLeap=0;
               }
            }
         }
      }
   }
   }
   SetTimeout--;
   if(StatTimer) // если таймер запущен
   {        
     if(!TimeOut) //Если время еще не истекло
     {
        if(TimerSec) TimerSec--; //Уменьшаем секунды
        else                     // Секунды = 0
        {
           if(TimerMin)         // Если минут>0 
           {
              TimerMin--;       // Уменьшаем минуты
              TimerSec=59;
              Redraw=1;
           }
           else                // Время истекло мин=0 и сек=0
           {
              StatSound=1200; // Включить звуковой сигнал на 1 минуту
              Button=0;
              TimeOut=1;      // Флажок окончания отсчета
           }
        }
     }     
   }
   IsHalfSec=1;         
   WasClock=1;     
}

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
   CountTime();
   HalfSec=0;
   WasClock=1;
}

// Timer 1 output compare B interrupt service routine
interrupt [TIM1_COMPB] void timer1_compb_isr(void)
{
// Place your code here
   if(!WasClock) CountTime();
   WasClock=0;
   HalfSec=1;
}

char EnterNumber(char N, char x, char Fill, char Min, char Max)
{
   SetTimeout=6;
   while(KeyPressed())        // Ждем отпускания кнопки(ок)
   {
      sleep_enable();
      idle();
      sleep_disable();
#asm("wdr")                   //сброс сторожевого таймера
   }
   Button=0;
   ButLast=0;               
   while(Button!=BUTTONMODE)  // Пока не нажата кнопка "MODE"
   {
      Button=0;
      while(!Button)
      {                       // Ждем нажатия кнопки
#asm("wdr")                   // сброс сторожевого таймера
         sleep_enable();
         idle();
         sleep_disable();
         if(IsHalfSec)
         {   
            IsHalfSec=0;
            lcd_gotoxy(x,1);
            if(HalfSec)
            {
               lcd_putchar(' ');
               lcd_putchar(' ');
            }
            else ShowNumberF(N, Fill);
         }
         if(!SetTimeout)
         {
             Button=BUTTONMODE;// через 5-6 секунд выходим по таймауту
             N=-1;             // Отрицательный результат - значение не введено
         }
      }
      StatSound=2;             // Единичный звуковой сигнал
      SetTimeout=6;               // Сбрасываем счетчик таймаута
      if(Button==BUTTONPLUS) if((++N)>Max) N=Min; // нажата кнопка "+"
      if(Button==BUTTONMINUS) if((--N)<Min) N=Max;// нажата кнопка "-"
#asm("wdr")                    // сброс сторожевого таймера
   }
   lcd_gotoxy(x,1);
   ShowNumberF(N, Fill);
   while(KeyPressed())        // Ждем отпускания кнопки(ок)
   {
      sleep_enable();
      idle();
      sleep_disable();
#asm("wdr")                   //сброс сторожевого таймера
   }
   Button=0;
   ButLast=0;               
   return N;
}


void SetTimer(void)
{
   StatSound=2;               // Единичный звуковой сигнал
   TimerSec=0;                // Секунды таймера обнуляем
   StatTimer=0;               // Таймер остановлен
   lcd_clear();               // Очистка дисплея
   ShowStr(WordSet);          // Сообщение "Уст. таймера"
   ShowStr(WordSetTimer);
   lcd_gotoxy(2,1);
   ShowNumberF(TimerMin,' ');  
   ShowStr(WordMinutes);      // Выводим значение таймера
   TimerMin = EnterNumber(0, 2, ' ', 0, 60);
   if(TimerMin>0)                // Если время введено не нулевое
   {
      StatTimer=1;             // Запускаем таймер
   }
//   else TimerMin=0;
   Redraw=1;                   // Необходимо сразу же перерисовать экран
   lcd_clear();
}

void SetTime(void)
{
   StatSound=2;
   StatTimer=0;
   lcd_clear();
   ShowStr(WordSet);
   ShowStr(WordClock);
   lcd_gotoxy(4,1);
   ShowNumberF(Hour,' ');
   lcd_putchar(':');
   ShowNumberF(Min,'0');
   lcd_putchar(':');
   ClockRun=0;
   Sec=0;
   ShowNumberF(0,'0');
   ClockRun=0;
   if((Temp=EnterNumber(Hour, 4, ' ', 0, 23))>=0)
   {
      Hour=Temp;
   }
   if((Temp=EnterNumber(Min, 7, '0', 0, 59))>=0)
   {
      ClockRun=0;
      Min=Temp;
   }
   ClockRun=1;
   Redraw=1;                   // Необходимо сразу же перерисовать экран
   lcd_clear();
}

void SetDate(void)
{
   StatSound=2;
   StatTimer=0;
   lcd_clear();
   ShowStr(WordSet);
   ShowStr(WordDate);
   lcd_gotoxy(3,1);
   ShowNumberF(Day,' ');
   lcd_putchar('//');
   ShowNumberF(Month,'0');
   lcd_putchar('//');
   lcd_putchar('2');
   lcd_putchar('0');
   ShowNumberF(Year,'0');
   if((Temp=EnterNumber(Year, 11, '0', 0, 99))>=0)
   {
      Year=Temp;
   }
   if(!(Year&3)) StatLeap=1;
   else StatLeap=0;
   if((Temp=EnterNumber(Month, 6, '0', 1, 12))>0)
   {
      Month=Temp;
   }
   i=DaysInMonth[Month]+((Month==2)&&StatLeap);
   if(Day>DaysInMonth[Month]) Day=i;
   if((Temp=EnterNumber(Day, 3, ' ', 1, DaysInMonth[Month]))>0)
   {
      Day=Temp;
   }
   WY=Year*365+(Year/4)+Day+6;
   for(i=0;i<(Month-1);i++) WY+=DaysInMonth[i];
   if(Month>2) WY+=StatLeap;
   WDay=WY%7;
}

void main(void)
{
// Declare your local variables here

// Reset Source checking
if (MCUCSR & 7)
   {
   // Power-on, BOD, PIN Reset
   MCUCSR=0;
   Min=5; Hour=2; Year=9;
   Day=4; Month=2; Sec=0; TimerMin=0; TimerSec=0; CounterT0=0; WDay=4;
   StatLeap=0, StatDS=0, StatTimer=0, Stat220=0, StatSound=0; 
   

   }
else
   {
   // Watchdog Reset
   MCUCSR=0;

   };
#pragma optsize-
   WDTCR=0x1F;
   WDTCR=0;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=P State2=P State1=P State0=P 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func2=In Func1=In Func0=In 
// State2=T State1=T State0=T 
PORTE=0x00;
DDRE=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock отключен
// Clock value: 512,000 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 4,000 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: On
TCCR1A=0x00;
TCCR1B=0x0D;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x0F;
OCR1AL=0x9F;
OCR1BH=0x07;
OCR1BL=0xCF;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
// INT2: Off
GICR|=0x40;
MCUCR=0x01;
EMCUCR=0x00;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x62;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 4800
UCSRA=0x00;
UCSRB=0x00;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x34;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ClockRun=1;
#asm("sei")
while(!(PIND.2)) // ждем появления сетевого питания
{ 
   sleep_enable();
   idle();
   sleep_disable();
}
MyInit();

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Global enable interrupts
StatSound=2;
Redraw=1;
while (1)
      {
        if(TimeOut&&(Button||(!StatSound))) // Во время сигнала нажата кнопка или прошла 1 минута
        {
          StatSound=1;                      // Прекращение звукового сигнала
          TimeOut=0;
          Button=0;
          StatTimer=0;
          Redraw=1;
          ButCnt=0;
        }

         if(Button==BUTTONMODE) SetTimer(); // Установка таймера
         else if(Button==BUTTONLONGMODE) 
         {
           SetDate();                       // Установка времени и даты
           SetTime();     
         }
      // Place your code here
         if(Stat220&&IsHalfSec)             // если есть сетевое питание и прерывание от Т1
         {
            IsHalfSec=0;
            if(Redraw)                      // обновляем показания индикатора
            {
              Redraw=0;
//#asm("cli")
              lcd_gotoxy(0,0);
              ShowNumberF(Hour, ' ');
              lcd_putchar(':');
              ShowNumberF(Min, '0');
              lcd_putchar(' ');
              if(StatTimer)                 // Если запущен таймер - выводим его показания
              {
                 ShowStr(WordTimer);
                 ShowNumberF(TimerMin,' ');
                 lcd_putchar(':');
                 ShowNumberF(TimerSec, '0');
              }
              else                          // Иначе выводим дату
              {
                 lcd_putchar(' ');
                 ShowStr(DaysOfWeek[WDay]);
                 lcd_putchar(' ');
                 ShowNumberF(Day, ' ');
                 lcd_putchar(' ');
                 ShowStr(MonthNames[Month-1]);
              }
              lcd_gotoxy(0,1);
              ShowStr(WordHouse);
              //GetHomeTemp();
              ShowTemp(TempIn);
              lcd_putchar(' ');
              lcd_gotoxy(9,1);
              ShowStr(WordStreet);
              //GetStreetTemp();
              ShowTemp(TempOut);
              lcd_putchar(' ');
//#asm("sei")              

            }
            else  // мигает разделитель часов и минут
            {
               if(Sec==50) GetHomeTemp(); // За 10 секунд до обновления получаем темп. в доме
               if(Sec==55) GetStreetTemp(); // За 5 сек. до обновления получаем темп. на улице
               lcd_gotoxy(2,0);
               if(HalfSec)
               {
                 lcd_putchar(' ');
                 if(StatTimer)
                 { 
                   lcd_gotoxy(13,0);
                   
                   if(TimerMin||TimerSec) lcd_putchar(' ');
                 }
               }
               else
               {
                 lcd_putchar(':');
                 if(StatTimer)
                 { 
                   lcd_gotoxy(13,0);
                   lcd_putchar(':');
                   ShowNumberF(TimerSec,'0');
                 }
               }
            }
         }
#asm("wdr")     //сброс сторожевого таймера
/*MCUCR|=0x20;    // разрешаем Idle
#asm("sleep") // Idle
MCUCR&=(~(0x20));    // запрещаем Idle
*/
   sleep_enable();   // ждем прерывания от таймеров или изменения состояния питания
   idle();
   sleep_disable();
      };
}
                        