Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Готовые конструкции » Фотореле. Сумеречный выключатель


Фотореле. Сумеречный выключатель

Сообщений 61 страница 90 из 108

61

Вариант прошивки для измерения температуры (оба канала). Диапазон показаний от -99 до 400.

Код:
'* Filename    : Универсальный 2х-канальный индикатор                          *
'* Revision    : 5.0                                                           *
'* Controller  : ATMEGA8                                                       *
'* Compiler    : BASCOM-AVR 2.0.6.1                                            *
'* Author      : MACTEPOK                                                      *
'*******************************************************************************
$regfile = "m8def.dat"                                      'определяем контроллер
$crystal = 8000000                                          'внутренний генератор
'$sim
$lib "mcsbyte.lbx"                                          'подключаем библиотеку функций

Config Pinc.0 = Input : Portc.0 = 1                         'кнопка УСТ
Config Pinc.1 = Input : Portc.1 = 1                         'кнопка Вверх
Config Pinc.2 = Input : Portc.2 = 1                         'кнопка Вниз

Config Portd = Output : Config Portb = Output               'порты на выход к которым подключен индикатор

Load1 Alias Portb.3                                         'нагрузка №1
Load2 Alias Portb.4                                         'нагрузка №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 , _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                                      'пункт меню
Dim Set_flag As Bit                                         'флаг режима настройки уставок
Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit           'флаги режима отображения подсказок на соответствующих каналах
Dim Default As Eram Byte At &H14                            'переменная EEPROM для записи начальных уставок для первого включения прибора


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го индикатора

For X = 1 To 6                                              ' присваиваем всем цифрам пустоту, чтоб в момент включения не высвечивались нули
Chislo(x) = 11
Next
'*********** ___ Переключение типа индикаторов (ОК/ОА) ___ *********************
   Readeeprom Indicator , 26
   If Pinc.0 = 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 Pinc.0 = 1 Then Exit For
         Waitms 10
      Next
   End If
'*******************************************************************************
If Default = 255 Then                                       'при первом запуске, когда Default=255
   Off1 = 100                                               'присваиваем начальный уставки
   On1 = 80
   Off2 = 120
   On2 = 90
   Indicator = &B00000000                                   ' для ОА. Indicator = &B00001000 для ОК
   Razryad_1 = &B11101110
   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 = 8 : 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                                                ' начало преобразования

Do
   If X > 40 Then                                           ' увеличили период опроса АЦП, чтобы значения не прыгали ======
      Stop Timer0 : Stop Timer1                             ' на время преобразования останавливаем таймеры
      Channel_1 = Getadc(5)                                 'опрос АЦП (диапазон от 0 до 1023) (1 канал)
'      Channel_1 = 1023 - Channel_1                          'инвертирование раскомментировать===========

'______ Для отрицательных температур (от -99 до 400) ___________________________
      Channel_1 = Channel_1 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      Channel_1 = Channel_1 - 100                           ' (диапазон от -99 до 400)
'_______________________________________________________________________________
'
      If Channel_1 > 400 Then Channel_1 = 400               'верхний предел показаний
      If Channel_1 < -99 Then Channel_1 = -99               'нижний предел показаний
      Channel_2 = Getadc(4)                                 'опрос АЦП (2 канал)
'______ Для отрицательных температур (от -99 до 400) ___________________________
      Channel_2 = Channel_2 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      Channel_2 = Channel_2 - 100                           ' (диапазон от -99 до 400)
'_______________________________________________________________________________
'
      If Channel_2 > 400 Then Channel_2 = 400               'верхний предел показаний
      If Channel_2 < -99 Then Channel_2 = -99               'нижний предел показаний
   X = 0                                                    '
   End If
   Start Timer0 : Start Timer1
   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м каналом нагрузки

Loop

