#define Bit(n) (1 << (n))
/*
  p |= Bit(n);                Для установки бита n в порту p:
  p &= ~Bit(n);               Для сброса бита n в порту p:
  if ((p & Bit(n)) != 0) ...  Для проверки бита n в порту p: (сравнение)
*/
#define EEADR1 16                                                               // коеффициент       (адрес EE, куда сохраняем,
#define EEADR2 22                                                               // общий расход       любой, больше 1)
#define EEADR3 32
#define EEADR4 44
#define EEADR5 50
#define EEADR6 56
#define EEADR7 62
#define EEADR8 68
#define EEADR9 74
#define EEADR10 80
#define EEADR11 87
#define EEADR12 93

#include <iom168.h>
#include <inavr.h>
#include <stdio.h>
#include <string.h>

static char _tempADC=0;
static char seg[4],seg_count=0;                                                 // массив для хранения числа одного их 4-х индикаторов при динамической индикации; номер выводимого индикатора
static char timer2comp=0,g_eesave_en=0;                                         // флаги для обновления экрана, сохранения в EE
static char str[10];
static unsigned short ADCrez=0,g_Hset=0,g_Vset=10,g_Sset=0,g_Mset;                                        // значение переменной в АЦП; коэффициент (производительность форсунки)
static char g_Uset=1,g_Hblk=3,g_Hled=0;                                         // выбор режима (User); "мигание" n-го разряда индикатора (дисплея); флаг для управлением миганием разряда
static unsigned short g_time_ovf=0;                                             // число "раз" переполнения таймера
static unsigned long g_fors_time=0,g_full_time=0,g_total_fuel=0,med_total_fuel=0;                // t(время) одного импулса; t всех имп. в ед. времени; сумма t всех имп. /1000 (делен. на 1000), т.к. иначе нам не хватит разрядности из-за очень большого числа
static unsigned long g_full_count=0,g_total_count=0,g2_total_count;
static unsigned long g_total_tachom=0,g_full_tachom=0;
static unsigned long med_total_count=0,money_temp_fuel=0,time_full=0;
static unsigned short g_time_s=0,mg_fuel=0,rash_stand=0,max_speed=0;                                     // время ед. времени, за которую показывается мгновенный час. расход;

//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = INT1_vect                                                      // INT1 (
__interrupt void MY_INT1 (void)                                                 // стандартная запись)
{
    if ((EICRA & Bit(ISC10)) != 0)                                              // прерывание произошло по нарастающему фронту
    {   TCCR1B = Bit(CS11);                                                     // запуск таймера c clk/8
        EICRA &= ~Bit(ISC10);                                                   // сбрасываем бит в регистре EICRA для инициализации следующего прерывания по спадающему фронту
    }
    else                                                                        // прерывание произошло по спаду
    {   TCCR1B = 0;                                                             // останов таймера
        EICRA |= Bit(ISC10);                                                    // устанавливаем бит в регистре EICRA для инициализации следующего прерывания по нарастающему фронту
        g_fors_time = g_time_ovf; g_fors_time = g_fors_time << 16; g_fors_time = g_fors_time + TCNT1;   // сумма полных переполнений таймера, 16-бит. значение, и его текущего 8-бит. значения
        g_full_time = g_full_time + g_fors_time;
        TCNT1 = 0; g_time_ovf=0;
        g_full_tachom ++;
    }
    
}

//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = INT0_vect                                                      // INT0 (
__interrupt void MY_INT0 (void)                                                 // стандартная запись)
{
    if ((EICRA & Bit(ISC00)) != 0)                                              // прерывание произошло по нарастающему фронту
    {  
         g_full_count ++;
         EICRA |= Bit(ISC00);                                                   // устанавливаем бит в регистре EICRA для инициализации следующего прерывания по нарастающему фронту
    }

}

//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = TIMER0_OVF_vect                                                // timer 0 overflow
__interrupt void MY_TIMER0_OVF (void)
{
    if ((PORTD & Bit(1)) == 0) {PORTD |= Bit(1);} else {PORTD &= ~Bit(1);}
}

