//-------------------------------------------------------------------------------
//
//      Наименование ПО:	mptt1_rliga.C
//      Компилятор:		Hi-Tech ANSI C-compiler
//      Среда разработки:	MPLAB IDE Microchip
//      Автор:			Сергей Зелепукин, РФ, г.Орел, sgreen.lab@gmail.com
//      Альфа и бета тест.:	Сергей Зелепукин
//      Вид лицензии:		GNU GPL, Copyleft
//	Соглашение:		Это программное обеспечение предоставляется "AS IS", 
//				без каких-либо гарантий. В частности ни автор, ни 
//				журнал "Радиолюбитель" не дает никаких гарантий любого
//				вида относительно ее пригодности для определенной цели.
//      Публикация:		220015, Беларусь, Минск-15 а/я 2, жур."Радиолюбитель",
//               		http://www.radioliga.com/
//
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
//      Внимание!
//      Выбор типа, установленного на PCB индикатора (ОА-ОК) осуществляется
//      посредством установки или удаления резистора R41 <A1>.
//      Резистор не установлен - <OA>, установлен - <OK>.
//      Наличие или отсутствие резистора R41 определяется на этапе монтажа <A1>.
//
//      Внимание!
//	Проект предусматривает возможность использования внешнего 12-bit АЦП
//	типа MCP3201, но данная функция является дополнением к основной задаче,
//	позволяющая при отсутствии контроллера PIC18F2523 использовать управляющий
//	контроллер типа PIC18F252 с внутренним АЦП 10-bit, не используемым в 
//	данном применении. Компиляция проекта под данный контроллер требует пере-
//	работки аппратной части прибора, с целью подключения внешнего АЦП.
//
//      Внимание!
//      программа аппаратно привязана к платам:
//                      MPTT1_A1_RL.pcb         - 2 relay;      mod A1
//                      MPTT1_A2_RL.pcb         - индикация     mod A2
//
//      История проекта:
//      07-feb-2011 ---- начало проекта                         ver. beta0;
//
//
//
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
//      Диапазон регулируемых °t вход Cu        - -50,0...+200 °С (дискретность 0,1 °С)
//      Диапазон регулируемых °t вход Pt        - -50,0...+400 °С (дискретность 0,1 °С)
//      Полный диапазон для Cu и Pt             - -77,0...+435 °С (дискретность 0,1 °С)
//      Дискретность индикации                  - 0,1°С (программно реализуемая)
//      ADC конвертор                           - внутренний 12-bit PIC18F2523
//      bit/°С для Cu и Pt                      - 8 bit/1°C
//      Нулевой уровень для RTD                 - 616 уровень A/D = 0,616 V
//
//      Диапазон задания выдержек времени
//      для "PAU" и "imP":                      - 500...5000 mS (диск. 5 mS спецкорректировка в программе "GETSETPARAM")
//                                              - 1.....9999 sec
//                                              - 1.....9999 min
//                                              - 1.....9999 hour
//
//      Режим работы прибора:                   - OFF (выключен и регулятор и таймер)
//                                              - Onr (только регулятор)
//                                              - Ont (только таймер)
//                                              - SEP (раздельно регулятор и таймер)
//                                              - Jn1 (совместно регулятор и таймер, регул. темпер. всегда)
//                                              - Jn2 (совместно регулятор и таймер, регул. темпер. после команды на запуск)
//
//      Режим формирования выдержек времени:    - AGE (Автогенератор)
//                                              - nGE (Автогенератор с заданием числа периодов)
//                                              - dvr (Задержанный одновибратор)
//                                              - Ovr (Одновибратор)
//                                              - dOn (Задержка включения нагрузки)
//
//      Тактовая частота EXTERNAL               - 8.00 MHz
//

//---------------------------------------------------------------------------
//----------------- Подключение для PIC18F2523 ------------------------------
//
//      Connect to Gnd                          - PORTA,0
//      Vin                                     - PORTA,1 (t °C)
//      LOADII "Timer"                          - PORTA,2
//      Vref                                    - PORTA,3 (+4,096V)
//      Connect to Gnd                          - PORTA,4
//      LOADI  "Regulator"                      - PORTA,5
//
//      Инд. "a"                                - PORTB,0
//      Инд. "b"                                - PORTB,1
//      Инд. "c"                                - PORTB,2
//      Инд. "d", кнопка "Mode indic °t/T"      - PORTB,3 (S4)
//      Инд. "e", кнопка "Больше" (Start/Cancel)- PORTB,4 (S1)
//      Инд. "f", Кнопка "Меньше"               - PORTB,5 (S2)
//      Инд. "g", контр.перемычки Д6 (a-b, А2)  - PORTB,6 (замкн = Д6, разом = работа)
//      Инд. "h", Кнопка "Set"                  - PORTB,7 (S3)
//
//      OA-OK, Десятые градусов                 - PORTC,0
//      OA-OK, Единицы градусов                 - PORTC,1
//      PWM_SOUND, Контроль "OA-OK"             - PORTC,2 (PWM: "0" - "OFF","1" - "On")(замк. -ОK, разомк. -OA)
//      Connect to Gnd                          - PORTС,3
//      Connect to Gnd                          - PORTС,4
//      OA-OK, Десятки градусов                 - PORTС,5
//      OA-OK, Сотни градусов                   - PORTС,6
//      INPUT (Start/Cancel time) Ext. chanel   - PORTС,7
//
//---------------------------------------------------------------------------
//
//                      ИСПОЛНЕНИЯ ПРИБОРА МПТТ 1
//
//-------------------------------------------------------------------
// Усл. обоз.   Исп.    Напр. пит.      Тип входа       Исп. элем.
// МПТТ 1-1     -00     ~220V           50М, 50П        2 реле
// МПТТ 1-2     -01     - // -          100М, 100П      2 реле
//-------------------------------------------------------------------

#include        <pic18.h>
#include        <stdlib.h>
#include        <stdio.h>

                                // -------- Выбор типа контроллера

//#define SELECT_18F252           // Если директива определена, то компиляция проекта
                                // будет выполнена под контроллер PIC18F252.


#define SELECT_18F2523        // Если директива определена, то компиляция проекта
                                // будет выполнена под контроллер PIC18F2523.


#ifdef  SELECT_18F252                                   // For 18F252
        #if defined (_18F252)
                __CONFIG (1,OSCSDIS & HS);
                __CONFIG (2,BOREN & BORV27 & PWRTEN & WDTDIS);
                __CONFIG (3,CCP2RC1);
                __CONFIG (4,DEBUGDIS & LVPDIS & STVREN);
                __CONFIG (5,CPALL);
                __CONFIG (6,WPC & WPB & WP0 & WP1 & WP2 & WP3);
                __CONFIG (7,TRU);
        #else
                #error Incorrect chip select. Need select PIC18F252 in MPLAB <menu\configure\select device>!
        #endif
#endif


#ifdef  SELECT_18F2523                                  // For 18F2523
        #if defined (_18F2523)
                __CONFIG (1,HS & FCMEN & IESOEN);
                __CONFIG (2,PWRTEN & BOREN & BORV28 & WDTDIS);
                __CONFIG (3,CCP2RC1 & PBDIGITAL & LPT1DIS & MCLRDIS);
                __CONFIG (4,STVRDIS & LVPDIS & XINSTDIS & DEBUGDIS);
                __CONFIG (5,CPALL);
                __CONFIG (6,WPA & WPB & WPC);
                __CONFIG (7,0xFFFF);
        #else
                #error Incorrect chip select. Need select PIC18F2523 in MPLAB <menu\configure\select device>!
        #endif
#endif





//      ------------ Инициализация EEPROM при программировании

//                        0         1         2         3
//                       SP        HYS       SPS       SPr
        __EEPROM_DATA(0xEE,0x02,0xCE,0xFF,0xEE,0x02,0x00,0x00);

//                        4         5         6         7
//                       PAU       imP       Amn       SSn
        __EEPROM_DATA(0x05,0x00,0x05,0x00,0x64,0x00,0x01,0x00);

//                        8         9        10         11
//                       mOd       mtm       UnP       Uni
        __EEPROM_DATA(0x00,0x00,0x03,0x00,0x01,0x00,0x01,0x00);

//                       12        13        14        15
//                       mUL       mSt       Pri       PFA
        __EEPROM_DATA(0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00);

//                       16        17        18        19
//                       CSr       ALC       tSr       md6
        __EEPROM_DATA(0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00);

//                       20        21        22        23
//                       SYS       nUL       428       385
        __EEPROM_DATA(0x02,0x00,0x00,0x04,0xDD,0x39,0x59,0x3F);

//                       24        25        26        27
//                       391    guard_0   guard_1   CRC_COPY1
        __EEPROM_DATA(0x67,0x3E,0x00,0x00,0x00,0x00,0x7F,0x06);

//                       28        29        30        31
//                       SP        HYS       SPS       SPr
        __EEPROM_DATA(0xEE,0x02,0xCE,0xFF,0xEE,0x02,0x00,0x00);

//                       32        33        34        35
//                       PAU       imP       Amn       SSn
        __EEPROM_DATA(0x05,0x00,0x05,0x00,0x64,0x00,0x01,0x00);

//                       36        37        38        39
//                       mOd       mtm       UnP       Uni
        __EEPROM_DATA(0x00,0x00,0x03,0x00,0x01,0x00,0x01,0x00);

//                       40        41        42        43
//                       mUL       mSt       Pri       PFA
        __EEPROM_DATA(0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00);

//                       44        45        46        47
//                       CSr       ALC       tSr       md6
        __EEPROM_DATA(0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00);

//                       48        49        50        51
//                       SYS       nUL       428       385
        __EEPROM_DATA(0x02,0x00,0x00,0x04,0xDD,0x39,0x59,0x3F);

//                       52        53        54        55
//                       391    guard_0   guard_1   CRC_COPY2
        __EEPROM_DATA(0x67,0x3E,0x00,0x00,0x00,0x00,0x7F,0x06);



void            PRIM_INIT(void);
void            EEPREAD(void);
void            EEPWRITE(void);
void            GETSETPARAM(unsigned char TMP_NMBPARAM);
void            KEY_INTERFACE(void);
void            KEY_1_2_SET(unsigned char TMP_KEY_12);
void            KEYSTATUS(void);
void            ANKEY_1_2_4(void);
void            UPDATEDISPLAY(void);
void            DELAY_MULTY(void);
void            ADSERVIS(void);
void            SUM_DIVISION(void);
void            SOUND(void);
void            D_POINT(void);
void            B2_BCD(int TMP_B2);
void            MAKE_MESSAGE(void);
void            OUT_IND(void);
void            DIR_FL_LOAD_HEAT(void);
void            DELAY_3sec_DIR_LOAD_HEAT(void);
void            AN_INPUT_TIME(void);
void            START_PRG_TIME(void);
void            DIR_LOAD_TIME(void);
void            CALC_CRC(void);
void            CHECK_CRC(void);
void            RESTORE_DATA(void);
void            SAVE_RESTORE_DATA(void);
void            SET_CONFIG_FLAG(void);
void            DYNAMIC_DISPLAY(void);
void            TEST_CHANG_SENSOR(void);
void            JNT_COMPARE_RESUL_IND_SPS_SPr(void);
void            START_PRG_JNT2(void);
void            BASE_ALGORITM_JNT2(void);
unsigned char   SSPBUF_SPI(void);
void            COPY1_to_COPY2(void);
void            SELECT_OA_OK_LEDS(void);


#define bitset(var,bitnumber) ((var) |= 1 << (bitnumber))       // Макрос установки бита
#define bitclr(var,bitnumber) ((var) &= ~(1 << (bitnumber)))    // Макрос снятия бита


//---------------------------------------
#define AMOUNTPAR_OPERATOR      8       // Кол-во парам. для оператора
#define AMOUNTPAR_NALADCHIK     11      // Кол-во парам. для наладчика
#define AMOUNTPAR_OPNAL         (AMOUNTPAR_OPERATOR + AMOUNTPAR_NALADCHIK)
                                        // Общее кол-во параметров OPERATOR, NALADCHIK
//---------------------------------------

#define AMOUNTPAR_MODE_D6       1       // Кол-во парам. режима настройки прибора по D6
#define AMOUNTPAR_SYS_D6        1       // Кол-во парам. номера системной конфигурации
#define AMOUNTPAR_nUL_D6        1       // Кол-во параметров настройку "0"
#define AMOUNTPAR_GAINRTD_D6    3       // Кол-во парам. для настройки шкалы RTD D6
#define AMOUNTPAR_guard         2       // Кол-во спецпараметров секретности
#define AMOUNTPAR_D6            (AMOUNTPAR_MODE_D6 + AMOUNTPAR_SYS_D6 + AMOUNTPAR_nUL_D6 + AMOUNTPAR_GAINRTD_D6 + AMOUNTPAR_guard)
                                        // Общее кол-во парам. для D6
//---------------------------------------

#define AMOUNTPAR_CRC           1       // Кол-во парам. контрольной суммы для "Оператор", "Наладчик", "Д6"
                                        // для копии 1. Всего 2 копии параметров.

//---------------------------------------

#define SIZE_BASE               ((AMOUNTPAR_OPNAL + AMOUNTPAR_D6 + AMOUNTPAR_CRC) * 2)
                                        // Кол-во базовых параметров

#define n_SP                    0       // Точка уставки SP
#define n_HYS                   1       // Зоны возврата HYS для SP
#define n_SPS                   2       // Точка автостарта отсчета времени "SPS" для "mOd" = "Jnt"
#define n_SPr                   3       // Точка автоcброса отсчета времени "SPr" для "mOd" = "Jnt"
#define n_PAU                   4       // Длительность "PAUSE"
#define n_imP                   5       // Длительность "ImPULSE"
#define n_Amn                   6       // Кол-во периодов для "nGE"
#define n_SSn                   7       // Состояние звука "SSn" (OFF, On) по оконч. фазы "Impulse"
#define n_mOd                   8       // Режим работы прибора (OFF, Onr, Ont, SEP, Jn1, Jn2)
#define n_mtm                   9       // Режим формир. выдер. времени (AGE, nGE, dvr, Ovr, dOn)
#define n_UnP                   10      // Единиц. измер. "PAUSE" (SEC, min, HOU)
#define n_Uni                   11      // Единиц. измер. "imPULSE" (SEC, min, HOU)
#define n_mUL                   12      // Множитель для "nGE" (1, 10, 100)
#define n_mSt                   13      // Режим запуска отсчета (1-0, 0-1, Pwr)
#define n_Pri                   14      // Приоритет вывода информации о температуре или времени без нажатия кнопки "Mode indic °t/T" (0 - time, 1 - °C)
#define n_PFA                   15      // Cостояние канала регул. темпер. при аварии сенсора (OFF, On)
#define n_CSr                   16      // Калибровка сенсора
#define n_ALC                   17      // Блокировка доступа в систему параметров "Оператор"
#define n_tSr                   18      // Тип сенсора (428, 385, 391)
#define n_md6                   19      // Режим наст. пар. по Д6 (man, AUt)
#define n_SYS                   20      // Номер исполнения прибора
#define n_nUL                   21      // Настройка "0" измерит. тракта
#define n_428                   22      // Настройка шкалы для Cu=4280
#define n_385                   23      // Настройка шкалы для Pt=3850
#define n_391                   24      // Настройка шкалы для Pt=3910
#define n_guard_0               25      // Специнформация
#define n_guard_1               26      // Специнформация
#define CRC_COPY1               27      // Контрольная сумма для COPY1
#define n_SP_COPY               28      // Начало COPY2
#define n_HYS_COPY              29      //
#define n_SPS_COPY              30      //
#define n_SPr_COPY              31      //
#define n_PAU_COPY              32      //
#define n_imP_COPY              33      //
#define n_Amn_COPY              34      //
#define n_SSn_COPY              35      //
#define n_mOd_COPY              36      //
#define n_mtm_COPY              37      //
#define n_UnP_COPY              38      //
#define n_Uni_COPY              39      //
#define n_mUL_COPY              40      //
#define n_mSt_COPY              41      //
#define n_Pri_COPY              42      //
#define n_PFA_COPY              43      //
#define n_CSr_COPY              44      //
#define n_ALC_COPY              45      //
#define n_tSr_COPY              46      //
#define n_md6_COPY              47      //
#define n_SYS_COPY              48      //
#define n_nUL_COPY              49      //
#define n_428_COPY              50      //
#define n_385_COPY              51      //
#define n_391_COPY              52      //
#define n_guard_0_COPY          53      //
#define n_guard_1_COPY          54      //
#define CRC_COPY2               55      // Контрольная сумма для COPY2

                                        // Внимание! Не изменять послед. режимов, привязка в "MAKE_MESSAGE"
                                        // Режим работы прибора:
#define mOd_OFF                 0       // Выключено
#define mOd_Onr                 1       // Только регулятор температуры
#define mOd_Ont                 2       // Только таймер
#define mOd_SEP                 3       // Раздельно и регулятор и таймер
#define mOd_Jn1                 4       // Совместно регулятор и таймер (старт нагрева при вкл. питания, старт времени после нагрева, нагрев включен всегда, выкл. времени по команде(внеш./внутр.))
#define mOd_Jn2                 5       // Совместно регулятор и таймер (старт нагрева по команде, старт времени после нагрева, выкл. нагрева после окончан. времени)

                                        // Режим формирования выдержек времени:
#define mtm_AGE                 0       // Автогенератор
#define mtm_nGE                 1       // Автогенератор с заданием числа периодов
#define mtm_dvr                 2       // Задержанный одновибратор
#define mtm_Ovr                 3       // Одновибратор
#define mtm_dOn                 4       // Задержка включения нагрузки
#define mtm_OFF                 5       // Выключено. Не используется и не задается

                                        // Режим запуска отсчета
#define mode_St_10              0       // 1->0, задний фронт
#define mode_St_01              1       // 0->1, передний фронт
#define mode_St_Pwr             2       // Pwr , при включении электропитания

                                        // Режим вывода информации
#define Pri_tim                 0       // Приоритет вывода данных о времени
#define Pri_rEG                 1       // Приоритет вывода данных о температуре

#define Unit_mS                 0       // Единица измерения времени mS
#define Unit_SEC                1       // Единица измерения времени SEC
#define Unit_min                2       // Единица измерения времени min
#define Unit_HOU                3       // Единица измерения времени HOUR

                                        // Режим наладки по Д6
#define mod_d6_man              0       // Ручная наладка
#define mod_d6_auto             1       // Автонастройка параметров

#define ALC_OFF                 0       // Блокировки параметров "оператор" и старт/отмена отсчета - нет
#define ALC_On                  1       // Полная блокировка
#define ALC_OnS                 2       // Блокировка, только старт/отмена отсчета времени или процесса

                                        // Тип сенсора
#define tSr_Cu428               0       // Тип сенсора - Cu4280
#define tSr_Pt385               1       // Тип сенсора - Pt3850
#define tSr_Pt391               2       // Тип сенсора - Pt3910

#define max_tPt                 4000    // Макс. знач. регул. t для Pt (дискр. 0,1 °С)
#define max_tCu                 2000    // Макс. знач. регул. t для Cu (дискр. 0,1 °С)

#define default_GAIN_C428       14813   // (0x39DD) Типовое значение коэфф. усилен. для Cu4280
#define default_GAIN_P385       16217   // (0x3F59) Типовое значение коэфф. усилен. для Pt3850
#define default_GAIN_P391       15975   // (0x3E67) Типовое значение коэфф. усилен. для Cu3910

#define mes_IND_t_T             0       // Индикация t °C (сообщение не используется, зарезервированно)
#define mes_VAL_PARAM           1       // Индикация знач. PARAM (сообщение не используется, зарезервированно)
#define mes_NAME_PAR            2       // Индикация имени параметра (сообщение не используется, зарезервированно)
#define mes_VAL_SPECIAL_PAR     3       // Индикация знач. спецпараметров (сообщение не используется, зарезервированно)
#define mes_SGr                 4       // Сообщение SGr в данной позиции не используется. Данное сообщ. при старте выводится из подпрог. "DYNAMIC_DISPLAY".
#define mes_PAS                 5       // Сообщение PAS при входе в "НАЛАДЧИК"
#define mes_OFF                 6       // Cообщение универсальное "OFF"
#define mes_On                  7       // Cообщение универсальное "On"
#define mes_mOd_Onr             8       // Сообщение режим работы только "Регулятор"
#define mes_mOd_Ont             9       // Сообщение режим работы только "Таймер"
#define mes_mOd_SEP             10      // Сообщение режим работы раздельно "Регулятор" и "Таймер"
#define mes_mOd_Jn1             11      // Сообщение режим работы совместно и "Регулятор" и "Таймер"
#define mes_mOd_Jn2             12      // Сообщение режим работы совместно и "Регулятор" и "Таймер"
#define mes_mtm_AGE             13      // Сообщение исполнение выдерж. времени "Автогенератор"
#define mes_mtm_nGE             14      // Сообщение исполнение выдерж. времени "Автогенератор с заданием числа периодов"
#define mes_mtm_dvr             15      // Сообщение исполнение выдерж. времени "Задержанный одновибратор"
#define mes_mtm_dOn             16      // Сообщение исполнение выдерж. времени "Задержка включения нагрузки"
#define mes_mtm_Ovr             17      // Сообщение исполнение выдерж. времени "Одновибратор"
#define mes_mAn                 18      // Cообщение mAn ручная настройка параметров D6
#define mes_AUt                 19      // Cообщение AUt автоматическая настройка параметров D6
#define mes_428                 20      // Cообщение C428 | Только по возрастающей
#define mes_385                 21      // Cообщение P385 | и без вставок
#define mes_391                 22      // Cообщение P391 | других сообщений!
#define mes_CAn                 23      // Cообщение CAn отмена автонастройки D6 по требованию пользователя
#define mes_rUn                 24      // Cообщение rUn старт автонастройки D6 по требованию пользователя
#define mes_End                 25      // Cообщение End автонастройка D6 завершена
#define mes_ErE                 26      // Cообщение ErE ошибка при операциях с EEPROM
#define mes_PFA                 27      // Cообщение PFA ошибка в цепях сенсора
#define mes_Udt                 28      // Cообщение Udt температуры наопределена (при аварии сенсора)
#define mes_CHS                 29      // Cообщение CHS изменен тип сенсора
#define mes_ACd                 30      // Cообщение ACd в доступе отказано
#define mes_CRC                 31      // Сообщение всех данных (полное повреждение данных, обе копии)
#define mes_EPw                 32      // Сообщение значения напряжения +12V вне диапаз. +9V...16V
#define mes_EEP                 33      // Cообщение EEP активна запись в EEPROM (выключение питания недопустимо)
#define mes_bLk                 34      // Cообщение bLk фактически это гашение индикации
#define mes_SPE                 35      // Cообщение SPE точка устаки SP и автостарта SPS равны (Equivalent)
#define mes_t_C                 36      // Cообщение t°C (требует специального символа в кодовой таблице)
#define mes_dCm                 37      // Сообщение dCm для "mtm" = "dOn". Фаза "Pause" завершена.
#define mes_m_1                 38      // Сообщение m_1 множитель х1 для nGE
#define mes_m10                 39      // Сообщение m10 множитель х10 для nGE
#define mes_100                 40      // Сообщение 100 множитель х100 для nGE
#define mes_tim                 41      // Сообщение tim приоритет вывода данных о времени (т.е. таймер)
#define mes_rEG                 42      // Сообщение rEG приоритет вывода данных о температуре (т.е. регулятор)
#define mes_Uni_mS              43      // Сообщение mS единица измерения времени
#define mes_Uni_SEC             44      // Сообщение SEC единица измерения времени
#define mes_Uni_min             45      // Сообщение mim единица измерения времени
#define mes_Uni_HOU             46      // Сообщение HOU единица измерения времени
#define mes_1_0                 47      // Сообщение 1->0, запуск отсчета времени по заднему фронту
#define mes_0_1                 48      // Сообщение 0->1, запуск отсчета времени по переднему фронту
#define mes_Pwr                 49      // Сообщение Pwr, запуск отсчета времени при включении электропитания прибора
#define mes_ErP                 50      // Сообщение ErP, ошибка установки временных параметров таймера
#define mes_StP                 51      // Сообщение StP, старт процесса Jnt2
#define mes_Stt                 52      // Сообщение Stt, старт отсчета времени для Jnt1 или Jnt2
#define mes_ArSt                53      // Сообщение ArSt, автосброс для Jn1 при прохожд. температуры объекта точки "SPr"
#define mes_OnS                 54      // Сообщение OnS, блокировка сброса отсчета времени или процесса "Jn2" с клавиатуры


                                //------- Таблица верхнего предела устанавл. параметра