'*******************************************************************************
' Индикация

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 = Abs(_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 _print < 0 Then Chislo(1) = 10                  'если значение отрицательное, устанавливаем в 1 разряде "-"

'      If Copy_print < 100 Then Chislo(1) = 11               'если  переменная < 100, то устанавливаем в 1м разряде пустоту ==верхний индикатор
'      If Copy_print < 10 Then Chislo(2) = 11                ' если  переменная < 10, то устанавливаем в 2м разряде пустоту=====================
   End If
   If Podskaz_flag_sec = 0 Then                             'если не выводим на 2й индикатор подсказки, то работаем с числами
      Copy_print_sec = Abs(_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            ' отсекаем последнюю цифру от числа _print_sec (123/10=12)
         Next
         If _print_sec < 0 Then Chislo(4) = 10              'если значение отрицательное, устанавливаем в 1 разряде "-"
 '      If _print_sec < 100 Then Chislo(4) = 11          'если  переменная < 100, то устанавливаем в 1м разряде пустоту  нижний индикатор
'      If _print_sec < 10 Then Chislo(5) = 11           ' если  переменная < 10, то устанавливаем в 2м разряде пустоту ====== Dig4,5,6
   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 = 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 = 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 = 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"

'*******************************************************************************
Cifri_ok:
' таблица сегментом для индикаторов с общим минусом      |Chislo(i)| Символ |
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9
Data 0 , 0 , 0 , 0 , 0 , 0 , 1                              '10           "-"
Data 0 , 0 , 0 , 0 , 0 , 0 , 0                              '11           "" пусто
Data 0 , 0 , 0 , 1 , 1 , 1 , 0                              '12           "L"
Data 0 , 0 , 1 , 0 , 1 , 0 , 1                              '13           "n"
Data 1 , 0 , 0 , 0 , 1 , 1 , 1                              '14           "F"
Data 1 , 0 , 0 , 1 , 1 , 1 , 1                              '15           "E"
Data 0 , 0 , 0 , 0 , 1 , 0 , 1                              '16           "r"

'*******************************************************************************
'
'*******************************************************************************
' Опрос кнопок
Bootons:
   Incr X
   Stop Timer1
      If Pinc.0 = 0 And Booton_flag = 0 And Pinc.1 = 1 And Pinc.2 = 1 Then Gosub Set_mode       ' Нажатие кнопки УСТ
      If Set_flag = 1 And Pinc.0 = 1 Then                   'Кнопки Вверх и Вниз активны только после входа в меню
         If Pinc.1 = 0 Then Gosub Up_const
         If Pinc.2 = 0 Then Gosub Down_const
      End If
      If Pinc.0 = 0 And Pinc.1 = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led1
      If Pinc.0 = 0 And Pinc.2 = 0 And View_menu = 0 And Booton_flag_2 = 0 Then Gosub Set_h_led2

      If Pinc.0 = 1 And Pinc.1 = 1 And Pinc.2 = 1 Then Reset Booton_flag       'сброс флага удержания кнопки
      If Pinc.0 = 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 < 400 Or On1 >= -99 Then Incr On1        ' добавляется второе условие при работе с отрицательными числами
      Case 2 :                                              ' в действительности отрицательные числа записваются в коде после значения 32768, поэтому в условии непонятные знаки равенства
            If Off1 < 400 Or Off1 >= -99 Then Incr Off1
      Case 3 :                                              '0      400                  32768                   65446  65535
            If On2 < 400 Or On2 >= -99 Then Incr On2        '------'----------------------'------------------------'---->
      Case 4 :                                              '0      400                32768/-32767               -99     -1
            If Off2 < 400 Or Off2 >= -99 Then Incr Off2
   End Select
   Waitms 15
Return
'
'
Down_const:
   Enable Interrupts : Enable Timer0 : Start Timer0
   Count = 0
   Select Case View_menu
      Case 1 :
            If On1 <= 400 Or On1 > -99 Then Decr On1        ' добавляется второе условие при работе с отрицательными числами
      Case 2 :
            If Off1 <= 400 Or Off1 > -99 Then Decr Off1
      Case 3 :
            If On1 <= 400 Or On2 > -99 Then Decr On2
      Case 4 :
            If Off2 <= 400 Or Off2 > -99 Then Decr Off2
   End Select
   Waitms 15
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

+2

62

Вау получилось! Проверил пока в протеусе ,вижу что цифровые показания как и предполагалось изменяются в правильном порядке , уставка также работает и в отриц. диапазоне!
Теперь на днях проведу практические испытания ( будем задействовать морозильную камеру в холодильнике :)) отпишусь....
В новой прошивке смотрю, если используем минусовые показания в каком либо канале то незначащие нули не гасятся,
нет на функциональности это не сказывается, просто привык что  в других схемах лишний нуль не виден....

Отредактировано Coviraylhik (2011-07-27 17:20:42)

0

63

Это уже дело вкуса  :D  Там на все случаи жизни скоро будут строки. Там только раскомментить надо

0

64

Попробовал новую прошивку на практике, в качестве датчика простой диод 1n4148.
Результат положительный!
Теперь мои выводы: сначала о хорошем, с программой порядок отрабатывает все как положено с -50 до 450.
Используется примитивный датчик диод,
Схемное решение позволяет выводить отрицательное значение температуры, использовав только положительное питания ( отриц. напряж. не требуется).
Диод  гораздо быстрее реагирует на изменение температуры, (сравниваю с датчиком на DS18 b20 термостат Attiny2313 на видео он внизу)
Теперь недостатки: сложноватая настройка
нет в измеряемой температуре линейности, которая наблюдалась в отстроенной мной ранее схеме с диапазоном положительных температур от 0 до + 100.
Тем не менее, для устройств автоматики, эта схема годится даже очень, взяв во внимание её дешевизну и скорость инерции датчика диода, показания стабильны.
Небольшое видео (могло быть и поменьше пришлось ждать пока датчик 1820 "догонит" °С :) ).... : показания датчика 1n4148 на верхнем индикаторе, сравнивается с термостатом на датчике DS18b20 Attiny2313  третий нижний индикатор.

