
#include <mega8.h>
#include <delay.h>
unsigned long vol2,cur2,cur1=0,vol1=0,vol,cur;
unsigned char i,j;
unsigned char glob_array[8];
#define g PORTC.2
#define c PORTC.3
#define h PORTC.4
#define d PORTC.5
#define e PORTD.0
#define a PORTD.1
#define f PORTD.2
#define b PORTD.3
#define e1 PORTD.5
#define e2 PORTD.6
#define e3 PORTD.7
#define e4 PORTB.0
#define e5 PORTB.1
#define e6 PORTB.2
#define e7 PORTB.3
#define e8 PORTB.4

interrupt [TIM1_OVF] void timer1_ovf_isr(void)   //прерывание по таймеру1 зажигаем сегменты и цифры
{
 unsigned char j;
TCNT1=65435;

 for (i=0;i<8;i++)     // восем знакомест заполняем содержимым
     {
             // ниже поджигаем нужный нам катод (в схеме стоят транзисторы инверторы то есть на транзистор + , а на катод -)
            
            switch (i)                                     
               {
                case (0): { e1=1;break;}
                case (1): { e2=h=1;break;}   //h это запятая по вольтам
                case (2): { e3=1;break;}
                case (3): { e4=1;break;}
                case (4): { e5=h=1;break;}  // h это запятая по амперам
                case (5): { e6=1;break;}
                case (6): { e7=1;break;}
                case (7): { e8=1;break;}
                }
             for (j=0;j<13;j++)
             {                                   
               switch (glob_array[i])
                 {   
                     case (0): { a=b=c=d=e=f=1;g=0; break;} // "0"                
                     case (1): { b=c=1;a=d=e=f=g=0; break;} // "1"
                     case (2): { a=b=g=e=d=1;c=f=0; break;} // "2"
                     case (3): { a=b=g=c=d=1;e=f=0; break;} 
                     case (4): { f=g=b=c=1;a=d=e=0; break;} 
                     case (5): { a=f=g=c=d=1;b=e=0; break;} 
                     case (6): { a=f=g=c=d=e=1;b=0; break;} 
                     case (7): { a=b=c=1;d=e=f=g=0; break;} 
                     case (8): { a=b=c=d=e=f=g=1; break;}   // "8"
                     case (9): { a=b=g=f=c=d=1;e=0; break;} // "9"
                     case (10): { b=c=d=e=f=1;a=g=0; break;}   // "U"
                     case (11): { a=b=c=e=f=g=1;d=0; break;}   // "A"
                     case (12): { g=1;a=b=c=d=e=f=0; break;}   // "-" 
                     case (13): { a=b=c=d=e=f=g=0; break;}   // "пробел"           
                    
                 }
              }
            delay_us(10);  
            e1=e2=e3=e4=e5=e6=e7=e8=a=b=c=d=e=f=g=h=0;  // гасим все к хуям
     }
    
 }
 

#define ADC_VREF_TYPE ((1<<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 zapmas ( int x1,unsigned char v)    //++++функц. заполнения массива цифрами АЦП
          {          
           char x2=-1;           // вспомог переменная
                     {
                       
                        while (x1>=0) 
                              { 
                                x2=x2+1;
                                x1=x1-1000; 
                               }
                                   if (v==1) glob_array[0]=x2; else glob_array[4]=x2;
                                   x1=x1+1000;
                     } 
                                              
            x2=-1;           // вспомог переменная  обьявить после настройки
                 while (x1>=0) 
                              { 
                                x2=x2+1;
                                x1=x1-100; 
                               }
                                  if (v==1) glob_array[1]=x2; else glob_array[5]=x2;
                                   x1=x1+100;
              x2=-1;
        
              while (x1>=0) 
                 {
                   x2=x2+1;
                   x1=x1-10;
                 }
                                   if (v==1) glob_array[2]=x2; else glob_array[6]=x2;
                                   x1=x1+10;

          }          
          
            
          
           
void main(void)
{


// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=In Bit0=In 
DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 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=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=T Bit3=0 Bit2=0 Bit1=0 Bit0=0 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (1<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 500,000 kHz
TCCR0=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
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) | (1<<TOIE0);


// ADC initialization
// ADC Clock frequency: 250,000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ACME);

#asm("sei")
       glob_array[3]=10;
       glob_array[7]=11;
while (1)
      {   

          #asm("cli")      // запрет прерываний на время считывания АЦП и заполненмя массива лед-индикатора

        cur=read_adc(6)*10;   // считываем значение тока с 6-го канала АЦП в переменную cur
        vol=read_adc(7)*3;   // считываем значение напряжения с 7-го канала АЦП в переменную vol
        vol=(vol*93+400)/100;   // коррекция показаний напруги 
      // cur=(cur*4833)/1000; //коррекция показаний тока  cur=(cur*963+37500)/1000; -для шунта 15 ампер
       // if (cur<50) cur1=0; // если ток менее 40ма то показывать 0 (из за гавнистости лм358)
        cur2=cur2+cur;
        vol2=vol2+vol;

        if (j==64)    // количество измерении
                  {
                   j=0;
                   vol1=vol2>>6; // среднее арифметическое показ. напряжения для вывода на лед
                   cur1=cur2>>6; // среднее арифметическое показ. тока для вывода на лед
                   zapmas (vol1, 1);
                   if ( glob_array[0]==0 ) glob_array[0]=13;  // если первый ноль, то вывести пробел
                   zapmas (cur1, 0);
                   vol2=0;
                   cur2=0;
                  }
       j++;
       if (cur1>1999) PORTD.4=1 ; else PORTD.4=0; //если ток более 1,99А включить кулер, иначе выключить
       if (vol1>3600) glob_array[0]=glob_array[1]=glob_array[2]=12;  //если напруга более 36 В то выводим прочерки
       if (cur1>5500) glob_array[4]=glob_array[5]=glob_array[6]=12;   // если ток более 5,5 ампер то выводим прочерки

       #asm("sei")  // разрешаем прерывания где происходит вывод показаний на лед индикатор
  
                
      }
}