const   int HI_PRED_BASE[] ={   4000,   // 00 параметр SP
                                250,    // 01 параметр HYS
                                4001,   // 02 параметр SPS (if Cu = 200.1 или Pt = 400.1, тогда SPS = SP и вывод сообщен. "SPE")
                                4100,   // 03 параметр SPr
                                9999,   // 04 параметр PAU
                                9999,   // 05 параметр imP
                                9999,   // 06 параметр Amn
                                1,      // 07 параметр SSn
                                5,      // 08 параметр mOd (OFF, Onr, Ont, SEP, Jn1, Jn2)
                                4,      // 09 параметр mtm (AGE, nGE, dvr, dOn, Ovr)
                                3,      // 10 параметр UnP
                                3,      // 11 параметр Uni
                                3,      // 12 параметр mUL
                                2,      // 13 параметр mSt
                                1,      // 14 параметр Pri
                                1,      // 15 параметр PFA
                                100,    // 16 параметр CSr
                                2,      // 17 параметр ALC
                                2,      // 18 параметр tSr
                                1,      // 19 параметр md6  (man, auto)
                                2,      // 20 параметр SYS
                                2048,   // 21 параметр nUL (Среднее знач. 1024)
                                17000,  // 22 параметр 428 (Среднее знач. 16384)
                                18000,  // 23 параметр 385 (Среднее знач. 16384)
                                18000}; // 24 параметр 391 (Среднее знач. 16384)

                                //------- Таблица нижнего предела устанавл. параметра

const   int LOW_PRED_BASE[] ={  -500,   // 00 параметр SP
                                -250,   // 01 параметр HYS
                                -500,   // 02 параметр SPS
                                -550,   // 03 параметр SPr
                                1,      // 04 параметр PAU
                                1,      // 05 параметр imP
                                1,      // 06 параметр Amn
                                0,      // 07 параметр SSn
                                0,      // 08 параметр mOd
                                0,      // 09 параметр mtm
                                0,      // 10 параметр UnP
                                0,      // 11 параметр Uni
                                1,      // 12 параметр mUL
                                0,      // 13 параметр mSt
                                0,      // 14 параметр Pri
                                0,      // 15 параметр PFA
                                -100,   // 16 параметр CSr
                                0,      // 17 параметр ALC
                                0,      // 18 параметр tSr
                                0,      // 19 параметр md6
                                1,      // 20 параметр SYS
                                2,      // 21 параметр nUL
                                13000,  // 22 параметр 428
                                14000,  // 23 параметр 385
                                14000}; // 24 параметр 391

//      Таблица доступа к параметрам
//
//      Здесь: z        = 5  - параметр mtm (AGE, nGE, dvr, Ovr, dOn),
//             line     = 6   - параметр mOd (OFF, Onr, Ont, SEP, Jn1, Jn2),
//             column   = 16 - список параметров.
//                                                       0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18
//                                                       SP HYS SPS SPr PAU imP Amn SSn mOd mtm UnP Uni mUL mSt Pri PFA CSr ALC tSr
//                                       z ln col                                                                               // mtm = AGE
const   unsigned char   TBL_ACSS_FORLAWR[5][6][19] =    {0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     // OFF
                                                         1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,     // Onr
                                                         0,  0,  0,  0,  1,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  1,  0,     // Ont
                                                         1,  1,  0,  0,  1,  1,  0,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,     // SEP
                                                         1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,     // Jn1
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,     // Jn2
                                                                                                                                 // mtm = nGE
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     // OFF
                                                         1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,     // Onr
                                                         0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  1,  0,     // Ont
                                                         1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,     // SEP
                                                         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,     // Jn1
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,     // Jn2
                                                                                                                                 // mtm = dvr
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     // OFF
                                                         1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,     // Onr
                                                         0,  0,  0,  0,  1,  1,  0,  1,  1,  1,  1,  1,  0,  1,  0,  0,  0,  1,  0,     // Ont
                                                         1,  1,  0,  0,  1,  1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,     // SEP
                                                         1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,     // Jn1
                                                         1,  1,  1,  0,  1,  1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,     // Jn2
                                                                                                                                 // mtm = Ovr
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     // OFF
                                                         1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,     // Onr
                                                         0,  0,  0,  0,  0,  1,  0,  1,  1,  1,  0,  1,  0,  1,  0,  0,  0,  1,  0,     // Ont
                                                         1,  1,  0,  0,  0,  1,  0,  1,  1,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,     // SEP
                                                         1,  1,  1,  1,  0,  1,  0,  1,  1,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,     // Jn1
                                                         1,  1,  1,  0,  0,  1,  0,  1,  1,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,     // Jn2
                                                                                                                                 // mtm = dOn
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,     // OFF
                                                         1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,     // Onr
                                                         0,  0,  0,  0,  1,  0,  0,  1,  1,  1,  1,  0,  0,  1,  0,  0,  0,  1,  0,     // Ont
                                                         1,  1,  0,  0,  1,  0,  0,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,     // SEP
                                                         1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,     // Jn1
                                                         0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1};    // Jn2

//                                                       0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18
//                                                       SP HYS SPS SPr PAU imP Amn SSn mOd mtm UnP Uni mUL mSt Pri PFA CSr ALC  tSr



//                                                       SP HYS SPS SPr PAU imP Amn SSn mOd mtm UnP Uni mUL mSt Pri PFA CSr ALC tSr  md6 SYS nUL 428 385 391
const   unsigned char   TBL_ACTIVITY_DPOINT_RTD[] = {    1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,   0,  1,  1,  1,  1};


                        //--------------------- Таблица имен параметров
const   unsigned char   TBL_NAME_PAR[25][4] = { 0x1B,0x1E,0x10,0x10,    // 00 SP
                                                0x1E,0x24,0x13,0x10,    // 01 HYS
                                                0x1E,0x1B,0x1E,0x10,    // 02 SPS
                                                0x1D,0x1B,0x1E,0x10,    // 03 SPr
                                                0x20,0x0A,0x1B,0x10,    // 04 PAU
                                                0x1B,0x18,0x14,0x10,    // 05 ImP
                                                0x19,0x18,0x0A,0x10,    // 06 Amn
                                                0x19,0x1E,0x1E,0x10,    // 07 SSn
                                                0x0D,0x1A,0x18,0x10,    // 08 mOd
                                                0x18,0x1F,0x18,0x10,    // 09 mtm
                                                0x1B,0x19,0x20,0x10,    // 10 UnP
                                                0x14,0x19,0x20,0x10,    // 11 Uni
                                                0x17,0x20,0x18,0x10,    // 12 mUL
                                                0x1F,0x1E,0x18,0x10,    // 13 mSt
                                                0x14,0x1D,0x1B,0x10,    // 14 Pri
                                                0x0A,0x0F,0x1B,0x10,    // 15 PFA
                                                0x1D,0x1E,0x0C,0x10,    // 16 CSr
                                                0x0C,0x17,0x0A,0x10,    // 17 ALC
                                                0x1D,0x1E,0x1F,0x10,    // 18 tSr
                                                0x06,0x0D,0x18,0x10,    // 19 md6
                                                0x1E,0x24,0x1E,0x10,    // 20 SYS
                                                0x17,0x20,0x19,0x10,    // 21 nUL
                                                0x08,0x02,0x04,0x10,    // 22 428
                                                0x05,0x08,0x03,0x10,    // 23 385
                                                0x01,0x09,0x03,0x10};   // 24 391


                        //--------------------- Таблица имен сообщений
const   unsigned char   TBL_MESSAGE[55][4]= {   0x10,0x10,0x10,0x10,    // 00 Ind_t       (сообщение не выводится)
                                                0x10,0x10,0x10,0x10,    // 01 VAL_PARAM   (сообщение не выводится)
                                                0x10,0x10,0x10,0x10,    // 02 NAME_PAR    (сообщение не выводится)
                                                0x10,0x10,0x10,0x10,    // 03 VAL_TMP_PAR (сообщение не выводится)
                                                0x17,0x1D,0x1A,0x10,    // 04 SGr
                                                0x1E,0x0A,0x1B,0x10,    // 05 PAS
                                                0x0F,0x0F,0x1A,0x10,    // 06 OFF
                                                0x19,0x1A,0x10,0x10,    // 07 On
                                                0x1D,0x19,0x1A,0x10,    // 08 Onr
                                                0x1F,0x19,0x1A,0x10,    // 09 Ont
                                                0x1B,0x0E,0x1E,0x10,    // 10 SEP
                                                0x01,0x19,0x15,0x10,    // 11 Jn1
                                                0x02,0x19,0x15,0x10,    // 12 Jn2
                                                0x0E,0x12,0x0A,0x10,    // 13 AGE
                                                0x0E,0x12,0x19,0x10,    // 14 nGE
                                                0x1D,0x21,0x0D,0x10,    // 15 dvr
                                                0x19,0x1A,0x0D,0x10,    // 16 dOn
                                                0x1D,0x21,0x1A,0x10,    // 17 Ovr
                                                0x19,0x0A,0x18,0x10,    // 18 mAn
                                                0x1A,0x1F,0x20,0x0A,    // 19 AUtO
                                                0x08,0x02,0x04,0x0C,    // 20 C428
                                                0x05,0x08,0x03,0x1B,    // 21 P385
                                                0x01,0x09,0x03,0x1B,    // 22 P391
                                                0x19,0x0A,0x0C,0x10,    // 23 CAn
                                                0x19,0x20,0x1D,0x10,    // 24 rUn
                                                0x0D,0x19,0x0E,0x10,    // 25 End
                                                0x0E,0x1D,0x0E,0x10,    // 26 ErE
                                                0x0A,0x0F,0x1B,0x10,    // 27 PFA
                                                0x1F,0x0D,0x20,0x10,    // 28 Udt
                                                0x1E,0x13,0x0C,0x10,    // 29 CHS
                                                0x0D,0x0C,0x0A,0x10,    // 30 ACd
                                                0x0C,0x1D,0x0C,0x10,    // 31 CrС
                                                0x22,0x1B,0x0E,0x10,    // 32 EPw
                                                0x1B,0x0E,0x0E,0x10,    // 33 EEP
                                                0x10,0x10,0x10,0x10,    // 34 bLk
                                                0x0E,0x1B,0x1E,0x10,    // 35 SPE
                                                0x0C,0x28,0x1F,0x10,    // 36 t^C
                                                0x18,0x0C,0x0D,0x10,    // 37 dCm
                                                0x01,0x10,0x18,0x10,    // 38 m_1
                                                0x00,0x01,0x18,0x10,    // 39 m10
                                                0x00,0x00,0x01,0x18,    // 40 m100
                                                0x0E,0x18,0x14,0x1F,    // 41 timE
                                                0x12,0x0E,0x1D,0x10,    // 42 rEG
                                                0x1E,0x18,0x10,0x10,    // 43 mS
                                                0x0C,0x0E,0x1E,0x10,    // 44 SEC
                                                0x19,0x14,0x18,0x10,    // 45 min
                                                0x20,0x1A,0x13,0x10,    // 46 HOU
                                                0x1A,0x26,0x01,0x10,    // 47 1->0, здесь 0 заменен на O
                                                0x01,0x26,0x1A,0x10,    // 48 0->1, здесь 0 заменен на O
                                                0x1D,0x22,0x1B,0x10,    // 49 Pwr
                                                0x1B,0x1D,0x0E,0x10,    // 50 ErP
                                                0x1B,0x1F,0x1E,0x10,    // 51 StP
                                                0x1F,0x1F,0x1E,0x10,    // 52 Stt
                                                0x1F,0x1E,0x1D,0x0A,    // 53 ArSt
                                                0x1E,0x19,0x1A,0x10};   // 54 OnS


                        //--------------------- Таблица динамического сообщения
const   unsigned char   DINAMIC_DATA[] = {      0x10,           // blank
                                                0x1E,           // S
                                                0x12,           // G
                                                0x1D,           // r
                                                0x10,           // blank на 3 знака, чтобы не было полного погасания
                                                0x10,           // blank
                                                0x10,           // blank
                                                0x18,           // m
                                                0x1B,           // P
                                                0x1F,           // t
                                                0x1F,           // t
                                                0x01,           // 1
                                                0x10,           // blank на 4 знака, т.е. полный индикатор
                                                0x10,           // blank
                                                0x10,           // blank
                                                0x10};          // blank



//      ВНИМАНИЕ!
//      Таблица символов не совпадает с таблицей символов всех остальных приборов.
//
//      Таблица символов для приборов оборудованный индикатором с общим катодом
//      для перехода к таблице с ОА необходимо сделать комплемент содержимому
//      Комплемент выполнен с импользованием исключ. ИЛИ в программе UPDATEDISPLAY
//                                                                                      Код h

const   unsigned char   LED_TABLE[] = {         0b00111111,     // led drive for 0      0
                                                0b00000110,     // led drive for 1      1
                                                0b01011011,     // led drive for 2      2
                                                0b01001111,     // led drive for 3      3
                                                0b01100110,     // led drive for 4      4
                                                0b01101101,     // led drive for 5      5
                                                0b01111101,     // led drive for 6      6
                                                0b00000111,     // led drive for 7      7
                                                0b01111111,     // led drive for 8      8
                                                0b01101111,     // led drive for 9      9
                                                0b01110111,     // led drive for A      A
                                                0b01111100,     // led drive for b      b
                                                0b00111001,     // led drive for C      C
                                                0b01011110,     // led drive for d      d
                                                0b01111001,     // led drive for E      E
                                                0b01110001,     // led drive for F      F
                                                0b00000000,     // blank led drive      10
                                                0b01000000,     // led drive for -      11
                                                0b00111101,     // led drive for G      12
                                                0b01110110,     // led drive for H      13
                                                0b00000100,     // led drive for i      14
                                                0b00001110,     // led drive for J      15
                                                0b01110010,     // led drive for K      16
                                                0b00111000,     // led drive for L      17
                                                0b01010101,     // led drive for m      18
                                                0b01010100,     // led drive for n      19
                                                0b00111111,     // led drive for O      1A
                                                0b01110011,     // led drive for P      1B
                                                0b01100111,     // led drive for q      1C
                                                0b01010000,     // led drive for r      1D
                                                0b01101101,     // led drive for S      1E
                                                0b01111000,     // led drive for t      1F
                                                0b00111110,     // led drive for U      20
                                                0b00011100,     // led drive for V      21
                                                0b01101010,     // led drive for W      22
                                                0b00110110,     // led drive for X      23
                                                0b01101110,     // led drive for Y      24
                                                0b01001001,     // led drive for Z      25
                                                0b01000000,     // led drive for -(тире)26
                                                0b01010011,     // led drive for ?      27
                                                0b01100011};    // led drive for °      28


//      -------------------------- РЕГИСТРЫ И ФЛАГИ ---------------------------
//      ---------------------------- BANK0 ------------------------------------


#define FL_ON_LOAD_TIME_STEPII  RA2             // Флаг упр. LOAD_TIME (Step II) (выв. 11, 12)
#define FL_CS_MCP3201           RA4             // Флаг выборки A/D MCP3201
#define FL_ON_LOAD_HEAT_STEPI   RA5             // Флаг упр. LOAD_HEAT (Step I)  (выв. 9, 10)
#define FL_DPOINT               RB7             // Флаг управления десятичной точкой
#define FL_PWM_OUT_SOUND        RC2             // Флаг управления подачей звукового сигнала (реально флаг используется, только для контрольного выкл. звука)
#define FL_AN_INPUT_ST_TIME     RC7             // Флаг анализа входного внешнего сигн. запуска (лог. "1" - старт)

static  int             BASE_DATA[] =           {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                                 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                                 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                                 0,0,0,0,0,0,0,0};
                                                // Всего - 56 слов.
static  unsigned char   *ADDR_FOR_CRC_COPY1;    // Указатель на адрес данных первой копии D6
static  unsigned char   *ADDR_FOR_CRC_COPY2;    // Указатель на адрес данных второй копии D6
static  unsigned int    COUN_3secL_STEPI;       // Счет. 2,5 сек для упр. реле STEPI (только BANK0 или BANK1)
static  unsigned int    COUN_3secH_STEPI;       // Счет. 2,5 сек для упр. реле (только BANK0 или BANK1)
static  unsigned char   LEDS_0;                 // Рег. хранен. данных для индик.(1 °C)
static  unsigned char   LEDS_1;                 // Рег. хранен. данных для индик.(10 °C)
static  unsigned char   LEDS_2;                 // Рег. хранен. данных для индик.(100 °C)
static  unsigned char   LEDS_3;                 // Рег. хранен. данных для индик.(1000 °C)
static  unsigned int    KEY1COUN4S_8S;          // Регистр определ. врем. непрерыв. наж. KEY1 4с или 8с
static  unsigned int    KEY2COUN4S_8S;          // Регистр определ. врем. непрерыв. наж. KEY2 4с или 8с
static  unsigned char   KEY1COUN;               // Счетчик клавиши "1"(1 бит равен 20мс)
static  unsigned char   KEY2COUN;               // Счетчик клавиши "2"(1 бит равен 20мс)
static  unsigned char   KEY4COUN;               // Счетчик клавиши "4"(1 бит равен 20мс)
static  unsigned char   KEY4STAT;               // Регистр статуса (кол-во нажат. клавиши в диап. 15сек)
static  int             PARAM;                  // Регистр параметра(Для врем. использ.)
static  int             HI_PRED;                // Регистр верхнего предел (Для врем. использ.)
static  int             LOW_PRED;               // Регистр нижнего предела (Для врем. использ.)
static  unsigned char   TEMPC;                  // Промеж. регистр управления ключами катодов
static  unsigned char   TEMP_PORTB;             // Промеж. регистр хранен. сост. PORTB
static  unsigned char   TEMP_PORTC;             // Промеж. регистр хранен. сост. PORTC
static  unsigned char   NMBPARAM;               // Регистр номера выбранного параметра
static  unsigned char   SET_SEL;                // Регистр выбора параметра по Set
static  unsigned char   COUN_SND;               // Cчетчик для звука
static  unsigned char   COUN05sec;              // Счетчик для задержки 05 сек
static  unsigned char   COUN1sec;               // Счетчик для задержки 1 сек
static  unsigned char   COUN1_5;                // Счетчик для задержки 1_5 сек
static  unsigned int    COUN15SET;              // Счетчик для режима SETUP
static  unsigned char   COUNPASW;               // Регистр счетчик для PASWORD
static  unsigned char   CUR_TYPE_SENS;          // Регистр хран.типа сенс.,определенного после старта
static  unsigned char   COUNT_MESSAGE;          // Счетчик для вывода сообщений
static  unsigned char   FLAGKEYS;
static  int             RESAD_D1;               // Регистр результата преобразования A/D для температуры
static  int             AVR_T_HINDR;            // Рег. хран. средн. знач. темпер. для определ. помехи (временная точка 2, т.е текущий результат)
static  int             AVR_T_HINDR_OLD1;       // Рег. хран. средн. знач. темпер. для определ. помехи (временная точка 1)
static  long            SUM_D1;                 // Регистр суммы для датч.1
static  unsigned char   COUN_HINDR_ULHIdelta_t; // Счетчик помехи для ультрабольших приращений температуры
static  unsigned char   COUN_HINDR_LOWdelta_t;  // Счетчик помехи для малых приращений температуры
static  int             RESUL_IND;              // Регистр результ. для индикации
static  long            RESUL_PID;              // Рег. данных для автонастройки
static  long            OLD_RESUL_IND;          // Регистр результ. для индикации в предыдущем цикле
static  int             COUN_SUMDIV;            // Счетчик для определения ср. знач. температуры
static  unsigned char   TMP_CONFIG_REG;         // Регистр временного хран. номера исполн. прибора
static  unsigned char   NMB_MESSAGE;            // Регистр номера сообщения
static  int             TMP_PARAM_MES;          // Временный параметр для функц. MAKE_MESSAGE
static  unsigned char   WR_EEPROM;              // Регистр-флаг команды активизации записи
static  unsigned char   WR_EEPROM1;             // Дублир. регистр-флаг команды актив. записи
static  unsigned char   ADDREEP;                // Регистр начального адреса данных в EEPROM
static  unsigned char   COUNT_EE;               // Cчетчик кол-ва байт передаваемого или принимаего параметра по I2C
static  unsigned char   TMP_COUNT_EE;           // Временный регистр кол-ва байт
static  unsigned char   *ADDR_BASE_DATA;        // Указатель на данные BASE_DATA
static  unsigned char   *TMP_ADDR_BASE_DATA;    // Временный указатель на данные BASE_DATA
static  int             TMP_VAL_CRC1;           // Регистр временного хранения результата проверки CRC для COPY1 данных D6
static  int             TMP_VAL_CRC2;           // Регистр временного хранения результата проверки CRC для COPY2 данных D6
static  unsigned char   COUNT_FOR_CRC;          // Счетчик для вычисления CRC
static  int             COUN_DEL_CANCEL_AUTOSET; // Счетчик задержки отмены режима автонастройки параметров
static  unsigned char   AMOUNT_BYTE_DYNAMIC_DATA; // Кол-во динамич. вывод сиволов бегущей строки
static  unsigned int    COUN_DELAY_SGr;         // Счетчик длительности вывода фазы сообщения "SGr" для бегущей строки.
static  unsigned char   COUN_RATE_DINAMIC_DATA; // Счетчик длительности индикации одного символа до момента его сдвига(фактически темп индикации)
static  unsigned char   NMB_SYMBOL;             // Номер выводимого символа из массива DINAMIC_DATA (бегущая строка)
static  unsigned char   COUN_DELAY_2X5mS_EEW;   // Счетчик задержки записи в EEPROM на два периода индикации, т.е. (5 mS) X 2
static  unsigned char   COUN_DEL_INP;           // Счетчик формирования длительности тестирования входного сигнала
static  unsigned char   COUN_STAT_INP;          // Счетчик для определения статуса входного управл. сигнала
static  unsigned char   REAL_VALUE_MULTIPLY;    // Регистр хран. реальн. знач. коэфф. умножен. для nGE
static  unsigned int    COUN_AMOUNT_PERIOD_IND; // Регист кол-ва остатка периодов для индикации (nGE) без множителя (mUL)
static  long            COUN_AMOUNT_PERIOD_nGE; // Счетчик кол-ва периодов для реж. nGE с учетом множителя (mUL)
static  unsigned int    COUN_mS;                // Счетчик mS
static  unsigned char   COUN_SEC;               // Счетчик SEC
static  unsigned char   COUN_min;               // Счетчик min
static  unsigned char   COUN_NMB_BEEP_END_PRG;  // Счетчик числа сигналов для окончания программы
static  unsigned char   REG_CURRENT_MODE;       // Регист хран. тек. режима(копия образа BASE_DATA[n_mtm], только однобайтная)
static  unsigned char   REG_TEST_MODE;          // Регистр проверки текущего режима по mtm
static  unsigned int    COUN_PAUSE;             // Рег. отсчета длит.паузы для DIR_LOAD
static  unsigned int    COUN_IMPULSE;           // Рег. отсчета длит.импульса для DIR_LOAD
static  unsigned char   COUN_SND_END_PRG;       // Промежуточный счетчик для звука окончания программы
static  unsigned int    COUN_DEL_5sec_Start_Stop_Jnt; // Счетчик задержки start/stop запуска отсчета для Jnt
static  unsigned char   COUN_DEL_SELECT_OA_OK;  // Счетчик задержки контроля типа индикатора
static  unsigned char   COUN_DEL_AVR_T_HINDR;   // Счетчик задержки формирования среднего значения со сдвигом во времени на 4 измерения