Процесс таков: датчики находятся в морозильной камере -26 °С, потом датчики помещаются в воду только что вскипевшего чайника…..
Процесс так сказать ясен..... :mybb:
Схема использованная в эксперименте,

увеличить

Отредактировано Coviraylhik (2011-07-28 23:27:43)

0

65

Пользователи на сайте все-таки настаивают на использовании LCD и  датчика 18b20. С одной стороны это уже новый проект и будет дороже, однако можно добавить функционала: увеличить число каналов АЦП и нагрузок, поддержка нескольких 18b20 и еще что нибудь придумать по ходу. По поводу старого проекта, уже не зню, что можно добавить.

Отредактировано MACTEPok (2011-08-01 12:00:01)

0

66

Дисплей от нокии в нашем городе 150 ре, и то довольно дефицитная вещь  :dontknow:  2х строчечные LCD порядка 300 ре. Чем уж богаты...

0

67

Если использовать LCD то  хорошо, бы те, которые есть гарантия всегда приобрести, от нокии конечно может и подешевле и графика ..... но у нас тоже напряг, полностью телефон купить это всегда пожалуйста :)

0

68

Вот ещё по последней прошивке возможна схема вольтамперметра для автомобиля, схема может, питаясь от однополярного питания выводить на дисплей отрицательные показания!!!
http://c2.at.ua/3m/S_V_A/-A/12V-9.940.0A.jpg
Проект в протеус.
Первый канал вольтметр ничего в  нем особенного, поэтому речь здесь не о нем.
А вот второй канал амперметр от +40.0 до -9.9А схема подобной пока не наблюдал на просторах интернета (шучу, есть на датчиках  тока типа  Allegro, но когда узнаете цену, то согласитесь со мной что датчик из проволоки гораздо интереснее (разница в цене 1500 раз!!!))
И так по порядку сначала о хорошем, в данном виде как есть в протеусе, схема работает правильно и отображаемые значения ампер соответствуют.
Но для автомобиля расположение шунта не стандартно (если использовать  схему там, где нет стартерного пуска, это вариант работоспособной схемы, только на практике нужно подключать генератор на корпус, а аккумулятор на шунт (в протеусе 1-я  схема наоборот….))
Так значит о чём я, кто может помочь с построением схемы аналоговой части, примерно по такой схеме, то есть шунт в стандартном подключении.
http://c2.at.ua/3m/S_V_A/-A/12V-9.940.0Ai.jpg
В данном варианте схема  действует (2-й вариант) но, как то не так…

