#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))

// *******************************************************************************
char CurrentDisp=0;
char symb[] = {128,230,40,36,70,20,16,166,0,4,2,80,152,96,24,26};  // таблица для отображения на LED цифр 0 - F
char dsym[] = {152,152};   // тут храним какой символ выводить на левый и правый индикаторы. Сейчас СС
int counter;

// *******************************************************************************
// Вывод символа на сдвоенный 7-ми сегментный индикатор
// включение нужного индикатор управляется PD0 - левый, PB0 - правый
// сегменты формируются на PB1-PB7;
void DispSymbol( char dispNo,  char sym)
{
   // включаем или выключаем левый индикатор
   if(dispNo==0)
      sbi(PORTD, PD0);
   else
      cbi(PORTD, PD0);
   // а правый включается или выключается автоматом, потому как "+ DispNo"
   PORTB = sym + dispNo;
}

// *******************************************************************************
// обработка прерывания от таймера каждые 2 мс меняем активный индикатор
// каждый 100-й раз пробуем получить значение с АЦП
SIGNAL(SIG_OVERFLOW0)
{
   // прерывания запрещаем
   counter++;
   cli();
   CurrentDisp ^= 1;                             // сменили дисплей с 0 на 1-й или наоборот
   DispSymbol(CurrentDisp,dsym[CurrentDisp]);    // вывели символ
   TIMSK |= (1<<TOIE0);
   TCNT0 = 0x83;                                 // запустили таймер снова
   sei();
}

int main(void)
{
   char js0, js1;
   counter=0;

   DDRD = 0x01;   // Порт D пин 0 - выход - будет включать левый индикатор дисплея
   DDRB = 0xFF;   // Порт B все пины - выход. PD0 будет включать правый индикатор, PB1-PB7 - сегменты 

   sbi(DDRC, PC5);

   DispSymbol(0,symb[10]);   // выводим на левый индикатор 'A' - просто так, чтоб было что-то

   dsym[0] = symb[7];        // формируем картинку 7F
   dsym[1] = symb[15];

   PORTC |= (1<<PC5);

   // Timer 0 используем для динамической индикации
   TCCR0 = 3;    // Делитель = 64
   TCNT0 = 0x83; // 2 мс
   TIMSK |= (1<<TOIE0);
   sei();


   // понеслась
   while(1)
   {
      if(counter>=5000)
      {
         PORTC &= ~(1<<PC5);
         ADMUX  = 0b11100000;
         ADCSRA = 0b11000110;
         // ждем выполнения преобразования
         while(ADCSRA && (1<<ADIF) != (1<<ADIF))
         {
            // используем только старший байт результата
            js0 = ADCH;
            js1 = js0 & 0x0F;          // младшие четыре бита будут символом на правом индикаторе
            js0 = (js0 & 0xF0) >> 4;   // старшие четыре бита будут символом на левом индикаторе
            dsym[0] = symb[js0];        // запомнили эти значения
            dsym[1] = symb[js1];
            cbi(ADCSRA, ADIF);
         }
         /*
         js0 = 0xA5;
         js1 = js0 & 0x0F;
         js0 = (js0 & 0xF0) >> 4;
         dsym[0] = symb[js0];
         dsym[1] = symb[js1];
         */
         counter=0;
         PORTC |= (1<<PC5);
      }
   }
}