static  bit             FL_CONFL_KEY;           // Флаг конфликта клавиатуры, т.е. нажата 1 или более клав.
static  bit             FL_PRESS_ANY_KEY;       // Флаг нажатия хотя-бы одной клавиши
static  bit             FL_RB3_MODE_IND;        // Флаг нажатого сост. кл. по RB3 (режим индикации: замкн- °С, разомкн. - T)
static  bit             FL_RB4_INC;             // Флаг нажатого сост. кл. по RB4
static  bit             FL_RB5_DEC;             // Флаг нажатого сост. кл. по RB5
static  bit             FL_RB6_D6;              // Перемычка Д6 (замк. -активна "D6", разом -"Work")
static  bit             FL_RB7_SET;             // Флаг нажатого сост. кл. по RB7
static  bit             FL_Cu100Pt100;          // Флаг соответсвия исполнения прибора для Cu100 или Pt100
static  bit             FL_MEH_RELE;            // Флаг наличия в приборе хотя-бы одного механического реле
static  bit             FL_2RELE;               // Флаг наличия в приборе 2-х реле(if FL=1, то в приборе 2 реле)
static  bit             FL_PRIM_START;          // Флаг первичного старта системы
static  bit             FL_05sec;               // Флаг состояния счетчика 05 сек
static  bit             FL_1sec;                // Флаг 1 сек задержки
static  bit             FL_1_5sec;              // Флаг завершения задержки по значению 1_5 сек
static  bit             KEY1FLAG;               // Флаг была нажата кл.1 !
static  bit             KEY2FLAG;               // Флаг была нажата кл.2 !
static  bit             KEY4FLAG;               // Флаг была нажата кл.4 !
static  bit             FLAG4sec;               // Флаг была нажата кл.4 более 4 сек
static  bit             KEY4AKT;                // Флаг активности кл.4
static  bit             FL_KEY1_4S;             // Флаг непрерывного нажатия кл.1 более 4 с
static  bit             FL_KEY1_8S;             // Флаг непрерывного нажатия кл.1 более 8 с
static  bit             FL_KEY2_4S;             // Флаг непрерывного нажатия кл.2 более 4 с
static  bit             FL_KEY2_8S;             // Флаг непрерывного нажатия кл.2 более 8 с
static  bit             FL_KEYAKT;              // Флаг активности клавиатуры
static  bit             FL_PRESS_K12;           // Флаг события нажатия кл.1 или кл.2
static  bit             FL_MK_NAL;              // Флаг активности процесса наладки
static  bit             FL_RUN_AUTOSETUP;       // Флаг активности процесса автонастройки параметров по D6
static  bit             FL_END_AUTOSETUP;       // Флаг успешного завершения автонастройки параметра
static  bit             FL_IND_RUNASETUP;       // Флаг необходимости вывода сообщения о начале автонастройки
static  bit             FL_IND_ENDASETUP;       // Флаг необходимости вывода сообщения о завершении автонастройки
static  bit             FL_IND_CANASETUP;       // Флаг необходимости вывода сообщения об отмене автонастройки
static  bit             FL_PERMIT_INC_ASETUP;   // Флаг разрешение инкремента параметра при AUTOSETUP по завершении SUMDIV
static  bit             FL_PERMIT_RUN_ASETUP;   // Флаг разрешение начала AUTOSETUP параметров по заверешении накопления суммы отсчетов SUMDIV
static  bit             FL_PERMIT_DIR_LOAD_HEAT; // Флаг разрешения управ. каналом "Regulator". Необходимо для исключ. подрабатывания задержки 3,5sec при "mSt" = "mode_St_Pwr"
static  bit             FL_ERR_DATH1;           // Флаг неисправности датч.1
static  bit             FL_NEG_B2BCD;           // Флаг негат. знач. резул. B2->BCD преобраз
static  bit             FL_AKT_WR_EEPROM;       // Флаг активности записи в EEPROM
static  bit             FL_EERDWRGUT;           // Флаг удачного завершения операц. с I2C
static  bit             FL_TESTWREE;            // Флаг старта проверки записи чтением в EEPROM
static  bit             FL_TESTWREE_DUBL;       // Дубль-флаг старта проверки записи чтением в EEPROM
static  bit             FL_AKT_TEST_WR_EEPROM;  // Флаг активного состояния проверки записи чтением в EEPROM
static  bit             FL_NEED_AKT_LOAD_STEPI; // Промежуточный флаг необ. активиз. нагр. для HEAT
static  bit             FL_CHANG_CUR_S;         // Флаг изменения текущего типа сенсора
static  bit             FL_ERR_SETPASW;         // Флаг ошибки установки PAS
static  bit             FL_ERR_CRC;             // Флаг повреждения данных
static  bit             FL_ERR_CRC_COPY1;       // Флаг повреждения данных COPY1
static  bit             FL_ERR_CRC_COPY2;       // Флаг повреждения данных COPY2
static  bit             FL_END_DELAY_SGr_LOGO;  // Флаг завершения остановки движения бегущей строки на 2c, на период вывода лого "SGr"
static  bit             FL_OLD_STATUS_INPUT;    // Флаг хранения предыдущего состояния входного сигнала
static  bit             FL_CUR_STATUS_INPUT;    // Флаг хранения текущего состояния входного сигнала
static  bit             FL_PHASE_PAUSE;         // Флаг активности фазы "PAUSE"
static  bit             FL_END_PHASE_PAUSE;     // Флаг заверщения фазы "PAUSE"
static  bit             FL_PHASE_IMPULSE;       // Флаг активности фазы "IMPULSE"
static  bit             FL_RUN_PRG_TIME;        // Флаг активности выполнения программы исполнения выдержек времени
static  bit             FL_RUN_PRG_TIME_JNT;    // Флаг активности выполнения программы для mOd = Jn1 || mOd = Jn2
static  bit             FL_RUN_PRG_JNT2;        // Флаг активности выполнения программы для mOd = Jn2
static  bit             FL_START_PRG_TIME;      // Флаг старта отсчета одновибратора
static  bit             FL_START_PRG_JNT2;      // Флаг старта исполнения программы для mOd = Jn2
static  bit             FL_NEED_START_PRG_TIME; // Флаг необходимости старта отсчета времени таймера
static  bit             FL_NEED_START_PRG_JNT2; // Флаг необходимости старта выполнения программы по mOd = Jnt
static  bit             FL_HAND_COUN_STAT_INP;  // Флаг ручного инкремента счетчика анализа входа
static  bit             FL_ERR_SET_PAR_TIME;    // Флаг ошибки установки временных параметров
static  bit             FL_SOUND_END_PRG;       // Флаг подачи сигнала по завершении фазы "IMPULSE"
static  bit             FL_ERR_SET_PAR;         // Флаг ошибки установки временных параметров
static  bit             FL_NEED_START_PRG_TIME_JNT; // Флаг необходимости запуска отсчета времени при mOd=Jnt. Флаг исключ. повторного запуска
static  bit             FL_CUR_STAT_JNT_START;  // Флаг текущего состояния команды запуска отсчета времени для "Jnt"
static  bit             FL_OLD_STAT_JNT_START;  // Флаг предыдущего состояния команды запуска отсчета времени для "Jnt"
static  bit             FL_PERMIT_RESTART_FOR_JN1; // Флаг разрешения повторного перезапуска процесса JN1
static  bit             FL_START_PROC_JNT2_StP; // Флаг для вывода сообщения о старте процесса JNT2
static  bit             FL_START_TIME_JN12_Stt; // Флаг для вывода сообщения о старте времени для JNT1 и JNТ2
static  bit             FL_AUTO_RESET_JN1;      // Флаг вывода сообщения об автосбросе прог. Jn1, т.е. температура объекта "прошла" значение параметра "SPr"
static  bit             FL_SET_INDIC_OK;        // Флаг установленого типа индикатора ("0" - <ОA>, "1" - <ОK>)
static  bit             FL_END_SUMDIV;          // Завершена подпрограмма SUM_DIVISION
static  bit             FL_RUN_CHECK_CRC;       // Флаг старта процесса вычисления CRC и последующего восстановления данных
static  bit             FL_CHANGE_BASE_DATA;    // Флаг фиксации факта изменения данных BASE_DATA и как следствие необходимости пересчете CRC и их перезаписи с учетом 2-х копий
static  bit             FL_END_WR_EEPROM;       // Флаг завершения записи данных в EEPROM
static  bit             FL_ON_PWM_BEEP;         // Флаг состояния выхода PWM_BEEP для END_PRG (Timer + Regul)
static  bit             FL_ULHIdelta_t;         // Флаг ультра большого значения приращения температуры
static  bit             bad_intr;

void main(void)
{
        PRIM_INIT();            // Первичная инициализация
CYCL:
        INTCON                  = 0b10000000;           // Вкл. глобаль. и периф. прерыв.,
        T1CON                   = 0b00000001;
        goto CYCL;

}

//-----------------------------------------------------------------------------
//              Область 5 и 20 мс прерываний
//              Прерывания от TMR1

static void interrupt isr(void) // Обработка прерываний по TMR1
{

//      --------        Область 5 мс прерываний  ----------

        if(!TMR1IF)                     // Was this a timer overflow?
                bad_intr = 1;           // NO! Shock horror!
        TMR1IF = 0;                     // Clear interrupt flag, ready for next
        TMR1H = 0xD9;                   // Экспериментально 8MHz
        TMR1L = 0x37;                   // Проверено 07-02-2011
        TEMPC <<= 1;
        if(TEMPC == 4)
                TEMPC = 32;
        if(TEMPC == 128 || TEMPC == 0)
                TEMPC = 1;
        KEYSTATUS();
        UPDATEDISPLAY();
        DYNAMIC_DISPLAY();
        D_POINT();
        if(FL_PRIM_START == 0)          // Завершен первичный старт!
                {
                if(FL_END_SUMDIV == 1)                  // Завершено суммирование?
                        {
                        FL_END_SUMDIV = 0;              // Перед SUM_DIVISION!
                        FL_RUN_CHECK_CRC = 1;           // Run test CRC
                        }

                if(BASE_DATA[n_mOd] == mOd_OFF)
                        {
                        COUN_3secL_STEPI = 700;         // HEAT_STEPI --- is OFF
                        COUN_3secH_STEPI = 700;
                        FL_NEED_AKT_LOAD_STEPI = 0;
                        FL_ON_LOAD_HEAT_STEPI = 0;
                        FL_NEED_START_PRG_TIME = 0;
                        FL_START_PRG_TIME = 0;          // TIME_STEPII --- is OFF
                        FL_RUN_PRG_TIME = 0;
                        FL_END_PHASE_PAUSE = 0;
                        FL_PHASE_PAUSE = 0;
                        FL_PHASE_IMPULSE = 0;
                        FL_CUR_STAT_JNT_START = 0;
                        FL_RUN_PRG_TIME_JNT = 0;
                        FL_NEED_START_PRG_JNT2 = 0;
                        FL_START_PRG_JNT2 = 0;
                        FL_RUN_PRG_JNT2 = 0;
                        FL_ON_LOAD_TIME_STEPII = 0;
                        }

                if(BASE_DATA[n_mOd] == mOd_Onr)
                        {
                        DIR_FL_LOAD_HEAT();
                        DELAY_3sec_DIR_LOAD_HEAT();
                        FL_NEED_START_PRG_TIME = 0;     // TIME_STEPII --- is OFF
                        FL_START_PRG_TIME = 0;
                        FL_RUN_PRG_TIME = 0;
                        FL_END_PHASE_PAUSE = 0;
                        FL_PHASE_PAUSE = 0;
                        FL_PHASE_IMPULSE = 0;
                        FL_CUR_STAT_JNT_START = 0;
                        FL_RUN_PRG_TIME_JNT = 0;
                        FL_NEED_START_PRG_JNT2 = 0;
                        FL_START_PRG_JNT2 = 0;
                        FL_RUN_PRG_JNT2 = 0;
                        FL_ON_LOAD_TIME_STEPII = 0;
                        }

                if(BASE_DATA[n_mOd] == mOd_Ont)
                        {
                                                        // HEAT_STEPI --- is OFF
                        COUN_3secL_STEPI = 700;         //
                        COUN_3secH_STEPI = 700;         //
                        FL_NEED_AKT_LOAD_STEPI = 0;     // Выключить
                        FL_ON_LOAD_HEAT_STEPI = 0;
                        AN_INPUT_TIME();
                        START_PRG_TIME();
                        DIR_LOAD_TIME();
                        FL_CUR_STAT_JNT_START = 0;
                        FL_RUN_PRG_TIME_JNT = 0;
                        FL_NEED_START_PRG_JNT2 = 0;
                        FL_START_PRG_JNT2 = 0;
                        FL_RUN_PRG_JNT2 = 0;
                        }

                if(BASE_DATA[n_mOd] == mOd_SEP)
                        {
                        DIR_FL_LOAD_HEAT();
                        DELAY_3sec_DIR_LOAD_HEAT();
                        AN_INPUT_TIME();
                        START_PRG_TIME();
                        DIR_LOAD_TIME();
                        FL_CUR_STAT_JNT_START = 0;
                        FL_RUN_PRG_TIME_JNT = 0;
                        FL_NEED_START_PRG_JNT2 = 0;
                        FL_START_PRG_JNT2 = 0;
                        FL_RUN_PRG_JNT2 = 0;
                        }

                if(BASE_DATA[n_mOd] == mOd_Jn1)         // Старт нагрева после Pwr= On,
                        {                               // старт времени после нагрева,
                        DIR_FL_LOAD_HEAT();             // нагрев непрерывно и после окончания времени.
                        DELAY_3sec_DIR_LOAD_HEAT();
                        JNT_COMPARE_RESUL_IND_SPS_SPr();
                        AN_INPUT_TIME();
                        START_PRG_TIME();
                        DIR_LOAD_TIME();
                        FL_NEED_START_PRG_JNT2 = 0;
                        FL_START_PRG_JNT2 = 0;
                        FL_RUN_PRG_JNT2 = 0;
                        }

                if(BASE_DATA[n_mOd] == mOd_Jn2)         // Старт нагрева по команде(внешней или внутрен.),
                        {                               // старт времени после нагрева,
                        AN_INPUT_TIME();
                        START_PRG_JNT2();
                        BASE_ALGORITM_JNT2();
                        }
                }
        ADSERVIS();
        SUM_DIVISION();
        if(TEMPC != 1)
                return;

//       --------  Область 20 мс прерываний    ----------

        if(FL_PRIM_START == 0)
                {
                if(FL_RUN_CHECK_CRC == 1)
                        {
                        FL_RUN_CHECK_CRC = 0;
                        CHECK_CRC();            // Разнести по фазе относительно SUM_DIVISION!
                        RESTORE_DATA();
                        }
                SET_CONFIG_FLAG();              // SET_CONFIG_FLAG после CHECK_RESTORE_DATA
                DELAY_MULTY();
                ANKEY_1_2_4();
                KEY_INTERFACE();
                MAKE_MESSAGE();
                OUT_IND();
                TEST_CHANG_SENSOR();
                EEPWRITE();
                }
        SELECT_OA_OK_LEDS();
        SOUND();

}       //      Область 5 и 20 мс прерываний завершена
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
void    PRIM_INIT(void)         // Первичная инициализация

{

//      ------------------------ Инициализация монитора напряжения питания

#if defined SELECT_18F2321 || defined SELECT_18F2520 || defined SELECT_18F2523 || defined SELECT_18F2550 || defined SELECT_18F2580 || defined SELECT_18F2620 || defined SELECT_18F2680  // For PIC18F2321, PIC18F2520, PIC18F2523, PIC18F2550, PIC18F2580, PIC18F2620, PIC18F2680
        HLVDCON                         = 0b00011001;   // HLVD is On, Voltage Detection = 3,46...3,63V
        HLVDIF                          = 0;
#endif

#if defined SELECT_18F2320 || defined SELECT_18F252 || defined SELECT_18F2539   // For PIC18F2320, PIC18F252, PIC18F2539
        LVDCON                          = 0b00011001;   // LVD is On, detect level is 3.!!V - 3.!!V
        LVDIF                           = 0;            // В самом начале. Флаг LVDIF не переносить.
#endif

//      ------------------------ Инициализация внутреннего тактового генератора

#ifdef  SELECT_18F252                                   // For PIC18F252
        OSCCON 				= 0b00000000;	// From primary oscillator
#endif

#if defined SELECT_18F2523				// For PIC18F2523
        OSCCON                          = 0b01110000;   // Primary oscillator HS, 8 MHz if base clock is bad (FCMEN)
        OSCTUNE = 0;
#endif

//      ------------------------ Инициализация портов

#ifdef  SELECT_18F252                                   // For PIC18F252
        ADCON0                          = 0;            // Выключить модуль A/D
        ADCON1                          = 0b10000110;   // Установить:  ALL digital, Right justified
#endif

#ifdef  SELECT_18F2523                                  // For PIC18F2523
        ADCON2                          = 0b10011010;   // Right justified, FOSC/32, 6 TAD
        ADCON1                          = 0b00011101;   // Установить:  RA0, RA1 -analog, RA2...RA12 -digit
        ADCON0                          = 0b00000101;   // Включить модуль A/D, select chanel 1
#endif

#ifdef  SELECT_18F252                                   // For PIC18F252
        TRISA                           = 0b11001011;   // Порт RA0, RA1, RA3  - вход, RA2, RA4, RA5 - на выход
        PORTA                           = 0b11011011;   //
        LATA                            = 0b11011011;
#endif

#ifdef  SELECT_18F2523                                  // For PIC18F2523
        TRISA                           = 0b11011011;   // Порт RA0, RA1, RA3, RA4 - вход, RA2, RA5 - на выход
        PORTA                           = 0b11001011;   //
        LATA                            = 0b11001011;
#endif

        TRISB                           = 0;            // Порт В на выход
        PORTB                           = 0;
        TRISC                           = 0b10010000;   // Порт С: 0...3, 5 - на выход; 4, 6, 7 - на вход
        PORTC                           = 0b10011000;   //
        TEMPC                           = 1;            // Впрыснуть "1" в TEMPC

//      ;------------------------- Инициализация регистров и флагов
        LEDS_0                          = 0x10;         // Производитель: ООО "SGREEN-LAB"
        LEDS_1                          = 0x10;         // Внимание! Не сокращать загрузку, так как
        LEDS_2                          = 0x10;         // возможен вывод случайных символов на индикатор!
        LEDS_3                          = 0x10;         // возможен вывод случайных символов на индикатор!
        FL_PRIM_START                   = 1;
        COUN_DEL_SELECT_OA_OK           = 1;            // При первичном старте "1", чтобы проверка по первому проходу!
        SELECT_OA_OK_LEDS();
        FL_END_DELAY_SGr_LOGO           = 0;
        COUN_DELAY_SGr                  = 312;          // 2 sec. Первичный старт и вывод сооб. "SGr"
        COUN_DELAY_2X5mS_EEW            = 2;
        FL_05sec                        = 0;
        COUN05sec                       = 12;
        FL_1sec                         = 0;
        COUN1sec                        = 25;
        FL_1_5sec                       = 0;
        COUN1_5                         = 175;
        COUN15SET                       = 1000;         // Инициал. счетчик 15 с для SETUP
        FL_KEYAKT                       = 0;            // Только перед CHECK_CRC_OPNAL();
        KEY4AKT                         = 0;
        FL_MK_NAL                       = 0;
        NMBPARAM                        = 0;
        SUM_D1                          = 0;
        RESUL_IND                       = 0;
        COUN_SUMDIV                     = 128;
        FL_END_SUMDIV                   = 0;
        FL_RUN_CHECK_CRC                = 0;
        COUN_HINDR_LOWdelta_t           = 64;
        COUN_DEL_AVR_T_HINDR            = 3;    // Для полчения 3-х временных периодов измерения температуры
        AVR_T_HINDR                     = 0;
        AVR_T_HINDR_OLD1                = 0;
        FL_ULHIdelta_t                  = 0;
        COUN_3secL_STEPI                = 700;
        COUN_3secH_STEPI                = 700;
        COUN_DEL_CANCEL_AUTOSET         = 8000;         // Определить 120с на автоматическую отмену автонатройки
        FL_PERMIT_INC_ASETUP            = 0;
        FL_PERMIT_RUN_ASETUP            = 0;
        FL_PERMIT_DIR_LOAD_HEAT         = 0;
        FL_ERR_SETPASW                  = 0;
        FL_RUN_AUTOSETUP                = 0;
        FL_END_AUTOSETUP                = 0;
        FL_IND_RUNASETUP                = 0;
        FL_IND_ENDASETUP                = 0;
        FL_IND_CANASETUP                = 0;
        FL_OLD_STATUS_INPUT             = 0;
        FL_CUR_STATUS_INPUT             = 0;
        FL_NEED_START_PRG_TIME          = 0;
        FL_NEED_START_PRG_JNT2          = 0;
        FL_HAND_COUN_STAT_INP           = 0;
        FL_PHASE_PAUSE                  = 0;
        FL_END_PHASE_PAUSE              = 0;
        FL_PHASE_IMPULSE                = 0;
        FL_RUN_PRG_TIME                 = 0;
        FL_RUN_PRG_TIME_JNT             = 0;
        FL_RUN_PRG_JNT2                 = 0;
        FL_ERR_SET_PAR_TIME             = 0;
        FL_CUR_STAT_JNT_START           = 0;
        FL_OLD_STAT_JNT_START           = 0;
        FL_PERMIT_RESTART_FOR_JN1       = 0;
        FL_START_PROC_JNT2_StP          = 0;
        FL_START_TIME_JN12_Stt          = 0;
        FL_AUTO_RESET_JN1               = 0;
        COUN_DEL_5sec_Start_Stop_Jnt    = 1000;         // 5sec
        COUN_mS                         = 200;
        COUN_SEC                        = 60;
        COUN_min                        = 60;
        COUN_DEL_INP                    = 12;           // Опред. длит. детермин. вх. сигнала (далее 10)
        COUN_STAT_INP                   = 0;
        REAL_VALUE_MULTIPLY             = 1;
        COUN_AMOUNT_PERIOD_nGE          = 1;
        COUN_NMB_BEEP_END_PRG           = 0;
        FL_START_PRG_TIME               = 0;
        FL_START_PRG_JNT2               = 0;
        FL_SOUND_END_PRG                = 0;
        COUN_SND_END_PRG                = 12;
        COUN_NMB_BEEP_END_PRG           = 0;
        COUN_SND                        = 25;
        FL_ERR_SET_PAR                  = 0;
        FL_NEED_START_PRG_TIME_JNT      = 0;
        FL_ON_PWM_BEEP                  = 0;
        WR_EEPROM                       = 0;
        WR_EEPROM1                      = 0;
        INTCON                          = 0;    // Не перемещать!
        FL_AKT_WR_EEPROM                = 0;    // Не перемещать!
        FL_END_WR_EEPROM                = 0;    // Не перемещать!
        KEYSTATUS();                            // Всегда перед считыванием данных из EEPROM

//      ;---------------------- Начало неразрываемого блока-----------------

//      ;------------------------ Считать данные  оператора, наладчика и регул. D6
        ADDREEP = 0;                            // Определить адрес в EE=00h
        COUNT_EE = SIZE_BASE * 2;               // Определить кол-во байт
        ADDR_BASE_DATA = (unsigned char *ADDR_BASE_DATA)&BASE_DATA[0];         // Получ.адрес первого записываемого байта в RAM PIC
        EEPREAD ();                             // Считать основные данные
        CHECK_CRC();
        RESTORE_DATA();                         // Все RESTORE после CHECK
        SAVE_RESTORE_DATA();
        CUR_TYPE_SENS = (unsigned char)BASE_DATA[n_tSr];
        SET_CONFIG_FLAG();                      // SET_CONFIG_FLAG после RESTORE_D6_DATA

        FL_CHANGE_BASE_DATA = 0;
        if(FL_ERR_CRC == 0)
                {
                if(BASE_DATA[n_tSr] == tSr_Cu428)
                        {
                        if(BASE_DATA[n_SP] > max_tCu)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SP] = max_tCu;          // Для Cu установить max SP = 200 °C
                                }
                        if(BASE_DATA[n_SPS] > (max_tCu + 1))
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SPS] = (max_tCu + 1);   // Для Cu установить max SPS = 200,1 °C
                                }
                        if(BASE_DATA[n_SPr] > (max_tCu + 100))
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SPr] = (max_tCu + 100); // Для Cu установить max SPr = 210 °C
                                }
                        }
                else
                        {
                        if(BASE_DATA[n_SP] > max_tPt)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SP] = max_tPt;      // Для Pt установить max SP = 375 °C
                                }
                        if(BASE_DATA[n_SPS] > (max_tPt + 1))
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SPS] = (max_tPt + 1);     // Для Pt установить max SPS = 375,1 °C
                                }
                        if(BASE_DATA[n_SPr] > (max_tPt + 100))
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_SPr] = (max_tPt + 100); // Для Pt установить max SPr = 385 °C
                                }
                        }

                if(BASE_DATA[n_UnP] == Unit_mS)
                        {
                        if(BASE_DATA[n_PAU] < 500 || BASE_DATA[n_PAU] > 5000)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_PAU] = 5000;
                                }
                        }

                if(BASE_DATA[n_Uni] == Unit_mS)
                        {
                        if(BASE_DATA[n_imP] < 500 || BASE_DATA[n_imP] > 5000)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_imP] = 5000;
                                }
                        }

                if(BASE_DATA[n_mOd] >= mOd_Jn1)                 // Этот блок всегда перед автостартом PRG!
                        {
                        if(BASE_DATA[n_mSt] > mode_St_01)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_mSt] = mode_St_01;  // Для режима работы прибора "Jn1" и "Jn2" нет запуска отсчета времени по "Pwr"
                                }
                        if(BASE_DATA[n_HYS] < 0)                // For "Heat"
                                {
                                if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                                        {                       // SPS = SP, т.е SPE
                                        if(BASE_DATA[n_SPr] >= BASE_DATA[n_SP])
                                                {
                                                FL_CHANGE_BASE_DATA = 1;
                                                BASE_DATA[n_SPr] = BASE_DATA[n_SP] - 50;
                                                }
                                        }
                                else
                                        {
                                        if(BASE_DATA[n_SPr] >= BASE_DATA[n_SPS])
                                                {
                                                FL_CHANGE_BASE_DATA = 1;
                                                BASE_DATA[n_SPr] = BASE_DATA[n_SPS] - 50;
                                                }
                                        }
                                }
                        else
                                {                               // For "Cool"
                                if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                                        {                       // SPS = SP, т.е SPE
                                        if(BASE_DATA[n_SPr] <= BASE_DATA[n_SP])
                                                {
                                                FL_CHANGE_BASE_DATA = 1;
                                                BASE_DATA[n_SPr] = BASE_DATA[n_SP] + 50;
                                                }
                                        }
                                else
                                        {
                                        if(BASE_DATA[n_SPr] <= BASE_DATA[n_SPS])
                                                {
                                                FL_CHANGE_BASE_DATA = 1;
                                                BASE_DATA[n_SPr] = BASE_DATA[n_SPS] + 50;
                                                }
                                        }
                                }
                        }

                if(BASE_DATA[n_mOd] == mOd_Jn2)                 // Этот блок всегда перед автостартом PRG!
                        {
                        if(BASE_DATA[n_mtm] < mtm_dvr || BASE_DATA[n_mtm] > mtm_Ovr)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_mtm] = mtm_Ovr;     // Для режима работы прибора "Jn2" нет режима исполнения выдержек времени "AGE" и "dOn"
                                }
                        }

                REG_TEST_MODE = REG_CURRENT_MODE = (unsigned char)BASE_DATA[n_mtm];    // Сохранить текущий режим после старта

                if((REG_CURRENT_MODE == mtm_AGE || BASE_DATA[n_mSt] == mode_St_Pwr) && (BASE_DATA[n_mOd] == mOd_Ont || BASE_DATA[n_mOd] == mOd_SEP))
                        {
                        FL_START_PRG_TIME = 1;
                        if(BASE_DATA[n_Pri] == Pri_rEG)
                                {
                                FL_CHANGE_BASE_DATA = 1;
                                BASE_DATA[n_Pri] = Pri_tim;
                                }
                        FL_PRIM_START = 0;              // Без вывода "SGr" и "Mptt406"
                        LEDS_0 = 0x10;                  // Исключить паразитную
                        LEDS_1 = 0x10;                  // подсветку
                        LEDS_2 = 0x10;                  // индикации
                        LEDS_3 = 0x10;                  //
                        }

                COUN_AMOUNT_PERIOD_IND = BASE_DATA[n_Amn];

                if(FL_CHANGE_BASE_DATA == 1)
                        {
                        CALC_CRC();                     // Внимание! В самом конце
                        COPY1_to_COPY2();
                        WR_EEPROM = 0xA5;               // Команда на запись
                        WR_EEPROM1 = 0x5A;              // Дублирующая команда на запись
                        ADDREEP = 0;
                        COUNT_EE = (SIZE_BASE) * 2;     // Кол-во байт, подлежащих записи
                        ADDR_BASE_DATA = (unsigned char *ADDR_BASE_DATA)&BASE_DATA[0];            // Получ.адрес первого счит.байта из PIC
                        }
                }