Отредактировано Coviraylhik (2011-08-02 02:54:02)

0

69

MACTEPok
привет , а можно ли сделать прошивку для измерения бортового напряжения в авто 0-5 - 0-15в и по второму каналу 0-5 - 0-50в , дело в том что у меня есть схема емкостного уровня топлива , а у него на выходе линейно изменяемое напряжение от 0 до 5 вольт и объем бака 0- 50 литров , просто все подобные схемы в сети редко есть до 50 в при входе ацп 0-5 , да и не хочется вешать еще один мк на индикацию уровня

0

70

gif-65
Без проблем. Я так понимаю, первый канал сделать предел 150, с учетом точки во втором разряде напряжение будет измеряться от 0.0 до 15.0 В. На второй наверно так же от 0.0 до 50.0 л. Выставлять необходимые уставки для световой индикации низкого уровня топлива и напряжения.
Рассмотрю ваши пожелания :) В пн могу уже выложить

0

71

MACTEPok
привет , спасибо что откликнулся , да все правильно , именно такое мне и надо , напряжение и объем с десятками , с уровнями тоже правильно , но может для напряжения можно еще и уставку высокого уровня - это тоже необходимый параметр , ну это конечно если не в напряг .
может кого из автомобилистов тоже  заинтересует  - вот ссылка на разработку емкостного измерителя уровня топлива http://zaz.kiev.ua/forum/viewtopic.php? … 58c85ed7ff можно ставить на любой бак , в смысле разного объема , датчик настраивается по 0 и максимуму .

Отредактировано gif-65 (2011-08-05 19:39:34)

0

72

gif-65   для для измерения бортового напряжения в авто от 0 до 50 вольт и емкостного уровня топлива должна подойти эта 0-5V_0-500
Ограничение измерения до 15 вольт будет в корне неправильно, потому что в случае неисправности генератора( а иногда и нормальный зарядный ток в зимнее время до 16V  это норма) вы не увидите реальных показаний , а от 0 до 50 вольт ничем не мешает и ни к чему не обязывает а делает вольтметр только универсальней.

Отредактировано Coviraylhik (2011-08-06 11:36:23)

0

73

Эксперимент с диодом в качестве датчика температуры от -50°С до 450°С , с программой от МАСТЕРка в проверенном мной диапазоне от -28°С до +100°С увенчался успехом! Правильность показаний сравнивал термостатом у которого датчик DS18B20/

Датчик диод по прежнему показывает измеряемую температуру резвее...:)
Вот правильная схема подключения диода

увеличить

0

74

Coviraylhik
привет ,зарядный  ток и 16 в , это как понять ? в борт сети должно быть 14,2 вольта - 14,4 максимально допустимое напряжение , и то при нем будешь менять акб каждый год и ежемесячно воду доливать , так что лично мне 15 вольт в принципе   достаточно чтобы увидеть неисправность в реле регуляторе , а выше мне  вроде как и не надо . по твоей ссылке это два канала по 0-5  500 , то есть можно каждый настроить на то что нужно .

Отредактировано gif-65 (2011-08-07 17:53:31)

0

75

Coviraylhik

отрицательные температуры финал.
убраны незначимые нули при индикации положительных температур;
убраны незначимые нули при индикации отрицательных температур, знак минус смещается на второй разряд при индикации однозначного числа;

Код:
'* Filename    : Универсальный 2х-канальный индикатор                          *
'* Revision    : 5.0                                                           *
'* Controller  : ATMEGA8                                                       *
'* Compiler    : BASCOM-AVR 2.0.6.1                                            *
'* Author      : MACTEPOK                                                      *
'*******************************************************************************
$regfile = "m8def.dat"                                      'определяем контроллер
$crystal = 8000000                                          'внутренний генератор
'$sim
$lib "mcsbyte.lbx"                                          'подключаем библиотеку функций

