На основе базовойсхемы несколько доработаная конструкция для цифрового манометра-термостата . Датчик ММ393А, конструктивно крепится на массу, его резистивное сопротивление составляет , от 0 до 300 ом, чтобы получить на входе АЦП диапазон напряжения от 0 до 5V используем в схеме ОУ. Операционный усилитель , хоть и является небольшим усложнением схемы, но с его помощью можно добиться неплохой точности показаний прибора, даже с таким примитивным датчиком давления как ММ393А ( это самый доступный, другие специализирование стоят достойных денег ). А выход из МК, настраиваемого порога включения/выключения с настраиваемым гистерезисом (или просто сигнал) дополнительного устройства, делает эту схему полноценной, для любого применения !!!! А так же, всё получается ещё интереснее когда это 2 в 1. Например: манометр/манометр , манометр/вольтметр ,
манометр/термостат
……… , ну в общем по этому же принципу схемы базовой схемы какие угодно комбинации устройств. В данном случае схема работает как
манометр/термостат.
Фото датчика давления .
Схема:
В схеме используется датчик— ММ393Ас рабочим давлением от 0 до 8 кг/см2
Настройка и управление (назначение кнопок , светодиодов) аналогично описаному в
базовой схеме.
Работать будет и с другими автомобильными датчиками серии ММ3ххх , вот примерные характеристики таких датчиков
Датчик ММ358 при отсутствии давления должен иметь сопротивление 160...175 Ом, при давлении в 2 кг/см2
— 110...114 Ом, при давлении в 4 кг/см2
— 58...65 Ом, при давлении в 6кг/см2
— 0...5 Ом Датчик 23.3839 при отсутствии давления должен иметь сопротивление 305...330 Ом, при давлении в 1,5 кг/см2
— 180...200 Ом, при давлении в 4,5 кг/см2
— 70...80 Ом, при давлении в 6кг/см2 — 0...8 Ом Датчик ММ393А при отсутствии давления должен иметь сопротивление 310...320 Ом, при давлении в 4
кг/см2
— 115...130 Ом, при давлении в 6
кг/см2
— 55...65 Ом, при давлении в 8
кг/см2
— 0...15 Ом.
Как видим принцип тут один и тот же.
Экслюзивное фото , что у датчика давления, внутри.
Вольтметр от 0.0 до 50.0 вольт, давление от 0.0 до 8.0 кг/см , канал давления с использованием корректировки экспонентой.
Для измерительной схемы с применением аналогово автомобильного датчика , автор этой программы MACTEPok сделал небольшую редакцию кода в этой программе.
Так как аналоговые датчики ММ3хх
имеют некоторую нелинейность изменения сопротивления при увеличении давления.
Для программной корректировки, в программу внесена експонента.
Any_var = Chvar_1 / 2000 ' 2000 - можно задавать изгиб линии Any_var = Negativ * Any_var ' Если закоментировать, изменим направление изгиба экспоненты Any_var = Exp(any_var) Chvar_1 = 1023 - Chvar_1 Chvar_1 = Chvar_1 / 12.786 ' диапазон до 80 Any_var = Chvar_1 * Any_var Chvar_1 = Any_var
Таким образом, получаем вот такую коректированую кривизну измерения 9955260.xls
Config Portd = Output : Config Portb = Output 'порты на выход к которым подключен индикатор
Load1 Alias Portb.3 'нагрузка №1 Load2 Alias Portb.4 'нагрузка №2 Vibor Alias Pinc.0 'кнопка Выбор Up Alias Pinc.1 'кнопка Вверх Down Alias Pinc.2 'кнопка Вниз
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'настраиваем АЦП Dim W As Byte , Y As Byte , X As Byte , I As Byte , Z As Byte , Chislo(6) As Integer , Channel_1 As Integer , On1 As Word , Off1 As Word , Channel_2 As Integer , On2 As Word , Off2 As Word , Sostoyanie As Byte , Sostoyanie_2 As Byte , Copy_print As Integer , Copy_print_sec As Integer , Copy_var As Integer , _print As Integer , _print_sec As Integer , Pokazaniya As Integer , View_menu As Byte , Booton_flag As Bit , Booton_flag_2 As Bit , Count As Word , Error_flag As Bit Dim Razryad_1 As Byte , Razryad_2 As Byte , Temp_najatiya As Byte , Indicator As Byte Dim Menu_punkt As Byte , Any_var As Single 'пункт меню Dim Set_flag As Bit 'флаг режима настройки уставок Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit 'флаги режима отображения подсказок на соответствующих каналах Dim Default As Eram Byte At &H14 'переменная EEPROM для записи начальных уставок для первого включения прибора Dim Adc_ready As Bit ' Флаг готовности АЦП Dim Chvar_1 As Single , Chvar_2 As Single ' промежуточные переменные для расчетов Dim Ch1 As Integer , Ch2 As Integer,
Const Negativ = -1
A Alias Portd.2 : B Alias Portd.6 : C Alias Portb.7 : D Alias Portb.2 'порты, к которым подключены сегменты индикатора E Alias Portd.0 : F Alias Portb.6 : G Alias Portd.7 : H Alias Portb.5 ' Dig1 Alias Portd.3 : Dig2 Alias Portd.4 : Dig3 Alias Portd.1 ' порты, к которым подключены общие аноды 1го индикатора Dig1_sec Alias Portd.5 : Dig2_sec Alias Portb.0 : Dig3_sec Alias Portb.1 ' порты, к которым подключены общие аноды 2го индикатора
For X = 1 To 6 ' присваиваем всем цифрам пустоту, чтоб в момент включения не высвечивались нули Chislo(x) = 11 Next '*********** ___ Переключение типа индикаторов (ОК/ОА) ___ ********************* Readeeprom Indicator , 26 If Vibor = 0 Then ' Удерживая кнопку УСТ, подаем питание. For X = 1 To 200 If X = 150 Then ' При длительном нажатии Set Booton_flag Toggle Indicator.3 ' Переключаем младший (четвертый) бит переменной. Номер бита выбрал произвольно Writeeeprom Indicator , 26 If Indicator = &B00000000 Then ' Если переключили на ОА, зажжем все сегменты идикатора для подтверждения Reset A : Reset B : Reset C : Reset D : Reset E : Reset F : Reset G : Reset H Set Dig1 : Set Dig2 : Set Dig3 : Set Dig1_sec : Set Dig2_sec : Set Dig3_sec End If If Indicator = &B00001000 Then ' Если переключили на ОK, зажжем все сегменты идикатора для подтверждения Set A : Set B : Set C : Set D : Set E : Set F : Set G : Set H Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig1_sec : Reset Dig2_sec : Reset Dig3_sec End If Waitms 1500 Exit For End If If Vibor = 1 Then Exit For Waitms 10 Next End If '******************************************************************************* If Default = 255 Then 'при первом запуске, когда Default=255 Off1 = 70 'присваиваем начальный уставки On1 = 50 Off2 = 140 On2 = 120 Indicator = &B00001000 ' для ОА. Indicator = &B00001000 для ОК Razryad_1 = &B10111011 Razryad_2 = &B10111011 Writeeeprom On1 , 0 ' Записываем в EEPROM уставку ON1 Writeeeprom Off1 , 5 ' Записываем в EEPROM уставку OFF1 Writeeeprom On2 , 10 ' Записываем в EEPROM уставку ON2 Writeeeprom Off2 , 14 ' Записываем в EEPROM уставку OFF2 Writeeeprom Razryad_1 , 16 Writeeeprom Razryad_2 , 17 Writeeeprom Indicator , 26 Default = 100 ' присваиваем значение 100(произвольное, отличное от 255) и больше этот кусок кода выполняться не будет End If Readeeprom On1 , 0 ' Считываем из EEPROM уставку ON1 Readeeprom Off1 , 5 ' Считываем из EEPROM уставку OFF1 Readeeprom On2 , 10 ' Считываем из EEPROM уставку ON2 Readeeprom Off2 , 14 ' Считываем из EEPROM уставку OFF2 Readeeprom Razryad_1 , 16 Readeeprom Razryad_2 , 17
Config Timer0 = Timer , Prescale = 64 : On Timer0 Pulse ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера Config Timer1 = Timer , Prescale = 1 : On Timer1 Bootons ' конфигурируем таймер 1 и назначаем подпрограмму которая выполняется при переполнении таймера Enable Interrupts : Enable Timer0 : Enable Timer1 ' разрешаем прерывания, таймер 0, таймер 1 Start Timer0 : Start Timer1 Start Adc ' начало преобразования
X = 50 ' чтобы опрос АЦП произошел в первом круге Do If X > 50 And Timer0 < 50 Then Stop Timer0 : Stop Timer1 ' на время преобразования останавливаем таймеры Ch1 = Getadc(5) ' Давление Ch2 = Getadc(4) ' Напряжение Chvar_1 = Ch1 Chvar_2 = Ch2 Start Timer0 : Start Timer1 Any_var = Chvar_1 / 2000 ' 2000 - можно задавать изгиб линии Any_var = Negativ * Any_var ' Если закоментировать, изменим направление изгиба экспоненты Any_var = Exp(any_var) Chvar_1 = 1023 - Chvar_1 Chvar_1 = Chvar_1 / 12.786 'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ============== Any_var = Chvar_1 * Any_var Chvar_1 = Any_var
Chvar_2 = Chvar_2 / 2.046 'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ============== If Chvar_2 > 500 Then Chvar_2 = 500 'верхний предел показаний
Stop Timer0 : Stop Timer1 If Ch1 < 1023 Then If Chvar_1 > 0 Then Channel_1 = Chvar_1 ' присваиваем значения переменных для индикации If Chvar_1 > 80 Then Channel_1 = 80 'верхний предел показаний Else Channel_1 = 0 End If Channel_2 = Chvar_2 Start Timer0 : Start Timer1 X = 0 End If
If On1 < Off1 Then 'если уставка ON1 < OFF1 то режим нагревателя If Channel_1 <= On1 Then Sostoyanie = 1 'если значение первого канала АЦП ниже уставки ON1, то включаем нагрузку №1 If Channel_1 >= Off1 Then Sostoyanie = 0 'если значение первого канала АЦП выше уставки OFF1, то выключаем нагрузку №1 Else 'если уставка ON1 > OFF1 то режим охладителя If Channel_1 >= On1 Then Sostoyanie = 1 'если значение первого канала АЦП выше уставки ON1, то включаем нагрузку №1 If Channel_1 <= Off1 Then Sostoyanie = 0 'если значение первого канала АЦП ниже уставки OFF1, то выключаем нагрузку №1 End If
If Sostoyanie = 1 Then Set Load1 Else Reset Load1 'управление 1м каналом нагрузки
If On2 < Off2 Then 'если уставка ON2 < OFF2 то режим нагревателя If Channel_2 <= On2 Then Sostoyanie_2 = 1 'если давление ниже уставки ON2, то включаем нагрузку №2 If Channel_2 >= Off2 Then Sostoyanie_2 = 0 'если давление выше уставки OFF2, то выключаем нагрузку №2 Else 'если уставка ON2 > OFF2 то режим охладителя If Channel_2 >= On2 Then Sostoyanie_2 = 1 'если давление выше уставки ON2, то включаем нагрузку №2 If Channel_2 <= Off2 Then Sostoyanie_2 = 0 'если давление ниже уставки OFF2, то выключаем нагрузку №2 End If
If Sostoyanie_2 = 1 Then Set Load2 Else Reset Load2 'управление 2м каналом нагрузки
Pulse: If View_menu <> 0 And Error_flag = 0 Then Incr Count 'если находимся в меню и нет ошибки ввода уставок,то инкриментируем счетчик, который отвечает за автоматический выход из меню (~ через 5 сек) If Count > 7000 Then 'задается время автоматического выхода из меню Count = 0 'сброс счетчика View_menu = 0 ' выход из меню в основной режим End If ' H = 1 ' выключаем точку на индикаторе Stop Timer0 'останавливаем таймер 0 Select Case View_menu 'в зависимости от пункта меню, записываем в переменные расчета следующие данные Case 0 : _print = Channel_1 ' основной режим. 1й индикатор показывает значение АЦП 1го канала _print_sec = Channel_2 ' основной режим. 2й индикатор показывает значение АЦП 2го канала Case 1 : _print = On1 ' 1й индикатор показывает значение уставки ON1 _print_sec = Channel_2 ' 2й индикатор показывает значение АЦП 2го канала Case 2 : _print = Off1 ' 1й индикатор показывает значение уставки OFF1 _print_sec = Channel_2 ' 2й индикатор показывает значение АЦП 2го канала Case 3 : _print = Channel_1 ' 1й индикатор показывает значение АЦП 1го канала _print_sec = On2 ' 2й индикатор показывает значение уставки ON2 Case 4 : _print = Channel_1 ' 1й индикатор показывает значение АЦП 1го канала _print_sec = Off2 ' 2й индикатор показывает значение уставки OFF2 End Select
If Podskaz_flag = 0 Then 'если не выводим на 1й индикатор подсказки, то работаем с числами Copy_print = _print ' Copy_var = Copy_print ' For I = 3 To 1 Step -1 ' цикл в котором разбивается переменная на 3 числа Chislo(i) = Copy_print Mod 10 ' заносим в масив последнюю цифру от числа Copy_print(123 mod 10 = 3) Copy_print = Copy_print / 10 ' отсекаем последнюю цифру от числа Copy_print (123/10=12) Next ' убираем незначимые нули If Copy_var < 100 Then Chislo(1) = 11 'для 2х значного числа ' If Copy_var < 10 Then Chislo(2) = 11 'для однозначного числа End If If Podskaz_flag_sec = 0 Then 'если не выводим на 2й индикатор подсказки, то работаем с числами Copy_print_sec = _print_sec ' Copy_var = Copy_print_sec For I = 6 To 4 Step -1 ' цикл в котором разбивается переменная на 3 числа Chislo(i) = Copy_print_sec Mod 10 ' заносим в масив последнюю цифру от числа _print(123 mod 10 = 3) Copy_print_sec = Copy_print_sec / 10 ' отсекаем последнюю цифру от числа Copy_print_sec (123/10=12) Next 'убираем незначимые нули If Copy_var < 100 Then Chislo(4) = 11 'для 2х значного числа ' If Copy_var < 10 Then Chislo(5) = 11 'для однозначного числа End If
If Indicator = 0 Then ' Гасим индикаторы перед выводом информации Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig1_sec : Reset Dig2_sec : Reset Dig3_sec ' Для индикатора с ОА Else Set Dig1 : Set Dig2 : Set Dig3 : Set Dig1_sec : Set Dig2_sec : Set Dig3_sec 'Для индикатора с ОK End If
Incr W : If W > 6 Then W = 1 ' выбираем какую цифру сейчас включать Y = 0 Gosub Look : A = Z ' переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А Gosub Look : B = Z Gosub Look : C = Z Gosub Look : D = Z Gosub Look : E = Z Gosub Look : F = Z Gosub Look : G = Z
Select Case W ' включаем цифру(разряд) которую выбрали (w). Подаем плюс на общий провод конкретной цифры (разряда) Case 1 : If Indicator = 0 Then Set Dig3 If Podskaz_flag = 0 Then H = Razryad_1.3 Else H = 1 Else Reset Dig3 If Podskaz_flag = 0 Then H = Razryad_1.3 Toggle H Else H = 0 End If End If Case 2 : If Indicator = 0 Then Set Dig2 If Podskaz_flag = 0 Then H = Razryad_1.2 Else H = 1 Else Reset Dig2 If Podskaz_flag = 0 Then H = Razryad_1.2 Toggle H Else H = 0 End If End If Case 3 : If Indicator = 0 Then Set Dig1 If Podskaz_flag = 0 Then H = Razryad_1.1 Else H = 1 Else Reset Dig1 If Podskaz_flag = 0 Then H = Razryad_1.1 Toggle H Else H = 0 End If End If Case 4 : If Indicator = 0 Then Set Dig3_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.3 Else H = 1 Else Reset Dig3_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.3 Toggle H Else H = 0 End If End If Case 5 : If Indicator = 0 Then Set Dig2_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.2 Else H = 1 Else Reset Dig2_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.2 Toggle H Else H = 0 End If End If Case 6 : If Indicator = 0 Then Set Dig1_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.1 Else H = 1 Else Reset Dig1_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.1 Toggle H Else H = 0 End If End If End Select '
Start Timer0 Return ' Look: ' подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму Z = Chislo(w) * 7 : Z = Y + Z ' определяем порядковый номер числа из таблици DATA. W - это цифра которую будем выводить 1..2..3, Y это номер сегмента (A=0 B=1 C=2...G=7) If Indicator = 0 Then Z = Lookup(z , Cifri_oa) ' выбираем из таблици включить или выключить нужный сегмент -OA Else Z = Lookup(z , Cifri_ok) '-OK End If Incr Y 'Y это номер сегмента (A=0 B=1 C=2...). Chislo(w) * 7 - переход на начало нужной строки Data.Z = Y + Z - по очереди перебираем сегменты в строке. Return ' Cifri_oa: ' таблица сегментом для индикаторов с общим плюсом |Chislo(i)| Символ | Data 0 , 0 , 0 , 0 , 0 , 0 , 1 '0 Data 1 , 0 , 0 , 1 , 1 , 1 , 1 '1 Data 0 , 0 , 1 , 0 , 0 , 1 , 0 '2 Data 0 , 0 , 0 , 0 , 1 , 1 , 0 '3 Data 1 , 0 , 0 , 1 , 1 , 0 , 0 '4 Data 0 , 1 , 0 , 0 , 1 , 0 , 0 '5 Data 0 , 1 , 0 , 0 , 0 , 0 , 0 '6 Data 0 , 0 , 0 , 1 , 1 , 1 , 1 '7 Data 0 , 0 , 0 , 0 , 0 , 0 , 0 '8 Data 0 , 0 , 0 , 0 , 1 , 0 , 0 '9 Data 1 , 1 , 1 , 1 , 1 , 1 , 0 '10 "-" Data 1 , 1 , 1 , 1 , 1 , 1 , 1 '11 "" Data 1 , 1 , 1 , 0 , 0 , 0 , 1 '12 "L" Data 1 , 1 , 0 , 1 , 0 , 1 , 0 '13 "n" Data 0 , 1 , 1 , 1 , 0 , 0 , 0 '14 "F" Data 0 , 1 , 1 , 0 , 0 , 0 , 0 '15 "E" Data 1 , 1 , 1 , 1 , 0 , 1 , 0 '16 "r"
'******************************************************************************* ' '******************************************************************************* ' Опрос кнопок Bootons: Incr X Stop Timer1 If Vibor = 0 And Booton_flag = 0 And Up = 1 And Down = 1 Then Gosub Set_mode ' Нажатие кнопки УСТ If Set_flag = 1 And Vibor = 1 Then 'Кнопки Вверх и Вниз активны только после входа в меню If Up = 0 Then Gosub Up_const If Down = 0 Then Gosub Down_const End If If Vibor = 0 And Up = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led1 If Vibor = 0 And Down = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led2
If Vibor = 1 And Up = 1 And Down = 1 Then Reset Booton_flag 'сброс флага удержания кнопки If Vibor = 1 Then Reset Booton_flag_2 Start Timer1 : Start Timer0 Return '******************************************************************************* ' ' Set_mode: Enable Interrupts : Enable Timer0 : Start Timer0
Set Set_flag ' поднимаем флаг режима настройки уставок (находимся в меню) Set Booton_flag ' поднимаем флаг удержания кнопки (пока не сбросится, в следующий пункт меню не попадаем) Count = 0 'сброс счетчика автоматического выхода из меню If On1 = Off1 Or On2 = Off2 Then Gosub Errors 'Блокировка ввода уставок. Переходим в подпрограмму индикации ошибки Incr View_menu ' следующий пункт меню If View_menu > 4 Then View_menu = 0 ' всего 4 пункта меню, 0й - основной режим
Select Case View_menu 'индикация подсказок пунктов меню Case 0 : ' --- Set Podskaz_flag Set Podskaz_flag_sec Chislo(1) = 10 Chislo(2) = 10 Chislo(3) = 10 Chislo(4) = 10 Chislo(5) = 10 Chislo(6) = 10 Reset Set_flag ' Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom Off2 , 14 ' запись уставки OFF2 в EEPROM
Case 1 : ' On1 Set Podskaz_flag 'Поднимаем флаг вывода подсказок (буквы) на 1й индикатор Chislo(3) = 1 Chislo(2) = 13 Chislo(1) = 0 Waitms 500
Case 2 : ' OF1 Set Podskaz_flag 'Поднимаем флаг вывода подсказок (буквы) на 1й индикатор Chislo(3) = 1 Chislo(2) = 14 Chislo(1) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom On1 , 0 ' запись уставки ON1 в EEPROM
Case 3 : ' On2 Set Podskaz_flag_sec 'Поднимаем флаг вывода подсказок (буквы) на 2й индикатор Chislo(6) = 2 Chislo(5) = 13 Chislo(4) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom Off1 , 5 ' запись уставки OFF1 в EEPROM
Case 4 : ' OFF2 Set Podskaz_flag_sec 'Поднимаем флаг вывода подсказок (буквы) на 2й индикатор Chislo(6) = 2 Chislo(5) = 14 Chislo(4) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom On2 , 10 ' запись уставки ON2 в EEPROM
End Select
Reset Podskaz_flag Reset Podskaz_flag_sec Return ' Errors: Set Error_flag ' поднимаем флаг ошибки If On1 = Off1 Then Set Podskaz_flag Chislo(1) = 15 Chislo(2) = 16 'Выводим подсказку Err и мигаем на 1м индикаторе Chislo(3) = 16 Waitms 500 Chislo(1) = 11 Chislo(2) = 11 Chislo(3) = 11 Waitms 500 Chislo(1) = 15 Chislo(2) = 16 Chislo(3) = 16 Waitms 500 Chislo(1) = 11 Chislo(2) = 11 Chislo(3) = 11 Waitms 500 End If If On2 = Off2 Then Set Podskaz_flag_sec Chislo(4) = 15 Chislo(5) = 16 'Выводим подсказку Err и мигаем на 2м индикаторе Chislo(6) = 16 Waitms 500 Chislo(4) = 11 Chislo(5) = 11 Chislo(6) = 11 Waitms 500 Chislo(4) = 15 Chislo(5) = 16 Chislo(6) = 16 Waitms 500 Chislo(4) = 11 Chislo(5) = 11 Chislo(6) = 11 Waitms 500 End If Select Case View_menu ' взависимости от того, в каком пункте меню ввели неверное значение Case 0 : ' возвращаем из EEPROM предыдущие значения Case 1 : Readeeprom On1 , 0 Case 2 : Readeeprom Off1 , 5 Case 3 : Readeeprom On2 , 10 Case 4 : Readeeprom Off2 , 14 End Select Decr View_menu ' возвращаемся в предыдущий пункт меню (в ошибочный) Count = 0 : Reset Error_flag Return ' Up_const: Enable Interrupts : Enable Timer0 : Start Timer0 Count = 0 Select Case View_menu Case 1 : If On1 < 80 Then Incr On1 ' Case 2 : ' If Off1 < 80 Then Incr Off1 Case 3 : ' If On2 < 500 Then Incr On2 ' Case 4 : ' If Off2 < 500 Then Incr Off2 End Select ' время задержки установки кн.+ значений уставок Waitms 100 Return ' ' Down_const: Enable Interrupts : Enable Timer0 : Start Timer0 Count = 0 Select Case View_menu Case 1 : If On1 > 0 Then Decr On1 ' добавляется второе условие при работе с отрицательными числами Case 2 : If Off1 > 0 Then Decr Off1 Case 3 : If On2 > 0 Then Decr On2 Case 4 : If Off2 > 0 Then Decr Off2 End Select Waitms 100 ' время задержки установки кн.- значений уставок Return ' ' Set_h_led1: Set Booton_flag_2 Rotate Razryad_1 , Left Stop Timer1 : Stop Timer0 Writeeeprom Razryad_1 , 16 Return ' ' Set_h_led2: Set Booton_flag_2 Rotate Razryad_2 , Left Stop Timer1 : Stop Timer0 Writeeeprom Razryad_2 , 17 Return
Config Portd = Output : Config Portb = Output 'порты на выход к которым подключен индикатор
Config 1wire = Portc.4 ' Порт для подключения датчика DS18B20
Load1 Alias Portb.3 'нагрузка №1 Load2 Alias Portb.4 'нагрузка №2 Vibor Alias Pinc.0 'кнопка Выбор Up Alias Pinc.1 'кнопка Вверх Down Alias Pinc.2 'кнопка Вниз
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'настраиваем АЦП Dim W As Byte , Y As Byte , X As Byte , I As Byte , Z As Byte , Chislo(6) As Integer , Channel_1 As Integer , Channel_1word As Word , On1 As Word , Off1 As Word , Channel_2 As Integer , On2 As Word , Off2 As Word , Sostoyanie As Byte , Sostoyanie_2 As Byte , Copy_print As Integer , Copy_print_sec As Integer , Copy_var As Integer , _print As Integer , _print_sec As Integer , Pokazaniya As Integer , View_menu As Byte , Booton_flag As Bit , Booton_flag_2 As Bit , Count As Word , Error_flag As Bit , Error_temp_flag As Bit Dim Razryad_1 As Byte , Razryad_2 As Byte , Temp_najatiya As Byte , Indicator As Byte Dim Menu_punkt As Byte , Any_var As Single 'пункт меню Dim Set_flag As Bit 'флаг режима настройки уставок Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit 'флаги режима отображения подсказок на соответствующих каналах Dim Default As Eram Byte At &H14 'переменная EEPROM для записи начальных уставок для первого включения прибора Dim Adc_ready As Bit ' Флаг готовности АЦП Dim Chvar_1 As Single , Chvar_2 As Integer ' промежуточные переменные для расчетов Dim Ch1 As Integer , Ch2 As Integer, Dim Numb As Word , Dsid1(8) As Byte , Bd1 As Byte , Bd2 As Byte , Bd(9) As Byte , ' Переменные для работы с DS18B20 Dim T1 As Single , T2 As Integer , Minus_flag As Bit , Read_flag As Bit , Conv_flag As Bit , Ds_count As Byte Const Negativ = -1
A Alias Portd.2 : B Alias Portd.6 : C Alias Portb.7 : D Alias Portb.2 'порты, к которым подключены сегменты индикатора E Alias Portd.0 : F Alias Portb.6 : G Alias Portd.7 : H Alias Portb.5 ' Dig1 Alias Portd.3 : Dig2 Alias Portd.4 : Dig3 Alias Portd.1 ' порты, к которым подключены общие аноды 1го индикатора Dig1_sec Alias Portd.5 : Dig2_sec Alias Portb.0 : Dig3_sec Alias Portb.1 ' порты, к которым подключены общие аноды 2го индикатора
'A Alias Portd.5 : B Alias Portd.7 : C Alias Portd.3 : D Alias Portd.1 'порты, к которым подключены сегменты индикатора 'E Alias Portd.0 : F Alias Portd.6 : G Alias Portd.4 : H Alias Portd.2 ' 'Dig1 Alias Portb.0 : Dig2 Alias Portb.1 : Dig3 Alias Portb.2 ' порты, к которым подключены общие аноды 1го индикатора 'Dig1_sec Alias Portb.5 : Dig2_sec Alias Portb.6 : Dig3_sec Alias Portb.7 ' порты, к которым подключены общие аноды 2го индикатора
'Numb = 1wirecount() 'If Numb > 0 Then Dsid1(1) = 1wsearchfirst() Else Set Error_temp_flag For X = 1 To 6 ' присваиваем всем цифрам пустоту, чтоб в момент включения не высвечивались нули Chislo(x) = 11 Next '*********** ___ Переключение типа индикаторов (ОК/ОА) ___ ********************* Readeeprom Indicator , 26 If Vibor = 0 Then ' Удерживая кнопку УСТ, подаем питание. For X = 1 To 200 If X = 150 Then ' При длительном нажатии Set Booton_flag Toggle Indicator.3 ' Переключаем младший (четвертый) бит переменной. Номер бита выбрал произвольно Writeeeprom Indicator , 26 If Indicator = &B00000000 Then ' Если переключили на ОА, зажжем все сегменты идикатора для подтверждения Reset A : Reset B : Reset C : Reset D : Reset E : Reset F : Reset G : Reset H Set Dig1 : Set Dig2 : Set Dig3 : Set Dig1_sec : Set Dig2_sec : Set Dig3_sec End If If Indicator = &B00001000 Then ' Если переключили на ОK, зажжем все сегменты идикатора для подтверждения Set A : Set B : Set C : Set D : Set E : Set F : Set G : Set H Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig1_sec : Reset Dig2_sec : Reset Dig3_sec End If Waitms 1500 Exit For End If If Vibor = 1 Then Exit For Waitms 10 Next End If '******************************************************************************* If Default = 255 Then 'при первом запуске, когда Default=255 Off1 = 70 'присваиваем начальный уставки On1 = 50 Off2 = 30 On2 = 27 ' Indicator = &B00001000 Indicator = &B00000000 ' для ОА. Indicator = &B00001000 для ОК Razryad_1 = &B10111011 Razryad_2 = &B11101110 Writeeeprom On1 , 0 ' Записываем в EEPROM уставку ON1 Writeeeprom Off1 , 5 ' Записываем в EEPROM уставку OFF1 Writeeeprom On2 , 10 ' Записываем в EEPROM уставку ON2 Writeeeprom Off2 , 14 ' Записываем в EEPROM уставку OFF2 Writeeeprom Razryad_1 , 16 Writeeeprom Razryad_2 , 17 Writeeeprom Indicator , 26 Default = 100 ' присваиваем значение 100(произвольное, отличное от 255) и больше этот кусок кода выполняться не будет End If Readeeprom On1 , 0 ' Считываем из EEPROM уставку ON1 Readeeprom Off1 , 5 ' Считываем из EEPROM уставку OFF1 Readeeprom On2 , 10 ' Считываем из EEPROM уставку ON2 Readeeprom Off2 , 14 ' Считываем из EEPROM уставку OFF2 Readeeprom Razryad_1 , 16 Readeeprom Razryad_2 , 17
Config Timer0 = Timer , Prescale = 64 : On Timer0 Pulse ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера Config Timer1 = Timer , Prescale = 1 : On Timer1 Bootons ' конфигурируем таймер 1 и назначаем подпрограмму которая выполняется при переполнении таймера Enable Interrupts : Enable Timer0 : Enable Timer1 ' разрешаем прерывания, таймер 0, таймер 1 Start Timer0 : Start Timer1 Start Adc ' начало преобразования
X = 60
Do If X > 50 And Timer0 < 50 Then Stop Timer0 : Stop Timer1 ' на время преобразования останавливаем таймеры Ch1 = Getadc(5) ' 1 канал 'опрос АЦП Chvar_1 = Ch1 Start Timer0 : Start Timer1 Any_var = Chvar_1 / 2000 ' 2000 - можно задавать изгиб линии Any_var = Negativ * Any_var Any_var = Exp(any_var) Chvar_1 = 1023 - Chvar_1 Chvar_1 = Chvar_1 / 12.035 'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ============== Any_var = Chvar_1 * Any_var Chvar_1 = Any_var Stop Timer0 : Stop Timer1 If Ch1 < 1023 Then If Chvar_1 > 0 Then Channel_1 = Chvar_1 ' присваиваем значения переменных для индикации If Chvar_1 > 85 Then Channel_1 = 85 'верхний предел показаний Else Channel_1 = 0 End If Start Timer0 : Start Timer1 X = 0 End If
If Conv_flag = 0 And Timer0 < 50 Then 1wreset ' 1wwrite &HCC ' Выдаем команду чтения ПЗУ 1wwrite &H44 ' Запуск измерения Set Conv_flag Ds_count = 0 End If ' If Read_flag = 1 And Timer0 < 50 Then ' 1wreset 1wwrite &HCC 1wwrite &HBE ' Команда чтения ОЗУ датчика Bd(1) = 1wread(9) If Bd(9) = Crc8(bd(1) , 8) Then Bd1 = Bd(1) ' Читаем нулевой байт Bd2 = Bd(2) ' Читаем первый байт If Bd2 >= 248 Then Bd1 = &H100 - Bd1 Bd2 = &HFF - Bd2 If Err = 0 Then Set Minus_flag ' Znak = "-" Else Reset Minus_flag ' Znak = "+" End If T1 = Bd1 / 16 ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16) T2 = Bd2 * 16 ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16) T1 = T1 + T2 ' T1 = T1 * 10 Chvar_2 = T1 'отсекаем от температуры все после запятой If Err = 0 Then If Chvar_2 > 120 Then Chvar_2 = 120 Channel_2 = Chvar_2 End If Reset Read_flag Reset Conv_flag End If End If If On1 < Off1 Then 'если уставка ON1 < OFF1 то режим нагревателя If Channel_1 <= On1 Then Sostoyanie = 1 'если значение первого канала АЦП ниже уставки ON1, то включаем нагрузку №1 If Channel_1 >= Off1 Then Sostoyanie = 0 'если значение первого канала АЦП выше уставки OFF1, то выключаем нагрузку №1 Else 'если уставка ON1 > OFF1 то режим охладителя If Channel_1 >= On1 Then Sostoyanie = 1 'если значение первого канала АЦП выше уставки ON1, то включаем нагрузку №1 If Channel_1 <= Off1 Then Sostoyanie = 0 'если значение первого канала АЦП ниже уставки OFF1, то выключаем нагрузку №1 End If
If Sostoyanie = 1 Then Set Load1 Else Reset Load1 'управление 1м каналом нагрузки
If Minus_flag = 0 Then If On2 < Off2 Then 'если уставка ON2 < OFF2 то режим нагревателя If Channel_2 <= On2 Then Sostoyanie_2 = 1 'если давление ниже уставки ON2, то включаем нагрузку №2 If Channel_2 >= Off2 Then Sostoyanie_2 = 0 'если давление выше уставки OFF2, то выключаем нагрузку №2 Else 'если уставка ON2 > OFF2 то режим охладителя If Channel_2 >= On2 Then Sostoyanie_2 = 1 'если давление выше уставки ON2, то включаем нагрузку №2 If Channel_2 <= Off2 Then Sostoyanie_2 = 0 'если давление ниже уставки OFF2, то выключаем нагрузку №2 End If End If
If Sostoyanie_2 = 1 Then Set Load2 Else Reset Load2 'управление 2м каналом нагрузки
Pulse: Stop Timer0 If View_menu <> 0 And Error_flag = 0 Then Incr Count 'если находимся в меню и нет ошибки ввода уставок,то инкриментируем счетчик, который отвечает за автоматический выход из меню (~ через 5 сек) If Count > 7000 Then 'задается время автоматического выхода из меню Count = 0 'сброс счетчика View_menu = 0 ' выход из меню в основной режим End If ' H = 1 ' выключаем точку на индикаторе 'останавливаем таймер 0 Select Case View_menu 'в зависимости от пункта меню, записываем в переменные расчета следующие данные Case 0 : _print = Channel_1 ' основной режим. 1й индикатор показывает значение АЦП 1го канала _print_sec = Channel_2 ' основной режим. 2й индикатор показывает значение АЦП 2го канала Case 1 : _print = On1 ' 1й индикатор показывает значение уставки ON1 _print_sec = Channel_2 ' 2й индикатор показывает значение АЦП 2го канала Case 2 : _print = Off1 ' 1й индикатор показывает значение уставки OFF1 _print_sec = Channel_2 ' 2й индикатор показывает значение АЦП 2го канала Case 3 : _print = Channel_1 ' 1й индикатор показывает значение АЦП 1го канала _print_sec = On2 ' 2й индикатор показывает значение уставки ON2 Case 4 : _print = Channel_1 ' 1й индикатор показывает значение АЦП 1го канала _print_sec = Off2 ' 2й индикатор показывает значение уставки OFF2 End Select
If Podskaz_flag = 0 Then 'если не выводим на 1й индикатор подсказки, то работаем с числами Copy_print = _print ' Copy_var = Copy_print ' For I = 3 To 1 Step -1 ' цикл в котором разбивается переменная на 3 числа Chislo(i) = Copy_print Mod 10 ' заносим в масив последнюю цифру от числа Copy_print(123 mod 10 = 3) Copy_print = Copy_print / 10 ' отсекаем последнюю цифру от числа Copy_print (123/10=12) Next ' убираем незначимые нули If Copy_var < 100 Then Chislo(1) = 11 'для 2х значного числа ' If Copy_var < 10 Then Chislo(2) = 11 'для однозначного числа End If If Podskaz_flag_sec = 0 Then 'если не выводим на 2й индикатор подсказки, то работаем с числами Copy_print_sec = _print_sec ' Copy_var = Copy_print_sec For I = 6 To 4 Step -1 ' цикл в котором разбивается переменная на 3 числа Chislo(i) = Copy_print_sec Mod 10 ' заносим в масив последнюю цифру от числа _print(123 mod 10 = 3) Copy_print_sec = Copy_print_sec / 10 ' отсекаем последнюю цифру от числа Copy_print_sec (123/10=12) Next 'убираем незначимые нули If Copy_var < 100 Then Chislo(4) = 11 'для 2х значного числа If Copy_var < 10 Then Chislo(5) = 11 'для однозначного числа If Minus_flag = 1 And View_menu < 3 Then Chislo(4) = 10 End If
If Indicator = 0 Then ' Гасим индикаторы перед выводом информации Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig1_sec : Reset Dig2_sec : Reset Dig3_sec ' Для индикатора с ОА Else Set Dig1 : Set Dig2 : Set Dig3 : Set Dig1_sec : Set Dig2_sec : Set Dig3_sec 'Для индикатора с ОK End If
Incr W : If W > 6 Then W = 1 ' выбираем какую цифру сейчас включать Y = 0 Gosub Look : A = Z ' переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А Gosub Look : B = Z Gosub Look : C = Z Gosub Look : D = Z Gosub Look : E = Z Gosub Look : F = Z Gosub Look : G = Z
Select Case W ' включаем цифру(разряд) которую выбрали (w). Подаем плюс на общий провод конкретной цифры (разряда) Case 1 : If Indicator = 0 Then Set Dig3 If Podskaz_flag = 0 Then H = Razryad_1.3 Else H = 1 Else Reset Dig3 If Podskaz_flag = 0 Then H = Razryad_1.3 Toggle H Else H = 0 End If End If Case 2 : If Indicator = 0 Then Set Dig2 If Podskaz_flag = 0 Then H = Razryad_1.2 Else H = 1 Else Reset Dig2 If Podskaz_flag = 0 Then H = Razryad_1.2 Toggle H Else H = 0 End If End If Case 3 : If Indicator = 0 Then Set Dig1 If Podskaz_flag = 0 Then H = Razryad_1.1 Else H = 1 Else Reset Dig1 If Podskaz_flag = 0 Then H = Razryad_1.1 Toggle H Else H = 0 End If End If Case 4 : If Indicator = 0 Then Set Dig3_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.3 Else H = 1 Else Reset Dig3_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.3 Toggle H Else H = 0 End If End If Case 5 : If Indicator = 0 Then Set Dig2_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.2 Else H = 1 Else Reset Dig2_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.2 Toggle H Else H = 0 End If End If Case 6 : If Indicator = 0 Then Set Dig1_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.1 Else H = 1 Else Reset Dig1_sec If Podskaz_flag_sec = 0 Then H = Razryad_2.1 Toggle H Else H = 0 End If End If End Select '
Start Timer0 Return ' Look: ' подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму Z = Chislo(w) * 7 : Z = Y + Z ' определяем порядковый номер числа из таблици DATA. W - это цифра которую будем выводить 1..2..3, Y это номер сегмента (A=0 B=1 C=2...G=7) If Indicator = 0 Then Z = Lookup(z , Cifri_oa) ' выбираем из таблици включить или выключить нужный сегмент -OA Else Z = Lookup(z , Cifri_ok) '-OK End If Incr Y 'Y это номер сегмента (A=0 B=1 C=2...). Chislo(w) * 7 - переход на начало нужной строки Data.Z = Y + Z - по очереди перебираем сегменты в строке. Return ' Cifri_oa: ' таблица сегментом для индикаторов с общим плюсом |Chislo(i)| Символ | Data 0 , 0 , 0 , 0 , 0 , 0 , 1 '0 Data 1 , 0 , 0 , 1 , 1 , 1 , 1 '1 Data 0 , 0 , 1 , 0 , 0 , 1 , 0 '2 Data 0 , 0 , 0 , 0 , 1 , 1 , 0 '3 Data 1 , 0 , 0 , 1 , 1 , 0 , 0 '4 Data 0 , 1 , 0 , 0 , 1 , 0 , 0 '5 Data 0 , 1 , 0 , 0 , 0 , 0 , 0 '6 Data 0 , 0 , 0 , 1 , 1 , 1 , 1 '7 Data 0 , 0 , 0 , 0 , 0 , 0 , 0 '8 Data 0 , 0 , 0 , 0 , 1 , 0 , 0 '9 Data 1 , 1 , 1 , 1 , 1 , 1 , 0 '10 "-" Data 1 , 1 , 1 , 1 , 1 , 1 , 1 '11 "" Data 1 , 1 , 1 , 0 , 0 , 0 , 1 '12 "L" Data 1 , 1 , 0 , 1 , 0 , 1 , 0 '13 "n" Data 0 , 1 , 1 , 1 , 0 , 0 , 0 '14 "F" Data 0 , 1 , 1 , 0 , 0 , 0 , 0 '15 "E" Data 1 , 1 , 1 , 1 , 0 , 1 , 0 '16 "r"
'******************************************************************************* ' '******************************************************************************* ' Опрос кнопок Bootons: Incr X If Conv_flag = 1 And Ds_count < 254 Then Incr Ds_count If Ds_count > 160 Then Set Read_flag End If Stop Timer1 If Vibor = 0 And Booton_flag = 0 And Up = 1 And Down = 1 Then Gosub Set_mode ' Нажатие кнопки УСТ If Set_flag = 1 And Vibor = 1 Then 'Кнопки Вверх и Вниз активны только после входа в меню If Up = 0 Then Gosub Up_const If Down = 0 Then Gosub Down_const End If If Vibor = 0 And Up = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led1 If Vibor = 0 And Down = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led2
If Vibor = 1 And Up = 1 And Down = 1 Then Reset Booton_flag 'сброс флага удержания кнопки If Vibor = 1 Then Reset Booton_flag_2 Start Timer1 : Start Timer0 Return '******************************************************************************* ' ' Set_mode: Enable Interrupts : Enable Timer0 : Start Timer0
Set Set_flag ' поднимаем флаг режима настройки уставок (находимся в меню) Set Booton_flag ' поднимаем флаг удержания кнопки (пока не сбросится, в следующий пункт меню не попадаем) Count = 0 'сброс счетчика автоматического выхода из меню If On1 = Off1 Or On2 = Off2 Then Gosub Errors 'Блокировка ввода уставок. Переходим в подпрограмму индикации ошибки Incr View_menu ' следующий пункт меню If View_menu > 4 Then View_menu = 0 ' всего 4 пункта меню, 0й - основной режим
Select Case View_menu 'индикация подсказок пунктов меню Case 0 : ' --- Set Podskaz_flag Set Podskaz_flag_sec Chislo(1) = 10 Chislo(2) = 10 Chislo(3) = 10 Chislo(4) = 10 Chislo(5) = 10 Chislo(6) = 10 Reset Set_flag ' Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom Off2 , 14 ' запись уставки OFF2 в EEPROM
Case 1 : ' On1 Set Podskaz_flag 'Поднимаем флаг вывода подсказок (буквы) на 1й индикатор Chislo(3) = 1 Chislo(2) = 13 Chislo(1) = 0 Waitms 500
Case 2 : ' OF1 Set Podskaz_flag 'Поднимаем флаг вывода подсказок (буквы) на 1й индикатор Chislo(3) = 1 Chislo(2) = 14 Chislo(1) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom On1 , 0 ' запись уставки ON1 в EEPROM
Case 3 : ' On2 Set Podskaz_flag_sec 'Поднимаем флаг вывода подсказок (буквы) на 2й индикатор Chislo(6) = 2 Chislo(5) = 13 Chislo(4) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom Off1 , 5 ' запись уставки OFF1 в EEPROM
Case 4 : ' OFF2 Set Podskaz_flag_sec 'Поднимаем флаг вывода подсказок (буквы) на 2й индикатор Chislo(6) = 2 Chislo(5) = 14 Chislo(4) = 0 Waitms 500 Stop Timer1 : Stop Timer0 Writeeeprom On2 , 10 ' запись уставки ON2 в EEPROM
End Select
Reset Podskaz_flag Reset Podskaz_flag_sec Return ' Errors: Set Error_flag ' поднимаем флаг ошибки If On1 = Off1 Then Set Podskaz_flag Chislo(1) = 15 Chislo(2) = 16 'Выводим подсказку Err и мигаем на 1м индикаторе Chislo(3) = 16 Waitms 500 Chislo(1) = 11 Chislo(2) = 11 Chislo(3) = 11 Waitms 500 Chislo(1) = 15 Chislo(2) = 16 Chislo(3) = 16 Waitms 500 Chislo(1) = 11 Chislo(2) = 11 Chislo(3) = 11 Waitms 500 End If If On2 = Off2 Then Set Podskaz_flag_sec Chislo(4) = 15 Chislo(5) = 16 'Выводим подсказку Err и мигаем на 2м индикаторе Chislo(6) = 16 Waitms 500 Chislo(4) = 11 Chislo(5) = 11 Chislo(6) = 11 Waitms 500 Chislo(4) = 15 Chislo(5) = 16 Chislo(6) = 16 Waitms 500 Chislo(4) = 11 Chislo(5) = 11 Chislo(6) = 11 Waitms 500 End If Select Case View_menu ' взависимости от того, в каком пункте меню ввели неверное значение Case 0 : ' возвращаем из EEPROM предыдущие значения Case 1 : Readeeprom On1 , 0 Case 2 : Readeeprom Off1 , 5 Case 3 : Readeeprom On2 , 10 Case 4 : Readeeprom Off2 , 14 End Select Decr View_menu ' возвращаемся в предыдущий пункт меню (в ошибочный) Count = 0 : Reset Error_flag Return ' Up_const: Enable Interrupts : Enable Timer0 : Start Timer0 Count = 0 Select Case View_menu Case 1 : If On1 < 85 Then Incr On1 ' Case 2 : ' If Off1 < 85 Then Incr Off1 Case 3 : ' If On2 < 120 Then Incr On2 ' Case 4 : ' If Off2 < 120 Then Incr Off2 End Select Waitms 30 Return ' ' Down_const: Enable Interrupts : Enable Timer0 : Start Timer0 Count = 0 Select Case View_menu Case 1 : If On1 > 0 Then Decr On1 ' добавляется второе условие при работе с отрицательными числами Case 2 : If Off1 > 0 Then Decr Off1 Case 3 : If On2 > 0 Then Decr On2 Case 4 : If Off2 > 0 Then Decr Off2 End Select Waitms 30 Return ' ' Set_h_led1: Set Booton_flag_2 Rotate Razryad_1 , Left Stop Timer1 : Stop Timer0 Writeeeprom Razryad_1 , 16 Return ' ' Set_h_led2: Set Booton_flag_2 Rotate Razryad_2 , Left Stop Timer1 : Stop Timer0 Writeeeprom Razryad_2 , 17 Return