//      ;---------------------- Конец неразрываемого блока-----------------

        FL_AKT_TEST_WR_EEPROM         = 0;
        FL_TESTWREE             = 0;
        FL_TESTWREE_DUBL        = 0;
        FL_ERR_DATH1            = 0;
        FL_NEED_AKT_LOAD_STEPI  = 0;
        COUNT_MESSAGE           = 30;

        //------------------------ Инициализация прерываний и TMR1--------------
        RCON                    = 0b11000000;           // Enable priority levels on interrupts
        INTCON                  = 0b10000000;           // Enables all high priority interrupts
        INTCON2                 = 0b10000000;           // All PORTB pull-ups are disabled
        INTCON3                 = 0;
        PIR1                    = 0;                    // Очистить флаги периф. прерыван.
        PIR2                    = 0;                    // Очистить флаги периф. прерыван.
        PIE1                    = 0b00000001;           // Разрешить прерывания от TMR1
        PIE2                    = 0;                    // Запретить все периф. прерыв.
        IPR1                    = 0b00000001;           // High priority for TMR1
        IPR2                    = 0;                    // All other in low priority
        T0CON                   = 0;                    // Timer0 is Off
        T1CON                   = 0b00000001;
        TMR1H                   = 0xC5;                 // Экспериментально
        TMR1L                   = 0xC6;                 // 12MHz
        T2CON                   = 0;                    // Timer2 is off
        T3CON                   = 0;                    // Timer3 is Off
        CCP1CON                 = 0;                    // CCP1 is off
        CCP2CON                 = 0;                    // CCP2 is off
        SSPCON1                 = 0;                    // SSP is Off
        TXSTA                   = 0b00000000;           //
        RCSTA                   = 0b00000000;           // Disabled USART

#if defined SELECT_18F2320 || defined SELECT_18F2321 || defined SELECT_18F2520 || defined SELECT_18F2523 || defined SELECT_18F2550 || defined SELECT_18F2620    // For PIC18F2320, PIC18F2321, PIC18F2520, PIC18F2550, PIC18F2580, PIC18F2620
        CMCON                   = 0b00000111;           // Comparators is Off
        CVRCON                  = 0b00000001;
#endif

}       //       Подпрограмма PRIM_INIT завершена
//-----------------------------------------------------------------------------

//-------------------------------------------------------------

void    EEPREAD(void)

{

        unsigned char TMP_EEDATA;

        EEADR = ADDREEP;        // Установить адрес в EEPROM
        NOP();
        EEPGD = 0;              // Установить область памяти данных
        CFGS = 0;               // Access FLASH Program or Data EEPROM memory
        NOP();
EERD_0: RD = 1;                 // Старт чтения
        TMP_EEDATA = EEDATA;    // Паразит, только из-за ошибок в chip 18F242
        *ADDR_BASE_DATA = TMP_EEDATA;
        ADDR_BASE_DATA++;       // Установить новый адрес данных в RAM PIC
        EEADR++;                // Установить новый адрес данных в EEPROM
        if(--COUNT_EE != 0)
                goto    EERD_0;
        FL_EERDWRGUT = 1;       // Подпрограмма завершена успешно


}//       Подпрограмма EEPREAD завершена
//------------------------------------------------------------

//-----------------------------------------------------------------------------

void    EEPWRITE(void)

{
        unsigned char EEP_TMP;
        unsigned char TMP_EEDATA;

        if(FL_TESTWREE == 1 && FL_TESTWREE_DUBL == 1)
                goto    EEWR_0;                 // Test write
        if(WR_EEPROM != 0xA5)                   // Нет команды активизации записи?
                goto    EEWR_3;
        if(WR_EEPROM1 != 0x5A)                  // Нет дублирующей команды активизации записи?
                goto    EEWR_3;

        if(FL_AKT_WR_EEPROM == 0)                   // Запись не активна?
                { //-------------- Первичная инициализация записи и запись 1-го байта из пакета
                if(COUNT_EE != (SIZE_BASE * 2))
                        goto EEWR_3;            // Несооответсвие кол-ва байт для записи
                if(WR == 1)
                        return;                 // Не заверш.запись в предыд. цикле. Поставить процесс в очередь
                EEIF = 0;
                FL_AKT_WR_EEPROM = 1;                       // Установить флаг активности записи
                TMP_COUNT_EE = COUNT_EE;                // Дублирование кол-ва байт
                TMP_ADDR_BASE_DATA = ADDR_BASE_DATA;    // Устан.указ. на адрес дан.в RAM PIC
                EEADR = ADDREEP;                        // Установить адрес данных  в EEPROM
                EEDATA = *TMP_ADDR_BASE_DATA;           // Загрузить данные для записи
                EEPGD = 0;                              // Установить область памяти данных
                CFGS = 0;                               // Access FLASH Program or Data EEPROM memory
                WREN = 1;                               // Разрешить процесс записи
                EECON2 = 0x55;
                EECON2 = 0xAA;
                WR = 1;                         // Старт записи
                return;
                }
        if(WR == 1)                           // Не завершена запись в EEPROM предыдущ. байта?
                return;
        if(--TMP_COUNT_EE == 0)
                {                               // Запись завершена, далее переход на контроль
                WREN = 0;                       // Заморозить процесс записи
                FL_AKT_WR_EEPROM = 0;
                FL_TESTWREE = FL_TESTWREE_DUBL = 1;
                FL_AKT_TEST_WR_EEPROM = 1;
                WR_EEPROM = 0;
                WR_EEPROM1 = 0;
                return;                         // Запись завершена, далее переход на контроль
                }
        EEIF = 0;                               // Программный сброс
        TMP_ADDR_BASE_DATA++;                   // Установить новый адрес данных в RAM PIC + 1
        EEADR ++;                               // Установить новый адрес данных в EEPROM + 1
        EEDATA = * TMP_ADDR_BASE_DATA;          // Загрузить данные для записи
        EEPGD = 0;                              // Установить область памяти данных
        CFGS = 0;                               // Access FLASH Program or Data EEPROM memory
        WREN = 1;                               // Разрешить процесс записи
        EECON2 = 0x55;
        EECON2 = 0xAA;
        WR = 1;                                 // Старт записи
        return;                                 // Выполнение записи в фоновом режиме

        //-----------------------Проверка записи чтением

EEWR_0: FL_TESTWREE = FL_TESTWREE_DUBL = 0;     // Сброс режима теста записи
        EEIF = 0;
        WREN = 0;                               // Заморозить процесс записи
        EEPGD = 0;                              // Выбрать память данных
        CFGS = 0;                               // Access FLASH Program or Data EEPROM memory
        TMP_ADDR_BASE_DATA = ADDR_BASE_DATA;    // Установить указ. на адрес данные BASE_DATA
        EEADR = ADDREEP;
        TMP_COUNT_EE = COUNT_EE;                // Загрузить счетчик кол-ва байт
EEWR_1: EEP_TMP = *TMP_ADDR_BASE_DATA;          // Поместить значен. из RAM PIC
        RD = 1;                                 // Старт чтения
        TMP_EEDATA = EEDATA;                    // Паразит, только из-за ошибок в chip 18F242
        TMP_ADDR_BASE_DATA++;                   // Перейти на след. адрес в RAM PIC
        if((EEP_TMP - TMP_EEDATA) != 0)         // Проверить соответствие байт RAM PIC и EEPROM PIC
                {
                FL_EERDWRGUT = 0;               // Запись завершена неудачно!
                goto EEWR_3;
                }
        EEADR++;                                // Перейти на след. адрес в EEP PIC
        if(--TMP_COUNT_EE !=0)
                goto EEWR_1;
        FL_AKT_TEST_WR_EEPROM = 0;
        FL_EERDWRGUT = 1;                       // Запись завершена успешно!
        FL_END_WR_EEPROM = 1;                   // Подать сигнал
        return;

EEWR_3:
        COUNT_EE = 0;
        EEADR = ADDREEP = (SIZE_BASE) * 2 + 1;  // Устан. адр. данных в EEPROM за пределами массива
        FL_AKT_WR_EEPROM = 0;
        FL_AKT_TEST_WR_EEPROM = 0;
        FL_TESTWREE = FL_TESTWREE_DUBL = 0;
        WR_EEPROM = WR_EEPROM1 = 0;
        WREN = 0;                               // Заморозить процесс записи


}//       Подпрограмма EEPWRITE завершена
//------------------------------------------------------------

//---------------------------------------------------------------------

unsigned char   SSPBUF_SPI(void)
{
        unsigned char    AD_CRASH_DELAY;

        AD_CRASH_DELAY = 0;
        NOP();                                  // Ошибки в чипе 16F886. Реально необходима задержка на 1 такт SCK,
        NOP();                                  // перед повторной загрузкой буфера "SSPBUF"

        if(FL_SET_INDIC_OK == 1)
                {                               // Для ОК
                SSPBUF = 0xFF;                  // Исключить мигание индикации
                }
        else
                {                               // Для ОA
                SSPBUF = 0x00;                  // Исключить мигание индикации
                }

        while(BF == 0)
                {
                AD_CRASH_DELAY++;
                if(AD_CRASH_DELAY > 50)
                        {
                        FL_CS_MCP3201 = 1;      // Deselect ADC-12 bit (MCP3201)
                        SSPEN = 0;              // Disables serial port and configures these pins as I/O port pins
                        return 0;               // Измеренение в состоянии "зависания"
                        }
                }
        return SSPBUF;

}       //      Подпрограмма SSPBUF_SPI завершена
//---------------------------------------------------------------------

//---------------------------------------------------------------------


void    GETSETPARAM(unsigned char TMP_NMBPARAM)


{
        long DIF_FOR_SCALE_SET0, TMP_VALUE_maxt;


        // ----------------------------- Загрузка параметра и определение базовых пределов

        HI_PRED = HI_PRED_BASE[TMP_NMBPARAM];
        LOW_PRED = LOW_PRED_BASE[TMP_NMBPARAM];
        PARAM = BASE_DATA[TMP_NMBPARAM];

        // ----------------------------- Огран. пределов задания в соответствии с типом параметра


        if(TMP_NMBPARAM == n_SP || TMP_NMBPARAM == n_SPS)
                {
                if(BASE_DATA[n_tSr] == tSr_Cu428)
                        {
                        if(TMP_NMBPARAM == n_SP)
                                HI_PRED = max_tCu;      // max = 200.0 °C for Cu
                        if(TMP_NMBPARAM == n_SPS)
                                HI_PRED = max_tCu + 1;  // max = 200.1 °C for Cu
                        }
                else
                        {
                        if(TMP_NMBPARAM == n_SP)
                                HI_PRED = max_tPt;      // max = 400.0 °C for Pt
                        if(TMP_NMBPARAM == n_SPS)
                                HI_PRED = max_tPt + 1;  // max = 400.1 °C for Pt
                        }
                }


        if(TMP_NMBPARAM == n_SPr)
                {
                if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                        {                               // SPS = SP, т.е SPE
                        if(BASE_DATA[n_HYS] < 0)        // For "Heat"
                                {
                                HI_PRED = BASE_DATA[n_SP] - 50;
                                }
                        else
                                {                       // For "Cool"
                                if(BASE_DATA[n_tSr] == tSr_Cu428)
                                        HI_PRED = max_tCu + 100;        // max = 210.0 °C for Cu
                                if(BASE_DATA[n_tSr] > tSr_Cu428)
                                        HI_PRED = max_tPt + 100;        // max = 410.0 °C for Pt
                                LOW_PRED = BASE_DATA[n_SP] + 50;
                                }
                        }
                else
                        {                               // SPS != SP
                        if(BASE_DATA[n_HYS] < 0)        // For "Heat"
                                {
                                HI_PRED = BASE_DATA[n_SPS] - 50;
                                }
                        else
                                {                       // For "Cool"
                                if(BASE_DATA[n_tSr] == tSr_Cu428)
                                        HI_PRED = max_tCu + 100;        // max = 210.0 °C for Cu
                                if(BASE_DATA[n_tSr] > tSr_Cu428)
                                        HI_PRED = max_tPt + 100;        // max = 410.0 °C for Pt
                                LOW_PRED = BASE_DATA[n_SPS] + 50;
                                }
                        }
                }

        if(TMP_NMBPARAM == n_HYS)
                {
                if(BASE_DATA[n_HYS] < 0)                // For "Heat"
                        {
                        if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                                {                       // SPS = SP, т.е SPE
                                if(BASE_DATA[n_SPr] >= BASE_DATA[n_SP])
                                        BASE_DATA[n_SPr] = BASE_DATA[n_SP] - 50;
                                }
                        else
                                {
                                if(BASE_DATA[n_SPr] >= BASE_DATA[n_SPS])
                                        BASE_DATA[n_SPr] = BASE_DATA[n_SPS] - 50;
                                }
                        }
                else
                        {                               // For "Cool"
                        if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                                {                       // SPS = SP, т.е SPE
                                if(BASE_DATA[n_SPr] <= BASE_DATA[n_SP])
                                        BASE_DATA[n_SPr] = BASE_DATA[n_SP] + 50;
                                }
                        else
                                {
                                if(BASE_DATA[n_SPr] <= BASE_DATA[n_SPS])
                                        BASE_DATA[n_SPr] = BASE_DATA[n_SPS] + 50;
                                }
                        }
                }

        if((TMP_NMBPARAM == n_PAU && BASE_DATA[n_UnP] == Unit_mS) || (TMP_NMBPARAM == n_imP && BASE_DATA[n_Uni] == Unit_mS))
                {
                HI_PRED = 5000;
                LOW_PRED = 500;
                }

        if(TMP_NMBPARAM == n_UnP && BASE_DATA[n_UnP] == Unit_mS)
                {
                if(BASE_DATA[n_PAU] < 500 || BASE_DATA[n_PAU] > 5000)
                        BASE_DATA[n_PAU] = 5000;
                }

        if(TMP_NMBPARAM == n_Uni && BASE_DATA[n_Uni] == Unit_mS)
                {
                if(BASE_DATA[n_imP] < 500 || BASE_DATA[n_imP] > 5000)
                        BASE_DATA[n_imP] = 5000;
                }


        if(TMP_NMBPARAM == n_mOd)
                {
                if(BASE_DATA[n_mOd] == mOd_Jn2 && (BASE_DATA[n_mtm] < mtm_dvr || BASE_DATA[n_mtm] > mtm_Ovr))
                        BASE_DATA[n_mtm] = mtm_Ovr;
                if((BASE_DATA[n_mOd] == mOd_Jn1 || BASE_DATA[n_mOd] == mOd_Jn2) && BASE_DATA[n_mSt] > mode_St_01)
                        BASE_DATA[n_mSt] = mode_St_01;
                }

        if((BASE_DATA[n_mOd] == mOd_Jn1 || BASE_DATA[n_mOd] == mOd_Jn2) && TMP_NMBPARAM == n_mSt)
                HI_PRED = mode_St_01;                           // Для режима работы прибора "Jn1" и "Jn2" нет запуска отсчета времени по "Pwr"

        if(BASE_DATA[n_mOd] == mOd_Jn2 && TMP_NMBPARAM == n_mtm)
                {
                LOW_PRED = mtm_dvr;                             // Для режима работы прибора "Jn2" нет исполнения выдержек времени "AGE", "nGE" и "dOn"
                HI_PRED = mtm_Ovr;
                }

        // ----------------------------- Проверка доступа к параметру
        if(TMP_NMBPARAM > AMOUNTPAR_OPERATOR)                   // Группа  не "ОПЕРАТОР"?
                goto SP1;
        if(FLAG4sec == 1)
                goto SP1;                                       // Установлен флаг нажатия кл.4 более 4 сек!
        if(BASE_DATA[n_ALC] == ALC_On)
                return;                                         // Доступ заблокирован! (уров. дост. операт)

SP1:
        // ---------------------------- Автонастройка параметров

        if(FL_RB6_D6 == 1 && BASE_DATA[n_md6] == mod_d6_auto && TMP_NMBPARAM != n_md6 && TMP_NMBPARAM != n_SYS)
                {                                               // Определен D6 и установлен режим автонастройки
                if(KEY2FLAG == 1 && FL_RUN_AUTOSETUP == 1)      // Прервать режим автонастройки
                        {
                        FL_RUN_AUTOSETUP = 0;
                        FL_END_AUTOSETUP = 0;
                        FL_IND_CANASETUP = 1;                   // Вывести сообщение об отмене автонастройки
                        }
                if(FL_RUN_AUTOSETUP == 1)                       // Активизирован режим автонастроки параметра!
                        {
                        if(FL_PERMIT_RUN_ASETUP == 1)
                                {                               // Да! Накопление суммы отсчетов температуры завершено!
                                DIF_FOR_SCALE_SET0 = RESUL_PID; // Это автоматически для nUL (t * 320)
                                if(TMP_NMBPARAM == n_428)
                                        {
                                        TMP_VALUE_maxt = max_tCu;
                                        TMP_VALUE_maxt *= 32;
                                        DIF_FOR_SCALE_SET0 -= TMP_VALUE_maxt;
                                        }
                                if(TMP_NMBPARAM == n_385 || TMP_NMBPARAM == n_391)
                                        {
                                        TMP_VALUE_maxt = max_tPt;
                                        TMP_VALUE_maxt *= 32;
                                        DIF_FOR_SCALE_SET0 -= TMP_VALUE_maxt;
                                        }
                                if(((DIF_FOR_SCALE_SET0 >= 0 && DIF_FOR_SCALE_SET0 <= 32) && TMP_NMBPARAM == n_nUL) || ((DIF_FOR_SCALE_SET0 >= 4 && DIF_FOR_SCALE_SET0 <= 48) && TMP_NMBPARAM != n_nUL))
                                        {                               // Допуск: nul_ (0,0...0,1°С), Cu_Pt_(+0,0125...0,15°С)
                                        FL_END_AUTOSETUP = 1;           // Завершить автонастройку!
                                        FL_IND_ENDASETUP = 1;           // Вывести сообщение о завершении автонастройки
                                        FL_RUN_AUTOSETUP = 0;           // Процесс завершен
                                        }
                                else
                                        {                               // Продолжить автонастройку
                                        if(FL_PERMIT_INC_ASETUP == 1)
                                                PARAM++;                // Здесь небольшая потеря монотонности инкремента. Не важно!
                                        if((DIF_FOR_SCALE_SET0 < -1120 || DIF_FOR_SCALE_SET0 > 1120) && TMP_NMBPARAM == n_nUL)
                                                PARAM += 5;             // диффер. от задания ± 3,5 °С для Null
                                        if((DIF_FOR_SCALE_SET0 < -960 || DIF_FOR_SCALE_SET0 > 960) && (TMP_NMBPARAM == n_385 || TMP_NMBPARAM == n_391))
                                                PARAM += 7;             // диффер. от задания ± 3 °С для Pt
                                        if((DIF_FOR_SCALE_SET0 < -640 || DIF_FOR_SCALE_SET0 > 640) && TMP_NMBPARAM == n_428)
                                                PARAM += 7;             // диффер. от задания ± 2 °С для Cu
                                        FL_PERMIT_INC_ASETUP = 0;       // Внимание! После проверки его же состояния
                                        }
                                if(PARAM > HI_PRED)
                                        PARAM = LOW_PRED;
                                if(--COUN_DEL_CANCEL_AUTOSET == 0 && FL_END_AUTOSETUP == 0)
                                        {                               // Отменить автонастройку
                                        FL_RUN_AUTOSETUP = 0;
                                        FL_END_AUTOSETUP = 0;
                                        FL_IND_CANASETUP = 1;           // Вывести сообщение об отмене автонастройки
                                        }
                                }
                        }
                else
                        {
                        COUN_DEL_CANCEL_AUTOSET = 8000;         // 120c
                        FL_END_AUTOSETUP = 0;
                        FL_RUN_AUTOSETUP = 0;
                        if(KEY1FLAG == 1)
                                {
                                FL_RUN_AUTOSETUP = 1;           // Старт автонастройки
                                FL_IND_RUNASETUP = 1;           // Вывести сообщение о начале автонастройки
                                FL_PERMIT_RUN_ASETUP = 0;
                                PARAM = LOW_PRED;               // Нижнее знач. начала автонастройки
                                }
                        }
                }
        else
                {

                // -----------------------------Изменение значения параметров
                if(KEY1FLAG == 1)                               // Была нажата клавиша 1(инкрем.выбран.парам.)
                        {
                        PARAM += 1;
                        if(FL_KEY1_4S == 1)
                                PARAM += 9;
                        if(FL_KEY1_8S == 1)
                                PARAM += 90;

                        if((TMP_NMBPARAM == n_PAU && BASE_DATA[n_UnP] == Unit_mS) || (TMP_NMBPARAM == n_imP && BASE_DATA[n_Uni] == Unit_mS))
                                {
                                PARAM += 4;
                                if(FL_KEY1_4S == 1)
                                        PARAM += 36;    // > 4s, (+1+9+4 - ранее выполнено!) В итоге: +50
                                if(FL_KEY1_8S == 1)
                                        PARAM += 60;    // > 4s, (+1+9+90+4+36 - ранее выполнено!) В итоге: +200
                                }

                        if(PARAM > HI_PRED)
                                PARAM = LOW_PRED;
                        if(TMP_NMBPARAM == n_HYS && (PARAM > -1 && PARAM <= 1))
                                PARAM = 1;                     // равно +0,1°С
                        }

                if(KEY2FLAG == 1)                               // Была нажата клавиша 1(декрем.выбран.парам.)
                        {
                        PARAM -= 1;
                        if(FL_KEY2_4S == 1)
                                PARAM -= 9;
                        if(FL_KEY2_8S == 1)
                                PARAM -= 90;

                        if((TMP_NMBPARAM == n_PAU && BASE_DATA[n_UnP] == Unit_mS) || (TMP_NMBPARAM == n_imP && BASE_DATA[n_Uni] == Unit_mS))
                                {
                                PARAM -= 4;
                                if(FL_KEY2_4S == 1)
                                        PARAM -= 36;    // > 4s, (-1 -9 -4 ранее выполнено!) В итоге: -50
                                if(FL_KEY2_8S == 1)
                                        PARAM -= 60;    // > 8s, (-1-9-90-4-36 - ранее выполнено!) В итоге: -200
                                }

                        if(PARAM < LOW_PRED)
                                PARAM = HI_PRED;
                        if(TMP_NMBPARAM == n_HYS && (PARAM >= -1 && PARAM < 1))
                                PARAM = -1;                    // равно -0,1°С
                        }
                }

        // ----------------------------- Спецкорректировка параметра

        if((TMP_NMBPARAM == n_PAU && BASE_DATA[n_UnP] == Unit_mS) || (TMP_NMBPARAM == n_imP && BASE_DATA[n_Uni] == Unit_mS))
                {
                PARAM /= 5;                    // Подавить промежуточные значения,
                PARAM *= 5;                    // требуемая дискретность = 5! для mS
                }

        //----------------------------- Сохранение параметров в ОЗУ

        BASE_DATA[TMP_NMBPARAM] = PARAM;

}
//            Подпрограмма GETSETPARAM завершена
//-------------------------------------------------------------------


