/*******************************************************
 Chip type               : ATmega8
AVR Core Clock frequency: 4,000000 MHz
*******************************************************/

#include <mega8.h>
#include <delay.h>
#include <ds18b20.h>
#include <m41t81.h>
#include <i2c.h>
#include <1wire.h>

#define clk PORTD.3   // пины на
#define din PORTD.4   // матрицы точнее на их драйверы
#define cs1 PORTB.6   //
#define cs2 PORTD.5
#define cs3 PORTD.6
#define cs4 PORTD.7
#define dec PINB.0     // клавитура минус
#define set PINB.1      // ввод
#define inc PINB.2     // плюс

unsigned int poket;
unsigned char adr,simv,k,size,c,m,s,c1=88,m1=79,s1=77,flas,brightness,w1,w2,timec;
//unsigned char ee_code[2][9]; // для адресов термодатчиков
unsigned char obraz1[40];  // (количество матриц + одна) *8 байт
unsigned char time[4];  // это время 
 int tem,a,tem2,w;
// char unsigned str1[]="    * ВРЕМЯ ";
// char unsigned str2[]="   ТЕМПЕРАТУРА В ГАРАЖЕ ";
// char unsigned str3[]="   НА УЛИЦЕ ";
 char unsigned str9[]="     ПРИВЕТ КУРГАНПРИБОР     ПРИВЕТ ЭЛЕКТРОМОНТЕР !!! ОТ А";
 char unsigned str12[]=" ЕХ_641   " ;
// далее образы заглавных букв кириллицы и символов, будут соответствовать кодам windows
// ВНИМАНИЕ !!! ОПРЕДЕЛЕНЫ ОБРАЗЫ ТОЛЬКО ЗАГЛАВНЫХ БУКВ, ПРИ ПОПЫТКЕ ВЫВЕСТИ ПРОПИСНУЮ БУДЕТ ПРОБЕЛ !!!
const unsigned char sim[34][8]=
       {{0x38,0x44,0x82,0x82,0xFE,0x82,0x82,0x82},{0xFC,0x80,0x80,0xFC,0x82,0x82,0x82,0xFC}, // А,Б
       {0xFC,0x82,0x82,0xFC,0x82,0x82,0x82,0xFC},{0xFE,0x82,0x80,0x80,0x80,0x80,0x80,0x80},  // В,Г
       {0x3C,0x44,0x44,0x44,0x44,0xFE,0x82,0x82},{0xFE,0x80,0x80,0xF8,0x80,0x80,0x80,0xFE},  // Д,Е
       {0x92,0x92,0x54,0x38,0x38,0x54,0x92,0x92},  // Ё,Ж  {0x66,0x0,0xFE,0x80,0xF8,0x80,0x80,0xFE},//ё
       {0x7C,0x82,0x2,0x3C,0x2,0x2,0x82,0x7C},{0x82,0x86,0x8A,0x92,0xA2,0xC2,0x82,0x82},  // З,И
       {0x38,0x82,0x86,0x8A,0x92,0xA2,0xC2,0x82},{0x84,0x88,0x90,0xE0,0x90,0x88,0x84,0x82},  // й,к
       {0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x82},{0x82,0xC6,0xAA,0x92,0x82,0x82,0x82,0x82},   // Л,М 
       {0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82},{0x7C,0x82,0x82,0x82,0x82,0x82,0x82,0x7C},  // Н,О
       {0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82},{0xFC,0x82,0x82,0x82,0xFC,0x80,0x80,0x80},   // П,Р
       {0x7C,0x82,0x80,0x80,0x80,0x80,0x82,0x7C},{0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10},  // С,Т
       {0x82,0x82,0x82,0x7E,0x2,0x2,0x82,0x7C},{0x7C,0x92,0x92,0x92,0x7C,0x10,0x10,0x10},   // У,Ф 
       {0x82,0x44,0x28,0x10,0x10,0x28,0x44,0x82},{0x88,0x88,0x88,0x88,0x88,0x88,0xF8,0xC},  // Х,Ц
       {0x82,0x82,0x82,0x82,0x7E,0x2,0x2,0x2},       //ч
       {0x92,0x92,0x92,0x92,0x92,0x92,0x92,0xFE},{0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x3},   // Ш,Щ
       {0xE0,0xA0,0xA0,0x3C,0x22,0x22,0x22,0x1C},{0x82,0x82,0x82,0xF2,0x8A,0x8A,0x8A,0xF2},   // Ъ,Ы 
       {0x80,0x80,0x80,0xFC,0x82,0x82,0x82,0xFC},{0xFC,0x2,0x2,0x7E,0x2,0x2,0x2,0xFC},  // Ь,Э
       {0x9C,0xA2,0xA2,0xE2,0xA2,0xA2,0xA2,0x9C},{0x7E,0x82,0x82,0x82,0x7E,0x22,0x42,0x82},   // Ю,Я
       {0x00,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x7C},            
       };