Config Pinc.0 = Input : Portc.0 = 1                         'кнопка Выбор
Config Pinc.1 = Input : Portc.1 = 1                         'кнопка Вверх
Config Pinc.2 = Input : Portc.2 = 1                         'кнопка Вниз

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                                      'пункт меню
Dim Set_flag As Bit                                         'флаг режима настройки уставок
Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit           'флаги режима отображения подсказок на соответствующих каналах
Dim Default As Eram Byte At &H14                            'переменная EEPROM для записи начальных уставок для первого включения прибора


'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го индикатора

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 = 100                                               'присваиваем начальный уставки
   On1 = 80
   Off2 = 120
   On2 = 90
   Indicator = &B00000000                                   ' для ОА. Indicator = &B00001000 для ОК
   Razryad_1 = &B11101110
   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 = 8 : 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                                                ' начало преобразования

Do
   If X > 40 Then                                           ' увеличили период опроса АЦП, чтобы значения не прыгали ======
      Stop Timer0 : Stop Timer1                             ' на время преобразования останавливаем таймеры
      Channel_1 = Getadc(5)                                 'опрос АЦП (диапазон от 0 до 1023) (1 канал)
'      Channel_1 = 1023 - Channel_1                          'инвертирование раскомментировать===========

'______ Для отрицательных температур (от -99 до 400) ___________________________
      Channel_1 = Channel_1 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      Channel_1 = Channel_1 - 100                           ' (диапазон от -99 до 400)
'_______________________________________________________________________________
'
      If Channel_1 > 400 Then Channel_1 = 400               'верхний предел показаний
      If Channel_1 < -99 Then Channel_1 = -99               'нижний предел показаний
      Channel_2 = Getadc(4)                                 'опрос АЦП (2 канал)
'______ Для отрицательных температур (от -99 до 400) ___________________________
      Channel_2 = Channel_2 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      Channel_2 = Channel_2 - 100                           ' (диапазон от -99 до 400)
'_______________________________________________________________________________
'
      If Channel_2 > 400 Then Channel_2 = 400               'верхний предел показаний
      If Channel_2 < -99 Then Channel_2 = -99               'нижний предел показаний
   X = 0                                                    '
   End If
   Start Timer0 : Start Timer1
   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м каналом нагрузки

Loop