//-----------------------------------------------------------------------------

        // Подпрограмма KEY_INTERFACE (базовая подпр. ввода через клавиатуру)

void    KEY_INTERFACE(void)

{
        unsigned char REG_AMOUNTPAR;

        if(KEY4AKT == 0)
                goto END_SET_NAL1;      // На выход! Не активна кл. 4
        FL_KEYAKT = 1;
        if(FL_CONFL_KEY == 1)
                goto END_SET_NAL;       // Конфл. На выход с сохранением!
        if(FL_RB6_D6 == 1 || FL_PRESS_ANY_KEY == 1)
                COUN15SET = 1000;       // Активна наладка по Д6? (загрузить 15 с)
        if(--COUN15SET != 0)            // Проверка завершения 15 сек при отсутст. нажат. клавиш
                goto CONTINUE;
        COUN15SET = 1000;
                goto    END_SET_NAL;    // Выход из KEY_INTERFACE по истеч. 15 сек c сохран.

CONTINUE:
        if(FLAG4sec == 0 && FL_MK_NAL == 0)      // Если FLAG4sec == 0?, то это режим "ОПЕРАТОР"
                {
                if(BASE_DATA[n_mOd] == mOd_OFF || FL_RB6_D6 == 1)
                        {
                        goto END_SET_NAL1;
                        }
                else
                        {
                        KEY4STAT = 2;
                        FL_MK_NAL = 1;
                        }
                }

        //      ---------------- // Вывести PAS                 ; KEY4STAT=0
        if(KEY4STAT == 0)
                goto K_IN_OUT;

        //      ---------------- // Установить PAS              ; KEY4STAT=1
        if(KEY4STAT == 1)
                {
                if(KEY1FLAG == 1)
                        COUNPASW++;
                TMP_PARAM_MES = COUNPASW;
                goto K_IN_OUT;
                }

        //      ---------------- // Проверка PAS(Выбрать пар)   ; KEY4STAT=2
                                        // Режим неопредел-ти   ; KEY4STAT=4
        if(KEY4STAT == 2 || KEY4STAT == 4)
                {
                if(FL_MK_NAL == 0 && COUNPASW != 15)            // Активна наладка прибора?
                        {
                        FL_ERR_SETPASW = 1;                     // Установить флаг неверного ввода пароля!
                        goto END_SET_NAL1;
                        }
                FL_MK_NAL = 1;                                  // Установить флаг активности наладки
                if(FLAG4sec == 0)
                        {                                       // Режим "ОПЕРАТОР"
                        REG_AMOUNTPAR = AMOUNTPAR_OPERATOR;     // Открыть только парам. "ОПЕРАТОР"
                        }
                else
                        {                                       // Режим "НАЛАДЧИК" или "РЕГУЛИРОВЩИК"
                        REG_AMOUNTPAR = AMOUNTPAR_NALADCHIK;    // Открыть только парам. "НАЛАДЧИК"
                        if(FL_RB6_D6 == 1)                      // Активизирован режим D6?
                                REG_AMOUNTPAR = AMOUNTPAR_D6 - AMOUNTPAR_guard;   // Открыть все параметры D6 кроме "guard"
                        }
                KEY_1_2_SET(REG_AMOUNTPAR);
                if(FL_PRESS_K12 == 1 && KEY4STAT == 4)
                        KEY4STAT = 2;                           // Загрузить в KEY4STAT 2!
                goto K_IN_OUT;                  // На выход
                }

        //      ---------------- // Устан. выбранного параметра ; KEY4STAT = 3
        if(KEY4STAT == 3)
                {
                GETSETPARAM(NMBPARAM);
                REG_CURRENT_MODE = BASE_DATA[n_mtm];            // Перезагрузить текущий режим
                if(FL_RB6_D6 == 1)                              // Определен D6?
                        {
                        if(NMBPARAM >= n_428 && NMBPARAM <= n_391)
                                CUR_TYPE_SENS = (NMBPARAM - n_428);
                        BASE_DATA[n_tSr] = CUR_TYPE_SENS;
                        }
                goto K_IN_OUT;
                }

        //      ---------------- // Конец наладки               ; KEY4STAT = 5

END_SET_NAL:                     // Выход с сохранением
                if(FL_RB6_D6 == 1)                      // Определен D6?
                        BASE_DATA[n_tSr] = CUR_TYPE_SENS = tSr_Pt391;   // По умолчанию Pt3910, перед CALC_CRC
                CALC_CRC();                     //
                COPY1_to_COPY2();
                WR_EEPROM = 0xA5;                       // Команда на запись
                WR_EEPROM1 = 0x5A;                      // Дублирующая команда на запись
                ADDREEP = 0;
                COUNT_EE = (SIZE_BASE) * 2;             // Кол-во байт для записи
                ADDR_BASE_DATA = (unsigned char *ADDR_BASE_DATA)&BASE_DATA[0];          // Получить адрес первого считываемого байта из RAM PIC


END_SET_NAL1:                   // Выход без сохранения
                FL_KEYAKT = 0;
                KEY4AKT = 0;
                FL_MK_NAL = 0;
                FLAG4sec = 0;
                SET_SEL = 0;
                COUNPASW = 0;
                KEY4STAT = 0;
                NMBPARAM = 0;

K_IN_OUT:
                KEY1FLAG = 0;   // На выход! Выход из подпрограммы в режиме установок
                KEY2FLAG = 0;
                KEY4FLAG = 0;
//
}       // Подпрограмма KEY_INTERFACE завершена
//-----------------------------------------------------------------------------

//---------------------------------------------------------------------

void    KEY_1_2_SET(unsigned char TMP_KEY_12)

{

        FL_PRESS_K12 = 0;
        // -------------------------------Проверка нажатия кл.1---------------------------
        if(KEY1FLAG == 1)               // Нажата кл.1?
                {
                FL_PRESS_K12 = 1;               // Нажата кл.1(больше)
INCNEW:         if(SET_SEL >= TMP_KEY_12 - 1)
                        {
                        SET_SEL = 0;
                        }
                else
                        {
                        SET_SEL++;
                        }
                }

        // -------------------------------Проверка нажатия кл.2---------------------------
        if(KEY2FLAG == 1)               // Нажата кл.2?
                {
                FL_PRESS_K12 = 1;               // Нажата кл.2(меньше)
DECNEW:         if(SET_SEL == 0)
                        {
                        SET_SEL = TMP_KEY_12 - 1;
                        }
                else
                        {
                        SET_SEL--;
                        }
                }

        // -------------------------------Расчет номера параметра-------------------------
        NMBPARAM = SET_SEL;
        if(FLAG4sec == 1)
                {
                NMBPARAM = SET_SEL + AMOUNTPAR_OPERATOR;
                if(FL_RB6_D6 == 1)                      // Активизирован режим D6?
                        NMBPARAM = SET_SEL + AMOUNTPAR_OPNAL;
                }

        if(FL_RB6_D6 == 1)                                      // Активизирован режим D6?
                return;

        if(TBL_ACSS_FORLAWR[BASE_DATA[n_mtm]][BASE_DATA[n_mOd]][NMBPARAM] == 0)
                {
                if(KEY1FLAG == 0 && KEY2FLAG == 0)
                        goto    INCNEW;                 // На след. параметр, если при вызове списка параметров он не активен
                if(KEY1FLAG == 1)
                        goto    INCNEW;                 // На следующий параметр, если при пролистывании параметров он не активен
                if(KEY2FLAG == 1)
                        goto    DECNEW;                 // На предыдущий параметр, если при пролистывании параметров он не активен
                }

}       // Подпрограмма KEY_1_2_SET завершена
//---------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    KEYSTATUS(void)

{

        FL_CONFL_KEY = FL_PRESS_ANY_KEY = FL_RB3_MODE_IND = FL_RB4_INC = FL_RB5_DEC = FL_RB6_D6 = FL_RB7_SET = 0;
        TEMP_PORTB = PORTB;             // Сохранить данные порта PORTB
        TEMP_PORTC = PORTC;             // Сохранить данные порта PORTC
        if(FL_SET_INDIC_OK == 1)
                {                       // Для ОК
                PORTC |= 0b01100011;    // Погасить индикацию (исключить зависимость от светодиодов)
                }
        else
                {                       // Для ОА
                PORTC &= 0b10011100;    // Погасить индикацию
                }
        PORTB = 0xFF;
        TRISB = 0xFF;                   // Настроить 0-7 - на вх.
        RBPU = 0;                       // Подключить резисторы
        FLAGKEYS = PORTB;               // Считать состояние клавиатуры и перемычек
        RBPU = 1;                       // Отключить резисторы
        TRISB = 0;                      // Настроить 0-7 - на вых.
        PORTB = TEMP_PORTB;             // Восстановить значение порта В
        PORTC = TEMP_PORTC;             // Восстановить значение порта C
        if((FLAGKEYS & 8) == 0)
                FL_RB3_MODE_IND = 1;    // Кнопка "Mode Ind" (Вывод на инд. °С)
        if((FLAGKEYS & 16) == 0)
                FL_RB4_INC = 1;         // Кнопка "Increment"
        if((FLAGKEYS & 32) == 0)
                FL_RB5_DEC = 1;         // Кнопка "Decrement"
        if((FLAGKEYS & 64) == 0)        // Перемычка D6 (0-активна наладка, 1-работа)
                FL_RB6_D6 = 1;
        if((FLAGKEYS & 128) == 0)
                FL_RB7_SET = 1;         // Кнопка "Set"
        FLAGKEYS ^= 0b11111111;
        FLAGKEYS &= 0b10111000;         // Устранить влияние перемычки по D6
        if(FLAGKEYS == 24 || FLAGKEYS == 40 || FLAGKEYS == 48 || FLAGKEYS > 128)
                FL_CONFL_KEY = 1;
        if(FLAGKEYS > 0)
                FL_PRESS_ANY_KEY = 1;


}       // Подпрограмма KEYSTATUS завершена
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------


void    ANKEY_1_2_4(void)

{
        //------------------------------ KEY1(PORTB,4)(БОЛЬШЕ)
        if(FL_RB4_INC == 0)
                {                       // Отжата
                KEY1COUN4S_8S = 0;
                FL_KEY1_4S = 0;
                FL_KEY1_8S = 0;
                if(KEY1COUN > 4)
                        KEY1FLAG = 1;
                KEY1COUN = 0;
                }
        else
                {                       // Нажата
                if(++KEY1COUN4S_8S >= 200)
                        FL_KEY1_4S = 1; // Клавиша непрерывн. нажата более 4 с
                if(KEY1COUN4S_8S >= 400)
                        FL_KEY1_8S = 1; // Клавиша непрерывн. нажата более 8 с
                if(++KEY1COUN > 12)
                        {
                        KEY1COUN = 0;
                        KEY1FLAG = 1;
                        }
                }
        //------------------------------ KEY2(PORTB,5)(МЕНЬШЕ)
        if(FL_RB5_DEC == 0)
                {                       // Отжата
                KEY2COUN4S_8S = 0;
                FL_KEY2_4S = 0;
                FL_KEY2_8S = 0;
                if(KEY2COUN > 4)
                        KEY2FLAG = 1;
                KEY2COUN = 0;
                }
        else
                {                       // Нажата
                if(++KEY2COUN4S_8S >= 200)
                        FL_KEY2_4S = 1; // Клавиша непрерывн. нажата более 4 с
                if(KEY2COUN4S_8S >= 400)
                        FL_KEY2_8S = 1; // Клавиша непрерывн. нажата более 8 с
                if(++KEY2COUN > 12)
                        {
                        KEY2COUN = 0;
                        KEY2FLAG = 1;
                        }
                }

        //------------------------------ KEY4(PORTB,7)(SET)
        if(FL_RB7_SET == 0)
                {
                if(KEY4COUN > 4 && KEY4COUN < 133)
                        {               // Клавиша нажата более 60 мс и менее 2 с
                        KEY4AKT = 1;
                        KEY4FLAG = 1;
                        KEY4STAT++;
                        }
                KEY4COUN = 0;
                }
        else
                {
                if(++KEY4COUN > 254 && FL_MK_NAL == 0)  // Исключ. доступа в "Наладчик" из "Оператор" при нажатии 4sec
                        {
                        FLAG4sec = 1;           // Клавиша непрерывно нажата более 3,8 сек
                        KEY4AKT = 1;
                        KEY4COUN--;
                        }
                }

}       //      Подпрограмма ANKEY_1_2_4() завершена
//-----------------------------------------------------------------------------


//;----------------------------------------------------------------------

void    UPDATEDISPLAY(void)

{

        unsigned char TMP_UPDDISP, TMP_UPDDISP1, TMP_UPDDISP2;

        if(TEMPC == 1)
                goto UPDATE0;
        if(TEMPC == 2)
                goto UPDATE1;
        if(TEMPC == 32)
                goto UPDATE2;
        goto UPDATE3;

UPDATE0:
        TMP_UPDDISP = LEDS_0;
        goto DISPLAY_OUT;

UPDATE1:
        TMP_UPDDISP = LEDS_1;
        if(FL_KEYAKT == 1)
                {
                if((TBL_ACTIVITY_DPOINT_RTD[NMBPARAM] == 0 || KEY4STAT == 1) && (LEDS_3 == 0 || LEDS_3 == 0x11) && LEDS_2 == 0 && LEDS_1 == 0)
                        TMP_UPDDISP = 0x10;             // Погасить разряд!
                }
        else
                {
                if(NMB_MESSAGE == mes_IND_t_T)
                        {
                        if(((BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 0) || (BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 1) || BASE_DATA[n_mOd] == mOd_Onr) && BASE_DATA[n_mOd] != mOd_Ont)
                                goto DISPLAY_OUT;       //
                        }
                if((LEDS_3 == 0 || LEDS_3 == 0x11) && LEDS_2 == 0 && LEDS_1 == 0)
                        TMP_UPDDISP = 0x10;     // Погасить разряд!
                }
        goto DISPLAY_OUT;

UPDATE2:
        TMP_UPDDISP = LEDS_2;
        if((LEDS_3 == 0 || LEDS_3 == 0x11) && LEDS_2 == 0 ) // LEDS_3 =0 или "-" (Гаш.допуск.)
                TMP_UPDDISP = 0x10;     // Погасить разряд!
        goto DISPLAY_OUT;

UPDATE3:
        TMP_UPDDISP = LEDS_3;
        if(LEDS_3 == 0)
                TMP_UPDDISP = 0x10;     // Индиц. разряд =0!(Погасить разряд);

DISPLAY_OUT:

        if(FL_SET_INDIC_OK == 1)
                {                               // Для ОК, без транзисторных ключей
                TMP_UPDDISP1 = TEMPC;           // Включ. разряда лог.'0'
                TMP_UPDDISP1 &= 0b01100011;
                TMP_UPDDISP1 ^= 0b11111111;     // Здесь переход от сдвиг '1' к сдвигу "0"
                TMP_UPDDISP2 = PORTC;           // Исключить "подмигивание" индикации на мкс
                TMP_UPDDISP2 |= 0b01100011;
                TMP_UPDDISP1 &= TMP_UPDDISP2;
                }
        else
                {                               // Для ОА, без транзисторных ключей
                TMP_UPDDISP1 = PORTC;           // Включ. разряда лог. '1'
                TMP_UPDDISP1 &= 0b10011100;
                TMP_UPDDISP1 ^= TEMPC;
                }
        if(FL_SET_INDIC_OK == 1)
                {
                PORTB = 0;                      // Для ОК. Погасить! Исключить перенос символа по разрядам!
                }
        else
                {
                PORTB = 0xFF;                   // Для ОА. Погасить! Исключить перенос символа по разрядам!
                }
        PORTC = TMP_UPDDISP1;
        PORTB = LED_TABLE[TMP_UPDDISP];

        if(FL_SET_INDIC_OK == 0)
                PORTB ^=0b11111111;     // Комплемент для перехода к OA

}
//-----------------------------------------------------------------------------

//---------------------------------------------------------------------

void    DELAY_MULTY(void)

{
        if(--COUN05sec != 0)    // -------Задержка 0,5 с
                goto    DLM0;
        COUN05sec = 12;
        if(FL_05sec == 1)
                {
                FL_05sec = 0;
                }
        else
                {
                FL_05sec = 1;
                }

DLM0:   if(--COUN1sec != 0)     // -------Задержка 1 с
                goto    DLM1;
        COUN1sec = 25;
        if(FL_1sec == 1)
                {
                FL_1sec = 0;
                }
        else
                {
                FL_1sec = 1;
                }

DLM1:   if(--COUN1_5 !=0)       // -------Задержка 1_5 с
                return;
        if(FL_1_5sec == 1)
                {
                FL_1_5sec = 0;
                COUN1_5 = 175;
                }
        else
                {
                FL_1_5sec = 1;
                COUN1_5 = 75;
                }

}       //      Подпрограмма DELAY_MULTY завершена
//-------------------------------------------------------------------

//---------------------------------------------------------------------

void    ADSERVIS(void)

{
        int TMP_ADRES, TMP_ADS1, TMP_ADS2;

        //------------------------------ A/D для t° ---------------

        TEMP_PORTB = PORTB;             // Сохранить данные PORTB

        if(FL_SET_INDIC_OK == 1)
                {
                PORTB = 0b00000000;     // Для ОК. Погасить!
                }
        else
                {
                PORTB = 0b11111111;     // Для ОА. Погасить!
                }

#ifndef SELECT_18F2523                  // Для PIC18252, PIC18F2520 и т.д.

        FL_CS_MCP3201 = 1;              // Deselect ADC-12bit(MCP3201)
        SSPSTAT = 0b00000000;           // SMP = 0, CKE = 0
        SSPCON1 = 0b00110010;           // Enable Master SPI, CKP = 1, bus mode 1,1, FOSC/64
        NOP();                          // Чтобы установились "SCK", "SDI"
        FL_CS_MCP3201 = 0;              // Select ADC-12bit(MCP3201)
        TMP_ADRES = 0;
        while(TMP_ADRES < 5)            // Просто задержка
                TMP_ADRES ++;
        TMP_ADRES = SSPBUF_SPI();
        TMP_ADRES <<= 8;
        TMP_ADRES &= 0x1F00;
        TMP_ADRES |= SSPBUF_SPI();
        FL_CS_MCP3201 = 1;              // Deselect ADC-12bit(MCP3201)
        SSPCON1 = 0b00010010;           // Disable Master SPI, bus mode 1,1, FOSC/64
        PORTB = TEMP_PORTB;             // Восстановить данные PORTB
        TMP_ADRES >>= 1;                // Смотри даташит!
        TMP_ADRES &= 0x0FFF;
        RESAD_D1 = TMP_ADRES;           // Здесь (t * 8)
        RESAD_D1 *= 5;                  // Здесь (t * 40)
        RESAD_D1 >>= 2;                 // Здесь (t * 10) псевдо 0,1°С
#endif

#ifdef  SELECT_18F2523                  // Только для PIC18F2523
        ADCON2  = 0b10011010;           // Right justified, FOSC/32, 6 TAD
        ADCON1  = 0b00011101;           // Установить:  RA0, RA1 -analog, RA2...RA12 -digit
        ADCON0  = 0b00000101;           // Включить модуль A/D, select chanel 1
        TMP_ADRES = 0;
        while(TMP_ADRES < 15)
                TMP_ADRES++;            // Просто задержка
        GODONE = 1;                     // Старт АЦП, канал  RA1
A_D_2:  if(GODONE == 1)
                goto A_D_2;
        PORTB = TEMP_PORTB;             // Восстановить данные PORTB
        TMP_ADRES = ADRESH;
        TMP_ADRES <<= 8;
        TMP_ADRES &= 0x0F00;
        TMP_ADRES |= ADRESL;
        TMP_ADRES &= 0x0FFF;
        RESAD_D1 = TMP_ADRES;           // Здесь (t * 8)
        RESAD_D1 *= 5;                  // Здесь (t * 40)
        RESAD_D1 >>= 2;                 // Здесь (t * 10) псевдо 0,1°С
#endif

        if(FL_PRIM_START == 1)
                return;                                 // bypass при первичном старте

        TMP_ADS1 = AVR_T_HINDR - TMP_ADRES;

        // -------------------------------------------- Kанал помехоподавления для больших изменений температуры
        //                                              Канал асинхронный!
        // -------------------------------------------- Асинхронный потому, что длит. периода измерения температуры (0.64с) меньше тестового времени равного 1с(по опыту эксп. систем)

        TMP_ADS2 = AVR_T_HINDR_OLD1 - TMP_ADRES;        // Среднее знач. с задержкой на 4 периода измерений, т.е. используются данные 2,56с давности!
        if(TMP_ADS2 < -750 || TMP_ADS2 > 750)           // delta_t ±75 °C (t * 10)
                {
                if(--COUN_HINDR_ULHIdelta_t == 0)
                        {
                        FL_ULHIdelta_t = 1;
                        SUM_D1 = RESAD_D1;
                        SUM_D1 <<= 7;                   // 128 измерений
                        SUM_D1 -= RESAD_D1;
                        COUN_SUMDIV = 1;
                        COUN_HINDR_ULHIdelta_t = 200;
                        return;
                        }
                }
        else
                {
                FL_ULHIdelta_t = 0;
                COUN_HINDR_ULHIdelta_t = 200;           // Зона нечувствительности по времени 1s для больших приращений температуры (больше 1s не задавать)
                }

        // -------------------------------------------- Kанал помехоподавления для малых изменений температуры
        //                                              Канал синхронный

        if(TMP_ADS1 > 3 || TMP_ADS1 < -3)               // delta_t = ±0,3 °C (t * 10)
                {
                if(COUN_HINDR_LOWdelta_t > 0)
                        {
                        RESAD_D1 = AVR_T_HINDR;         // Здесь (t * 10)
                        COUN_HINDR_LOWdelta_t--;
                        return;
                        }
                }
        else
                {
                COUN_HINDR_LOWdelta_t = 64;            // 1/2 от длительности цикла измерения
                if(FL_RB6_D6 == 1 && BASE_DATA[n_md6] == mod_d6_auto) // Определен D6 и установлен режим автонастройки
                        COUN_HINDR_LOWdelta_t = 8;     // 1/2 от длительности цикла автонастройки
                }

}       //      Подпрограмма ADSERVIS завершена
//-------------------------------------------------------------------