const unsigned char sim1[32][8]=
       {
       {0x10,0x38,0x38,0x38,0x10,0x10,0x0,0x10},{0x28,0x28,0x28,0x28,0x0,0x0,0x0,0x0},   // !," 
       {0x14,0x14,0xFE,0x28,0x28,0xFE,0x50,0x50},{0x7C,0x92,0x90,0x7C,0x12,0x12,0x92,0x7C},  // #,$
       {0x0,0xC2,0xC4,0x8,0x10,0x20,0x46,0x86},{0x38,0x44,0x38,0x50,0x88,0x8C,0x82,0x7C},   // %,&
       {0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0},   // ВЕРХ ЗАПЯТАЯ              
       {0x02,0x02,0x04,0x04,0x04,0x04,0x02,0x02},{0x80,0x80,0x40,0x40,0x40,0x40,0x80,0x80},   // (,) 
       {0x0,0x10,0x54,0x38,0xFE,0x38,0x54,0x10},{0x0,0x0,0x10,0x10,0x7C,0x10,0x10,0x0},  // *,+
       {0x22,0x42,0x42,0x82,0xFE,0x2,0x2,0x2},{0x0,0x0,0x0,0x7C,0x0,0x0,0x0,0x0},   // ,,- 
       {0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x60},{0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x20},   // .,/ 
       {0x7C,0x82,0x86,0x8A,0x92,0xA2,0xC2,0x7C},{0x8,0x18,0x28,0x48,0x8,0x8,0x8,0x8},   // 0,1 
       {0x7C,0x82,0x2,0xE,0x30,0x40,0x80,0xFE},{0x7C,0x82,0x2,0x3C,0x2,0x2,0x82,0x7C},  // 2,3
       {0x22,0x42,0x42,0x82,0xFE,0x2,0x2,0x2},{0xfE,0x80,0x80,0x7C,0x2,0x2,0x82,0x7C},   // 4,5
       {0x7C,0x82,0x80,0xfc,0x82,0x82,0x82,0x7C},{0x7e,0x82,0x2,0x4,0x4,0x8,0x8,0x10},   // 6,7 
       {0x7C,0x82,0x82,0x7c,0x82,0x82,0x82,0x7c},{0x7C,0x82,0x82,0x82,0x7e,0x2,0x82,0x7C},  // 8,9
       {0x0,0x18,0x18,0x0,0x0,0x18,0x18,0x0},{0x0,0x18,0x18,0x0,0x0,0x18,0x18,0x8},   // :,;
       {0x4,0x8,0x10,0x20,0x20,0x10,0x8,0x4},{0x0,0x0,0x0,0x7E,0x0,0x7E,0x0,0x0},   // <,= 
       {0x20,0x10,0x8,0x4,0x4,0x8,0x10,0x20},{0x3C,0x42,0x42,0x4,0x8,0x00,0x0,0x10},  // >,? 
       {0x38,0x44,0x44,0x44,0x38,0x0,0x0,0x0},  // градус, не соответствует коду windows !!!     
 };
 const unsigned char sim2[13][8]=     // уменьшенные цифры ( не совпадают с кодами windows)
 {
       {0x70,0x88,0x88,0x98,0xa8,0xc8,0x88,0x70},{0x10,0x30,0x50,0x10,0x10,0x10,0x10,0x38},   // 0,1 
       {0x70,0x88,0x8,0x8,0x30,0x40,0x80,0xf8},{0x70,0x88,0x8,0x30,0x8,0x8,0x88,0x70},  // 2,3
       {0x48,0x48,0x88,0x88,0xf8,0x8,0x8,0x8},{0xf8,0x80,0x80,0x70,0x8,0x8,0x88,0x70},   // 4,5             
       {0x70,0x88,0x80,0xf0,0x88,0x88,0x88,0x70},{0x78,0x88,0x8,0x8,0x10,0x10,0x20,0x20},  // 6,7 
       {0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70},{0x70,0x88,0x88,0x88,0x78,0x8,0x88,0x70},  // 8,9
       {0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0},{0x60,0x90,0x90,0x90,0x60,0x0,0x0,0x0},  // -,градус
        {0x70,0x88,0x80,0x80,0x80,0x80,0x88,0x70},  // цельсия
 };
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
  // прерывания не используем но обьявляем а что, а вдруг !!!
}

       void only_gigit (unsigned char code) // в режиме стационарного отображения поиск образа и заполнение
       {                                    // нулевой матрицы его содержимым (только цифры, минус, градус, и зак цельсия
        unsigned char i=63,j;
        while (i<79)  //160
           {
            i++;
            if (code==i) 
            {
              for (j=0;j<8;j++)
               obraz1[j+32]=sim2[i-64] [j];
                i=79;
            }
           }
       
       }
       void poc()  //*********** запись в микросхему MAX7219 данных, старший-адрес, младший-команда или байт информации
             // в 16-ти битной переменной poket адрес+данные                                                                      
       { 
         unsigned char i;
         for (i=16;i>0;i--)    //16 раз совершаем действие (2 байта)
         {
           if (adr==1) cs4=0;
           if (adr==2) cs3=0;    // ВЫБОР номера матрицы ( фактически порта на котором сидит её cs)
           if (adr==3) cs2=0;
           if (adr==4) cs1=0;
           if ((poket>>(i-1))&1) // побитно вводим информацию в микросхему
              {
               din=1;      // устанавлмвая высокий уровень на вход для данных
               clk=1;      // захват данных разрешаем
              }
           else 
              {
               din=0;       // или низкий уровень в зависимости от исходного кода
               clk=1;
              };
              clk=0;       //  завершаем захват
        } ;
      cs2=cs1=cs3=cs4=1;          //сбрасываем cs-ы
 
 
       } 
       void obrzap (unsigned char code) //**********заполнение массива образом символа 8х8 
                                     //невидимой (нулевой) матрицы ( из которой начинается сдвиг)
                                   
       {  
       unsigned char i=191,j;
      
          if (code>191)
       {
         
         while (i<225)  //160
           {
            i++;
            if (code==i) 
            {
              for (j=0;j<8;j++)
               obraz1[j+32]=sim[i-192] [j];
                i=225;
            }
           }
          }
           else
          {
            i=32;
             while (i<64)  //160
             {
                i++;
                if (code==i) 
                    {
                      for (j=0;j<8;j++)
                       obraz1[j+32]=sim1[i-33] [j];
                       i=64;
                    }
             }           
          }
       }
       void matrclr() //************очистка матрицы
       {
             poket=0x0100;     
             poc();
             poket=0x0200;     ;
             poc();
             poket=0x0300;
             poc();
             poket=0x0400; 
             poc();
             poket=0x0500;  
             poc();
             poket=0x0600;    
             poc();
             poket=0x0700;   
             poc();
             poket=0x0800;   
             poc();           
       }
       void matrinit()   //********* инициализация микросхем матриц
       {
              poket=0x0F00;
              poc();
              poket=0x0C01;
              poc();
              poket=0x0B07;
              poc();;
              poket=0x0900;
              poc();
              poket=0x0A06;        // яркость  01-0f      
              poc();
       }
       void vivod ()    //**********запись в матрицы содержимого (всех четырёх) из массива obraz1
       {                //для ускорения не стал это делать в циклах
       adr=1;                     //адрес матрицы в которую будет запись
       poket=0x100+obraz1[0];//содержимое ввода      
       poc();                     // ввод
       poket=0x200+obraz1[1];    
       poc();
       poket=0x300+obraz1[2];
       poc();
       poket=0x400+obraz1[3];  
       poc();
       poket=0x500+obraz1[4];    
       poc();
       poket=0x600+obraz1[5];     
       poc();
       poket=0x700+obraz1[6];  
       poc();
       poket=0x800+obraz1[7];   
       poc();
     
       
       adr=2;
       poket=0x100+obraz1[8];     
       poc();
       poket=0x200+obraz1[9];    
       poc();
       poket=0x300+obraz1[10];
       poc();
       poket=0x400+obraz1[11];  
       poc();
       poket=0x500+obraz1[12];    
       poc();
       poket=0x600+obraz1[13];     
       poc();
       poket=0x700+obraz1[14];  
       poc();
       poket=0x800+obraz1[15];   
       poc();
       
       adr=3;
       poket=0x100+obraz1[16];     
       poc();
       poket=0x200+obraz1[17];    
       poc();
       poket=0x300+obraz1[18];
       poc();
       poket=0x400+obraz1[19];  
       poc();
       poket=0x500+obraz1[20];    
       poc();
       poket=0x600+obraz1[21];     
       poc();
       poket=0x700+obraz1[22];  
       poc();
       poket=0x800+obraz1[23];   
       poc();
     
       
       adr=4;
       poket=0x100+obraz1[24];     
       poc();
       poket=0x200+obraz1[25];    
       poc();
       poket=0x300+obraz1[26];
       poc();
       poket=0x400+obraz1[27];  
       poc();
       poket=0x500+obraz1[28];    
       poc();
       poket=0x600+obraz1[29];     
       poc();
       poket=0x700+obraz1[30];  
       poc();
       poket=0x800+obraz1[31];   
       poc();       
          
       }
       
       
        sdvig_vniz (unsigned char i)//***********сдвиг вниз из нулевой матрицы в матрицу номер i
       {
       unsigned char j,h,g;
       g=(32-(i*8))+7; // находим начало массива соответствующей j матрицы (1-4) первая крайняя правая
       for (h=0;h<8;h++)
       {
       i=g;
       for (j=0;j<8;j++)
        {
        
        obraz1[i]=obraz1[i-1];
        i--;
        
        }
        obraz1[g-7]=obraz1[39-h];
        vivod ();
    delay_ms(30);   // скорость сдвига
        }
       }
       
             
       void sdvig()     //**********сдвигает побитно 8 строк 8 раз (из невидимой матрицы в первую правую)
                  // и последующие на матрицу влево и с помощью vivod () выводит движение на табло
 { 
              unsigned char s0,s;
              for (s0=0;s0<8;s0++)  //8 раз сдвигать 8 строк
       { 
                   for (s=0;s<8;s++)  // 8 строк сдвинуть
                     {  
                        obraz1[s]=obraz1[s]<<1;
                        if ((obraz1[s+8]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s] &= ~(1 << 0);   // иначе установить в 0 
                         obraz1[s+8]=obraz1[s+8]<<1;
                         
            
                        if ((obraz1[s+16]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s+8]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s+8] &= ~(1 << 0);   // иначе установить в 0 
                         obraz1[s+16]=obraz1[s+16]<<1;
                         

                        if ((obraz1[s+24]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s+16]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s+16] &= ~(1 << 0);   // иначе установить в 0 
                         obraz1[s+24]=obraz1[s+24]<<1;
                         
            
                        if ((obraz1[s+32]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s+24]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s+24] &= ~(1 << 0);   // иначе установить в 0 
                         obraz1[s+32]=obraz1[s+32]<<1;                         
                         
                     }
         vivod (); 
         delay_ms(a); //пауза - задаёт скорость движения глобальная переменная а
      }
      }
      
        void sdvig2(unsigned char q1)     //**********сдвигает побитно 8 строк 8 раз (из невидимой матрицы в первую правую)
                  // и последующую (всего две что справа) на матрицу влево и с помощью vivod () выводит движение на табло
 { 
              unsigned char s0,s;
              for (s0=0;s0<8;s0++)  //8 раз сдвигать 8 строк
       { 
                   for (s=0;s<8;s++)  // 8 строк сдвинуть
                     {  
               if (q1==3)      
                     
                      {  
                        obraz1[s+8]=obraz1[s+8]<<1;
                         if ((obraz1[s+16]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                         obraz1[s+8]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                         else
                         obraz1[s+8] &= ~(1 << 0);   // иначе установить в 0 
                         obraz1[s+16]=obraz1[s+16]<<1;                       
                       } 
                 if (q1==2) obraz1[s+16]=obraz1[s+16]<<1;       
                        if ((obraz1[s+24]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s+16]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s+16] &= ~(1 << 0);   // иначе установить в 0 
                        obraz1[s+24]=obraz1[s+24]<<1;
                        
                        if ((obraz1[s+32]>>(7))&1)   //если 7-й бит (крайний левый бит) равен 1
                        obraz1[s+24]|= (1 << 0);    //то нулевой бит след матрицы установить в 1
                        else
                        obraz1[s+24] &= ~(1 << 0);   // иначе установить в 0 
                        obraz1[s+32]=obraz1[s+32]<<1;
                        
                        
                     }
         vivod (); 
         delay_ms(a); //пауза - задаёт скорость движения глобальная переменная а
      }
      }     
      
           set_num (unsigned char max,unsigned char num) // ******установка параметра num, max его максимальное значение
          {
          //  rtc_read_time(&c, &m, &s);
        //   if(s-sec2!=0) {sec2=s;if (flas==1) flas=0 ;else flas=1;} 
           if (dec==0) if(num>0) {num--;flas=1;} ;
           if (inc==0) if(num<max) {num++;flas=1;};
           return (num);          
          }
          
      void sdvig_vpravo()  //*******************сдвиг вправо на 2 для вывода минут
      {
       unsigned char j;
       for (j=0;j<8;j++) obraz1[39-j]=obraz1[39-j]>>2;
      } 
               
              void      set_time()    // установка времени*******************
           {
           unsigned char c1,m1;   // временные переменыые часов и минут
         char unsigned str4[]="   УСТАНОВКА ЧАСОВ  ";     //№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
           char unsigned str5[]="   УСТАНОВКА МИНУТ  ";
           a=10;
            flas=1;
             obrzap(32);                      
           size=sizeof(str4)-1;   //определяем размер  текста
           for(k=1;k<size;k++)   //выводим  текст "установка часов"
            {
              simv=(str4[k]) ;
              obrzap (simv) ;
              sdvig();
            }
           

       
            obrzap(215); //вывоим букву "Ч"
            sdvig();     //сдвигаем её 
            obrzap(45);  //выводим тире "-"
            sdvig();     //сдвигаем тире и Ч
            obrzap(32);  // далее 2 пробела
            sdvig();
            sdvig();
            obrzap ((c1/10)+48);   // десятки часов первоначальный вывод
            sdvig2(2);              //вывод и сдвиг
            obrzap ((c1%10)+48);   //единицы часов
            sdvig2(2);                              
            a=25;          // задаём скорость сдвига
          rtc_read_time(&c1, &m1, &s); // считываем во временные переменные значение часов и минут
   while (set==1)    // пока не нажата кнопка "set" изменяем значение часов
       { 
          c1=set_num (23,c1); //изменяем значение часов
   
                  if(flas==1)  // если было изменение параметра то
                  {
                  
                   obrzap ((c1/10)+48);   // десятки часов
                   sdvig2(2);              //вывод и сдвиг
                   obrzap ((c1%10)+48);   //единицы часов
                   sdvig2(2);
                   flas=0;
                   delay_ms(50);
           }
           
                   
                
       }
           delay_ms(500);
            flas=1;
             a=10;
                    obrzap(32);                       
           size=sizeof(str5)-1;   //определяем размер  текста
           for(k=1;k<size;k++)   //выводим  текст "установка минут"
            {
              simv=(str5[k]) ;
              obrzap (simv) ;
              sdvig();
            }
           
                 obrzap(204);
                 sdvig();
                   obrzap(45);
                   sdvig();
                   obrzap(32);
                   sdvig();
                   sdvig();
                   obrzap ((m1/10)+48);   // десятки минут первоначальный вывод
                   sdvig2(2);              //вывод и сдвиг
                   obrzap ((m1%10)+48);   //единицы минут
                   sdvig2(2);                                      
                   a=0;      //пауза0
   while (set==1)    // пока не нажата кнопка "set" изменяем значение минут
       { 
          m1=set_num (59,m1); //изменяем значение минут
   
                  if(flas==1) //если были именения то вывести новые показания 
              {    
             
                   obrzap ((m1/10)+48);   // десятки минут
                   sdvig2(2);              //вывод и сдвиг
                   obrzap ((m1%10)+48);   //единицы минут
                   sdvig2(2);
                   flas=0;       // флаг обновления показаний в ноль
                    delay_ms(20);
               };
           }

      

           a=20;     
           rtc_set_time(c1, m1, 00);   // запись новых данных в микросхему часов
        rtc_read_time(&c, &m, &s); // считываем значения часов,минут,секун
        only_gigit ((c/10)+64);   // десятки часов
        sdvig_vniz(4);            //вывод и сдвиг               
        only_gigit ((c%10)+64);   //единицы часов
        sdvig_vniz(3);
         only_gigit ((m/10)+64);   //десятки минут 
        sdvig_vpravo();
        sdvig_vniz(2);
         only_gigit ((m%10)+64);    //единицы минут
        sdvig_vpravo();
        sdvig_vniz(1);            
           m1++;
           c1++;        
           } 
           
      void temper (int temp)  // **********************вывод температуры в строку
      {
       if (temp<0)      // если показание отрицательное
         {
       obrzap (45);   //выводим минус
       sdvig();
           temp=-temp;        //инвертируем показание 
         }
         a=15;    //замедляем
         if (temp<99)  // если показания корректные (датчик подключен и исправен)
         {               
          obrzap ((temp/10)+48);   //десятки градусов
          if ((temp/10)>0) sdvig(); //если десятки градусов равны 0 то не выводить
           obrzap ((temp%10)+48);   // единицы градусов
           sdvig();
           obrzap (64);  // знак градус
           sdvig();
           obrzap (209);  // "С" цельсия
           sdvig();
        }
        else 
        {
          obrzap (63);  // "?" вопрос если проблемы с датчиком
           sdvig();
           }     
      } 

            
      void set_brightness()       //****** процедура№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№ 
      { 
      
       char unsigned str6[]="   УСТАНОВКА ЯРКОСТИ Я-  ";
       size=sizeof(str6)-1;   //определяем размер  текста
       a=20;
       obrzap(32);
           for(k=1;k<size;k++)   //выводим  текст "установка яркости"
            {
              simv=(str6[k]) ;
              obrzap (simv) ;
              sdvig();
            }
                   obrzap ((brightness/10)+48);   // первоначальный вывод  
                   sdvig2(2);              //вывод и сдвиг
                   obrzap ((brightness%10)+48);   //единицы 
                   sdvig2(2);            
                   a=0;
            
   while (set==1)    // пока не нажата кнопка "set" изменяем значение яркости
       { 
          brightness=set_num (0xf,brightness); //изменяем значение 
   
                  if(flas==1) //если были именения то изменить яркость у всех 4-х матриц 
              {   
                   poket=(0x0A*0x100+brightness); //ввод значения в матрицы
                   adr=1;
                   poc();
                   adr=2;
                   poc();
                   adr=3;
                   poc();
                   adr=4;
                   poc();
                                                   
                   obrzap ((brightness/10)+48);   // десятки 
                   sdvig2(2);              //вывод и сдвиг
                   obrzap ((brightness%10)+48);   //единицы 
                   sdvig2(2);
                   flas=0;       // флаг обновления показаний в ноль
                   
                    delay_ms(180);
               };
            rtc_write(0x10,brightness); //запись нового значения яркости в ОЗУ часов реального времени  
           }            
        rtc_read_time(&c, &m, &s); // считываем значения часов,минут,секун
        only_gigit ((c/10)+64);   // десятки часов
        sdvig_vniz(4);            //вывод и сдвиг               
        only_gigit ((c%10)+64);   //единицы часов
        sdvig_vniz(3);
         only_gigit ((m/10)+64);   //десятки минут 
        sdvig_vpravo();
        sdvig_vniz(2);
         only_gigit ((m%10)+64);    //единицы минут
        sdvig_vpravo();
        sdvig_vniz(1);
            
   }    

  void set_clibration()
    {
      char unsigned str10[]="   УСТАНОВКА КОРРЕКЦИИ ХОДА К   "; //######################################
      signed char colibration,q;//colibration-значение коррекции 0т -31 до+31 для RTC M41T81 0х08 регистр.
      char znak;
      a=5;   // скорость бегущей строки при изменении парамертра
      flas=1; // флаг выставляем в 1 для первоначального отображения значения colibration
       obrzap(32); // стираем значение невидимой матрицы                     
        size=sizeof(str10)-1;   //определяем размер  текста
         for(k=1;k<size;k++)   //выводим  текст "установка коррекции хода"
            {
              simv=(str10[k]) ;
               obrzap (simv) ;
                sdvig();
            }
             colibration=rtc_read (0x08); //считываем значение ранее записанного в ОЗУ в переменную colibration
              if ((colibration & (1 << 5))==0) znak=0; else znak=1;// определяем знак (направление коррекции +-.
               colibration &= ~(1 << 7); // обнулить 7 бит
                colibration &= ~(1 << 6); // обнулить 6 бит                           
                 colibration &= ~(1 << 5); // обнулить 5 бит, они нам не нужны
                  if (znak==0) colibration=-colibration;//если значение было отрицательным, инвертируем его для расчётов 
       
       while (set==1) // пока не нажата кнопка "set" выполнять
           {
                       
              if (dec==0) if(colibration>(-31)) {colibration--;flas=1;} ;// проверка нажатия кнопки "-"
              if (inc==0) if(colibration<31) {colibration++;flas=1;}  // проверка нажатия кнопки "+"                      
               if(flas==1)  //если было изменение параметра то 
                   {
                          if (colibration>0) {obrzap (43);q=1;} // если значение больше нуля вывести "+"
                          if (colibration<0)      // если меньше нуля то
                            {
                              q=-1;// инвертировать в положительное (далее при выводе на табло)
                              obrzap (45);          // вывести минус
                            } 
                          if (colibration==0){obrzap (32);q=1;}// если равно нулю вывести пробел
                          sdvig2(3);
                          obrzap (((colibration*q)/10)+48);   // десятки  
                          sdvig2(3);              //вывод и сдвиг
                          obrzap (((colibration*q)%10)+48);   //единицы 
                          sdvig2(3);                          
                          flas=0;                           
                   }
           }
         if (colibration<0) colibration=-colibration;else colibration=colibration+32;       
         rtc_write(0x08,colibration); //запись нового значения 
         rtc_read_time(&c, &m, &s); // считываем значения часов,минут,секун
         only_gigit ((c/10)+64);   // десятки часов
         sdvig_vniz(4);            //вывод и сдвиг               
         only_gigit ((c%10)+64);   //единицы часов
         sdvig_vniz(3);
         only_gigit ((m/10)+64);   //десятки минут 
         sdvig_vpravo();
         sdvig_vniz(2);
         only_gigit ((m%10)+64);    //единицы минут
         sdvig_vpravo();
        sdvig_vniz(1);                     
               }
       //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      
      time_show(unsigned char j)   //*************вывод времени 
    {  
      while (j>0)
          { 
       
       rtc_write(0x0c,0);//обнуляем HALT-bit что бы часы пошли 
       rtc_read_time(&c, &m, &s); // считываем значения часов,минут,секун
       
       if ((c/10)!=(c1/10)) 
       {
        only_gigit ((c/10)+64);   // десятки часов
        sdvig_vniz(4);            //вывод и сдвиг 
       };
       if ((c%10)!=(c1%10))
       {              
        only_gigit ((c%10)+64);   //единицы часов
        sdvig_vniz(3);
       };              //

       if ((m1/10)!=(m/10))
       { 
        only_gigit ((m/10)+64);   //десятки минут 
        sdvig_vpravo();
        sdvig_vniz(2);
       };
       if ((m1%10)-(m%10)!=0)
       { 
        only_gigit ((m%10)+64);    //единицы минут
        sdvig_vpravo();
        sdvig_vniz(1);
       };
       
       if (s1!=s) {j--;if (k==1) k=0; else k=1;} // если была смена секунды изменить флаг к
      if (k==1)         //если к=1 вывести двоеточие
      {                 //ниже вывод двоеточия непосредственно в матрицу ( точнее в драйвер матрицы)
      
        obraz1[9] |= (1 << 0);
      obraz1[10] |= (1 << 0);
      obraz1[13] |= (1 << 0);
      obraz1[14] |= (1 << 0);
      adr=2;      
       poket=0x200+obraz1[9];    
       poc();
       poket=0x300+obraz1[10];
       poc(); 
       poket=0x600+obraz1[13];    
       poc();
       poket=0x700+obraz1[14];
       poc();
       } 
       else                 // если к=0 то потушить двоеточие
      {
      
      obraz1[9]&= ~ (1 << 0);
      obraz1[10] &= ~ (1 << 0);
      obraz1[13] &= ~ (1 << 0);
      obraz1[14] &= ~ (1 << 0);
      adr=2;      
       poket=0x200+obraz1[9];    
       poc();
       poket=0x300+obraz1[10];
       poc(); 
       poket=0x600+obraz1[13];    
       poc();
       poket=0x700+obraz1[14];
       poc();
       }       
                   
        rtc_read_time(&c1, &m1, &s1); // считываем время
        if (set==0)  set_time();   //если нажата кнопка set запустить процедуру установки времени
        if (dec==0)  set_brightness();  //если нажата кнопка - запустить процедуру установки яркости
        if (inc==0)  set_clibration();
        delay_ms(500);
        
       } 
       }
       
       temp_show(unsigned char j)  //****************вывод температуры  j- время вывода в секундвх
       { unsigned char q; //номер знакоместа
       
 
          q=4; 

              
             tem2=ds18b20_temperature(0); //считываем температуру              
       if (tem2<0)      // если показание отрицательное
         {
           only_gigit (74);   //выводим минус
           sdvig_vpravo();
           sdvig_vniz(q);
           q--;
           tem2=-tem2;        //инвертируем показание
            
         }
         
         if (tem2<99)  // если показания корректные (датчик подключен и исправен)
         {               
          only_gigit ((tem2/10)+64);   //десятки градусов
          if ((tem2/10)>0)
          {   
              sdvig_vpravo();
              sdvig_vniz(q); //если десятки градусов равны 0 то не выводить
              q--;
           }   
           only_gigit ((tem2%10)+64);   // единицы градусов выводить по любому 
           sdvig_vpravo();
           sdvig_vniz(q);
           q--;
           only_gigit (75);  // знак градус
           sdvig_vpravo();
           sdvig_vniz(q);
           q--; 
           if (q>=1)    //если не последнее знакоместо то вывести ещё и знак "цельсия"
           {
            only_gigit (76);
            sdvig_vpravo();
            sdvig_vniz(q);
            q--;
            obrzap (224); //затереть содержимое нулевой матрицы
            }
            if (q==1) //если всё уже выведено и последнее знакоместо ещё не заполнено то стереть его
            {
            obrzap (224);     // вывод пробела
            sdvig_vniz(q);
            }

        }
        else 
        { 
          for (q=4;q>0;q--)
          {
          obrzap (63);  // "?" вопрос если проблемы с датчиком
          sdvig_vniz(q);
          }
           
           }
                         
           while (j>0)
           {
           
            rtc_read_time(&c1, &m1, &s1); // считываем время
           delay_ms(50);
           rtc_read_time(&c1, &m1, &s); // считываем время
            if (s1!=s) j--;          
           }
     
           }
// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}

         
               

void main(void)
{

// Port B initialization
// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (1<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=P Bit1=P Bit0=P 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=In Bit1=In Bit0=In 
DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=(0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1,0486 s
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<TOIE0);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

// ADC initialization
// ADC Clock frequency: 62,500 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
SFIOR=(0<<ACME);


// Bit-Banged I2C Bus initialization
// I2C Port: PORTD
// I2C SDA bit: 1
// I2C SCL bit: 0
// Bit Rate: 100 kHz
// Note: I2C settings are specified in the
// Project|Configure|C Compiler|Libraries|I2C menu.
i2c_init();

// 1 Wire Bus initialization
// 1 Wire Data port: PORTD
// 1 Wire Data bit: 2
// Note: 1 Wire port settings are specified in the
// Project|Configure|C Compiler|Libraries|1 Wire menu.

w1_init();
delay_ms(500);
#asm("sei") 
     adr=1;      //первая матрица
     matrinit(); // инициализируем микросхему
     matrclr();  // стираем  её
     adr=2;     // вторую тоже самое
     matrinit(); 
     matrclr();
     adr=3;      //так далее
     matrinit(); 
     matrclr();  
     adr=4;     
     matrinit(); 
     matrclr();     
     i2c_init();   // инициализируем ай ту си
     w1_init();   // инициализируем один вире
     size=rtc_read(0x08);    // хз  но в прошлом проекте часы без этого не шли 
     size &= ~(1 << 6);
     rtc_write(0x08,size); 
     brightness=rtc_read (0x10); //считываем значение яркости, ранее записанное в ОЗУ часов ранее (до откл. питания)
     if (brightness>15) brightness=6; //если в ОЗУ часов ХЗ что,то установить яркость 6
                   poket=(0x0A*0x100+brightness); //ввод значения яркости в матрицы
                   adr=1;
                   poc();
                   adr=2;
                   poc();
                   adr=3;
                   poc();
                   adr=4;
                   poc();     
      size=sizeof(str9)-1;  //выводим  текст ПРИВЕТСТВИЯ
       a=20; // скорость бегущей строки
       for(k=1;k<size;k++)
       {
       simv=(str9[k]) ;
       obrzap (simv) ;
       sdvig();  
       }           
       obrzap (225);
       sdvig();
      size=sizeof(str12)-1;  //выводим  текст ПРИВЕТСТВИЯ
       for(k=1;k<size;k++)
       {
       simv=(str12[k]) ;
       obrzap (simv) ;
       sdvig();  
       }        
     
while (1)        //основной цикл


      { 
             rtc_read_time(&c, &m, &s); // считываем значения часов,минут,секу для первого вывода
             only_gigit ((c/10)+64);   // десятки часов
             sdvig_vniz(4);            //замещение старого показания
             only_gigit ((c%10)+64);   //единицы часов
             sdvig_vniz(3);
             only_gigit ((m/10)+64);   //десятки минут 
             sdvig_vpravo();          //центровка цифры на 2 позиции вправо (для симметрии относительно двоеточия)
             sdvig_vniz(2);           // замещение старого показания
             only_gigit ((m%10)+64);    //единицы минут далее то же самое
             sdvig_vpravo();
             sdvig_vniz(1);        
             time_show(30);
             temp_show(4);
             

      if (c>7 && c<21) // ЭТО  КОГДА ЯРКО СВЕТИТЬ  после 7 утра и до 21 
                {   poket=(0x0A*0x100+brightness); // миним яркость 
                   adr=1;
                   poc();
                   adr=2;
                   poc();
                   adr=3;
                   poc();
                   adr=4;
                   poc();  
                   }
                      
      else       //изменяем значение, в ночное время яркость 0
                {   poket=(0x0A*0x100);
                   adr=1;
                   poc();
                   adr=2;
                   poc();
                   adr=3;
                   poc();
                   adr=4;
                   poc();  
                   }      
      

        if (set==0)  set_time();   //если нажата кнопка set запустить процедуру установки времени
        if (dec==0)  set_brightness();  //если нажата кнопка - запустить процедуру установки яркости
        if (inc==0)  set_clibration();
        

          
        }       
        }