//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = TIMER1_OVF_vect                                                // timer 1 overflow - таймер переполнения
__interrupt void MY_TIMER1_OVF (void)
{
g_time_ovf ++;                                                                  // считаем "разряды" (число раз переполнения 65536) и увеличиваем на 1

    if (g_time_ovf > 46)                                                        // 2 сек нет сигнала - 12000000/8/65536 = 23 (раз) - это 1 сек.(примерно) -- без этой функции программа будет считать форсунку открытой при включенном зажигании и неработающем двигателе, тем самым... сами понимаете
    {
      TCCR1B = 0;                                                                // останов таймера
      EICRA |= Bit(ISC10);                                                       // устанавливаем бит в регистре EICRA для инициализации следующего прерывания по нарастающему фронту
      TCNT1 = 0; g_time_ovf=0;
      g_eesave_en=1;                                                             // ставим флаг для сохранения по этому событию в EE
    }    
}
//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = ADC_vect                                                       // ADC - 10-бит АЦП
__interrupt void MY_ADC (void)
{
  ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8);                                   // считывание из 2-х регистров 10-битного значения АЦП, (сначало младший (L), потом старший (H)
  _tempADC = 1;
}
//-----------------------------------------------------------------------------------------------------------------------------
#pragma vector = TIMER2_COMPA_vect                                               // ф-ция для установки флага ПО СРАВНЕНИЮ с заданным числом раз его отсчетов (у нас 11719), т.е. каждые 11719 тиков таймера прибавляется 1 (у нас 33);
__interrupt void MY_TIMER2_COMPARE (void)                                       // и если мы принудительно сбросим флаг (в период времени) до 33, то по достижению 33 флаг сам снова установится (у нас это используется для
{                                                                               // обновления экрана при динамической индикации, см. ниже в main)
timer2comp=1;
}
//-----------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------
void init ()                                                                    // начальная инициализация
{
char m=0;                                                                       // вспомогательная переменная для чтения из EE
DDRD |= Bit(5);                                                                 // порты на выход
DDRD |= Bit(6);
DDRD |= Bit(7);
DDRB |= Bit(0);
DDRB |= Bit(1);
DDRB |= Bit(2);
DDRB |= Bit(3);
DDRB |= Bit(4);

DDRC |= Bit(3);
DDRC |= Bit(4);
DDRC |= Bit(5);
DDRD |= Bit(0);

DDRD |= Bit(4);
PORTD &= ~Bit(3);                                                               // INT1  (по умолчанию на вход) и сбросить бит, установить в 0 (нет сигнала с форсунки)
PORTD &= ~Bit(2);

DDRD |= Bit(1);

seg[0]=4; seg[1]=94; seg[2]=28; seg[3]=119;                                     // начальный "тестовый" вывод на индикатор "Audi"

//------------------------------------------------------------- watchdog
WDTCSR = Bit(WDE) | Bit(WDCE);
WDTCSR = Bit(WDE) | Bit(WDP2) | Bit(WDP1) | Bit(WDP0);
WDTCSR &= ~Bit(WDCE);
//------------------------------------------------------------- timer counter 2
OCR2A = 33;                                                                     // установка "делителя" в регистре сравнения для определения частоты обновления "экрана" индикатора 12000000/1024(делитель см. ниже) / 33 = 360, 360/4=90 - частота "мерцания" одного разряда индикатора
TIMSK2 |= Bit(OCIE2A);                                                          // устанавливаем флаг разрешения прерывания по событию "совпадение" таймера/счетчика Т2
TCCR2A = Bit(WGM21);                                                            // путем побитного "сравнения" установить биты в разрядах регистра TCCR2 : CTC(сброс при совпадении), остальные - для установки делителя в 1024
TCCR2B = Bit(CS22) | Bit(CS21) | Bit(CS20);
//------------------------------------------------------------- timer counter 1
TIMSK1 |= Bit(TOIE1);                                                            // устанавливаем флаг разрешения прерывания по переполнению таймера/счетчика Т1
//------------------------------------------------------------- timer counter 0
TIMSK0 |= Bit(TOIE0);
TCCR0B = Bit(CS01);
//----------------------------------------------------------------------- INT 1
EICRA |= Bit(ISC11);                                                            // начальная (и const всегда) установка бита для условия генерации внеш. прерывания по любому фронту
EICRA |= Bit(ISC10);                                                            // начальная установка бита для условия генерации внеш. прерывания по нарастающему фронту
EIMSK |= Bit(INT1);                                                             // разрешение внешнего прерывания INT1
//----------------------------------------------------------------------- INT 0
EICRA |= Bit(ISC01);                                                            // начальная (и const всегда) установка бита для условия генерации внеш. прерывания по любому фронту
EICRA |= Bit(ISC00);                                                            // начальная установка бита для условия генерации внеш. прерывания по нарастающему фронту
EIMSK |= Bit(INT0);                                                              // разрешение внешнего прерывания INT0
//------------------------------------------------------------------------- ADC
ADMUX = Bit(REFS0) | Bit(REFS1);                                                // внутренний источнник опорного напряжения - 2.56 V
ADCSRA = Bit(ADEN) | Bit(ADIE) | Bit(ADPS2) | Bit(ADPS1) | Bit(ADPS0);          // путем побитного "сравнения" установить биты в разрядах регистра ADCSR : АЦП включено, остальные - для установки делителя частоты преобразования в 128
ADCSRA |= Bit(ADSC);                                                            // запуск каждого преобразования в режиме одиночного преобразования (у нас) по первому нарастающему фронту тактового сигнала
DIDR0 |= Bit(ADC0D);
//--------------------------------------------------------------------- read EE
__EEGET(g_Hset, EEADR1); g_Hset = g_Hset << 8; __EEGET(m, EEADR1+1); g_Hset = g_Hset + m;   // чтение 1-го байта 16-бит g_Hset по адресу EEADR1 с последующим чтением второго байта по адресу EEADR1+1
if (g_Hset > 9999) g_Hset = 517;                                                  // при первой прошивки "обнулить в памяти" все F -ы

__EEGET(g_Vset, EEADR3); g_Vset = g_Vset << 8; __EEGET(m, EEADR3+1); g_Vset = g_Vset + m;
if (g_Vset > 9999) g_Vset = 440;

__EEGET(max_speed, EEADR5); max_speed = max_speed << 8; __EEGET(m, EEADR5+1); max_speed = max_speed + m;
if (max_speed > 9999) max_speed = 0;

__EEGET(g_Sset, EEADR8); g_Sset = g_Sset << 8; __EEGET(m, EEADR8+1); g_Sset = g_Sset + m;
if (g_Sset > 9999) g_Sset = 60;

__EEGET(g_Mset, EEADR10); g_Mset = g_Mset << 8; __EEGET(m, EEADR10+1); g_Mset = g_Mset + m;
if (g_Mset > 9999) g_Mset = 1860;


__EEGET(g_total_fuel, EEADR2); g_total_fuel = g_total_fuel << 8;                // чтение 1-го байта 32-бит g_total_fuel по адресу EEADR2 с последующим чтением второго и т.д. байта; по адресу EEADR2 считываем данные и заносим их в g_total_fuel,
__EEGET(m, EEADR2+1); g_total_fuel = g_total_fuel + m; g_total_fuel = g_total_fuel << 8;   // затем сдвигаем данные на 8 разрядов влево, тем самым увеличивая разрядность g_total_fuel до 16 бит, далее считываем данные по адресу EEADR2+1 и
__EEGET(m, EEADR2+2); g_total_fuel = g_total_fuel + m; g_total_fuel = g_total_fuel << 8;   // заносим их в "m", после к предыдущему значению g_total_fuel прибавляем "m" и записываем все g_total_fuel с последующим сдвигом влево также на 8
__EEGET(m, EEADR2+3); g_total_fuel = g_total_fuel + m;                          // разрядов и увеличением размера g_total_fuel до 3-х байт, и т.д. до 4-х(32) байт(бит), и в итоге, с полным считыванием конечного значения g_total_fuel из EE;
                                                                                // у нас сделано так, что мы из памяти берем полное время открытия форсунки, чтобы затем подставив его в "нашу" формулу расчитать полный расход и вывести его на дисплей
//----------
__EEGET(g_total_count, EEADR4); g_total_count = g_total_count << 8;
__EEGET(m, EEADR4+1); g_total_count = g_total_count + m; g_total_count = g_total_count << 8;
__EEGET(m, EEADR4+2); g_total_count = g_total_count + m; g_total_count = g_total_count << 8;
__EEGET(m, EEADR4+3); g_total_count = g_total_count + m;

//----------
__EEGET(med_total_fuel, EEADR6); med_total_fuel = med_total_fuel << 8;
__EEGET(m, EEADR6+1); med_total_fuel = med_total_fuel + m; med_total_fuel = med_total_fuel << 8;
__EEGET(m, EEADR6+2); med_total_fuel = med_total_fuel + m; med_total_fuel = med_total_fuel << 8;
__EEGET(m, EEADR6+3); med_total_fuel = med_total_fuel + m;

//----------
__EEGET(med_total_count, EEADR7); med_total_count = med_total_count << 8;
__EEGET(m, EEADR7+1); med_total_count = med_total_count + m; med_total_count = med_total_count << 8;
__EEGET(m, EEADR7+2); med_total_count = med_total_count + m; med_total_count = med_total_count << 8;
__EEGET(m, EEADR7+3); med_total_count = med_total_count + m;

//----------
__EEGET(g2_total_count, EEADR9); g2_total_count = g2_total_count << 8;
__EEGET(m, EEADR9+1); g2_total_count = g2_total_count + m; g2_total_count = g2_total_count << 8;
__EEGET(m, EEADR9+2); g2_total_count = g2_total_count + m; g2_total_count = g2_total_count << 8;
__EEGET(m, EEADR9+3); g2_total_count = g2_total_count + m;

//----------
__EEGET(money_temp_fuel, EEADR11); money_temp_fuel = money_temp_fuel << 8;
__EEGET(m, EEADR11+1); money_temp_fuel = money_temp_fuel + m; money_temp_fuel = money_temp_fuel << 8;
__EEGET(m, EEADR11+2); money_temp_fuel = money_temp_fuel + m; money_temp_fuel = money_temp_fuel << 8;
__EEGET(m, EEADR11+3); money_temp_fuel = money_temp_fuel + m;

//----------
__EEGET(time_full, EEADR12); time_full = time_full << 8;
__EEGET(m, EEADR12+1); time_full = time_full + m; time_full = time_full << 8;
__EEGET(m, EEADR12+2); time_full = time_full + m; time_full = time_full << 8;
__EEGET(m, EEADR12+3); time_full = time_full + m;

//-----------------------------------------------------------------------------
__enable_interrupt();                                                           // разрешить все прерывания (в регистре SREG установить бит 7, называющийся " I "
}
//-----------------------------------------------------------------------------------------------------------------------------
char OutDisp ()                                                                 // динамическая индикация и "сканирование клавиатуры"
{
static char key=0;                                                              // переменная для хранения номера нажатой кнопки

    PORTD &= ~Bit(0);                                                           // общие аноды разрядов индикатора отключить (погасить) 
    PORTC &= ~Bit(5);
    PORTC &= ~Bit(4);
    PORTC &= ~Bit(3);

  if ((seg[seg_count] & Bit(0)) != 0)   {PORTD &= ~Bit(6);} else {PORTD |= Bit(6);}   // вывод данных на сегменты "соответствующего" индикатора: включение сегмента происходит по нулевому сигналу; например
  if ((seg[seg_count] & Bit(1)) != 0)   {PORTD &= ~Bit(7);} else {PORTD |= Bit(7);}   // seg[0] = 11011000, тогда путем побитного "сравнения" с "11111111" зажечь (напротив 1) или погасить (напротив 0)
  if ((seg[seg_count] & Bit(2)) != 0)   {PORTB &= ~Bit(0);} else {PORTB |= Bit(0);}   // соответствующие сегменты одного индикатора; а также "упорядочивание" выходов портов на сегменты с номером разряда
  if ((seg[seg_count] & Bit(3)) != 0)   {PORTB &= ~Bit(1);} else {PORTB |= Bit(1);}   // 8-бит числа и в соответствии с "a b c d e f g h" : PD6-a(0-й, младший разряд), PD7-b, ..., PB4-g, PD5-h(7-й, старший)
  if ((seg[seg_count] & Bit(4)) != 0)   {PORTB &= ~Bit(2);} else {PORTB |= Bit(2);}
  if ((seg[seg_count] & Bit(5)) != 0)   {PORTB &= ~Bit(3);} else {PORTB |= Bit(3);}
  if ((seg[seg_count] & Bit(6)) != 0)   {PORTB &= ~Bit(4);} else {PORTB |= Bit(4);}
  if ((seg[seg_count] & Bit(7)) != 0)   {PORTD &= ~Bit(5);} else {PORTD |= Bit(5);}

    if (seg_count == 0) {PORTD |= Bit(0);} else {PORTD &= ~Bit(0);}             // включение соответствующего индикатора
    if (seg_count == 1) {PORTC |= Bit(5);} else {PORTC &= ~Bit(5);}
    if (seg_count == 2) {PORTC |= Bit(4);} else {PORTC &= ~Bit(4);}
    if (seg_count == 3) {PORTC |= Bit(3);} else {PORTC &= ~Bit(3);}

  if ((PINC & Bit(2)) != 0) {key |= Bit(seg_count); } else {key &= ~Bit(seg_count);}   // чтение кнопок ("сканирование клавиатуры): если нажата n-кнопка, прописываем в key соответствующий бит по номеру n-кнопки, которая
                                                                                // определяется при включении соответствующего индикатора: (первый (0-вой) - 0001 (1), второй - 0010 (2), 3-й - 0100 (4), 4-й - 1000 (8)
seg_count++;                                                                    // динамический переход на следующий индикатор
if (seg_count > 3) seg_count=0;                                                 // зацикливание функции
return key;                                                                     // вернуть значение key для последующего использования для определения нажатой кнопки
}
//-----------------------------------------------------------------------------------------------------------------------------
char getCode (char ch)                                                          // "сопоставление" символам из таблицы ASCII "наших" символов,
{                                                                               // составленных из отдельных сегментов индикаторв при помощи
    switch (ch)                                                                 // представления в десятичном коде, например:
    {   case '0': return  63; // "0"                                            // 63 - 0b00111111, а это "зажечь" сегменты - abcdef, следовательно на индикаторе высветится цифра - 0
        case '1': return   6; // "1"                                            // 0b00000110 - bc
        case '2': return  91; // "2"                                            // 0b01011011 - ab de g
        case '3': return  79; // "3"
        case '4': return 102; // "4"
        case '5': return 109; // "5"
        case '6': return 125; // "6"
        case '7': return   7; // "7"
        case '8': return 127; // "8"
        case '9': return 111; // "9"
        case 'U': return  62; // 
        case 'H': return 118; // 
        case 'F': return 113; // 
        case ' ': return   0; // 
        case 'L': return  56; // 
        case 'C': return  57; // 
        case 'P': return 115; // 
        case 'E': return 121; // 
        case 'W': return  55; // "П"
        case 'Y': return 110; //
        case 'G': return  49; // "Г"
        case 'A': return 119; //
        case 'u': return  28; //
        case 'd': return  94; //
        case 'i': return   4; //
        case 'o': return  92; //
        case 'n': return  84; //
        case 't': return 120; //
        case 'c': return  88; //
        case 'h': return 116; //
        case 'r': return  80; //
        case '-': return  64; //
        case 's': return  97; //
//        case 'O': return  99; //
    }
return 1;                                                                       // на всякий, "пожарный" (будет гореть один верхний сегмент "a" на индикаторе)
}
//-----------------------------------------------------------------------------------------------------------------------------
void SetDataDisp (char mode, unsigned long parameter)                          // представление 16-тиричного числа в виде 10-тичного
{                                                                               // и вывод его посредством строки ("картинки")
static char s;
    switch (mode)
    {   case 0:                                                                 // тестовый вывод - "4321"
                break;
        case 1:                                                                 // напряжение
                sprintf (str,"U%3d",parameter);                                 // выводим "U"(напряжение); первые 3 разряды целого 10-тичного числа; 16-тиричную переменную в parameter преобразовываем в 10-тичную и выводим(зажигаем) на индикаторе в виде строки посредством функции getCode
                s=getCode (str[0]); seg[3]=s;                       // посредством функции getCode зажигаем на 1-ом слева(лв.) индикаторе - "U"; при побитном ИЛИ устанавливаем бит в 7-ом разряде, тем самым зажигая сегмент "h", т.е. точку на 1-ом лв. индикаторе; обновление массива данных для вывода на дисплей(индикаторы), т.е. обновление 1-го лв. индикатора с последующим его зажиганием функцией OutDisp
                s=getCode (str[1]); seg[2]=s;                                   // посредством функции getCode зажигаем на 2-ом лв. индикаторе - 1-ую цифру первых 3-х разрядов(%3d) целого числа, преобразованного из переменной parameter, формула вывода напряжения (в диапазоне ~ 5-18V) выведена в главной ф-ции main (ниже)
                s=getCode (str[2]); s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;
        case 2:                                                                 // общий расход
                sprintf (str,"F%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s; // также, при нулевом значении выводим на дисплей "0", и если от 0 до 99,9 литров, зажигаем точку на этом индикаторе; при расходе от 100 и больше литров, расход показывается без десятых, в целых литрах
                s=getCode (str[3]); seg[0]=s;                                   // ...если значение "0", на дисплее будут гореть 3 и 4 лв. индикаторы - "0.0"
                break;        
        case 3:                                                                 // часовой расход
                sprintf (str,"H%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;                                   // ..."0.0"
                break;        
        case 4:                                                                 // настройка (поразрядное мигание дисплея; описание "миганий" с 1-го лв. разряда по 4-й)
                sprintf (str,"%04d",parameter); 
                if (g_Hblk == 3)                                                // если надо вывести мигание на 1-й лв. разряд дисплея
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (' '); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}    // если флаг=1, переводим его в 0 и выполняем все после "if", иначе, если 0, его в 1 и выполняем после "else" : если 1, гасим (пробел) 1-й лв. разряд индикатора, в остальные
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);} // разряды выводим полученные значения из "main", если 0, во все разряды выводим полученные значения из "main", тем самым инициируя режим мигания n-го(1) разряда
                }
                if (g_Hblk == 2) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (' '); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                if (g_Hblk == 1) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (' '); seg[0]=getCode (str[3]);}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                if (g_Hblk == 0) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (' ');}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                break;    
        //-----
        case 5:                                                                 // расход на 100 км
                sprintf (str,"P%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 6:                                                                 // общий путь
                sprintf (str,"W%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 7:                                                                 // скорость
                sprintf (str,"C%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                        
        //-----
        case 8:                                                                 //  средний расход на 100 км
                sprintf (str,"Y%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                        
        case 9:                                                                 // расход стоя
                sprintf (str,"G%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                        
        case 10:                                                                 // макс. скорость
                sprintf (str,"s%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                                        
        case 11:                                                                 // превышение скорости
                sprintf (str,"d%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                                        
        case 12:                                                                 // время впрыска
                sprintf (str,"t%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); if (s == 0) {s = 63;} seg[0]=s;
                break;        
        case 14:                                                                 // wave on
                sprintf (str,"d on",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 15:                                                                 // wave off
                sprintf (str,"d0FF",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 16:                                                                 // off indicators
                sprintf (str,"    ",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 17:                                                                 // общий путь-2
                sprintf (str,"L%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;        
        case 18:                                                                 // тахометр
                sprintf (str,"%4d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;                        
        case 19:                                                                 // (тахометр)
                sprintf (str,"060P",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); seg[1]=s;
                s=getCode (str[3]); s=s|(1<<7); seg[0]=s;
                break;                        
        case 20:                                                                 // стоимость
                sprintf (str,"r%3lu",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); if (s == 0) {s = 63;} seg[0]=s;
                break;        
        case 21:                                                                 // настройка (поразрядное мигание дисплея; описание "миганий" с 1-го лв. разряда по 4-й)
                sprintf (str,"%04d",parameter);
                if (g_Hblk == 3)                                                // если надо вывести мигание на 1-й лв. разряд дисплея
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (' '); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}    // если флаг=1, переводим его в 0 и выполняем все после "if", иначе, если 0, его в 1 и выполняем после "else" : если 1, гасим (пробел) 1-й лв. разряд индикатора, в остальные
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);} // разряды выводим полученные значения из "main", если 0, во все разряды выводим полученные значения из "main", тем самым инициируя режим мигания n-го(1) разряда
                }
                if (g_Hblk == 2) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (' '); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                if (g_Hblk == 1) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (' '); seg[0]=getCode (str[3]);}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                if (g_Hblk == 0) 
                { if (g_Hled == 1) {g_Hled=0; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (' ');}
                              else {g_Hled=1; seg[3]=getCode (str[0]); seg[2]=getCode (str[1]); seg[1]=getCode (str[2]); seg[0]=getCode (str[3]);}
                }
                seg[2] = seg[2] | (1<<7);
                break;
        case 22:                                                                 // стоимость old
                sprintf (str,"o%3lu",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); if (s == 0) {s = 63;} seg[0]=s;
                break;
        case 23:                                                                 // ср. скорость
                sprintf (str,"c%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;
        case 24:                                                                 //  old средний расход на 100 км
                sprintf (str,"A%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;
        case 25:                                                                 // "моторное" время
                sprintf (str,"h%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); if (s == 0) {s = 63;} if (parameter < 1000) s=s|(1<<7); seg[2]=s;
                s=getCode (str[2]); if (s == 0) {s = 63;} if ((parameter >= 1000)&(parameter < 10000)) s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); if (s == 0) {s = 63;} seg[0]=s;
                break;        
        case 26:                                                                 // min напряжение
                sprintf (str,"u%3d",parameter);
                s=getCode (str[0]); seg[3]=s;
                s=getCode (str[1]); seg[2]=s;
                s=getCode (str[2]); s=s|(1<<7); seg[1]=s;
                s=getCode (str[3]); seg[0]=s;
                break;

                
        default: seg[0]=6; seg[1]=91; seg[2]=79; seg[3]=102;                    // по идее быть не должно, но на всякий "пожарный", если что, выведем "4321"
                break;
    }
}
//-----------------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------- а теперь - о главном :)
void main ()
{
static char key=0,key_old=0,_t2=0,_temp=0,_temp2=0; 
static unsigned short key_count=0,timer_count=0,mg_rash=0;                      // время нажатого состояния кнопки;
static unsigned short way_fuel=0,way2_fuel=0,way_med=0,rash_way=0,med_rash_way=0,mg_speed=0,mg_speed_old=0; // ,max_speed_old=0;
static unsigned long med_fuel=0,tm=0,med_full_count=0,med_rash=0;                                           // "средний" расход и переменная (tm) для расчета "g_total_fuel" с учетом деления на 1000 
static unsigned long med_full_time=0,med_fuel_2=0,tm_2=0;
static unsigned long money_full_fuel=0,money_old_fuel=0;

static unsigned short way_med_old=0,way_med_temp=0,med_rash_way_old=0,speed_med_old=0;
static unsigned long med_rash_old=0,med_rash_temp=0,time_speed_med=0,mg_speed_med=0;
static unsigned long time_hour=0,time_hour_old_a=0,time_hour_old_c=0;
static float time_hour_old=0,time_hour_old_b=0;

static float Uadc=0,Umin=0;
static unsigned short ADCmin=0;

static unsigned short total_tachom_max_old=0,total_tachom_max=0;
static unsigned short ADCcp=0,x1=0,x2=0,x3=0,x4=0,x5=0,x6=0,x7=0,x8=0,x9=0,x10=0,x11=0,x12=0,x13=0,x14=0,x15=0,x16=0;
static char timer_count_a=0;


init ();                                                                        // запускаем ф-цию начальной инициализации

_temp = 1;
_temp2 = 1;
ADCmin = 900;

for (;;)                                                                        // запускаем бесконечный цикл
{
  __watchdog_reset();
    //----------------
    if (g_Uset == 26)
    {
      if (_tempADC == 1)
      {
        if (ADCrez < ADCmin) {ADCmin = ADCrez;}
        ADCSRA |= Bit(ADSC);
        _tempADC = 0;
      }
    }
    //-----
    if (g_Uset == 1)
    {
      if (timer_count_a > 11)
      {
                    if (_tempADC == 1)
                    {
                      x1=x2;
                      x2=x3;
                      x3=x4;
                      x4=x5;
                      x5=x6;
                      x6=x7;
                      x7=x8;
                      x8=x9;
                      x9=x10;
                      x10=x11;
                      x11=x12;
                      x12=x13;
                      x13=x14;
                      x14=x15;
                      x15=x16;
                      x16=ADCrez;
                      ADCSRA |= Bit(ADSC);
                      _tempADC = 0;
                    }
        timer_count_a=0;
      }
    }

    //----------------

    if (timer2comp == 1)                                                        // выполнение (ниже) кода с частотой 11719/33=360 Гц
    {
    //-----
                                                                                // часовой расход
            if (g_time_s < 360) {g_time_s++;}                                   // ждем истечения 1-й сек.
              else {g_time_s=0;                                                 // обнуляем время, чтобы в следующий раз посчитать новый мгнв. расход
                    mg_rash = (unsigned long) (g_full_time * g_Hset ) / ((12000000 / 8) / 6 ) ; // считаем текущий мгнв. расход в литрах;
                    med_fuel += g_full_time; med_full_time = g_full_time; g_full_time=0;                     // записываем в med_fuel сумму из "g_full_time" (время всех имп. в ед. времени - у нас 1 сек.) и "med_fuel" - числа 50 (как пример), см. ниже, которое осталось от "целой части после деления на 1000"), и после "g_full_time" обнуляем для последующего нового использования при определения нового мгнв. час. расхода
                    mg_speed_old = (unsigned long) (g_full_count * 3600 / (g_Vset));                       // скорость

                if   (mg_speed_old >= 70) 
                     {
                      time_speed_med++;
                      mg_speed = mg_speed_old;                                  // скорость
                      rash_way = ((unsigned long)mg_rash * 100 / ((unsigned long)mg_speed));           // мгновенный расход на 100 км
                      med_full_count = g_full_count;
                     }
                else {
                      rash_way = 0, mg_speed = 0;
                      med_full_count=0; med_full_time=0;
                     }

    //-----

                g_total_tachom = g_full_tachom; g_full_tachom=0;

                total_tachom_max_old = total_tachom_max;
                if (g_total_tachom > total_tachom_max_old) {total_tachom_max = g_total_tachom;}           // макс. обороты
                else {total_tachom_max = total_tachom_max_old;}

                if (g_total_tachom > 330)
                {
                  g_total_tachom = 330;
                  total_tachom_max = 330;
                }

                  
    //-----
                    g_total_count += g_full_count; g2_total_count += g_full_count;
                    med_total_count += med_full_count; med_full_count=0; g_full_count=0;
                    way_med = (unsigned long) (med_total_count / (g_Vset));     // средний путь (прошедшее расстояние при скорости более 5 км/ч)
                    med_fuel_2 += med_full_time; med_full_time=0;
                    if (med_fuel_2 > 1000) { tm_2 = med_fuel_2 / 1000; med_total_fuel += tm_2; med_fuel_2 -= tm_2*1000;}
                    med_rash = (unsigned long) (med_total_fuel * g_Hset ) / ((1200000 / 8)* 6);
                    
                    if (way_med > 0)
                         {med_rash_way = (unsigned long) (med_rash * 100) / (way_med);}
                    else {med_rash_way = 0;}
                    
          //-----------          
                    if (_temp == 1)
                    {
                      _temp = 0;
                      way_med_temp = way_med;
                      med_rash_temp = med_rash;
                    }
                    
                    way_med_old = (way_med - way_med_temp);
                    med_rash_old = (med_rash - med_rash_temp);
                    med_rash_way_old = (((unsigned long)med_rash_old) * 100) / ((unsigned long)way_med_old);
                    if (way_med_old < 1) med_rash_way_old = 0;
                    
                    if (_temp2 == 1)
                    {
                      _temp2 = 0;
                      time_speed_med = 1;
                      mg_speed_med = 0;
                    }
                    mg_speed_med = mg_speed_med + mg_speed;
                    speed_med_old = ((unsigned long)mg_speed_med) / ((unsigned long)time_speed_med);
          //-----------          
                    
                if ((mg_speed > (g_Sset*10)) && (g_Sset != 0) && (_t2 <= 1))
                    {
                      TCCR0B = Bit(CS01);
                      _t2++;
                    }
                else
                    {TCCR0B = 0; PORTD &= ~Bit(1);
                     if (mg_speed <= ((g_Sset*10) - 50))
                       {
                         _t2 = 0;
                       }
                    }


                way_fuel = (unsigned long) (g_total_count / (g_Vset));          // общий пройденный путь
                way2_fuel = (unsigned long) (g2_total_count / (g_Vset));          // общий пройденный путь-2
//                max_speed_old = max_speed;
                if (mg_speed > max_speed) {max_speed = mg_speed;}           // макс. скорость
//                else {max_speed = max_speed_old;}

                                                                                // общий расход
            if (med_fuel > 1000) { tm = med_fuel / 1000; g_total_fuel += tm; med_fuel -= tm*1000; // т.к. значение в g_total_fuel получается очень большим, то мы уменьшаем его в 1000 раз, а в формуле для определения полного расхода учитываем то, что нам надо умножить на "лишнюю" 1000 для получения правильного результата; если med_fuel > 1000, (например, 500050), то мы
                mg_fuel = (unsigned long) (g_total_fuel * g_Hset ) / ((1200000 / 8)* 6); }        // в "tm" записываем целое число от деления на 1000 (500) и прибавляем его к "g_total_fuel" (например, 20), в итоге получаем - 520; в "med_fuel" у нас теперь будет - (500050-500*1000=50) число - 50, которое будет учитываться для определения "среднего" расхода, см. выше

                rash_stand = (mg_fuel - med_rash);
                
                
                if (money_full_fuel > 99999) money_full_fuel = 0;
                money_full_fuel = (((unsigned long)mg_fuel) * ((unsigned long)g_Mset)) / 100;
                money_old_fuel = (money_full_fuel - money_temp_fuel);

                
                
                if ((mg_rash > 0) | (mg_speed_old > 0))
                {
                  time_full++;
                  time_hour_old = ((float)time_full * 100) / 3439;              // 3439=3600/1.047
                  time_hour_old_a = time_hour_old / 100;
                  time_hour_old_b = ((float)time_hour_old) - ((float)time_hour_old_a * 100);
                  time_hour_old_c = ((float)time_hour_old_b * 0.6);
                  time_hour = time_hour_old_c + (time_hour_old_a * 100);
                }
                   
                   }
            
                                                                                // сохранение общего расхода
            if (g_eesave_en == 1) { __EEPUT(EEADR2,g_total_fuel >> 24); __EEPUT(EEADR2+1,g_total_fuel >> 16);     // если 2 сек. нет сигнала с форсунки, сохраняем в EE полное время (новое, т.к. при включении мы из EE считываем старое, и если оно не равно 0, то оно, естественно, будет учитываться при получении нового значения) открытия форсунки, чтобы нам в последствии считывая его показать полный расход, расчитанный по "нашей" формуле значение в g_total_fuel
                __EEPUT(EEADR2+2,g_total_fuel >> 8); __EEPUT(EEADR2+3,(char)g_total_fuel);        // мы сдвигаем на 24 разряда вправо, и оставшийся один старший байт заносим в адрес EEADR2, далее знач. в g_total_fuel сдвигаем на 16 разрядов вправо, а т.к. функции "__EEPUT" оперирует "char" значением, то после сдвига в адрес EEADR2+1 запишется младший байт оставшегося 2-х байтного числа, а это 2-й старший байт 4-х байтной переменной g_total_fuel,
                                                                                // затем записываем в адрес EEADR2+2 - 3-й байт, и в EEADR2+3 - 4-й (младший) байт g_total_fuel; если писать правильно, то перед g_total_fuel надо было бы записать - "(unsigned char)", но в нашем компиляторе (IAR) в настройках стоит, что "unsigned char" можно писать просто как "char", что и показано в последней строчке; ну и затем сбрасываем флаг, чтобы быть готовыми к новому сохранению
                                    __EEPUT(EEADR4,g_total_count >> 24); __EEPUT(EEADR4+1,g_total_count >> 16);   // сохранение общего пробега
                __EEPUT(EEADR4+2,g_total_count >> 8); __EEPUT(EEADR4+3,(char)g_total_count);
                
                __EEPUT(EEADR5,max_speed >> 8); __EEPUT(EEADR5+1,(char)max_speed);
                
                                    __EEPUT(EEADR6,med_total_fuel >> 24); __EEPUT(EEADR6+1,med_total_fuel >> 16);
                __EEPUT(EEADR6+2,med_total_fuel >> 8); __EEPUT(EEADR6+3,(char)med_total_fuel);

                                    __EEPUT(EEADR7,med_total_count >> 24); __EEPUT(EEADR7+1,med_total_count >> 16);
                __EEPUT(EEADR7+2,med_total_count >> 8); __EEPUT(EEADR7+3,(char)med_total_count);

                                    __EEPUT(EEADR9,g2_total_count >> 24); __EEPUT(EEADR9+1,g2_total_count >> 16);   // сохранение общего пробега-2
                __EEPUT(EEADR9+2,g2_total_count >> 8); __EEPUT(EEADR9+3,(char)g2_total_count);

                                    __EEPUT(EEADR11,money_temp_fuel >> 24); __EEPUT(EEADR11+1,money_temp_fuel >> 16);
                __EEPUT(EEADR11+2,money_temp_fuel >> 8); __EEPUT(EEADR11+3,(char)money_temp_fuel);

                                    __EEPUT(EEADR12,time_full >> 24); __EEPUT(EEADR12+1,time_full >> 16);
                __EEPUT(EEADR12+2,time_full >> 8); __EEPUT(EEADR12+3,(char)time_full);
                
                g_eesave_en=0;
                                   }
    //----------------
    key_old = key;                                                              // сохраняем в "old" номер кнопки, которая была отпущена последней - используем это для: антидребезга, включения по отжатию(отпусканию) кнопок и времени нажатия кнопок
    key = OutDisp ();                                                           // берем новое значение номера кнопки, которая нажата в текущий момент, из ф-ции "OutDisp"
    if (key == 0) PORTD |= Bit(4); else PORTD &= ~Bit(4);                       // если не нажата ни одна кнопка - зажигаем светодиод, при нажатии любой кнопки - гасим
        if (key != key_old)                                                     // если нажата новая кнопка (а не продолжает оставаться нажатой "старая" кнопка)
        {   
            if (key_count > 720)                                                // нажатие более 2 сек. и антидребезг
            {
              if ((key_old & Bit(3)) != 0) {                                    // нажата кнопка 3 (1-ая лв.) - (т.к. после считывания все кнопки отжаты (считываем по отпусканию), и нам надо взять значение последней нажатой кнопки, то используем значение в "key_old", а не "key")
                                              if (g_Uset == 2)  {g_total_count = 0;
                                                                 g_total_fuel = 0;
                                                                 med_total_fuel = 0;
                                                                 med_total_count = 0;   // при удержании кнопки более 2 сек. в режиме полного расхода, обнуляем последний (g_Uset - см. ниже)
                                                                 med_rash = 0;
                                                                 way_med =0;
                                                                 money_full_fuel=0;
                                                                 money_temp_fuel = money_full_fuel;
                                                                 _temp = 1;
                                                                 _temp2 = 1;}
                                              if (g_Uset == 21)  {g_Uset = 22;}
                                              if (g_Uset == 23)  {money_temp_fuel = money_full_fuel;}
                                              if (g_Uset == 1)  {g_Uset = 26;}
                                              if (g_Uset == 27)  {time_full = 0;}
                                              if (g_Uset == 26)  {ADCmin = 900;}
                                           }
        //---
              if ((key_old & Bit(2)) != 0) {
                                              if (g_Uset == 5)  {g_Uset = 4;}         // если находимся в режиме часового расхода - входим в режим ввода коэф-та
                                              if (g_Uset == 3)  {g_Uset = 6;}
                                           }
        //---
              if ((key_old & Bit(1)) != 0) {
                                              if (g_Uset == 7)  {g_Uset = 8;}
                                              if (g_Uset == 11) {max_speed = 0;}
                                              if (g_Uset == 12)  {g_Uset = 14;}
                                              if (g_Uset == 19)  {g_Uset = 20;}
                                              if (g_Uset == 24)  {_temp2 = 1;}
                                           }
        //---
              if ((key_old & Bit(0)) != 0) {
                                              if (g_Uset == 25)  {_temp = 1;}
                                              if (g_Uset == 15) {g2_total_count = 0;}
                                              if (g_Uset == 16 | g_Uset == 17) {g_Uset = 18;}
                                           }

              key_count=0;
            }
        //----------
            if (key_count > 33)                                                 // нажатие менее 2 сек. и антидребезг
            {
                if ((key_old & Bit(0)) != 0) {if (g_Uset == 4)                  // нажата кнопка 0 (4-ая лв.) и активирован режим ввода коэф-та
                                              { if (g_Hblk == 3) {g_Hblk = 2;}  // если мигает (для установки нового значения) 1-й лв. разряд - передти к установке
                                           else if (g_Hblk == 2) {g_Hblk = 1;}
                                           else if (g_Hblk == 1) {g_Hblk = 0;}
                                           else if (g_Hblk == 0) {g_Hblk = 3; key_old = 0; g_Uset = 5; __EEPUT(EEADR1,g_Hset >> 8);
                                                                                          __EEPUT(EEADR1+1,(char)g_Hset); } // запись в EE
                                              }
                                             } 
        //---
                if ((key_old & Bit(0)) != 0) {if (g_Uset == 8)
                                              { if (g_Hblk == 3) {g_Hblk = 2;}
                                           else if (g_Hblk == 2) {g_Hblk = 1;}
                                           else if (g_Hblk == 1) {g_Hblk = 0;}
                                           else if (g_Hblk == 0) {g_Hblk = 3; key_old = 0; g_Uset = 7; __EEPUT(EEADR3,g_Vset >> 8);
                                                                                          __EEPUT(EEADR3+1,(char)g_Vset); }
                                              }
                                             }
        //---
                if ((key_old & Bit(0)) != 0) {if (g_Uset == 14)
                                              { if (g_Hblk == 3) {g_Hblk = 2;}
                                           else if (g_Hblk == 2) {g_Hblk = 1;}
                                           else if (g_Hblk == 1) {g_Hblk = 0;}
                                           else if (g_Hblk == 0) {g_Hblk = 3; key_old = 0; g_Uset = 12; __EEPUT(EEADR8,g_Sset >> 8);
                                                                                          __EEPUT(EEADR8+1,(char)g_Sset); }
                                              }
                                             }
        //---
                if ((key_old & Bit(0)) != 0) {if (g_Uset == 22)
                                              { if (g_Hblk == 3) {g_Hblk = 2;}
                                           else if (g_Hblk == 2) {g_Hblk = 1;}
                                           else if (g_Hblk == 1) {g_Hblk = 0;}
                                           else if (g_Hblk == 0) {g_Hblk = 3; key_old = 0; g_Uset = 21; __EEPUT(EEADR10,g_Mset >> 8);
                                                                                          __EEPUT(EEADR10+1,(char)g_Mset); }
                                              }
                                             }
        //----------
                if ((key_old & Bit(1)) != 0) {if (g_Uset == 4)                  // нажата кнопка 1
                                              { if (g_Hblk == 3) {if (g_Hset >= 1000) { g_Hset = g_Hset - 1000;}}
                                                if (g_Hblk == 2) {if (g_Hset >= 100) { g_Hset = g_Hset - 100;}}
                                                if (g_Hblk == 1) {if (g_Hset >= 10) { g_Hset = g_Hset - 10;}}
                                                if (g_Hblk == 0) {if (g_Hset >= 1) { g_Hset = g_Hset - 1;}}
                                              }
                                             }   
        //---
                if ((key_old & Bit(1)) != 0) {if (g_Uset == 8)
                                              { if (g_Hblk == 3) {if (g_Vset >= 1000) { g_Vset = g_Vset - 1000;}}
                                                if (g_Hblk == 2) {if (g_Vset >= 100) { g_Vset = g_Vset - 100;}}
                                                if (g_Hblk == 1) {if (g_Vset >= 10) { g_Vset = g_Vset - 10;}}
                                                if (g_Hblk == 0) {if (g_Vset >= 1) { g_Vset = g_Vset - 1;}}
                                              }
                                             }
        //---
                if ((key_old & Bit(1)) != 0) {if (g_Uset == 14)
                                              { if (g_Hblk == 3) {if (g_Sset >= 1000) { g_Sset = g_Sset - 1000;}}
                                                if (g_Hblk == 2) {if (g_Sset >= 100) { g_Sset = g_Sset - 100;}}
                                                if (g_Hblk == 1) {if (g_Sset >= 10) { g_Sset = g_Sset - 10;}}
                                                if (g_Hblk == 0) {if (g_Sset >= 1) { g_Sset = g_Sset - 1;}}
                                              }
                                             }
        //---
                if ((key_old & Bit(1)) != 0) {if (g_Uset == 22)
                                              { if (g_Hblk == 3) {if (g_Mset >= 1000) { g_Mset = g_Mset - 1000;}}
                                                if (g_Hblk == 2) {if (g_Mset >= 100) { g_Mset = g_Mset - 100;}}
                                                if (g_Hblk == 1) {if (g_Mset >= 10) { g_Mset = g_Mset - 10;}}
                                                if (g_Hblk == 0) {if (g_Mset >= 1) { g_Mset = g_Mset - 1;}}
                                              }
                                             }
        //----------
                if ((key_old & Bit(2)) != 0) {if (g_Uset == 4)                  // нажата кнопка 2
                                              { if (g_Hblk == 3) {if ((g_Hset + 1000) < 10000) {g_Hset = g_Hset + 1000;}}
                                                if (g_Hblk == 2) {if ((g_Hset + 100) < 10000) {g_Hset = g_Hset + 100;}}
                                                if (g_Hblk == 1) {if ((g_Hset + 10) < 10000) {g_Hset = g_Hset + 10;}}
                                                if (g_Hblk == 0) {if ((g_Hset + 1) < 10000) {g_Hset = g_Hset + 1;}}
                                              }
                                             }
        //---
                if ((key_old & Bit(2)) != 0) {if (g_Uset == 8)
                                              { if (g_Hblk == 3) {if ((g_Vset + 1000) < 10000) {g_Vset = g_Vset + 1000;}}
                                                if (g_Hblk == 2) {if ((g_Vset + 100) < 10000) {g_Vset = g_Vset + 100;}}
                                                if (g_Hblk == 1) {if ((g_Vset + 10) < 10000) {g_Vset = g_Vset + 10;}}
                                                if (g_Hblk == 0) {if ((g_Vset + 1) < 10000) {g_Vset = g_Vset + 1;}}
                                              }
                                             }
        //---
                if ((key_old & Bit(2)) != 0) {if (g_Uset == 14)
                                              { if (g_Hblk == 3) {if ((g_Sset + 1000) < 10000) {g_Sset = g_Sset + 1000;}}
                                                if (g_Hblk == 2) {if ((g_Sset + 100) < 10000) {g_Sset = g_Sset + 100;}}
                                                if (g_Hblk == 1) {if ((g_Sset + 10) < 10000) {g_Sset = g_Sset + 10;}}
                                                if (g_Hblk == 0) {if ((g_Sset + 1) < 10000) {g_Sset = g_Sset + 1;}}
                                              }
                                             }
        //---
                if ((key_old & Bit(2)) != 0) {if (g_Uset == 22)
                                              { if (g_Hblk == 3) {if ((g_Mset + 1000) < 10000) {g_Mset = g_Mset + 1000;}}
                                                if (g_Hblk == 2) {if ((g_Mset + 100) < 10000) {g_Mset = g_Mset + 100;}}
                                                if (g_Hblk == 1) {if ((g_Mset + 10) < 10000) {g_Mset = g_Mset + 10;}}
                                                if (g_Hblk == 0) {if ((g_Mset + 1) < 10000) {g_Mset = g_Mset + 1;}}
                                              }
                                             }
        //----------
                if ((key_old & Bit(3)) != 0) {                                  // нажата кнопка 3 (3,2,1,0)
                                                if (g_Uset == 0)  g_Uset = 1;
                                          else  if (g_Uset == 23 | g_Uset == 5 | g_Uset == 3 | g_Uset == 9 | g_Uset == 10 | g_Uset == 7 | g_Uset == 12 | g_Uset == 11 | g_Uset == 6 | g_Uset == 15 | g_Uset == 16 | g_Uset == 17 | g_Uset == 18 | g_Uset == 19 | g_Uset == 20 | g_Uset == 24 | g_Uset == 25 | g_Uset == 27)  g_Uset = 1;
                                          else  if (g_Uset == 1)  g_Uset = 2;   // 
                                          else  if (g_Uset == 2)  g_Uset = 21;  //
                                          else  if (g_Uset == 21) g_Uset = 23;  //
                                          else  if (g_Uset == 4)  g_Uset = 5;
                                          else  if (g_Uset == 8)  g_Uset = 7;
                                          else  if (g_Uset == 14) g_Uset = 12;
                                          else  if (g_Uset == 22) g_Uset = 21;
                                          else  if (g_Uset == 26) g_Uset = 27;
                                             }
        //---
                if ((key_old & Bit(2)) != 0) {                                  // нажата кнопка 2
                                                if (g_Uset == 9 | g_Uset == 1 | g_Uset == 2 | g_Uset == 7 | g_Uset == 12 | g_Uset == 11 | g_Uset == 15 | g_Uset == 16 | g_Uset == 17 | g_Uset == 18 | g_Uset == 19 | g_Uset == 20 | g_Uset == 21 | g_Uset == 23 | g_Uset == 24 | g_Uset == 25 | g_Uset == 26 | g_Uset == 27)  g_Uset = 5;
                                          else  if (g_Uset == 5)  g_Uset = 3;
                                          else  if (g_Uset == 3)  g_Uset = 9;
                                          else  if (g_Uset == 6)  g_Uset = 10;
                                          else  if (g_Uset == 10) g_Uset = 3;
                                             }
        //---
                if ((key_old & Bit(1)) != 0) {                                  // нажата кнопка 1
                                                if (g_Uset == 19 | g_Uset == 12 | g_Uset == 1 | g_Uset == 2 | g_Uset == 10 | g_Uset == 5 | g_Uset == 3 | g_Uset == 9 | g_Uset == 6 | g_Uset == 15 | g_Uset == 16 | g_Uset == 17 | g_Uset == 18 | g_Uset == 21 | g_Uset == 23 | g_Uset == 25 | g_Uset == 26 | g_Uset == 27)  g_Uset = 7;
                                          else  if (g_Uset == 7)  g_Uset = 11;
                                          else  if (g_Uset == 11) g_Uset = 24;
                                          else  if (g_Uset == 24) g_Uset = 19;
                                          else  if (g_Uset == 20) g_Uset = 19;
                                             }
        //---
                if ((key_old & Bit(0)) != 0) {                                  // нажата кнопка 0
                                                if (g_Uset == 1 | g_Uset == 2 | g_Uset == 10 | g_Uset == 5 | g_Uset == 3 | g_Uset == 6 | g_Uset == 9 | g_Uset == 7 | g_Uset == 11 | g_Uset == 16 | g_Uset == 17 | g_Uset == 18 | g_Uset == 19 | g_Uset == 20 | g_Uset == 21 | g_Uset == 23 | g_Uset == 24 | g_Uset == 24 | g_Uset == 26 | g_Uset == 27)  g_Uset = 25;
                                          else  if (g_Uset == 25)  g_Uset = 15;
                                          else  if (g_Uset == 15) g_Uset = 12;
                                          else  if (g_Uset == 12)
                                                   {
                                                     if (TIMSK0 & Bit(TOIE0) == 1) {TIMSK0 &= ~Bit(TOIE0); g_Uset = 17;}
                                                     else {TIMSK0 |= Bit(TOIE0); g_Uset = 16;}
                                                   }  
                                             }

                if (g_Vset < 10) {g_Vset = 10;}
            }
        //----------
        }
    if (key != 0 && key == key_old) {key_count++;} else {key_count=0;}
    //----------------
    if (timer_count > 180)                                                      // 0.5 сек. - это задержка для вывода напряжения, т.к. значения сразу берутся с АЦП и
    {                                                                           // быстро изменяющиеся значения начинают "сливаться", тогда как по остальным режимам
                                                                                // обсчет ведется 1 раз в сек., и эта задержка на эти режимы ни как ни влияет
        switch (g_Uset)                                                         // режим вывода (пользовательский - User)
        {   case 0:                                                             // тестовый вывод - "4321"
                    break;
            case 1: // ADCSRA |= Bit(ADSC);                                        // вывод напряжения
                    ADCcp = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10+x11+x12+x13+x14+x15+x16) >> 4;
                    Uadc = (0.1929 * (float)ADCcp) + 13;
                    SetDataDisp (1,(unsigned short)Uadc);
                    break;
            case 2: SetDataDisp (2,mg_fuel);                                    // общий расход
                    break;
            case 3: SetDataDisp (8,med_rash_way);
                    break;
            case 4: SetDataDisp (4,g_Hset);
                    break;

            case 5: if (mg_speed < 70) SetDataDisp (3,mg_rash);                 // часовой расход                
                    else SetDataDisp (5,rash_way);
                    break;
            case 6: SetDataDisp (6,way_fuel);
                    break;
            case 7: SetDataDisp (7,mg_speed/10);
                    break;
            case 8: SetDataDisp (4,g_Vset);
                    break;
                    
            case 9: if (mg_rash == 0)
                      {
                        SetDataDisp (12,0);
                      }
                    else
                      {
                        SetDataDisp (12,(g_fors_time*0.065)); //g_fors_time*0.065
                      }
                    break;
            case 10:SetDataDisp (9,rash_stand);
                    break;
            case 11:SetDataDisp (10,max_speed);
                    break;
            case 12:SetDataDisp (11,g_Sset);
                    break;
            case 14:SetDataDisp (4,g_Sset);
                    break;
            case 15:SetDataDisp (17,way2_fuel);
                    break;
            case 16:SetDataDisp (14,0);                                           // wave_sleep on
                    break;
            case 17:SetDataDisp (15,0);                                           // wave_sleep off
                    break;
            case 18:SetDataDisp (16,0);                                           // off indicators
                    break;
            case 19:if ((mg_rash == 0) | (g_total_tachom > 330))                  // тахометр - max 8000 об/мин
                      {
                        SetDataDisp (19,0);
                      }
                    else
                      {
                        SetDataDisp (18,(g_total_tachom*29));
                      }
                    break;
            case 20:SetDataDisp (18,(total_tachom_max*29));
                    break;
            case 21:SetDataDisp (20,money_full_fuel);
                    break;
            case 22:SetDataDisp (21,g_Mset);
                    break;
            case 23:if (money_old_fuel > 99999) money_old_fuel = 0;
                    SetDataDisp (22,money_old_fuel);
                    break;
            case 24:if (speed_med_old > 9999) speed_med_old = 0;
                    SetDataDisp (23,speed_med_old);
                    break;
            case 25:SetDataDisp (24,med_rash_way_old);
                    break;
            case 26:// ADCSRA |= Bit(ADSC);                                        // вывод min напряжения
                    Umin = (0.1929 * (float)ADCmin) + 13;
                    SetDataDisp (26,(unsigned short)Umin);
                    break;
            case 27:SetDataDisp (25,time_hour);
                    break;
                    
            default:
                    break;
        }
      timer_count=0;
    }
    timer_count++; timer_count_a++;
    //----------------
    timer2comp=0;
    }

}
}