//---------------------------------------------------------------------


void    SUM_DIVISION(void)

{
        int     TMP_SUMDIV;
        long    koeff, TMP_SUM_D1, TMP_RESUL_IND;

        SUM_D1 += RESAD_D1;
        if(--COUN_SUMDIV != 0)
                return;
        COUN_SUMDIV = 128;                      // Загрузить для следующего цикла
        FL_END_SUMDIV = 1;                      // Разрешены, разнесенные по фазе, длительные во времени, подпрограммы
        FL_PERMIT_INC_ASETUP = 1;               // Разрешено +1 для AUTOSETUP
        FL_PERMIT_RUN_ASETUP = 1;               // Разрешен RUN для AUTOSETUP
        FL_PERMIT_DIR_LOAD_HEAT = 1;            // Разрешен управ. для "Regulator", только для "mSt" = "mode_St_Pwr"
        if(FL_RB6_D6 == 1 && BASE_DATA[n_md6] == mod_d6_auto)   // Определен D6 и установлен режим автонастройки
                {
                COUN_SUMDIV = 16;               // Значение для автоматики настройки!
                SUM_D1 = SUM_D1 * 8;            // Привести к уровню 128 отсчетов
                }
        AVR_T_HINDR = SUM_D1 / 128;             // Здесь (t * 10)
        if(--COUN_DEL_AVR_T_HINDR == 0)
                {
                COUN_DEL_AVR_T_HINDR = 3;       // Для формир. 3-х интерв. измерения!
                AVR_T_HINDR_OLD1 = AVR_T_HINDR; // В конце блока!
                }
        SUM_D1 -= 98560;                        // Вычесть 98560, привести к "0"(ноль равен уровню 616 = 0,616 V, а здесь 770 * 128 = ((616*5)/4) * 128)
        SUM_D1 /= 8;                            // Здесь (t * 160)
        SUM_D1 = SUM_D1 + (BASE_DATA[n_nUL] - 1024) * 2; // Настроить "0" с шагом 0,0125 °С. Глубина 12,8 °С
        if(SUM_D1 > 119200)
                SUM_D1 = 119200;                // max = 745°C при (t * 160)
        if(NMBPARAM != n_nUL)                   // Настроить "GAIN", для SEt0 "GAIN" = 1
                {
                SUM_D1 = SUM_D1 * BASE_DATA[(n_428 + BASE_DATA[n_tSr])];
                SUM_D1 = SUM_D1 / 16384;        // Разделить на 16384 (здесь t * 160)
                }
        SUM_D1 *= 2;                            // Здесь (t * 320)
        TMP_SUM_D1 = SUM_D1 * 128;
        switch(BASE_DATA[n_tSr])
                {
                case tSr_Cu428:                 // W100 = 1,4280

                        if(SUM_D1 >= 0)
                                {
                                TMP_SUM_D1 = 0;         // t >= 0!
                                }
                        else
                                {
                                koeff = 282333184;      // t < 0!
                                }
                        break;

                case tSr_Pt385:                 // W100 = 1,3850

                        if(SUM_D1 >= 0)
                                {
                                koeff = 277200896;      // t >= 0!
                                }
                        else
                                {
                                koeff = 317005824;      // t < 0!
                                }
                        break;

                case tSr_Pt391:                 // W100 = 1,3910
                        if(SUM_D1 >= 0)
                                {
                                koeff = 278913024;      // t >= 0!
                                }
                        else
                                {
                                koeff = 321802240;      // t < 0!
                                }
                        break;
                }

        SUM_D1 = SUM_D1 + TMP_SUM_D1/((koeff/SUM_D1) - 256);

        if(FL_RB6_D6 == 0)
                {
                if(SUM_D1 > -15 && SUM_D1 < 15)                 //  -0,046875°C > t < 0,046875°C
                        SUM_D1 = 0;                             // t = 0 °C
                }
        if(SUM_D1 < 0)
                {
                if(SUM_D1 > OLD_RESUL_IND)
                        SUM_D1 -= 27;                           // t = t - 0,084375 °C (здесь t * 320)
                }
        if(SUM_D1 > 0)
                {
                if(SUM_D1 < OLD_RESUL_IND)
                        SUM_D1 += 27;                           // t = t + 0,084375 °C (здесь t * 320)
                }

        RESUL_PID = SUM_D1;                                     // Здесь (t * 320)

        TMP_RESUL_IND = SUM_D1 / 32;                            // Здесь (t * 10) Подавить величины менее 0,1 °С
        OLD_RESUL_IND = TMP_RESUL_IND;                          // Здесь (t * 10) Подавить величины менее 0,1 °С
        OLD_RESUL_IND *= 32;                                    // Здесь (t * 320)
        RESUL_IND = (int)TMP_RESUL_IND;                         // Здесь (t * 10)
        SUM_D1 = 0;                                             // Обнулить для следующего цикла
        if(FL_RB6_D6 == 0)
                RESUL_IND += BASE_DATA[n_CSr];                  // Настройка "Csr", здесь t * 10


        // -------------------------------------------- Блок системы помехоподавления
        //                                              В самом конце!

        COUN_HINDR_LOWdelta_t = 64;                             // 1/2 от длительности цикла измерения
        if(FL_RB6_D6 == 1 && BASE_DATA[n_md6] == mod_d6_auto)   // Определен D6 и установлен режим автонастройки
                COUN_HINDR_LOWdelta_t = 8;                      // 1/2 от длительности цикла автонастройки

        // --------------------------------------------- Конец блока системы помехоподавления

        FL_ERR_DATH1 = 0;
        if(BASE_DATA[n_mOd] == mOd_OFF || BASE_DATA[n_mOd] == mOd_Ont)
                return;                                         // Для выбранных режимов нет контроля сенсора!
        if(RESUL_IND < -600 || (RESUL_IND > 4250 && BASE_DATA[n_tSr] > tSr_Cu428) || (RESUL_IND > 3000 && BASE_DATA[n_tSr] == tSr_Cu428))
                FL_ERR_DATH1 = 1;                       // Установить флаг аварии сенсора


}       //      Подпрограмма SUM_DIVISION завершена
//-------------------------------------------------------------------

//---------------------------------------------------------------------

void    SOUND(void)

{

        if(FL_PRIM_START == 1)
                {
                if(COUN_DELAY_SGr > 260)
                        goto NOTA_RE;           // Старт системы, нота "Ре"!
                goto SND_OFF;
                }

        if(FL_IND_ENDASETUP == 1 || FL_END_WR_EEPROM == 1 || ((FL_START_PROC_JNT2_StP == 1 || FL_START_TIME_JN12_Stt == 1 || FL_AUTO_RESET_JN1 == 1) && BASE_DATA[n_SSn] == 1))
                goto NOTA_RE;                           // Нота "Ре". Общесистемные сигналы!

        if(((FL_EERDWRGUT == 0 || FL_ERR_CRC == 1 || (FL_CHANG_CUR_S == 1 && FL_AKT_WR_EEPROM == 0 && FL_AKT_TEST_WR_EEPROM == 0 && FL_END_WR_EEPROM == 0)) && FL_1_5sec == 1) || FL_ERR_SET_PAR == 1 || FL_ERR_SETPASW == 1 || (FL_AKT_WR_EEPROM == 1 && FL_05sec == 1) || (FL_ERR_SET_PAR_TIME == 1 && BASE_DATA[n_SSn] == 1)) // Сигналы тревоги и предупреждения, нота "До"
                goto NOTA_DO;                           // Нота "До". Сигналы тревоги и предупреждения!

        if(FL_ERR_DATH1 == 1 && BASE_DATA[n_mOd] != mOd_Ont && BASE_DATA[n_mOd] != mOd_OFF && FL_RB6_D6 == 0)                   // Ошибка датчика?
                {
                if(FL_05sec == 1)
                        {
                        goto NOTA_RE;                   // Нота "Ре"
                        }
                else
                        {
                        goto NOTA_MI;                   // Нота "Ми"
                        }
                }

        if(FL_SOUND_END_PRG == 1)
                {
                if(--COUN_SND_END_PRG > 0)
                        goto SND_01;
                COUN_SND_END_PRG = 12;
                if(++COUN_NMB_BEEP_END_PRG < 6)
                        {
                        if(FL_ON_PWM_BEEP == 0)
                                {
                                FL_ON_PWM_BEEP = 1;     // Подать звуковой сигнал!
                                }
                        else
                                {
                                FL_ON_PWM_BEEP = 0;     // Снять звуковой сигнал!
                                }
                        }
                else
                        {
                        FL_ON_PWM_BEEP = 0;
                        FL_SOUND_END_PRG = 0;
                        COUN_NMB_BEEP_END_PRG = 0;
                        }

SND_01:         if(FL_ON_PWM_BEEP == 1)
                        {
                        if(COUN_NMB_BEEP_END_PRG == 5)
                                goto NOTA_DO;           // Подать сигн. нота "До"!
                        goto NOTA_RE;                   // Подать сигн. нота "Ре"!
                        }
                }

SND_OFF:                                // Сначала SND_OFF, а затем все ноты!
        TMR2ON = 0;                             // TMR2 is Off
        CCP1CON = 0;                            // CCP1 is Off
        FL_PWM_OUT_SOUND = 0;                   // Sound is Off
        return;

NOTA_DO:
        T2CON = 0b00000101;                     // TMR2 is On, Prescaler is 4
        CCP1CON = 0b00001100;                   // CCP1 is: Single output; On;
        PR2 = 238;                              // 2093.0 Hz, "До" 4-я октава
        CCPR1L = 119;                           // 1/2 периода "До"
        return;

NOTA_RE:
        T2CON = 0b00000101;                     // TMR2 is On, Prescaler is 4
        CCP1CON = 0b00001100;                   // CCP1 is: Single output; On;
        PR2 = 212;                              // 2349.2 Hz, "Ре" 4-я октава
        CCPR1L = 106;                           // 1/2 периода "Ре"
        return;

NOTA_MI:
        T2CON = 0b00000101;                     // TMR2 is On, Prescaler is 4
        CCP1CON = 0b00001100;                   // CCP1 is: Single output; On;
        PR2 = 189;                              // 2637.0 Hz, "Ми" 4-я октава
        CCPR1L = 94;                            // 1/2 периода "Ми"
        return;

}       //      Подпрограмма SOUND завершена
//-------------------------------------------------------------------

//-------------------------------------------------------------------

void    D_POINT(void)

{

        if(FL_SET_INDIC_OK == 1)
                {               // Для ОК
                FL_DPOINT = 0;  // Заранее выключить децимальную точку
                }
        else
                {               // Для ОA
                FL_DPOINT = 1;  // Заранее выключить децимальную точку
                }

        if(FL_PRIM_START == 1)
                return;
        if(TEMPC == 1)
                goto D_POINT0;  // Активны десятые градуса
        if(TEMPC == 2)
                goto D_POINT1;  // Активны единицы градуса
        if(TEMPC == 32)
                goto D_POINT2;  // Активны десятки градусов
        goto D_POINT3;          // Активны сотни градусов


D_POINT0:       //      ------- Индикация фаза "Impulse" таймера или "Наладка Д6" прибора в целом (STEP II)
        if(FL_RB6_D6 == 1)
                {               // Активна наладка D6
                if(FL_05sec == 0 && FL_RUN_AUTOSETUP == 1)
                        return;
                goto D_P_ON;            // Зажечь DP. Мигание DP, если autosetup параметров!
                }
        else
                {               // Работа
                if(FL_KEYAKT == 1 || (FL_RB3_MODE_IND == 1 && FL_KEYAKT == 0 && BASE_DATA[n_mOd] >= mOd_SEP))
                        return;

                if(BASE_DATA[n_mOd] >= mOd_Ont)
                        {
                        if(FL_RUN_PRG_TIME == 1)
                                {
                                if(FL_PHASE_IMPULSE == 0)
                                        return;
                                if(REG_CURRENT_MODE == mtm_dOn)        // Для режима "dOn"
                                        goto D_P_ON;    // Фаза "IMPULSE"! Зажечь непрерыв. DP для "dOn"
                                if(FL_1sec == 1)
                                        return;
                                goto D_P_ON;            // Фаза "IMPULSE"! Зажечь DP
                                }
                        else
                                {
                                if(REG_CURRENT_MODE != mtm_Ovr)         // Ожидание фазы "IMPULSE"
                                        return;
                                if(FL_1_5sec == 0)                      // Режим работы "OVr"!
                                        return;
                                goto D_P_ON;
                                }
                        }
                else
                        {
                        return;         // Погасить DP. Не выбран ни один из режимов таймера.
                        }
                }

D_POINT1:       //      ------- Индикация децимальной точки °С

        if(FL_KEYAKT == 1)
                {
                if((TBL_ACTIVITY_DPOINT_RTD[NMBPARAM] == 1 && KEY4STAT == 3) || (FL_RB6_D6 == 1 && NMB_MESSAGE == mes_VAL_SPECIAL_PAR && (NMBPARAM >= n_nUL && NMBPARAM <= n_391))) // For RTD
                        goto D_P_ON;            // Включить DP.
                return;                         // Погасить DP.
                }
        else
                {
                if(NMB_MESSAGE == mes_IND_t_T)
                        {
                        if(((BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 0) || (BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 1) || BASE_DATA[n_mOd] == mOd_Onr) && BASE_DATA[n_mOd] != mOd_Ont)
                                goto D_P_ON;    // Включить DP.
                        return;                 // Погасить DP.
                        }
                else
                        {
                        return;                 // Погасить DP.
                        }
                }

D_POINT2:       //      ------- Индикация фаза "Pause" таймера (STEP II)

        if(FL_KEYAKT == 1 || FL_RB6_D6 == 1 || (FL_RB3_MODE_IND == 1 && FL_KEYAKT == 0 && BASE_DATA[n_mOd] >= mOd_SEP))
                return;

        if(BASE_DATA[n_mOd] >= mOd_Ont)
                {
                if(FL_RUN_PRG_TIME == 1)
                        {
                        if(FL_PHASE_PAUSE == 0)
                                return;
                        if(FL_1sec == 1)
                                return;
                        goto D_P_ON;            // Фаза "PAUSE"! Зажечь децимальную точку
                        }
                else
                        {
                        if(REG_CURRENT_MODE == mtm_Ovr)
                                return;
                        if(FL_1_5sec == 0)      // Режим работы (AGE, nGE, dVr, dOn)
                                return;
                        goto D_P_ON;
                        }
                }
        else
                {
                return;         // Погасить DP. Не выбран ни один из режимов таймера.
                }

D_POINT3:       //      ------- Индикация канала "Heat/Cool" (STEP I)

        if(FL_KEYAKT == 1 || FL_RB6_D6 == 1 || (FL_RB3_MODE_IND == 1 && FL_KEYAKT == 0 && BASE_DATA[n_mOd] >= mOd_SEP))
                return;
        if(BASE_DATA[n_mOd] > mOd_OFF)
                {
                if(FL_NEED_AKT_LOAD_STEPI == 0)
                        {                               // Команда на выключение
                        if(FL_ON_LOAD_HEAT_STEPI == 1 && FL_05sec == 1)
                                goto D_P_ON;            // Включить DP.Мигание DP 0,5s
                        return;                         // Выключить DP
                        }
                else
                        {                               // Команда на включение
                        if(FL_ON_LOAD_HEAT_STEPI == 0 && FL_05sec == 1)
                                return;                 // Выключить DP. Мигание DP 0,5s
                        goto D_P_ON;                    // Включить DP
                        }
                }
        else
                {
                return;
                }

D_P_ON:

        if(FL_SET_INDIC_OK == 1)
                {               // Для ОК
                FL_DPOINT = 1;  // Включить DP
                }
        else
                {               // Для ОA
                FL_DPOINT = 0;  // Включить DP
                }

}       //       Подпрограмма D_POINT завершена
//------------------------------------------------------------


//-----------------------------------------------------------------------------

void    B2_BCD(int TMP_B2)

{
        LEDS_3 = LEDS_2 = LEDS_1 = LEDS_0 = 0;
        FL_NEG_B2BCD = 0;       // Сбросить флаг негативн. знач. B2 -> BCD преобр.

        if(TMP_B2 < 0)
                {
                FL_NEG_B2BCD = 1;       // Устан. флаг негат. знач. B2 -> BCD преобр.
                TMP_B2 = abs(TMP_B2);
                }
        if(TMP_B2 >= 1000)
        {
                do      {
                        TMP_B2 = TMP_B2 - 1000;
                        ++LEDS_3;
                        }
                while(TMP_B2 >=1000);
        }

        if(TMP_B2 >= 100)
        {
                do      {
                        TMP_B2 = TMP_B2 - 100;
                        LEDS_2++;
                        }
                while(TMP_B2 >=100);
        }

        if(TMP_B2 >= 10)
        {
                do      {
                        TMP_B2 = TMP_B2 - 10;
                        LEDS_1++;
                        }
                while(TMP_B2 >=10);
        }

        LEDS_0 = (unsigned char)TMP_B2;

}       //      Подпрограмма B2_BCD завершена
//-----------------------------------------------------------------------------

//---------------------------------------------------------------------

void    MAKE_MESSAGE(void)