'*******************************************************************************
' Индикация

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 = Abs(_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 _print < 0 Then                                    'если значение отрицательное, устанавливаем  "-" в нужном разряде
         If Copy_var >= 10 Then Chislo(1) = 10 Else Chislo(1) = 11       'для 2х значного числа
         If Copy_var < 10 Then Chislo(2) = 10               'для однозначного числа
      Else                                                  'если значение положительное, убираем незначимые нули
         If Copy_var < 100 Then Chislo(1) = 11              'для 2х значного числа
         If Copy_var < 10 Then Chislo(2) = 11               'для однозначного числа
      End If
   End If
   If Podskaz_flag_sec = 0 Then                             'если не выводим на 2й индикатор подсказки, то работаем с числами
      Copy_print_sec = Abs(_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 _print_sec < 0 Then                                'если значение отрицательное, устанавливаем  "-" в нужном разряде
         If Copy_var >= 10 Then Chislo(4) = 10 Else Chislo(4) = 11       'для 2х значного числа
         If Copy_var < 10 Then Chislo(5) = 10               'для однозначного числа
      Else                                                  'если значение положительное, убираем незначимые нули
         If Copy_var < 100 Then Chislo(4) = 11              'для 2х значного числа
         If Copy_var < 10 Then Chislo(5) = 11               'для однозначного числа
      End If
   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 = 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 = 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 = 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"

'*******************************************************************************
Cifri_ok:
' таблица сегментом для индикаторов с общим минусом      |Chislo(i)| Символ |
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9
Data 0 , 0 , 0 , 0 , 0 , 0 , 1                              '10           "-"
Data 0 , 0 , 0 , 0 , 0 , 0 , 0                              '11           "" пусто
Data 0 , 0 , 0 , 1 , 1 , 1 , 0                              '12           "L"
Data 0 , 0 , 1 , 0 , 1 , 0 , 1                              '13           "n"
Data 1 , 0 , 0 , 0 , 1 , 1 , 1                              '14           "F"
Data 1 , 0 , 0 , 1 , 1 , 1 , 1                              '15           "E"
Data 0 , 0 , 0 , 0 , 1 , 0 , 1                              '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 < 400 Or On1 >= -99 Then Incr On1        ' добавляется второе условие при работе с отрицательными числами
      Case 2 :                                              ' в действительности отрицательные числа записваются в коде после значения 32768, поэтому в условии непонятные знаки равенства
            If Off1 < 400 Or Off1 >= -99 Then Incr Off1
      Case 3 :                                              '0      400                  32768                   65446  65535
            If On2 < 400 Or On2 >= -99 Then Incr On2        '------'----------------------'------------------------'---->
      Case 4 :                                              '0      400                32768/-32767               -99     -1
            If Off2 < 400 Or Off2 >= -99 Then Incr Off2
   End Select
   Waitms 15
Return
'
'
Down_const:
   Enable Interrupts : Enable Timer0 : Start Timer0
   Count = 0
   Select Case View_menu
      Case 1 :
            If On1 <= 400 Or On1 > -99 Then Decr On1        ' добавляется второе условие при работе с отрицательными числами
      Case 2 :
            If Off1 <= 400 Or Off1 > -99 Then Decr Off1
      Case 3 :
            If On1 <= 400 Or On2 > -99 Then Decr On2
      Case 4 :
            If Off2 <= 400 Or Off2 > -99 Then Decr Off2
   End Select
   Waitms 15
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

+1

76

gif-65
Первый канал - вольтметр. Показания от 0 до 15.0
Второй канал - датчик уровня. Показания от 0 до 50.0
Установлены точки во втором разряде.

Код:
'* Filename    : Универсальный 2х-канальный индикатор                          *
'* Revision    : 5.0                                                           *
'* Controller  : ATMEGA8                                                       *
'* Compiler    : BASCOM-AVR 2.0.6.1                                            *
'* Author      : MACTEPOK                                                      *
'*******************************************************************************
$regfile = "m8def.dat"                                      'определяем контроллер
$crystal = 8000000                                          'внутренний генератор
'$sim
$lib "mcsbyte.lbx"                                          'подключаем библиотеку функций

Config Pinc.0 = Input : Portc.0 = 1                         'кнопка Выбор
Config Pinc.1 = Input : Portc.1 = 1                         'кнопка Вверх
Config Pinc.2 = Input : Portc.2 = 1                         'кнопка Вниз

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                                      'пункт меню
Dim Set_flag As Bit                                         'флаг режима настройки уставок
Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit           'флаги режима отображения подсказок на соответствующих каналах
Dim Default As Eram Byte At &H14                            'переменная EEPROM для записи начальных уставок для первого включения прибора


'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го индикатора

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 = 120                                               'присваиваем начальный уставки
   On1 = 110
   Off2 = 60
   On2 = 50
   Indicator = &B00000000                                   ' для ОА. 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 = 8 : 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                                                ' начало преобразования

Do
   If X > 40 Then                                           ' увеличили период опроса АЦП, чтобы значения не прыгали ======
      Stop Timer0 : Stop Timer1                             ' на время преобразования останавливаем таймеры
      Channel_1 = Getadc(5)                                 ' Вольтметр                                'опрос АЦП (диапазон от 0 до 1023) (1 канал)
'      Channel_1 = 1023 - Channel_1                          'инвертирование раскомментировать===========
      Channel_1 = Channel_1 / 68.2                          'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      If Channel_1 > 150 Then Channel_1 = 150               'верхний предел показаний
      Channel_2 = Getadc(4)                                 ' Датчик уровня                               'опрос АЦП (2 канал)
      Channel_2 = Channel_2 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      If Channel_2 > 500 Then Channel_2 = 500               'верхний предел показаний
   X = 0                                                    '
   End If
   Start Timer0 : Start Timer1
   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м каналом нагрузки

Loop

'*******************************************************************************
' Индикация

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 = 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 = 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 = 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"

'*******************************************************************************
Cifri_ok:
' таблица сегментом для индикаторов с общим минусом      |Chislo(i)| Символ |
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9
Data 0 , 0 , 0 , 0 , 0 , 0 , 1                              '10           "-"
Data 0 , 0 , 0 , 0 , 0 , 0 , 0                              '11           "" пусто
Data 0 , 0 , 0 , 1 , 1 , 1 , 0                              '12           "L"
Data 0 , 0 , 1 , 0 , 1 , 0 , 1                              '13           "n"
Data 1 , 0 , 0 , 0 , 1 , 1 , 1                              '14           "F"
Data 1 , 0 , 0 , 1 , 1 , 1 , 1                              '15           "E"
Data 0 , 0 , 0 , 0 , 1 , 0 , 1                              '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 < 150 Then Incr On1                      '
      Case 2 :                                              '
            If Off1 < 150 Then Incr Off1
      Case 3 :                                              '
            If On2 < 500 Then Incr On2                      '
      Case 4 :                                              '
            If Off2 < 500 Then Incr Off2
   End Select
   Waitms 15
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 On1 > 0 Then Decr On2
      Case 4 :
            If Off2 > 0 Then Decr Off2
   End Select
   Waitms 15
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

0

77

MACTEPok
привет , а готовую  прошивку можно ?

0

78

Файл 15_50

0

79

MACTEPok
спасибо , думаю завтра уже запрограммирую .

0

80

MACTEPok
привет запрограммировал прошивкой 15 50  , до 15 вольт показывает без десятых , 50 показывает с десятыми ,
перепрошил 0-5 0-500 , все заработало так как надо .
http://i016.radikal.ru/1108/b2/1c697c47822et.jpg
это то что получилось в итоге .

Отредактировано gif-65 (2011-08-12 23:11:57)

0

81

gif-65 Пардон. Не углядел, в прошивке в формуле запятую не в том месте поставил. Hex выложу во вторник.

0

82

gif-65

Исправленная прошивка 15_50

0

83

MACTEPok
спасибо , а можно сделать чтобы  аварийные уровни напряжения  12 в и 15 в зажигали светодиод .

Отредактировано gif-65 (2011-08-17 20:15:08)

0

84

Так это ж можно задать кнопками управления самостоятельно. Нажатием кнопки "Выбор” происходит выбор уставок порога срабатывания каждого канала нагрузки. Кнопками "+” и "-” изменение значения уставок.

0

85

Сколько в бортовой сети нормальное напряжение во время работы? Например 13.5v. Устанавливаем уставки On1 = 13.7, Of1 = 13.5. При напряжении  13,7v, светодиод этого канала загорится. Потухнет только при достижении значения 13,5 или ниже

0

86

MACTEPok
привет , это понятно , а если мне надо контролировать 15в и 12, 5 одновременно , при достижении одного из этих уровней надо выдать сигнал об аварии - зажечь светодиод  , такое возможно ? в бортовой сети нормальным считается напряжение 13,8 -14,2в все что ниже и выше это аварийные режимы , просто ломает еще к двум мк - тини 15 и меге8 лепить два компаратора чтобы контролировать аварийные уровни напряжения .

1 верхний порог- при напряжении больше уст. 14,5 - включить светодиод - при напряжении 14,4 в - выключить
2 нижний порог -при напряжении ниже  уст. 13в - включить светодиод - при 13в - выключить .

Отредактировано gif-65 (2011-08-18 21:12:51)

0

87

Уважаемый! Соберите себе вот такую хрень: http://avr.inf.ua/avto volt.html

0

88

FDoich
если бы мне нужен был просто индикатор напряжения , я бы его собрал и без мк , тем  более тини 13 -25 сейчас купить практически невозможно , во всяком случае у нас .

0

89

Чтобы сильно не исправлять прошиву, изменил условия сравнения уставок на первом канале  :dontcare:

Код:
'* Filename    : Универсальный 2х-канальный индикатор                          *
'* Revision    : 5.0                                                           *
'* Controller  : ATMEGA8                                                       *
'* Compiler    : BASCOM-AVR 2.0.6.1                                            *
'* Author      : MACTEPOK                                                      *
'*******************************************************************************
$regfile = "m8def.dat"                                      'определяем контроллер
$crystal = 8000000                                          'внутренний генератор
'$sim
$lib "mcsbyte.lbx"                                          'подключаем библиотеку функций

Config Pinc.0 = Input : Portc.0 = 1                         'кнопка Выбор
Config Pinc.1 = Input : Portc.1 = 1                         'кнопка Вверх
Config Pinc.2 = Input : Portc.2 = 1                         'кнопка Вниз

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                                      'пункт меню
Dim Set_flag As Bit                                         'флаг режима настройки уставок
Dim Podskaz_flag As Bit , Podskaz_flag_sec As Bit           'флаги режима отображения подсказок на соответствующих каналах
Dim Default As Eram Byte At &H14                            'переменная EEPROM для записи начальных уставок для первого включения прибора


'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го индикатора

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 = 120                                               'присваиваем начальный уставки
   On1 = 110
   Off2 = 60
   On2 = 50
   Indicator = &B00000000                                   ' для ОА. 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 = 8 : 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                                                ' начало преобразования

Do
   If X > 40 Then                                           ' увеличили период опроса АЦП, чтобы значения не прыгали ======
      Stop Timer0 : Stop Timer1                             ' на время преобразования останавливаем таймеры
      Channel_1 = Getadc(5)                                 ' Вольтметр                                'опрос АЦП (диапазон от 0 до 1023) (1 канал)
'      Channel_1 = 1023 - Channel_1                          'инвертирование раскомментировать===========
      Channel_1 = Channel_1 / 6.82                          'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      If Channel_1 > 150 Then Channel_1 = 150               'верхний предел показаний
      Channel_2 = Getadc(4)                                 ' Датчик уровня                               'опрос АЦП (2 канал)
      Channel_2 = Channel_2 / 2.046                         'пересчет тут любая формула для требуемого диапазона или необходимой характеристики ==============
      If Channel_2 > 500 Then Channel_2 = 500               'верхний предел показаний
   X = 0                                                    '
   End If
   Start Timer0 : Start Timer1

      If Channel_1 <= On1 Or Channel_1 >= Off1 Then Sostoyanie = 1 Else Sostoyanie = 0       'если значение первого канала АЦП ниже уставки ON1, то включаем нагрузку №1

   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м каналом нагрузки

Loop

'*******************************************************************************
' Индикация

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 = 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 = 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 = 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"

'*******************************************************************************
Cifri_ok:
' таблица сегментом для индикаторов с общим минусом      |Chislo(i)| Символ |
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9
Data 0 , 0 , 0 , 0 , 0 , 0 , 1                              '10           "-"
Data 0 , 0 , 0 , 0 , 0 , 0 , 0                              '11           "" пусто
Data 0 , 0 , 0 , 1 , 1 , 1 , 0                              '12           "L"
Data 0 , 0 , 1 , 0 , 1 , 0 , 1                              '13           "n"
Data 1 , 0 , 0 , 0 , 1 , 1 , 1                              '14           "F"
Data 1 , 0 , 0 , 1 , 1 , 1 , 1                              '15           "E"
Data 0 , 0 , 0 , 0 , 1 , 0 , 1                              '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 < 150 Then Incr On1                      '
      Case 2 :                                              '
            If Off1 < 150 Then Incr Off1
      Case 3 :                                              '
            If On2 < 500 Then Incr On2                      '
      Case 4 :                                              '
            If Off2 < 500 Then Incr Off2
   End Select
   Waitms 15
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 On1 > 0 Then Decr On2
      Case 4 :
            If Off2 > 0 Then Decr Off2
   End Select
   Waitms 15
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

Отредактировано MACTEPok (2011-08-19 16:56:16)

+1

90

Ну и дела  :| , программа похоже проста как велосипед, любой каприз. :cool:

0


Вы здесь » Программирование ATMEL в BASCOM. » Готовые конструкции » Фотореле. Сумеречный выключатель