{
        int TMP_FOR_MES_UNIT;

        if(FL_KEYAKT == 1)
                {       //------------- Режим настройки системы "ОПЕРАТОР", "НАЛАДЧИК", "РЕГУЛИРОВЩИК D6"

                NMB_MESSAGE = mes_IND_t_T;                      // Индикация значения температуры или времени

                if(KEY4STAT == 0)                               // Сообщение "PAS"
                        NMB_MESSAGE = mes_PAS;

                if(KEY4STAT == 1)                               // Значение "PAS"
                        NMB_MESSAGE = mes_VAL_SPECIAL_PAR;

                if(KEY4STAT == 2 || KEY4STAT == 4)              // Имя параметра
                        {
                        NMB_MESSAGE = mes_NAME_PAR;
                        if((NMBPARAM == n_PAU || NMBPARAM == n_imP) && FL_1_5sec == 1) // Вывести единицу измерения
                                {
                                if(NMBPARAM == n_PAU)
                                        TMP_FOR_MES_UNIT = BASE_DATA[n_UnP];
                                if(NMBPARAM == n_imP)
                                        TMP_FOR_MES_UNIT = BASE_DATA[n_Uni];

                                switch(TMP_FOR_MES_UNIT)
                                        {
                                        case Unit_mS:           // mS
                                                NMB_MESSAGE = mes_Uni_mS;
                                                break;

                                        case Unit_SEC:          // SEC
                                                NMB_MESSAGE = mes_Uni_SEC;
                                                break;

                                        case Unit_min:          // min
                                                NMB_MESSAGE = mes_Uni_min;
                                                break;

                                        case Unit_HOU:          // HOU
                                                NMB_MESSAGE = mes_Uni_HOU;
                                                break;
                                        }
                                }
                        }

                if(FL_RB6_D6 == 1)
                        {               //------------  Режим "РЕГУЛИРОВЩИК D6"

                        if(KEY4STAT == 3)
                                {

                                if(NMBPARAM == n_SYS)
                                        NMB_MESSAGE = mes_VAL_PARAM;

                                if(NMBPARAM == n_md6)                  // Параметр (md6)
                                        {
                                        if(PARAM == 0)
                                                NMB_MESSAGE = mes_mAn;  // mAn
                                        if(PARAM == 1)
                                                NMB_MESSAGE = mes_AUt;  // AUt
                                        }

                                }

                        if((KEY4STAT == 2 || KEY4STAT == 4) && FL_1_5sec == 1 && (NMBPARAM >= n_nUL && NMBPARAM <= n_391))
                                {
                                if(NMBPARAM == n_nUL)
                                        TMP_PARAM_MES = 1000;           // For RTD. NULL = 100,0 Ом (50,0 ) Ом 0 °С
                                if(NMBPARAM == n_428)
                                        TMP_PARAM_MES = 1856;           // Cu4280 = 185,60 (92,8) Ом 200 °С
                                if(NMBPARAM == n_385)
                                        TMP_PARAM_MES = 2471;           // Pt3850 = 247,1 (123,55) Ом, 400 °С
                                if(NMBPARAM == n_391)
                                        TMP_PARAM_MES = 2494;           // Pt3910 = 249,41 (124,70) Ом, 400 °С
                                if(FL_Cu100Pt100 == 0)
                                        TMP_PARAM_MES >>= 1;            // Cu50(Pt50) разделить на 2
                                NMB_MESSAGE = mes_VAL_SPECIAL_PAR;      // Сообщение о значении сопротивления настройки по магазину
                                }

                        if(FL_IND_CANASETUP == 1)
                                {
                                if(--COUNT_MESSAGE != 0)
                                        {
                                        NMB_MESSAGE = mes_CAn;         // Oтмена процесса автонаст. (CAn)
                                        return;
                                        }
                                COUNT_MESSAGE = 30;
                                FL_IND_CANASETUP = 0;
                                }

                        if(FL_IND_RUNASETUP == 1)
                                {
                                if(--COUNT_MESSAGE != 0)
                                        {
                                        NMB_MESSAGE = mes_rUn;         // Запуск проц. автонаст. (rUn)
                                        return;
                                        }
                                COUNT_MESSAGE = 30;
                                FL_IND_RUNASETUP = 0;
                                }

                        if(FL_IND_ENDASETUP == 1)
                                {
                                if(--COUNT_MESSAGE != 0)
                                        {
                                        NMB_MESSAGE = mes_End;         // Завершен проц. автонаст. (End)
                                        return;
                                        }
                                COUNT_MESSAGE = 30;
                                FL_IND_ENDASETUP = 0;
                                }
                        }

                else
                        {               //------------  Режим "ОПЕРАТОР", "НАЛАДЧИК"

                        if(KEY4STAT == 3)                               // Устан. знач. параметра
                                {
                                NMB_MESSAGE = mes_VAL_PARAM;            // Индикация значения параметра

                                if(NMBPARAM == n_SPS)
                                        {
                                        if((BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428))
                                                NMB_MESSAGE = mes_SPE;
                                        }

                                if(NMBPARAM == n_SSn || NMBPARAM == n_PFA || NMBPARAM == n_ALC)
                                        {
                                        if(PARAM == 0)
                                                NMB_MESSAGE = mes_OFF;          // OFF
                                        if(PARAM == 1)
                                                NMB_MESSAGE = mes_On;           // On
                                        if(PARAM == 2)
                                                NMB_MESSAGE = mes_OnS;          // OnS, только для "ALC"

                                        }

                                if(NMBPARAM == n_mOd)                           // Режим работы прибора
                                        {
                                        if(PARAM == mOd_OFF)
                                                NMB_MESSAGE = mes_OFF;          // OFF
                                        if(PARAM == mOd_Onr)
                                                NMB_MESSAGE = mes_mOd_Onr;      // Onr
                                        if(PARAM == mOd_Ont)
                                                NMB_MESSAGE = mes_mOd_Ont;      // Ont
                                        if(PARAM == mOd_SEP)
                                                NMB_MESSAGE = mes_mOd_SEP;      // SEP
                                        if(PARAM == mOd_Jn1)
                                                NMB_MESSAGE = mes_mOd_Jn1;      // Jnt1
                                        if(PARAM == mOd_Jn2)
                                                NMB_MESSAGE = mes_mOd_Jn2;      // Jnt2
                                        }

                                if(NMBPARAM == n_mtm)                           // Режим исполнения выдержек времени
                                        {
                                        if(PARAM == mtm_AGE)
                                                NMB_MESSAGE = mes_mtm_AGE;      // AGE
                                        if(PARAM == mtm_nGE)
                                                NMB_MESSAGE = mes_mtm_nGE;      // nGE
                                        if(PARAM == mtm_dvr)
                                                NMB_MESSAGE = mes_mtm_dvr;      // dvr
                                        if(PARAM == mtm_Ovr)
                                                NMB_MESSAGE = mes_mtm_Ovr;      // Ovr
                                        if(PARAM == mtm_dOn)
                                                NMB_MESSAGE = mes_mtm_dOn;      // dOn
                                        if(PARAM == mtm_OFF)
                                                NMB_MESSAGE = mes_OFF;          // OFF
                                        }

                                if(NMBPARAM == n_UnP || NMBPARAM == n_Uni)      // Единица измерения времени
                                        {
                                        if(PARAM == Unit_mS)
                                                NMB_MESSAGE = mes_Uni_mS;       // mS
                                        if(PARAM == Unit_SEC)
                                                NMB_MESSAGE = mes_Uni_SEC;      // SEC
                                        if(PARAM == Unit_min)
                                                NMB_MESSAGE = mes_Uni_min;      // min
                                        if(PARAM == Unit_HOU)
                                                NMB_MESSAGE = mes_Uni_HOU;      // HOU
                                        }

                                if(NMBPARAM == n_mUL)                           // Множитель для nGE
                                        {
                                        if(PARAM == 1)
                                                NMB_MESSAGE = mes_m_1;          // x1
                                        if(PARAM == 2)
                                                NMB_MESSAGE = mes_m10;          // x10
                                        if(PARAM == 3)
                                                NMB_MESSAGE = mes_100;          // x100
                                        }

                                if(NMBPARAM == n_mSt)                           // Режим запуска отсчета времени
                                        {
                                        if(PARAM == 0)
                                                NMB_MESSAGE = mes_1_0;          // 1->0
                                        if(PARAM == 1)
                                                NMB_MESSAGE = mes_0_1;          // 0->1
                                        if(PARAM == 2)
                                                NMB_MESSAGE = mes_Pwr;          // Pwr
                                        }

                                if(NMBPARAM == n_Pri)                           // Приоритет вывода температуры/времени без нажатия кнопки
                                        {
                                        if(PARAM == 0)
                                                NMB_MESSAGE = mes_tim;          // Время
                                        if(PARAM == 1)
                                                NMB_MESSAGE = mes_t_C;          // Температура
                                        }

                                if(NMBPARAM == n_tSr)                          // Тип сенсора
                                        {
                                        NMB_MESSAGE = mes_428;
                                        NMB_MESSAGE += PARAM;                   // Расчет номера сообщения
                                                                                // Сообщение "C428" медь
                                                                                // Сообщение "P385" платина
                                                                                // Сообщение "P391" платина
                                        }

                                }
                        }

                if((FL_ERR_SET_PAR_TIME == 1 && BASE_DATA[n_mOd] > mOd_Onr) || FL_START_PROC_JNT2_StP == 1 || FL_START_TIME_JN12_Stt == 1)
                        goto MES_N00;

                if(FL_RB4_INC == 0 && FL_RB5_DEC == 0 && FL_RUN_AUTOSETUP == 0 && FL_05sec == 0)  // Не нажата любая из этих клавиш!
                        NMB_MESSAGE = mes_bLk;                  // Погасить индикацию. Не нажата ни одна из клавиш
                                                                // и не запущена автонастройка
                }
        else
                {               //----------------------------- Режим работа

                if(FL_AKT_WR_EEPROM == 1)
                        {
                        if(FL_05sec == 1)
                                {
                                NMB_MESSAGE = mes_EEP;          // Выв.на индик. сообщ. идет запись в EEPROM
                                }
                        else
                                {
                                NMB_MESSAGE = mes_bLk;          // Погасить индикацию
                                }
                        return;
                        }

                if(FL_ERR_SETPASW == 1 || (FL_ERR_SET_PAR_TIME == 1 && BASE_DATA[n_mOd] > mOd_Onr) || FL_START_PROC_JNT2_StP == 1 || FL_START_TIME_JN12_Stt == 1 || FL_AUTO_RESET_JN1 == 1 || FL_END_WR_EEPROM == 1)
                        {
MES_N00:                if(--COUNT_MESSAGE != 0)
                                {
                                if(FL_ERR_SETPASW == 1)
                                        {
                                        NMB_MESSAGE = mes_ACd;  // Выв.на индик. в доступе отказано (ACd)
                                        return;
                                        }
                                if(FL_ERR_SET_PAR_TIME == 1)
                                        {
                                        NMB_MESSAGE = mes_ErP;  // Выв.на индик. (ErP)  неверное задание параметров времени
                                        return;
                                        }
                                if(FL_START_PROC_JNT2_StP == 1)
                                        {
                                        NMB_MESSAGE = mes_StP;  // Выв.на индик. (StP)  Старт процесс JNT2
                                        return;
                                        }
                                if(FL_START_TIME_JN12_Stt == 1)
                                        {
                                        NMB_MESSAGE = mes_Stt;  // Выв.на индик. (Stt)  Старт время для JNT1 или JNT2
                                        return;
                                        }
                                if(FL_AUTO_RESET_JN1 == 1)
                                        {
                                        NMB_MESSAGE = mes_ArSt;  // Выв.на индик. (ArSt)  Автосброс для Jn1, температура объекта прошла точку "SPr"
                                        return;
                                        }
                                if(FL_END_WR_EEPROM == 1)
                                        {
                                        NMB_MESSAGE = mes_End;  // Завершенa запись данных в EEPROM (End)
                                        return;
                                        }
                                }
                        COUNT_MESSAGE = 30;
                        if(FL_ERR_SETPASW == 1)
                                {
                                FL_ERR_SETPASW = 0;
                                return;
                                }
                        if(FL_ERR_SET_PAR_TIME == 1)
                                {
                                FL_ERR_SET_PAR_TIME = 0;
                                return;
                                }
                        if(FL_START_PROC_JNT2_StP == 1)
                                {
                                FL_START_PROC_JNT2_StP = 0;     // Сначала StP, а
                                return;
                                }
                        if(FL_START_TIME_JN12_Stt == 1)
                                {
                                FL_START_TIME_JN12_Stt = 0;     // затем Stt и в предыдущем блоке также!
                                return;
                                }
                        if(FL_AUTO_RESET_JN1 == 1)
                                {
                                FL_AUTO_RESET_JN1 = 0;          //
                                return;
                                }
                        if(FL_END_WR_EEPROM == 1)
                                {
                                FL_END_WR_EEPROM = 0;
                                return;
                                }
                        }

                if(FL_SOUND_END_PRG == 1)
                        {
                        NMB_MESSAGE = mes_End;                  // Завершен процесс по Jn1 или Jn2
                        return;
                        }

                if(FL_EERDWRGUT == 0 && FL_1_5sec == 1)         // Ошибка при операциях с EEPROM?
                        {
                        NMB_MESSAGE = mes_ErE;                  // Выв.на индик. ошибку EEPROM (ErE)
                        return;
                        }

                if(FL_ERR_DATH1 == 1 && BASE_DATA[n_mOd] != mOd_Ont && BASE_DATA[n_mOd] != mOd_OFF)
                        {
                        if(FL_05sec == 1)
                                {
                                if(FL_1_5sec == 1)
                                        {
                                        NMB_MESSAGE = mes_Udt;  // Вывести на индик. неизвестна темпер. (Udt)
                                        }
                                else
                                        {
                                        NMB_MESSAGE = mes_PFA;  // Вывести на индик. аварию сенсора (PFA)
                                        }
                                }
                        else
                                {
                                NMB_MESSAGE = mes_bLk;          // Погасить индикацию. Индик. процесса отмены процесса Prtm
                                }
                        return;
                        }

                if(FL_ERR_CRC == 1 && FL_1_5sec == 1)
                        {
                        NMB_MESSAGE = mes_CRC;                  // Повреждение всех данных, кроме SYS
                        return;                                 // Системная кофигурация цела
                        }

                if(FL_CHANG_CUR_S == 1 && FL_1_5sec == 1)
                        {
                        NMB_MESSAGE = mes_CHS;  // Выв.на индик. изменен сенсор (CHS)
                        return;
                        }

                if(BASE_DATA[n_mOd] >= mOd_SEP && FL_1_5sec == 1 && ((BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 0) || (BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 1)))
                        {
                        NMB_MESSAGE = mes_t_C;                  // Сначала mes. "t°C", а затем значение собственно °t
                        return;
                        }

                if(FL_RUN_PRG_TIME == 1 && REG_CURRENT_MODE == mtm_nGE && FL_RB5_DEC == 1 && FL_1_5sec == 1)
                        {
                        if(BASE_DATA[n_mUL] == 1)
                                NMB_MESSAGE = mes_m_1;
                        if(BASE_DATA[n_mUL] == 2)
                                NMB_MESSAGE = mes_m10;
                        if(BASE_DATA[n_mUL] == 3)
                                NMB_MESSAGE = mes_100;
                        return;
                        }

                if((FL_RUN_PRG_TIME == 1 && FL_PHASE_IMPULSE == 1 && REG_CURRENT_MODE == mtm_dOn) && ((BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 0) || (BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 1)))
                        {
                        NMB_MESSAGE = mes_dCm;
                        return;
                        }

                if(BASE_DATA[n_mOd] == mOd_OFF) // Режим "OFF", и таймер и регулятор выключены.
                        {
                        NMB_MESSAGE = mes_OFF;
                        return;
                        }


                NMB_MESSAGE = mes_IND_t_T;      // Индикация значения температуры или времени
                }

}       //      Подпрограмма MAKE_MESSAGE завершена
//-------------------------------------------------------------------

//---------------------------------------------------------------------

void    OUT_IND(void)

{
        int TMP_PARAM_B2_BCD;                   // Переменная, только для конфликта клав-ры

        if(NMB_MESSAGE == mes_IND_t_T)
                {
                if((BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 0) || (BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 1) || BASE_DATA[n_mOd] == mOd_Onr || FL_RB6_D6 == 1)
                        {
                        TMP_PARAM_B2_BCD = RESUL_IND;
                        B2_BCD(TMP_PARAM_B2_BCD);
                        if(FL_NEG_B2BCD == 1)
                                LEDS_3 = 0x11;
                        }

                if(((BASE_DATA[n_Pri] == Pri_rEG && FL_RB3_MODE_IND == 1) || (BASE_DATA[n_Pri] == Pri_tim && FL_RB3_MODE_IND == 0) || BASE_DATA[n_mOd] == mOd_Ont) && BASE_DATA[n_mOd] != mOd_Onr && FL_RB6_D6 == 0)
                        {
                        if(FL_RUN_PRG_TIME == 1)
                                {
                                if(REG_CURRENT_MODE == mtm_nGE && FL_RB5_DEC == 1 && FL_1_5sec == 0)
                                        {
                                        B2_BCD(COUN_AMOUNT_PERIOD_IND);
                                        return;
                                        }
                                if(FL_PHASE_PAUSE == 1)
                                        B2_BCD(COUN_PAUSE);     // Вывести остаток фазы "PAUSE"
                                if(FL_PHASE_IMPULSE == 1)
                                        B2_BCD(COUN_IMPULSE);   // Вывести остаток фазы "IMPULSE"
                                }
                        else
                                {
                                if(REG_CURRENT_MODE == mtm_Ovr)
                                        {
                                        B2_BCD(BASE_DATA[n_imP]);       // (OVr)
                                        }
                                else
                                        {
                                        B2_BCD(BASE_DATA[n_PAU]);       // (AGE, nGE, dvr, dOn)
                                        }
                                }
                        }
                }

        if(NMB_MESSAGE == mes_VAL_PARAM)        // Индикация значения PARAM для KEY_INTER
                {
                TMP_PARAM_B2_BCD = PARAM;
                B2_BCD(TMP_PARAM_B2_BCD);
                if(FL_NEG_B2BCD == 1)
                        LEDS_3 = 0x11;
                }

        if(NMB_MESSAGE == mes_NAME_PAR)         // Индикация имени параметра
                {
                LEDS_0 = TBL_NAME_PAR[NMBPARAM][0];
                LEDS_1 = TBL_NAME_PAR[NMBPARAM][1];
                LEDS_2 = TBL_NAME_PAR[NMBPARAM][2];
                LEDS_3 = TBL_NAME_PAR[NMBPARAM][3];
                }

        if(NMB_MESSAGE == mes_VAL_SPECIAL_PAR)  // Индикац. значения спец.параметров
                {
                B2_BCD(TMP_PARAM_MES);
                if(FL_NEG_B2BCD == 1)
                        LEDS_3 = 0x11;
                }

        if(NMB_MESSAGE > mes_VAL_SPECIAL_PAR)   // Вывод "чисто" сообщений
                {
                LEDS_0 = TBL_MESSAGE[NMB_MESSAGE][0];
                LEDS_1 = TBL_MESSAGE[NMB_MESSAGE][1];
                LEDS_2 = TBL_MESSAGE[NMB_MESSAGE][2];
                LEDS_3 = TBL_MESSAGE[NMB_MESSAGE][3];
                }

}       //      Подпрограмма OUT_IND завершена
//-------------------------------------------------------------------

//------------------------------------------------------------

void    DIR_FL_LOAD_HEAT(void)

{
        int     TMP_DFL;

        TMP_DFL = BASE_DATA[n_SP] + BASE_DATA[n_HYS];

        if(FL_ERR_CRC == 1 || FL_EERDWRGUT == 0 || FL_RB6_D6 == 1 || FL_PERMIT_DIR_LOAD_HEAT == 0 || (FL_MK_NAL == 1 && FLAG4sec == 1))
                {
                FL_NEED_AKT_LOAD_STEPI = 0;             // Выключить при авариях данного типа
                return;
                }

        if(BASE_DATA[n_HYS] < 0)        // HYS
                {                                       // Для нагревателя
                if(RESUL_IND >= BASE_DATA[n_SP])
                        FL_NEED_AKT_LOAD_STEPI = 0;     // Выключить
                if(RESUL_IND <= TMP_DFL)
                        FL_NEED_AKT_LOAD_STEPI = 1;     // Включить
                }

        else
                {                                       // Для охладителя
                if(RESUL_IND <= BASE_DATA[n_SP])
                        FL_NEED_AKT_LOAD_STEPI = 0;     // Выключить
                if(RESUL_IND >= TMP_DFL)
                        FL_NEED_AKT_LOAD_STEPI = 1;     // Включить
                }

        if(FL_ERR_DATH1 == 1)                           // Установлен флаг ошибки сенсора?
                {
                if(BASE_DATA[n_PFA] == 0)
                        {
                        FL_NEED_AKT_LOAD_STEPI = 0;             // Выключить
                        }
                else
                        {
                        FL_NEED_AKT_LOAD_STEPI = 1;             // Включить
                        }
                }

}//------------------------------------------------------------

//------------------------------------------------------------

void DELAY_3sec_DIR_LOAD_HEAT(void)

{

        if(FL_NEED_AKT_LOAD_STEPI == 0)
                {
                if(FL_ON_LOAD_HEAT_STEPI == 0)  // ---------- Команда на выключение
                        {
                        COUN_3secL_STEPI = 700; // Загрузить счетчик 3,5 с
                        COUN_3secH_STEPI = 700; // Загрузить счетчик 3,5 с
                        }
                else
                        {
                        if(--COUN_3secL_STEPI == 0)
                                {
                                COUN_3secL_STEPI = 700;
                                FL_ON_LOAD_HEAT_STEPI = 0;
                                }

                        }
                }
        else
                {
                if(FL_ON_LOAD_HEAT_STEPI == 1)  // ---------- Команда на включение
                        {
                        COUN_3secL_STEPI = 700; // Загрузить счетчик 3,5 с
                        COUN_3secH_STEPI = 700; // Загрузить счетчик 3,5 с
                        }
                else
                        {
                        if(--COUN_3secH_STEPI == 0)
                                {
                                COUN_3secH_STEPI = 700;
                                FL_ON_LOAD_HEAT_STEPI = 1;
                                }
                        }
                }

}
//------------------------------------------------------------

//------------------------------------------------------------

void    AN_INPUT_TIME(void)


{

        if(FL_ERR_CRC == 1 || FL_EERDWRGUT == 0 || FL_RB6_D6 == 1 || (FL_MK_NAL == 1 && FLAG4sec == 1))
                {

                COUN_DEL_5sec_Start_Stop_Jnt = 1000;

                FL_NEED_START_PRG_TIME = 0;
                FL_START_PRG_TIME = 0;
                if(BASE_DATA[n_mtm] == mtm_AGE && BASE_DATA[n_mOd] < mOd_Jn1)
                        FL_START_PRG_TIME = 1;          // Готовность к перезапуску для "AGE"
                FL_RUN_PRG_TIME = 0;

                FL_NEED_START_PRG_JNT2 = 0;
                FL_START_PRG_JNT2 = 0;
                FL_RUN_PRG_JNT2 = 0;

                FL_END_PHASE_PAUSE = 0;
                FL_PHASE_PAUSE = 0;
                FL_PHASE_IMPULSE = 0;

                FL_ON_LOAD_TIME_STEPII = 0;
                FL_CUR_STAT_JNT_START = 0;
                return;
                }


        if(--COUN_DEL_INP != 0)
                {
                FL_HAND_COUN_STAT_INP = 0;
                if(BASE_DATA[n_ALC] == ALC_OFF)                 // Если блокировки нет, то разрешить
                        {                                       // ручной инкремент счетчика
                        if(FL_RB4_INC == 1 && KEY4AKT == 0)
                                FL_HAND_COUN_STAT_INP = 1;
                        }
                if(FL_AN_INPUT_ST_TIME == 1 || FL_HAND_COUN_STAT_INP == 1)
                        COUN_STAT_INP++;                        // Инкремент: ручной или внешний
                }
        else
                {
                FL_NEED_START_PRG_TIME = 0;                     // Априорно сбросить
                FL_NEED_START_PRG_JNT2 = 0;                     // Априорно сбросить
                FL_CUR_STATUS_INPUT = 0;                        // Априорно сбросить
                COUN_DEL_INP = 10;
                if(COUN_STAT_INP >= 5)
                        FL_CUR_STATUS_INPUT = 1;

                switch(REG_CURRENT_MODE)                        // Выбор по mtm
                        {
                        case mtm_AGE:                           // AGE
                                if(BASE_DATA[n_mOd] < mOd_Jn1)
                                        {
                                        FL_RUN_PRG_TIME = 1;
                                        }
                                else
                                        {
                                        if(FL_CUR_STAT_JNT_START == 1)
                                                {
                                                if(FL_RUN_PRG_TIME == 0)
                                                        FL_START_PRG_TIME = 1;
                                                }
                                        else
                                                {
                                                FL_RUN_PRG_TIME = 0;
                                                FL_START_PRG_TIME = 0;
                                                FL_END_PHASE_PAUSE = 0;
                                                FL_PHASE_PAUSE = 0;
                                                FL_PHASE_IMPULSE = 0;
                                                }
                                        }
                                break;

                        case mtm_OFF:                           // OFF
                                break;

                        default:                                //  nGE, dVr, dOn, OVr
                                if(BASE_DATA[n_mSt] > mode_St_10)
                                        {                       // 0 » 1, Pwr
                                        if(FL_OLD_STATUS_INPUT == 0 && FL_CUR_STATUS_INPUT == 1)
                                                {
                                                if(BASE_DATA[n_mOd] == mOd_Jn2)
                                                        {
                                                        FL_NEED_START_PRG_JNT2 = 1;             // mOd_Jn2
                                                        }
                                                else
                                                        {
                                                        if(BASE_DATA[n_mOd] == mOd_Jn1)
                                                                {                               // mOd_Jn1
                                                                if(FL_RUN_PRG_TIME == 1 || FL_PERMIT_RESTART_FOR_JN1 == 1)
                                                                        FL_NEED_START_PRG_TIME = 1;
                                                                }
                                                        else
                                                                {                               // mOd_OFF, mOd_Onr, mOd_Ont, mOd_SEP
                                                                FL_NEED_START_PRG_TIME = 1;
                                                                }
                                                        }
                                                }
                                        }
                                else
                                        {                       // 1 » 0
                                        if(FL_OLD_STATUS_INPUT == 1 && FL_CUR_STATUS_INPUT == 0)
                                                {
                                                if(BASE_DATA[n_mOd] == mOd_Jn2)
                                                        {
                                                        FL_NEED_START_PRG_JNT2 = 1;             // mOd_Jn2
                                                        }
                                                else
                                                        {
                                                        if(BASE_DATA[n_mOd] == mOd_Jn1)
                                                                {                               // mOd_Jn1
                                                                if(FL_RUN_PRG_TIME == 1 || FL_PERMIT_RESTART_FOR_JN1 == 1)
                                                                        FL_NEED_START_PRG_TIME = 1;
                                                                }
                                                        else
                                                                {                               // mOd_OFF, mOd_Onr, mOd_Ont, mOd_SEP
                                                                FL_NEED_START_PRG_TIME = 1;
                                                                }
                                                        }
                                                }
                                        }
                                break;
                        }
                FL_OLD_STATUS_INPUT = FL_CUR_STATUS_INPUT;
                COUN_STAT_INP = 0;
                }
}
//------------------------------------------------------------

//------------------------------------------------------------

void    START_PRG_TIME(void)

{
        if(REG_TEST_MODE - REG_CURRENT_MODE  != 0)
                {                               // Режим работы был изменен
                if(REG_CURRENT_MODE == mtm_AGE && BASE_DATA[n_mOd] < mOd_Jn1)
                        {                       // mtm: {AGE}; mOd: {OFF, Onr, Ont, SEP}
                        FL_ON_LOAD_TIME_STEPII = 0;
                        FL_RUN_PRG_TIME = 0;
                        FL_START_PRG_TIME = 1;
                        }
                else
                        {                       // mtm: {nGE, dVr, dOn, Ovr, OFF}; mOd: {Jn1, Jn2}
                        FL_ON_LOAD_TIME_STEPII = 0;
                        FL_RUN_PRG_TIME = 0;
                        FL_START_PRG_TIME = 0;
                        FL_END_PHASE_PAUSE = 0;
                        FL_PHASE_PAUSE = 0;
                        FL_PHASE_IMPULSE = 0;
                        }
                }
        else
                {                               // Режим работы не изменялся
                switch(REG_CURRENT_MODE)        // Выбор по mOd
                        {

                        case mtm_AGE:           // mtm = AGE
                                break;

                        case mtm_OFF:           // mtm = OFF
                                FL_ON_LOAD_TIME_STEPII = 0;
                                FL_RUN_PRG_TIME = 0;
                                FL_START_PRG_TIME = 0;
                                FL_END_PHASE_PAUSE = 0;
                                FL_PHASE_PAUSE = 0;
                                FL_PHASE_IMPULSE = 0;
                                break;

                        default:                // mtm = nGE, dVr, dOn, Ovr
                                if(FL_NEED_START_PRG_TIME == 1)
                                        FL_START_PRG_TIME = 1;
                                if((FL_NEED_START_PRG_TIME == 1 && FL_RUN_PRG_TIME == 1) || (FL_KEY1_4S == 1 && KEY4AKT == 0 && BASE_DATA[n_ALC] == ALC_OFF && FL_RUN_PRG_TIME == 1))
                                        {
                                        FL_ERR_SET_PAR_TIME = 1;
                                        FL_RUN_PRG_TIME = 0;
                                        FL_START_PRG_TIME = 0;
                                        }
                                FL_NEED_START_PRG_TIME = 0;
                                break;
                        }
                }

        REG_TEST_MODE = REG_CURRENT_MODE;

}       //      Подпрограмма START_PRG_TIME завершена
//------------------------------------------------------------

//-----------------------------------------------------------------------------

void    JNT_COMPARE_RESUL_IND_SPS_SPr(void)

{

        int TEMP_BASE_DATA_n_SP_n_SPS;          // Временный регистр попеременного хранения данных уставок n_SP или n_SPS

        FL_PERMIT_RESTART_FOR_JN1 = 0;

        if((BASE_DATA[n_SPS] == (max_tCu + 1) && BASE_DATA[n_tSr] == tSr_Cu428) || (BASE_DATA[n_SPS] == (max_tPt + 1) && BASE_DATA[n_tSr] > tSr_Cu428))
                {
                TEMP_BASE_DATA_n_SP_n_SPS = BASE_DATA[n_SP];    // For "SPS" == "SP", (т.е. "SPE")
                }
        else
                {
                TEMP_BASE_DATA_n_SP_n_SPS = BASE_DATA[n_SPS];   // For "SPS" != "SP"
                }

        if(FL_RUN_PRG_TIME == 0)
                {
                if(BASE_DATA[n_HYS] < 0)
                        {                       // For "Heat"
                        if((RESUL_IND >= (TEMP_BASE_DATA_n_SP_n_SPS + BASE_DATA[n_HYS] - 20)) && (RESUL_IND <= (TEMP_BASE_DATA_n_SP_n_SPS - BASE_DATA[n_HYS] + 20)))
                                {
                                FL_PERMIT_RESTART_FOR_JN1 = 1;
                                FL_CUR_STAT_JNT_START = 1;
                                }
                        }
                else
                        {                       // For "Cool"
                        if((RESUL_IND >= (TEMP_BASE_DATA_n_SP_n_SPS - BASE_DATA[n_HYS] - 20)) && (RESUL_IND <= (TEMP_BASE_DATA_n_SP_n_SPS + BASE_DATA[n_HYS] + 20)))
                                {
                                FL_PERMIT_RESTART_FOR_JN1 = 1;
                                FL_CUR_STAT_JNT_START = 1;
                                }
                        }
                }

        if(BASE_DATA[n_HYS] < 0)
                {                               // For "Heat"
                if(RESUL_IND <= BASE_DATA[n_SPr])
                        FL_CUR_STAT_JNT_START = 0;
                }
        else
                {                               // For "Cool"
                if(RESUL_IND >= BASE_DATA[n_SPr])
                        FL_CUR_STAT_JNT_START = 0;
                }

        if((FL_CUR_STAT_JNT_START == 1 && FL_RUN_PRG_TIME_JNT == 0) && BASE_DATA[n_mtm] != mtm_AGE && BASE_DATA[n_mtm] != mtm_OFF)
                {
                if(--COUN_DEL_5sec_Start_Stop_Jnt == 0)
                        {
                        COUN_DEL_5sec_Start_Stop_Jnt = 1000;    // 5sec
                        FL_RUN_PRG_TIME_JNT = 1;                // Исключить повторный запуск отсчета
                        FL_NEED_START_PRG_TIME = 1;
                        }
                }

        if(((FL_CUR_STAT_JNT_START == 0 && FL_RUN_PRG_TIME_JNT == 1) && BASE_DATA[n_mtm] != mtm_AGE && BASE_DATA[n_mtm] != mtm_OFF) && BASE_DATA[n_mOd] != mOd_Jn2)
                {
                if(--COUN_DEL_5sec_Start_Stop_Jnt == 0)
                        {
                        COUN_DEL_5sec_Start_Stop_Jnt = 1000;    // 5sec
                        FL_RUN_PRG_TIME_JNT = 0;                // Подготовить след. запуск
                        if(FL_RUN_PRG_TIME == 1)
                                FL_NEED_START_PRG_TIME = 1;     // Осуществить запуск отсчета времени таймера поверх уже исполняемого для Jn1.
                                                                // Искусственный конфликт запуска отсчета!
                        }
                }

        if(FL_OLD_STAT_JNT_START == 1 && FL_CUR_STAT_JNT_START == 0 && BASE_DATA[n_mOd] == mOd_Jn1 && FL_KEYAKT == 0)
                FL_AUTO_RESET_JN1 = 1;

        FL_OLD_STAT_JNT_START = FL_CUR_STAT_JNT_START;

}       //      Подпрограмма JNT_COMPARE_RESUL_IND_SPS_SPr завершена
//-----------------------------------------------------------------------------

//------------------------------------------------------------

void    START_PRG_JNT2(void)

{

        if(FL_NEED_START_PRG_JNT2 == 1)
                FL_START_PRG_JNT2 = 1;
        if((FL_NEED_START_PRG_JNT2 == 1 && FL_RUN_PRG_JNT2 == 1) || (FL_KEY1_4S == 1 && KEY4AKT == 0 && BASE_DATA[n_ALC] == ALC_OFF && FL_RUN_PRG_JNT2 == 1))
                {
                FL_ERR_SET_PAR_TIME = 1;
                FL_RUN_PRG_JNT2 = 0;
                FL_RUN_PRG_TIME_JNT = 0;
                FL_START_PRG_JNT2 = 0;
                }
        FL_NEED_START_PRG_JNT2 = 0;


}       //      Подпрограмма START_PRG_JNT2 завершена
//------------------------------------------------------------

//------------------------------------------------------------

void    BASE_ALGORITM_JNT2(void)

{

        if(FL_RUN_PRG_JNT2 == 0)
                {
                if(FL_START_PRG_JNT2 == 1)
                        {
                        FL_START_PROC_JNT2_StP = 1;     // Signal StP
                        FL_RUN_PRG_JNT2 = 1;
                        }
                FL_START_PRG_JNT2 = 0;
                COUN_3secL_STEPI = 700;         // HEAT_STEPI --- is OFF
                COUN_3secH_STEPI = 700;
                FL_NEED_AKT_LOAD_STEPI = 0;
                FL_ON_LOAD_HEAT_STEPI = 0;
                FL_START_PRG_TIME = 0;          // TIME_STEPII --- is OFF
                FL_RUN_PRG_TIME = 0;
                FL_END_PHASE_PAUSE = 0;
                FL_PHASE_PAUSE = 0;
                FL_PHASE_IMPULSE = 0;
                FL_ON_LOAD_TIME_STEPII = 0;
                FL_CUR_STAT_JNT_START = 0;
                return;
                }

        DIR_FL_LOAD_HEAT();
        DELAY_3sec_DIR_LOAD_HEAT();
        JNT_COMPARE_RESUL_IND_SPS_SPr();
        START_PRG_TIME();
        DIR_LOAD_TIME();

}       //      Подпрограмма BASE_ALGORITM_JNT2 завершена
//------------------------------------------------------------

//------------------------------------------------------------

void    DIR_LOAD_TIME(void)

{
        unsigned char TMP_ADD_VALUE;

        if(FL_RUN_PRG_TIME == 1)
                goto    DR_L_0;
        if(FL_START_PRG_TIME == 0)
                {
                FL_ON_LOAD_TIME_STEPII = 0;
                return;
                }
        if(BASE_DATA[n_mOd] >= mOd_Jn1)
                FL_START_TIME_JN12_Stt = 1;     // Подать сигнал начала времени для Jn1 и Jn2
        FL_RUN_PRG_TIME = 1;                    // Начало загрузки программы
        FL_START_PRG_TIME = 0;
        COUN1sec = 33;                          // Синхронизация D_POINT
        FL_1sec = 1;                            //
        COUN_mS = 200;
        COUN_SEC = 60;
        COUN_min = 60;
        if(REG_CURRENT_MODE == mtm_Ovr)
                {                               // mtm = Ovr
                FL_ON_LOAD_TIME_STEPII = 1;     // Выполнить переключение исполнительного элемента
                FL_END_PHASE_PAUSE = 1;         // Фаза "PAUSE" для данного режима отсутствует
                FL_PHASE_PAUSE = 0;
                FL_PHASE_IMPULSE = 1;           // Сразу индикация режима "IMPULSE"
                }
        else
                {                               // mtm = AGE, nGE, dvr, OFF
                FL_END_PHASE_PAUSE = 0;
                FL_PHASE_PAUSE = 1;
                FL_PHASE_IMPULSE = 0;
                }
        COUN_PAUSE = BASE_DATA[n_PAU];          // Загрузить длительность выдержки PAUSE
        COUN_IMPULSE = BASE_DATA[n_imP];        // Загрузить длительность выдержки IMPULSE
        switch(BASE_DATA[n_mUL])                // Определить реальное значение множителя
                {
                case 1:
                        REAL_VALUE_MULTIPLY = 1;
                        break;
                case 2:
                        REAL_VALUE_MULTIPLY = 10;
                        break;
                case 3:
                        REAL_VALUE_MULTIPLY = 100;
                        break;
                }
        COUN_AMOUNT_PERIOD_nGE = BASE_DATA[n_Amn] * REAL_VALUE_MULTIPLY;        // Расчет числа периодов для nGE
        COUN_AMOUNT_PERIOD_IND = BASE_DATA[n_Amn];
        return;

DR_L_0: if(FL_END_PHASE_PAUSE == 1)
                {
                if(REG_CURRENT_MODE == mtm_dOn) // Режим "dOn" ?
                        return;                 // Бесконечно включить исполнительный элемент
                goto DR_L_2;
                }
        if(BASE_DATA[n_UnP] == Unit_mS)         // "PAUSE" = mS?
                goto    DR_L_3;
                if(--COUN_mS > 0)
                        return;
                COUN_mS = 200;
        if(BASE_DATA[n_UnP] == Unit_SEC)        // "PAUSE" = SEC?
                goto    DR_L_3;
                if(--COUN_SEC != 0)
                        return;
                COUN_SEC = 60;
        if(BASE_DATA[n_UnP] == Unit_min)        // "PAUSE" = min?
                goto    DR_L_3;
                if(--COUN_min != 0)
                        return;
                COUN_min = 60;
DR_L_3: if(BASE_DATA[n_UnP] == Unit_mS)
                COUN_PAUSE -= 4;                // Для mS декремент через 5 mS (здесь 4 и далее 1)
        if(--COUN_PAUSE > 0)
                return;
        FL_ON_LOAD_TIME_STEPII = 1;             // Выполнить перек. исполн. элемента
        FL_END_PHASE_PAUSE = 1;                 // Фаза "ПАУЗА" завершена!
        FL_PHASE_PAUSE = 0;
        FL_PHASE_IMPULSE = 1;
        if(REG_CURRENT_MODE == mtm_dOn)        // Режим "dOn" ?
                goto DR_L_1;
        return;

DR_L_2: if(BASE_DATA[n_Uni] == Unit_mS)         // "IMPULSE" = mS ?
                goto    DR_L_4;
                if(--COUN_mS > 0)
                        return;
                COUN_mS = 200;
        if(BASE_DATA[n_Uni] == Unit_SEC)        // "IMPULSE" = SEC ?
                goto    DR_L_4;
                if(--COUN_SEC !=0)
                        return;
                COUN_SEC = 60;
        if(BASE_DATA[n_Uni] == Unit_min)        // "IMPULSE" = min?
                goto    DR_L_4;
                if(--COUN_min != 0)
                        return;
                COUN_min = 60;
DR_L_4: if(BASE_DATA[n_Uni] == Unit_mS)
                COUN_IMPULSE -= 4;              // Для mS декремент через 5 mS (здесь 4 и далее 1)
        if(--COUN_IMPULSE > 0)
                return;
        FL_ON_LOAD_TIME_STEPII = 0;             // Исполнит. элемент в исходное состояния (подготовка к новому циклу)
        FL_PHASE_IMPULSE = 0;
        FL_RUN_PRG_TIME = 0;                    // Программа завершена, если не nGE!
        if(BASE_DATA[n_mOd] == mOd_Jn2)
                {
                FL_RUN_PRG_JNT2 = 0;
                FL_RUN_PRG_TIME_JNT = 0;
                COUN_DEL_5sec_Start_Stop_Jnt = 1000;
                }
        if(REG_CURRENT_MODE == mtm_AGE || REG_CURRENT_MODE == mtm_nGE)        // Опред. реж. AGE или nGE?
                {
                FL_RUN_PRG_TIME = 1;
                FL_END_PHASE_PAUSE = 0;
                FL_PHASE_PAUSE = 1;
                COUN_PAUSE = BASE_DATA[n_PAU];          // Загрузить длительность выдержки PAUSE
                COUN_IMPULSE = BASE_DATA[n_imP];        // Загрузить длительность выдержки IMPULSE
                if(REG_CURRENT_MODE == mtm_nGE && --COUN_AMOUNT_PERIOD_nGE == 0)
                        {
                        FL_RUN_PRG_TIME = 0;            // Полное завершение для nGE
                        if(BASE_DATA[n_mOd] == mOd_Jn2)
                                {
                                FL_RUN_PRG_JNT2 = 0;
                                FL_RUN_PRG_TIME_JNT = 0;
                                COUN_DEL_5sec_Start_Stop_Jnt = 1000;
                                }
                        }
                if(REG_CURRENT_MODE == mtm_nGE && COUN_AMOUNT_PERIOD_nGE != 0)
                        {
                        TMP_ADD_VALUE = 0;
                        if(REAL_VALUE_MULTIPLY > 1)
                                TMP_ADD_VALUE = REAL_VALUE_MULTIPLY;
                        COUN_AMOUNT_PERIOD_IND = (COUN_AMOUNT_PERIOD_nGE + TMP_ADD_VALUE) / REAL_VALUE_MULTIPLY;
                        }
                }
DR_L_1: FL_SOUND_END_PRG = 0;
        if(BASE_DATA[n_SSn] == 1 && BASE_DATA[n_Uni] > Unit_mS)
                {
                if(BASE_DATA[n_Uni] == Unit_SEC && BASE_DATA[n_imP] < 5)
                        {
                        FL_SOUND_END_PRG = 0;   // Не подавать сигнал при timp < 5s
                        }
                else
                        {
                        FL_SOUND_END_PRG = 1;   // Подать сигнал по завершении импульса
                        }
                }
        if(REG_CURRENT_MODE == mtm_nGE && COUN_AMOUNT_PERIOD_nGE != 0)
                FL_SOUND_END_PRG = 0;           // Запрет сигн.! Счетчик не равен 0

}
//------------------------------------------------------------

//-----------------------------------------------------------------------------

void    CALC_CRC(void)

{
        BASE_DATA[CRC_COPY1] = 0;
        ADDR_FOR_CRC_COPY1 = (unsigned char *ADDR_FOR_CRC_COPY1)&BASE_DATA[0];
        for(COUNT_FOR_CRC = 0; COUNT_FOR_CRC < (((SIZE_BASE / 2) - 1) * 2); COUNT_FOR_CRC++)
                {
                BASE_DATA[CRC_COPY1] += *ADDR_FOR_CRC_COPY1;
                ADDR_FOR_CRC_COPY1++;
                }

}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    CHECK_CRC(void)

{

        FL_ERR_CRC_COPY1 = FL_ERR_CRC_COPY2 = 0;        // В априори нет ошибок!
        if(FL_KEYAKT == 1)                              // На момент активности клавиатуры
                return;                                 // заблокировать контроль CRC для OPNAL

        TMP_VAL_CRC1 = 0;
        TMP_VAL_CRC2 = 0;

        ADDR_FOR_CRC_COPY1 = (unsigned char *ADDR_FOR_CRC_COPY1)&BASE_DATA[0];
        ADDR_FOR_CRC_COPY2 = (unsigned char *ADDR_FOR_CRC_COPY2)&BASE_DATA[(SIZE_BASE / 2)];

        for(COUNT_FOR_CRC = 0; COUNT_FOR_CRC < (((SIZE_BASE / 2) - 1) * 2); COUNT_FOR_CRC++)
                {
                TMP_VAL_CRC1 += *ADDR_FOR_CRC_COPY1;
                ADDR_FOR_CRC_COPY1++;
                TMP_VAL_CRC2 += *ADDR_FOR_CRC_COPY2;
                ADDR_FOR_CRC_COPY2++;
                }
        if(TMP_VAL_CRC1 != BASE_DATA[CRC_COPY1] || TMP_VAL_CRC1 == 0)
                FL_ERR_CRC_COPY1 = 1;                   // Повреждены данные в COPY1 D6
        if(TMP_VAL_CRC2 != BASE_DATA[CRC_COPY2] || TMP_VAL_CRC2 == 0)
                FL_ERR_CRC_COPY2 = 1;                   // Повреждены данные в COPY2 D6


}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    RESTORE_DATA(void)

{

        FL_ERR_CRC = 0;     // В априори нет ошибок!

        if(FL_ERR_CRC_COPY1 == 0 && FL_ERR_CRC_COPY2 == 0)      // Все данные в норме
                return;

        if(FL_ERR_CRC_COPY1 == 1 && FL_ERR_CRC_COPY2 == 0)      // Повреждена COPY1
                {                                               // COPY2 -> COPY1
                for(COUNT_FOR_CRC = 0; COUNT_FOR_CRC < (SIZE_BASE / 2); COUNT_FOR_CRC++)
                        {
                        BASE_DATA[(COUNT_FOR_CRC)] = BASE_DATA[((SIZE_BASE / 2) + COUNT_FOR_CRC)];
                        }
                }

        if(FL_ERR_CRC_COPY1 == 0 && FL_ERR_CRC_COPY2 == 1)      // Повреждена COPY2
                {
                COPY1_to_COPY2();                               // COPY1 -> COPY2
                }

        if(FL_ERR_CRC_COPY1 == 1 && FL_ERR_CRC_COPY2 == 1)      // Повреждены обе копии
                {
                FL_ERR_CRC = 1;                         // Все данные повреждены!
                BASE_DATA[n_SP]         = 750;          // Восстановить по умолчанию
                BASE_DATA[n_HYS]        = -50;
                BASE_DATA[n_SPS]        = 750;
                BASE_DATA[n_SPr]        = 0;
                BASE_DATA[n_PAU]        = 5;
                BASE_DATA[n_imP]        = 5;
                BASE_DATA[n_Amn]        = 100;
                BASE_DATA[n_SSn]        = 1;
                BASE_DATA[n_mOd]        = mOd_OFF;      // 0
                BASE_DATA[n_mtm]        = mtm_Ovr;      // 4
                BASE_DATA[n_UnP]        = Unit_SEC;     // 1
                BASE_DATA[n_Uni]        = Unit_SEC;     // 1
                BASE_DATA[n_mUL]        = 1;
                BASE_DATA[n_mSt]        = 1;
                BASE_DATA[n_Pri]        = 0;
                BASE_DATA[n_PFA]        = 0;
                BASE_DATA[n_CSr]        = 0;
                BASE_DATA[n_ALC]        = 0;
                BASE_DATA[n_tSr]        = tSr_Pt391;
                BASE_DATA[n_md6]        = mod_d6_auto;
                BASE_DATA[n_SYS]        = 2;
                BASE_DATA[n_nUL]        = 1024;
                BASE_DATA[n_428]        = default_GAIN_C428;
                BASE_DATA[n_385]        = default_GAIN_P385;
                BASE_DATA[n_391]        = default_GAIN_P391;
                BASE_DATA[n_guard_0]    = 0;
                BASE_DATA[n_guard_1]    = 0;
                BASE_DATA[CRC_COPY1] = BASE_DATA[CRC_COPY2] = 0;        // Ввести искусственную ошибку
                }

}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    SAVE_RESTORE_DATA(void)

{

        if(FL_ERR_CRC_COPY1 == 0 && FL_ERR_CRC_COPY2 == 0)        // Все данные в норме
                return;

        if(FL_ERR_CRC_COPY1 == 1 && FL_ERR_CRC_COPY2 == 1)        // Все данные повреждены
                return;

        if(FL_ERR_CRC_COPY1 == 1 || FL_ERR_CRC_COPY2 == 1)        // Повреждена COPY1 или COPY2
                {
                WR_EEPROM = 0xA5;                       // Команда на запись
                WR_EEPROM1 = 0x5A;                      // Дублирующая команда на запись
                ADDREEP = 0;
                COUNT_EE = (SIZE_BASE) * 2;             // Кол-во байт, подлежащих записи
                ADDR_BASE_DATA = (unsigned char *ADDR_BASE_DATA)&BASE_DATA[0];            // Получ.адрес первого счит.байта из PIC
                }

}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    SET_CONFIG_FLAG(void)

{

        TMP_CONFIG_REG = (unsigned char)BASE_DATA[n_SYS];

        FL_Cu100Pt100 = 0;

        FL_MEH_RELE = FL_2RELE = 1;                     // Пока нет полупроводников
                                                        // всегда = 1!
        if(TMP_CONFIG_REG == 2)
                FL_Cu100Pt100 = 1;

}       //      Подпрограмма SET_CONFIG_FLAG завершена
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    DYNAMIC_DISPLAY(void)
{

        if(FL_PRIM_START == 0)
                return;
        if(FL_END_DELAY_SGr_LOGO == 0)
                {
                LEDS_3 = DINAMIC_DATA[0];       // Именно в такой последовательности!
                LEDS_2 = DINAMIC_DATA[1];       // Именно в такой последовательности!
                LEDS_1 = DINAMIC_DATA[2];       // Здесь многократная загрузка, плоховато!
                LEDS_0 = DINAMIC_DATA[3];
                if(--COUN_DELAY_SGr > 0)        // Пауза бегущей строки на 2с для индикации логотипа "SGr". Загрузка в первичной инициализации.
                        return;
                FL_END_DELAY_SGr_LOGO = 1;      // Первичная загрузка бегущей сроки и вывод "SGr" лого завершены!
                COUN_RATE_DINAMIC_DATA = 40;
                AMOUNT_BYTE_DYNAMIC_DATA = sizeof DINAMIC_DATA; // Автоопределение кол-ва байт бегущей сроки
                AMOUNT_BYTE_DYNAMIC_DATA -= 4;  // Потому, что 4-е символа уже загружены в LEDS_x!
                NMB_SYMBOL = 3;                 // Потому, что 4-е символа уже загружены в LEDS_x! (0, 0+1, 1+1 = 2)
                }
        if(--COUN_RATE_DINAMIC_DATA != 0)
                return;
        COUN_RATE_DINAMIC_DATA = 40;            // Определить скорость движения символов
        NMB_SYMBOL++;
        LEDS_3 = LEDS_2;
        LEDS_2 = LEDS_1;
        LEDS_1 = LEDS_0;
        LEDS_0 = DINAMIC_DATA[NMB_SYMBOL];
        if(--AMOUNT_BYTE_DYNAMIC_DATA == 0)
                FL_PRIM_START = 0;

}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    TEST_CHANG_SENSOR(void)

{
        if(FL_KEYAKT == 0)
                {                       // Выполнить, если клавиатура не активна!
                FL_CHANG_CUR_S = 0;
                if(CUR_TYPE_SENS != BASE_DATA[n_tSr])
                        FL_CHANG_CUR_S = 1;
                }

}       //      Подпрограмма TEST_CHANG_SENSOR завершена
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
        // Подпрограмма выбирает тип установленного
        // в системе индикатора <OA-OK> по состоянию перемычки
        //
        // Input: PORTC,2 - тип индикатора (перемыч. замк. - OK, разомкн. - ОА)
        // Otput: FL_SET_INDIC_OK
        //
        // Внимание!
        // Канал проверки типа индикатора и PWM Sound совмещены, поэтому
        // есть специфика работы системы в этой части и дополнительные
        // требования к резисторам в цепи управления Sound (BEEP).
        // Для нормальной работы процесса распознавания типа индикатора
        // необходимо, чтобы lev"0" <= 1V, lev"1" >= 4V!
        // Рекомендуется в цепи базы транзистора управления установить резистор
        // номиналом 30К, а на +5V  подключить"подтягивающий" резистор 6,2К, под-
        // ключенный непосредственно на порт RC2 контроллера.
        // Параллельно переходу Б-Э транзистора обязательно подключить
        // резистор 56...75К!
        // Примечание - при неуверенном распознавании типа индикатора рекомендуется
        // добавить команд "NOP"  для компенсации емкости монтажа.
        // В нашем варианте считается, что емкость PCB и прочих элементов составляет
        // не более 50пФ!

void    SELECT_OA_OK_LEDS(void)
{


        if(--COUN_DEL_SELECT_OA_OK != 0)
              return;
        COUN_DEL_SELECT_OA_OK = 50;     // Период опроса 1с
        TRISC2 = 1;                     // PWM на вход, начало теста <ОА-ОК>
        NOP();                          // Для установления напряж. на вх. линии
        NOP();                          // Для установления напряж. на вх. линии
        NOP();                          // Для установления напряж. на вх. линии
        FL_SET_INDIC_OK = 0;            // По умолчанию <OA>
        if(RC2 == 1)
                FL_SET_INDIC_OK = 1;    // Выбран       <OK> (перемычка замк. или установлен резистор контроля <OK>)
        TRISC2 = 0;                     // PWM на выход, работа на "Sound"


}       //      Подпрограмма SELECT_OA_OK_LEDS завершена
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

void    COPY1_to_COPY2(void)

{
        for(COUNT_FOR_CRC = 0; COUNT_FOR_CRC < (SIZE_BASE / 2); COUNT_FOR_CRC++)
                {
                BASE_DATA[((SIZE_BASE / 2) + COUNT_FOR_CRC)] = BASE_DATA[(COUNT_FOR_CRC)];
                }

}       //      Подпрограмма COPY1_to_COPY2 завершена

//-----------------------------------------------------------------------------


