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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » ! Исследование 7-seg LED индикации !


! Исследование 7-seg LED индикации !

Сообщений 1 страница 15 из 15

1

Разные варианты вывода на 7-seg индикаторы в среде компилятора Bascom

Архивы по ссылкам  перезалиты  на яндекс диск  17.12.2014

0

2

8 разрядов 7-seg LED, через 3 ножки контроллера

2 индикатора по 4 разряда, 2х74HC595  = 3 ножки контроллера.

http://s4.uploads.ru/t/nutHQ.jpghttp://s4.uploads.ru/t/HSylY.jpg
http://s4.uploads.ru/t/uw4A2.jpghttp://s5.uploads.ru/t/PwiBT.jpg

Исходник

'*******************************************************************************
'*************                                                       ***********
'*************       Динамическая индикация на основе сдвиговых      ***********
'*************                регистров 74HC595                      ***********
'*************     (задействовано всего 3 вывода микроконтроллера)   ***********
'*************                                                       ***********
'*******************************************************************************

' Контроллер: ATMEGA8A или любой другой "AVR" с небольшими переделками исходника
' Версия компилятора: BASCOM-AVR 2.0.7.1
' Автор: sasha_1973

'*******************************************************************************
'-------------------------------------------------------------------------------
'---------------     Конфигурация используемого контроллера     ----------------
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 8000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-----------------     Определение переменных и констант     -------------------
'-------------------------------------------------------------------------------
Начальные_настройки:       ' Просто метка, для удобства
'-------------------------------------------------------------------------------

  Dim Тип_индикатора As Byte       ' Переменная, для хранения значения типа индикатора
  Тип_индикатора = 0       ' Если тип_индикатора = 1 , то ОК , если Тип_индикатора = 0 , То ОA

'---------------------------------------------

  Const Делитель_timer2 = 64
  Const Количество_разрядов = 8       ' Количество используемых разрядов

'---------------------------------------------

  Const Частота_мигания = 200       ' Значение частоты мигания знакоместа на LED дисплее при Флаг_мигание(n) = 1
  Const Длительность_горения_при_мигании = 100       ' Значение длительности свечения знакоместа на LED дисплее при Флаг_мигание(n) = 1

'---------------------------------------------

  Const Минимальная_яркость_led = 1       ' Уровень минимального значения яркости (в регитре OCR2)
  Const Максимальная_яркость_led = 255       ' Уровень максимального значения яркости (в регитре OCR2)
  Const Скорость_изменения_яркости_led = 5       ' Значение скорости изменения яркости LED индикации

'---------------------------------------------

  Const Значение_переменной = 50
  Const Скорость_изменения_переменной = 100       ' Переменная, для хранения значения задержки "Waitms"

'-------------------------------------------------------------------------------

  Dim Цикл_led As Byte       ' переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды)
  Dim Код_цифры As Byte       ' переменная для загрузки в регистры сдвига
  Dim Флаг_stop As Byte       ' если Флаг_stop = 1, перезагружаем МК
  Dim Цикл_записи As Byte       ' переменная, для записи в 74HC595
  Dim Буфер_led_1 As Word       ' переменная, для 1-го индикатора
  Dim Буфер_led_2 As Word       ' переменная, для 2-го индикатора
  Dim Яркость_led As Byte       ' переменная, для регулировки яркости LED дисплея
  Dim Флаг_яркость As Byte       ' флаг для регулировки яркости LED дисплея
  Dim Счетчик_миганий As Word       ' счетчик для обработки частоты и длительности мигания
  Dim Счетчик_мигания As Word       ' счетчик времени мигания
  Dim Счетчик_разрядов As Byte       ' переменная, для перебирания разрядов
  Dim Переменная_word_1 As Word       ' переменная, которую будем выводить
  Dim Переменная_word_2 As Word       ' переменная, которую будем выводить
  Dim Счетчик_яркость_led As Byte       ' переменная, для изменения яркости
  Dim Выводимая_цифра_led As Byte       ' переменная, для загрузки цифр в порт
  Dim Выводимые_данные_led As Word       ' переменная, для хранения выводимых данных
  Dim Копия_выводимые_данные_led As Word       ' переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды)
  Dim Цифра(количество_разрядов) As Byte       ' значения 6-ти разрядов
  Dim Разряд(количество_разрядов) As Byte       ' переменная для работы с индикацией
  Dim Флаг_точка(количество_разрядов) As Byte       ' флаги точек 6-ти разрядов
  Dim Флаг_мигание(количество_разрядов) As Byte       ' флаги мигания разрядов
  Dim Флаг_гашение(количество_разрядов) As Byte       ' флаги гашения нужного разряда для 4-х разрядов
  Dim Дополнительный_символ(количество_разрядов) As Byte       ' переменная, для хранения значения дополнительного символа при Флаг_дополнительный_символ(n) = 1
  Dim Флаг_дополнительный_символ(количество_разрядов) As Byte       ' флаг сигнализирующий о выводе дополнительных символов

'-------------------------------------------------------------------------------
'---------------     Настройка портов МК для LED индикации     -----------------
'-------------------------------------------------------------------------------

  Config Portd.7 = Output       ' вывод SH_CP регистра (тактовые импульсы)
  Синхроимпульсы Alias Portd.7

  Config Portb.0 = Output       ' вывод DS регистра (данные)
  Данные Alias Portb.0

  Config Portd.6 = Output       ' вывод ST_CP регистра(защелка)
  Защелка Alias Portd.6

'-------------------------------------------------------------------------------
'-----------     Подпрограмма выполняемая после прерывания TIMER2     ----------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'------------     Настройка таймера для обновления LED индикации     -----------
'-------------------------------------------------------------------------------

  Config Timer2 = Timer , Prescale = Делитель_timer2       ' конфигурируем таймер индикации

'-------------------------------------------------------------------------------
'-----------     Подпрограмма выполняемая после прерывания TIMER2     ----------
'-------------------------------------------------------------------------------

  On Compare2 Регулировка_яркости_led       ' Прерывание регулировки яркости индикатора
  On Timer2 Обработка_прерывания_timer2       ' метка на прерывание индикации

'-------------------------------------------------------------------------------

  Declare Sub Запись_в_74hc595()
  Declare Sub Регулировка_яркости_led()
  Declare Sub Индикация_7seg_led()
  Declare Sub Обработка_прерывания_timer2()

'-------------------------------------------------------------------------------
'------------------------     Работа с прерываниями     ------------------------
'-------------------------------------------------------------------------------

  Enable Timer2       ' и для индикации в частности

  Enable Compare2

  Enable Interrupts       ' разрешаем прерывания

'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Переменная_word_1 = Значение_переменной
  Wait 2
'-------------------------------------------------------------------------------
  Do : Nop
'-------------------------------------------------------------------------------


    If Флаг_stop = 0 Then

        Decr Переменная_word_1

        If Переменная_word_1 = 0 Then       'Переменная_word_1 = Значение_переменной

            Флаг_stop = 1
            Переменная_word_1 = Значение_переменной

            Флаг_точка(1) = 1
'            Флаг_точка(2) = 1
            Флаг_точка(3) = 1
'            Флаг_точка(4) = 1
            Флаг_точка(5) = 1
'            Флаг_точка(6) = 1
            Флаг_точка(7) = 1
'            Флаг_точка(8) = 1

            Флаг_мигание(1) = 1
            Флаг_мигание(2) = 1
            Флаг_мигание(3) = 1
            Флаг_мигание(4) = 1
            Флаг_мигание(5) = 1
            Флаг_мигание(6) = 1
            Флаг_мигание(7) = 1
            Флаг_мигание(8) = 1

'            Флаг_гашение(1) = 1
'            Флаг_гашение(2) = 1
'            Флаг_гашение(3) = 1
'            Флаг_гашение(4) = 1
'            Флаг_гашение(5) = 1
'            Флаг_гашение(6) = 1
'            Флаг_гашение(5) = 1
'            Флаг_гашение(6) = 1

            Флаг_дополнительный_символ(1) = 1 : Дополнительный_символ(1) = 10
            Флаг_дополнительный_символ(2) = 1 : Дополнительный_символ(2) = 11
            Флаг_дополнительный_символ(3) = 1 : Дополнительный_символ(3) = 12
            Флаг_дополнительный_символ(4) = 1 : Дополнительный_символ(4) = 10

            Флаг_дополнительный_символ(5) = 1 : Дополнительный_символ(5) = 12
            Флаг_дополнительный_символ(6) = 1 : Дополнительный_символ(6) = 10
            Флаг_дополнительный_символ(7) = 1 : Дополнительный_символ(7) = 15
            Флаг_дополнительный_символ(8) = 1 : Дополнительный_символ(8) = 14

           Wait 2
           Config Watchdog = 2048
           Start Watchdog
           Wait 2

        End If

        Буфер_led_1 = Переменная_word_1

        Incr Переменная_word_2

        If Переменная_word_2 > 9999 Then Переменная_word_2 = 0

        Буфер_led_2 = Переменная_word_2

    End If

'-------------------------------------------------------------------------------
    Waitms Скорость_изменения_переменной
'-------------------------------------------------------------------------------
  Loop
End
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************** Подпрограмма обработки прерывания TIMER0 ****************
'***************** происходит каждые 2,048 ms ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_прерывания_timer2:
'-------------------------------------------------------------------------------
    rCall Индикация_7seg_led
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Индикация_7seg_led:
'-------------------------------------------------------------------------------
'---   Занимаемся регулировкой яркости LED индикации (написано для примера, в железе, маловероятно, что будет использоваться именно этот вариант)  ---
'-------------------------------------------------------------------------------
    Incr Счетчик_яркость_led
    If Счетчик_яркость_led = Скорость_изменения_яркости_led Then
        Счетчик_яркость_led = 0
        If Флаг_яркость = 0 Then Incr Яркость_led Else Decr Яркость_led
        If Яркость_led = Максимальная_яркость_led Then Флаг_яркость = 1
        If Яркость_led = Минимальная_яркость_led Then Флаг_яркость = 0
    End If
'-------------------------------------------------------------------------------
'--------------   Устанавливаем уровень яркости LED индикации    ---------------
'-------------------------------------------------------------------------------
    Ocr2 = Яркость_led
'-------------------------------------------------------------------------------
'------   В цикле разбиваем сформированый "Буфер_led_string" на разряды   ------
'-------------------------------------------------------------------------------

    Выводимые_данные_led = Буфер_led_1

    Копия_выводимые_данные_led = Выводимые_данные_led

    For Цикл_led = 4 To 1 Step -1       ' цикл в котором разбивается переменная на 4 числа
        Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
        Цифра(цикл_led) = Выводимые_данные_led       '
        Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10
    Next

    Выводимые_данные_led = Буфер_led_2

    Копия_выводимые_данные_led = Выводимые_данные_led

    For Цикл_led = 8 To 5 Step -1       ' цикл в котором разбивается переменная на 4 числа
        Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
        Цифра(цикл_led) = Выводимые_данные_led       '
        Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10
    Next

'-------------------------------------------------------------------------------
'----   Перебираем разряды, в каждом прерывании выводим следующий разряд   -----
'-------------------------------------------------------------------------------
'-----   Выбираем разряд для загрузки в обработчик вывода на 7-seg LED     -----
'-------------------------------------------------------------------------------
    Incr Счетчик_разрядов

    If Счетчик_разрядов > Количество_разрядов Then Счетчик_разрядов = 0       ' выбираем разряд для загрузки
'-------------------------------------------------------------------------------
' Участок кода отвечающий за мигание разрядов, вывод точки и дополнительных символов
'-------------------------------------------------------------------------------
'----------------------------   Подготовка к миганию  --------------------------
'-------------------------------------------------------------------------------
    Incr Счетчик_мигания

    If Счетчик_мигания > Частота_мигания Then Счетчик_мигания = 1       ' длительность мигания
'-------------------------------------------------------------------------------
'-----------------------   Выводим дополнительные симвоы   ---------------------
'-------------------------------------------------------------------------------
        If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then

            Select Case Счетчик_разрядов
              Case 1 To 4
                If Тип_индикатора = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                End If
              Case 5 To 8
                If Тип_индикатора = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                End If
            End Select
'-------------------------------------------------------------------------------
'----------------------   Иначе выводим основные данные   ----------------------
'-------------------------------------------------------------------------------
          Else
'-------------------------------------------------------------------------------
'-------   Если не мигаем и ничего другого не выводим, выводим основное   ------
'-------------------------------------------------------------------------------
            Выводимая_цифра_led = Цифра(счетчик_разрядов)

              Select Case Счетчик_разрядов
                Case 1 To 4
                  If Тип_индикатора = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                  End If
                Case 5 To 8
                  If Тип_индикатора = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                  End If
              End Select

        End If
'-------------------------------------------------------------------------------
'-------------   Если необходимо, выводим точку в нужном разряде   -------------
'-------------------------------------------------------------------------------
      If Флаг_точка(счетчик_разрядов) = 1 Then
              Выводимая_цифра_led = Выводимая_цифра_led Xor &B00000001
      End If
'-------------------------------------------------------------------------------
' Выходим из "Участок кода отвечающий за мигание разрядов, вывод точки и дополнительных символов"
'-------------------------------------------------------------------------------
'    End If
'-------------------------------------------------------------------------------
'---------------------     Загружаем в порт код цифры   ------------------------
'-------------------------------------------------------------------------------
    rcall Запись_в_74hc595
'-------------------------------------------------------------------------------
'----------------     Готовимся к загрузке в порт кода разряда   ----------------
'-------------------------------------------------------------------------------
    If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_мигания > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then       ' если флаг мигания выставлен и счетчик > 200
        If Тип_индикатора = 1 Then Выводимая_цифра_led = Lookup(16 , Разряды_ok)       ' забираем в переменную код цифры
      Else       ' иначе (флаг не выставлен, либо счетчик < 200)
        If Тип_индикатора = 1 Then
            Выводимая_цифра_led = Lookup(счетчик_разрядов , Разряды_ok)       ' забираем в переменную код цифры
          Else
            Выводимая_цифра_led = Lookup(счетчик_разрядов , Разряды_oa)       ' забираем в переменную код цифры
        End If
    End If
'-------------------------------------------------------------------------------
'---------------------     Загружаем в порт код разряда   ----------------------
'-------------------------------------------------------------------------------
    rcall Запись_в_74hc595
'-------------------------------------------------------------------------------
'-----------------   Непосредственный вывод на LED индикатор   -----------------
'-------------------------------------------------------------------------------
      Защелка = 1
'      Waitus 5
      Защелка = 0
'-------------------------------------------------------------------------------
'---------------------   Возвращаемся туда, где прервались   -------------------
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Запись_в_74hc595:
'-------------------------------------------------------------------------------
   For Цикл_записи = 0 To 7       ' цикл для записи байта данных в регистр
     If Выводимая_цифра_led.7 = 0 Then Данные = 0 Else Данные = 1       
         Синхроимпульсы = 1       ' подаем импульс на вход тактовых импульсов для сдвига регистра (запись в регистр)
'         Waitus 5
         Синхроимпульсы = 0
         Shift Выводимая_цифра_led , Left , 1       ' сдвигаем все биты переменной влево на один бит
   Next Цикл_записи

   Данные = 0
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Регулировка_яркости_led:
'-------------------------------------------------------------------------------
    If Тип_индикатора = 1 Then
        Выводимая_цифра_led = Lookup(0 , Разряды_ok)       ' забираем в переменную код цифры
      Else
        Выводимая_цифра_led = Lookup(0 , Разряды_oa)       ' забираем в переменную код цифры
    End If
'-------------------------------------------------------------------------------
'---------------------     Загружаем в порт код разряда   ----------------------
'-------------------------------------------------------------------------------
    rcall Запись_в_74hc595
'-------------------------------------------------------------------------------
'-----------------   Непосредственный вывод на LED индикатор   -----------------
'-------------------------------------------------------------------------------
  Непосредсвенный_вывод_на_led:
'-------------------------------------------------------------------------------
      Защелка = 1
'      Waitus 5
      Защелка = 0
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Цифры_oa:
'-------------------------------------------------------------------------------
    Data &H81       ' 0
    Data &HF3       ' 1
    Data &H49       ' 2
    Data &H61       ' 3
    Data &H33       ' 4
    Data &H25       ' 5
    Data &H05       ' 6
    Data &HF1       ' 7
    Data &H01       ' 8
    Data &H21       ' 9
'------------------------------
    Data &H0F       ' t  -  10
    Data &H0D       ' E  -  11
    Data &H25       ' S  -  12
    Data &H81       ' O  -  13
    Data &H19       ' P  -  14
    Data &H47       ' o  -  15
    Data &HFF       ' Пусто  -  16
'-------------------------------------------------------------------------------
  Цифры_ok:
'-------------------------------------------------------------------------------
    Data &H7E       ' 0  -  0
    Data &H0C       ' 1  -  1
    Data &HB6       ' 2  -  2
    Data &H9E       ' 3  -  3
    Data &HCC       ' 4  -  4
    Data &HDA       ' 5  -  5
    Data &HFA       ' 6  -  6
    Data &H0E       ' 7  -  7
    Data &HFE       ' 8  -  8
    Data &HDE       ' 9  -  9
'------------------------------
    Data &HF0       ' t  -  10
    Data &HF2       ' E  -  11
    Data &HDA       ' S  -  12
    Data &H7E       ' O  -  13
    Data &HE6       ' P  -  14
    Data &HB8       ' o  -  15
    Data &H00       ' Пусто  -  16

'-------------------------------------------------------------------------------
  Разряды_oa:
'-------------------------------------------------------------------------------
    Data &B00000000       ' Не светится
    Data &B00000001       ' 1
    Data &B00000010       ' 2
    Data &B00000100       ' 3
    Data &B00001000       ' 4
    Data &B00010000       ' 5
    Data &B00100000       ' 6
    Data &B01000000       ' 7
    Data &B10000000       ' 8
'-------------------------------------------------------------------------------
  Разряды_ok:       ' разряды
'-------------------------------------------------------------------------------
    Data &B11111111       ' Не светится
    Data &B11111110       ' 1
    Data &B11111101       ' 2
    Data &B11111011       ' 3
    Data &B11110111       ' 4
    Data &B11101111       ' 5
    Data &B11011111       ' 6
    Data &B10111111       ' 7
    Data &B01111111       ' 8
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

Схема, исходник, прошивка, эмуляция - скачать      перезалито 17.12.2014

0

3

Статическая (n) разрядов 7-seg LED, через 3 ножки контроллера

Статическая индикация на 74HC595 и 7-seg Led индикаторах.

Плюсы:
Яркость
Практически не потребляет ресурсов МК
Отсутствуют всевозможные засветки индикаторов
Большое число разрядов, ограничено только частотой МК

Минус - 1 разряд = 1 регистр 74HC595

Огромный минус - большое потребление

Исходник. Написан пользователем этого форума под ником "МАСТЕРок"

'* Filename    : SPI индикатор                                                 *
'* Revision    : 1.0                                                           *
'* Controller  : ATMEGA8                                                       *
'* Compiler    : BASCOM-AVR 2.0.7.1                                            *
'* Author      : MACTEPOK                                                      *
'*******************************************************************************

$regfile = "m8def.dat"       'определяем контроллер
$crystal = 1000000  'внутренний генератор
'$sim
'$lib "mcsbyte.lbx"                                          'подключаем библиотеку функций
$hwstack = 40
$swstack = 16
$framesize = 32

Config Portb = Output

Ds Alias Portb.2    ' шина данных
St_cp Alias Portb.1 ' защелка регистров
Sh_cp Alias Portb.0 ' сдвиг

'-------------------------------------------------------------------------------
Declare Sub Zapis   ' процедура записи даных в регистр
Declare Sub Destroy ' процедура разделения переменных на разряды
'-------------------------------------------------------------------------------
'*******************************************************************************

Dim Out_word(4) As Word       ' массив выводимых на индикаторы переменных
Dim N As Byte
Dim Chislo(16) As Byte       ' массив с разрядами выводимых чисел
Dim Text_message(16) As Byte       ' массив с разрядами выводимого текста
Dim Blink_count As Byte       ' период морганий значний на индикаторах
Dim Blinkcount_flag As Bit       ' флаг морганий значний на индикаторах---------------------------------числа:   1    2    3    4
Dim Point_flag As Word       'массив битов, хранения флагов точек.    Для всех разрядов выводимых чисел: &B 0000 0000 0000 0000                                       '
Dim Blink_flag As Word       'массив битов, хранения флагов моргания. Для всех разрядов выводимых чисел: &B 0000 0000 0000 0000
Dim Text_flag As Word       'массив битов, хранения флагов вывода текста на индикаторы
Dim Invblink_flag As Bit       ' промежуточная переменная типа Bit
Dim Indicator_type As Byte       ' тип индикатора (ОА = 0; ОК <> 0)

Const Blinker = 3   ' ~ 1 сек период моргания значний на индикаторах
'DEMO
Dim Blinker_count As Byte       ' счетчики
Dim Point_count As Byte
Const Shifter1 = 50 ' период смены мигания в разрядах
Const Shifter2 = 10 ' период смены точки  в разрядах
                                      '
Out_word(1) = 111
Out_word(2) = 2222
Out_word(3) = 3333
Out_word(4) = 4444

Point_flag = &B0000000000000001       ' точка в краейне правом разряде
Blink_flag = &B1000000000000000       ' мигает крайний левый разряд
Text_flag = &B1000010000100001       ' выводим текст в указанных разрядах индикаторов
For N = 1 To 16
   Text_message(n) = 11       ' тут записываем в массив необходимую текстовую инфу
Next

Config Timer0 = Timer , Prescale = 256 : On Timer0 Timers       ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts : Enable Timer0 : Start Timer0       ' разрешаем прерывания
Do
   For N = 1 To 4   ' здесь происходит изменение переменных
      Incr Out_word(n)
      If Out_word(n) > 9999 Then Out_word(n) = 0
   Next
   Call Destroy
   Call Zapis       ' за раз отправляем в регистр все 16 разрядов
   Waitms 50
Loop

'
'-------------------------------------------------------------------------------
Sub Destroy         ' содержание функции разделения переменных на разряды
   Local I As Byte
   Local M As Byte
   Local K As Byte  ' счетчик элементов массива
   Local L As Byte  ' счетчик цикла (считаем число переменных для вывода на индикаторы)
   Local Cod_var As Byte       ' промежуточная переменная типа Byte
   Local Copy_print As Integer       ' промежуточная переменная типа Integer
   K = 0            ' обнуляем
   M = 0
   For L = 4 To 1 Step -1       ' для каждой переменной
      Copy_print = Out_word(l)       ' копируем в промежуточную переменную
      For I = 4 To 1 Step -1       ' в регистры будем записывать всего 4х4 = 16 чисел (разрядов)
         Incr K
         Cod_var = Copy_print Mod 10       ' отделяем от переменных крайний правый разряд (остаток от деления на 10)
         If Text_flag.m = 1 Then       ' если в данном разряде текст, то записываем номер символа
            Chislo(k) = Text_message(k)       ' записываем в массив для дальнейшей передачи в сдвиговые регистры
         Else       ' иначе
            Chislo(k) = Cod_var       ' записываем в массив номер числа
         End If
         Incr M
         Copy_print = Copy_print / 10
      Next
   Next
End Sub
'
'-------------------------------------------------------------------------------
Sub Zapis           ' содержание функции записи в регистр
   Local I As Byte
   Local K As Byte  ' счетчик элементов массива
   Local L As Byte  ' счетчик цикла (считаем число переменных для вывода на индикаторы)
   Local Cod_var As Byte       ' промежуточная переменная типа Byte

   For L = 16 To 1 Step -1
      K = L         ' переменная для определения индекса битов в переменной Point_flag
      Decr K
      Cod_var = Lookup(chislo(l) , Cody)       ' извлекаем код числа для индикации
      If Indicator_type = 0 Then       ' если индикаторы с ОА
         Invblink_flag = Point_flag.k       ' компируем текущий бит в промежуточную переменную
         Toggle Invblink_flag       ' инвертируем
         If Text_flag.k = 0 Then Cod_var.5 = Invblink_flag       ' записываем этот бит на знакоместо сегмента h
         If Blink_flag.k = 1 And Blinkcount_flag = 1 Then Cod_var = &B11111111       ' здесь очищаем разряд, если мигаем
      Else
         If Blink_flag.k = 1 And Blinkcount_flag = 1 Then Cod_var = &B00000000       ' здесь очищаем разряд, если мигаем
         If Text_flag.k = 0 Then Cod_var.5 = Point_flag.k       ' записываем этот бит на знакоместо сегмента h
      End If
      For I = 0 To 7       ' цикл для записи байта данных в регистр
         If Cod_var.7 = 0 Then Ds = 0 Else Ds = 1       ' если седьмой (последний) бит переменной равен 0, то отправляем 0 на ввод данных. (для индикатора с ОА. Для индикатора с ОК изменить условие не противоположное, таблицу данных не трогать!)
         Sh_cp = 1  ' подаем импульс на вход тактовых импульсов для сдвига регистра (запись в регистр)
         Sh_cp = 0
         Shift Cod_var , Left , 1       ' сдвигаем все биты переменной влево на один бит
      Next
      Ds = 0
   Next
   St_cp = 1        ' защелкиваем регистры
   St_cp = 0
End Sub
'
' прерывание от Timer0
'-------------------------------------------------------------------------------
Timers:
   Incr Blink_count ' увеличиваем счетчик
   If Blink_count = Blinker Then       ' когда равен периоду
      Toggle Blinkcount_flag       ' меняем состояние флага моргания
      Blink_count = 0       ' обнуляем
   End If
'DEMO
   Incr Blinker_count : Incr Point_count
   If Blinker_count = Shifter1 Then       ' тут отсчитываем период смены индикатора с морганием
      Shift Blink_flag , Right , 1
      Blinker_count = 0
   End If
   If Point_count = Shifter2 Then       ' тут отсчитываем период смены индикатора  с точкой
      Shift Point_flag , Left , 1
      Point_count = 0
   End If
Return
'-------------------------------------------------------------------------------
' Таблица данных
'-------------------------------------------------------------------------------
Cody:               ' ОA     &B dehc abfg
Data &B00100001     '0 - "0"      a
Data &B11101011     '1 - "1"     --
Data &B00110010     '2 - "2"   f|  |b
Data &B01100010     '3 - "3"    | g|
Data &B11101000     '4 - "4"     --
Data &B01100100     '5 - "5"   e|  |c
Data &B00100100     '6 - "6"    |  |
Data &B11100011     '7 - "7"     -- h
Data &B00100000     '8 - "8"      d
Data &B01100000     '9 - "9"
Data &B11111111     '10 - "пусто"
' текст:
Data &B10110100     '11 - "F"
'и т.д.

http://s4.uploads.ru/t/mGgfi.jpg

http://s5.uploads.ru/t/BAz3K.jpg

http://s4.uploads.ru/t/9ZOzi.jpg

Платки под индикаторы приобретались здесь

Исходник + эмуляция в "Протеус" - скачать    перезалито 17.12.2014

0

4

Посегментная 8-х разрядная LED индикация Atmega8A

Именно посегментная, т.е. в единицу времени светится 1 сегмент.

Исходник написан с непосредсвенным участием коллеги из Нижнего Новгорода под ником "MACTEPok".

Atmega8A, 8 Мгц (внутренний генератор), Prescale = 1, 8 разрядов, посегментная индикация, при 3 V потребление 10 mA, частота вывода на весь 1 разряд(8 сегментов) = 73 Гц. При выводе 4-х разрядов, частоту МК можно уменьшить.

Полный исходник с ОК, кому надо можно переделать ОА. Все прокоментировано.

'*******************************************************************************
'* Revision    : 1.0                                                           *
'* Controller  : ATMEGA8A                                                      *
'* Compiler    : BASCOM-AVR 2.0.7.1                                            *
'* Author      : sasha_1973@mail.ru                                            *
'*******************************************************************************************************
'-------------------------------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 8000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32
'-------------------------------------------------------------------------------------------------------
'*******************************************************************************************************
'-------------------------------------------------------------------------------
  $lib "mcsbyte.lbx"
  $lib "mcsbyteint.lib"
  $lib "ds1307clock.lib"
'-------------------------------------------------------------------------------
'**************************************************************************************************************************************************************************************************
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Config Adc = Single , Prescaler = Auto , Reference = Avcc       ' Prescaler может быть 2,4,8,16,32,64 или Auto, в случае Auto компилятор выбирает подходящую частоту работы АЦП.
'  Config Adc = Free , Prescaler = 32 , Reference = Avcc      ' Источник опорного напряжения Reference может быть: Aref – внешний источник, Avcc – напряжение питания схемы и Internal – внутренний
'  Режимы считывания: Single - единичное считывание, результаты заносятся в ADCL, ADCH; Free – постоянное считывание, результаты заносятся в ADCL, ADCH, но происходит всё автономно
'  Enable Adc                                      ' Разрешаем работу АЦП
'---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'***************************************************************************************************************************************************************************************************
'-------------------------------------------------------------------------------
  Config Timer2 = Timer , Prescale = 1 , Clear Timer = 0       ' конфигурируем таймер индикации    PRESCALE= 1|8|64|256|1024
  On Compare2 Регулировка_яркости_led       ' прерывание регулировки яркости индикатора
  On Timer2 Индикация_7seg_led       ' ' метка на прерывание индикации
'-------------------------------------------------------------------------------
'*******************************************************************************
'************    Окончательная настройка портов для LED индикации    ***********
'*******************************************************************************
'-------------------------------------------------------------------------------
  Ddrc = &B0000000 : Ddrd = &B11111111 : Ddrb = &B11111111
'-------------------------------------------------------------------------------
  Пищалка Alias Portd.7 : Точка_led Alias Portd.6
'-------------------------------------------------------------------------------
  A Alias Portb.0 : B Alias Portb.1 : C Alias Portb.2 : D Alias Portb.3 : E Alias Portb.4 : F Alias Portb.5 : G Alias Portb.6 : H Alias Portb.7       'порты, к которым подключены сегменты индикаторов
  Разряд_1 Alias Portd.0 : Разряд_2 Alias Portd.1 : Разряд_3 Alias Portd.2 : Разряд_4 Alias Portd.3 : Разряд_5 Alias Portd.4 : Разряд_6 Alias Portd.5 : Разряд_7 Alias Portd.6 : Разряд_8 Alias Portd.7       '  порты, к которым подключены общие выводы индикаторов
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************    Определение переменных и констант    *******************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Dim Сегмент As Byte
  Dim Цикл_led As Byte       ' переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды)
  Dim Разряд(8) As Byte       ' значения разрядов для 4-х разрядов
  Dim Яркость_led As Byte       ' переменная, для регулировки яркости LED
  Dim Копия_разряд As Byte       ' переменная, для временного хранения выводимого разряда
  Dim Флаг_точка(8) As Byte       ' флаги точек для 4-х разрядов
  Dim Флаг_гашение(8) As Byte       ' флаги гашения нужного разряда для 4-х разрядов
  Dim Флаг_мигание(8) As Byte       ' флаги мигания нужного разряда для 4-х разрядов
  Dim Счетчик_миганий As Word       ' счетчик для обработки частоты и длительности мигания
  Dim Частота_мигания As Word       ' переменная, для хранения значения частоты мигания при  Флаг_мигание(n) = 1
  Dim Счетчик_разрядов As Byte       ' счетчик перебора разрядов
  Dim Флаг_стоп_таймер_1 As Bit       ' флаг сигнализирующий об окончании счета таймера
  Dim Флаг_сменить_разряд As Bit       ' флаг сигнализирующий о необходимости сменить разряд
  Dim Выводимая_цифра_led As Byte       ' переменная, для загрузки цифр в порт
  Dim Выводимые_данные_led As Word       ' переменная, для хранения выводимых данных
  Dim Дополнительный_символ(8) As Byte       ' переменная, для хранения значения дополнительного символа при  Флаг_дополнительный_символ(n) = 1
  Dim Копия_выводимые_данные_led As Word       ' переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды)
  Dim Флаг_дополнительный_символ(8) As Byte       ' флаг сигнализирующий о выводе дополнительных символов
  Dim Длительность_горения_при_мигании As Word       ' переменная, для хранения значения длительности горения знакоместа при Флаг_мигание(n) = 1
'-------------------------------------------------------------------------------
'*******************************************************************************
'************************    Определение подпрограмм    ************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Declare Sub Регулировка_яркости_led()
'-------------------------------------------------------------------------------
'*******************************************************************************
'***********************    Первоначальные установки    ************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Яркость_led = 50 : Ocr2 = Яркость_led       ' значение яркости в регистре сравнения
  Частота_мигания = 800       ' значение частоты мигания знакоместа на LED дисплее при
  Длительность_горения_при_мигании = 400       ' значение длительности горения знакоместа на LED дисплее
'-------------------------------------------------------------------------------

  Выводимые_данные_led = 10       ' значение выводимое на LED дисплее

'-------------------------------------------------------------------------------
'*******************************************************************************
'*************************    Работа с прерываниями    *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Enable Interrupts       ' Разрешаем работу прерываний
'  Enable Compare2a                                ' Разрешаем работу прерывания по СОВПАДЕНИЮ
  Enable Timer2       ' Разрешаем работу прерывания по ПЕРЕПОЛНЕНИЮ
'  Enable Int1                                     ' Разрешаем работу прерывания INT1 (секундные импульсы с Ds1307)
'  Enable Adc                                      ' Разрешаем работу АЦП
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************************    Начало программы    ****************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Do : Nop       ' крутимся здесь, ожидая прерывание
'--------------------------
    If Выводимые_данные_led < 1 Then

       Выводимые_данные_led = 0

       Флаг_мигание(1) = 1       ' включено мигание 1 знакоместа
       Флаг_мигание(2) = 0
       Флаг_мигание(3) = 1       ' включено мигание 3 знакоместа
       Флаг_мигание(4) = 0
       Флаг_мигание(5) = 1       ' включено мигание 5 знакоместа
       Флаг_мигание(6) = 0
       Флаг_мигание(7) = 1       ' включено мигание 7 знакоместа
       Флаг_мигание(8) = 0

       Флаг_точка(1) = 0
       Флаг_точка(2) = 1       ' включена точка 2 знакоместа
       Флаг_точка(3) = 0
       Флаг_точка(4) = 1       ' включена точка 4 знакоместа
       Флаг_точка(5) = 0
       Флаг_точка(6) = 1       ' включена точка 6 знакоместа
       Флаг_точка(7) = 0
       Флаг_точка(8) = 1       ' включена точка 8 знакоместа

       Флаг_гашение(1) = 0
       Флаг_гашение(2) = 1       ' включено гашение 2 знакоместа
       Флаг_гашение(3) = 0
       Флаг_гашение(4) = 0
       Флаг_гашение(5) = 0
       Флаг_гашение(6) = 0
       Флаг_гашение(7) = 1       ' включено гашение 7 знакоместа
       Флаг_гашение(8) = 0

       Флаг_дополнительный_символ(1) = 1 : Дополнительный_символ(1) = 23       ' выводим дополнительный символ "Е"
       Флаг_дополнительный_символ(2) = 1 : Дополнительный_символ(2) = 30       ' выводим дополнительный символ "n"
       Флаг_дополнительный_символ(3) = 1 : Дополнительный_символ(3) = 18       ' выводим дополнительный символ "d"
       Флаг_дополнительный_символ(4) = 1 : Дополнительный_символ(4) = 1       ' выводим дополнительный символ "1"
       Флаг_дополнительный_символ(5) = 1 : Дополнительный_символ(5) = 14       ' выводим дополнительный символ "t"
       Флаг_дополнительный_символ(6) = 1 : Дополнительный_символ(6) = 23       ' выводим дополнительный символ "Е"
       Флаг_дополнительный_символ(7) = 1 : Дополнительный_символ(7) = 5       ' выводим дополнительный символ "S"
       Флаг_дополнительный_символ(8) = 1 : Дополнительный_символ(8) = 14       ' выводим дополнительный символ "t"

      Set Флаг_стоп_таймер_1

    End If

    If Флаг_стоп_таймер_1 = 0 Then Decr Выводимые_данные_led       ': If Выводимые_данные_led > 9999 Then Выводимые_данные_led = 0

'    Incr Выводимые_данные_led

    Waitms 36       ' Приблизительная задержка 1 сек при текущих частотных и предделительных настройках
'---------------
  Loop
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                ******************************
'*****************          ПОДПРОГРАММЫ          ******************************
'*****************                                ******************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Индикация_7seg_led:       ' прерывание таймера Т2 (индикация)
'-------------------------------------------------------------------------------
    Stop Timer2
'----------------
          Копия_выводимые_данные_led = Выводимые_данные_led

          For Цикл_led = 8 To 1 Step -1       '> Цикл в котором переменная разбивается на количество требуемых разрядов, (в данном случае 4 разряда)
              Копия_разряд = Копия_выводимые_данные_led Mod 10
              Разряд(цикл_led) = Копия_разряд       '
              Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
          Next Цикл_led
'-------------------------------------------------------------------------------
'----------------------   гасим все разряды индикатора   -----------------------
'-------------------------------------------------------------------------------
    Call Регулировка_яркости_led       ' в принципе, гашение тут без надобности, индикатор и так выключается в прерывании Регулировка_яркости_led. Если же индикация работает БЕЗ регулировки яркости, то гашение ОБЯЗАТЕЛЬНО.
'-------------------------------------------------------------------------------
'----   перебираем разряды, в каждом прерывании выводим следующий разряд   -----
'-------------------------------------------------------------------------------
    If Флаг_сменить_разряд = 1 Then
        Incr Счетчик_разрядов
        If Счетчик_разрядов > 8 Then Счетчик_разрядов = 1       ' выбираем разряд для загрузки в обработчик вывода на 7-seg LED
        Reset Флаг_сменить_разряд
    End If
'-------------------------------------------------------------------------------
'--------------   участок кода отвечающий за мигание разрядов   ----------------
'-------------------------------------------------------------------------------
    Incr Счетчик_миганий : If Счетчик_миганий > Частота_мигания Then Счетчик_миганий = 1       ' длительность мигания

    If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_миганий > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then       ' если флаг мигания этого разряда выставлен и счетчик > 200
        Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' выводим пустое место
'        Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' выводим пустое место
      Else       ' иначе (флаг не выставлен, либо счетчик < 200)
        If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then
            Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' выводим дополнительный_символ
'            Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' выводим дополнительный_символ
          Else
            Выводимая_цифра_led = Разряд(счетчик_разрядов)
              Select Case Счетчик_разрядов
                Case 1 To 8
                 Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)
'                Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)
              End Select
        End If
      If Флаг_точка(счетчик_разрядов) = 1 Then       ' если необходимо, добавляем точку
          Выводимая_цифра_led = Выводимая_цифра_led Xor &H80       ' или &B10000000  добавляем к выводимой цифре точку    Цифры_ok
'          Выводимая_цифра_led = Выводимая_цифра_led Xor &H7F       ' или &B01111111  добавляем к выводимой цифре точку    Цифры_oa
      End If
    End If
'-------------------------------------------------------------------------------
'---------------------     загружаем в порт код цифры   ------------------------
'-------------------------------------------------------------------------------
    Portb = 0

    Select Case Счетчик_разрядов       ' и включаем соответствующий разряд индикатора
      Case 1 : Reset Разряд_1
      Case 2 : Reset Разряд_2
      Case 3 : Reset Разряд_3
      Case 4 : Reset Разряд_4
      Case 5 : Reset Разряд_5
      Case 6 : Reset Разряд_6
      Case 7 : Reset Разряд_7
      Case 8 : Reset Разряд_8
    End Select

    Portb.сегмент = Выводимая_цифра_led.сегмент

    Incr Сегмент
    If Сегмент > 7 Then
        Сегмент = 0
        Set Флаг_сменить_разряд
    End If

    Выход_индикация_7seg_led:
'----------------
   Start Timer2
'----------------
  Return  ' выход из обработчика прерывания
'-------------------------------------------------------------------------------
'*******************************************************************************

'        A = Выводимая_цифра_led.0                 ' Сегмент "А"
'        B = Выводимая_цифра_led.1                 ' Сегмент "B"
'        C = Выводимая_цифра_led.2                 ' Сегмент "C"
'        D = Выводимая_цифра_led.3                 ' Сегмент "D"
'        E = Выводимая_цифра_led.4                 ' Сегмент "E"
'        F = Выводимая_цифра_led.5                 ' Сегмент "F"
'        G = Выводимая_цифра_led.6                 ' Сегмент "G"
'        H = Выводимая_цифра_led.7                 ' Сегмент "Точка"

'*******************************************************************************
'-------------------------------------------------------------------------------
  Цифры_ok:       ' цифры
'-----------
    Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F       '0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    Data &H40 , &H00 , &H63 , &H39 , &H78 , &H5C , &H38 , &H74 , &H5E , &H77       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
    Data &H58 , &H31 , &H76 , &H79 , &H50 , &H71 , &H1C , &H73 , &H37 , &H80       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П". "."
    Data &H54       ', &H , &H , &H , &H , &H , &H , &H , &H , &H       '"n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
  Цифры_oa:
'-----------
    Data &HC0 , &HF9 , &HA4 , &HB0 , &H99 , &H92 , &H82 , &HF8 , &H80 , &H90       '0,1,2,3,4,5,6,7,8,9
    Data &HBF , &HFF , &H9C , &HC6 , &H87 , &HA3 , &HC7 , &H8B , &HA1 , &H88       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
    Data &HA7 , &HCE , &H89 , &H86 , &HAF , &H8E , &HE3 , &H8C , &HC8 , &H7F       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П", "."
    Data &HAB       ', &H , &H , &H , &H , &H , &H , &H , &H , &H       '"n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'-------------------------------------------------------------------------------
  Регулировка_яркости_led:       ' прерывание таймера Т0 (регулировка яркости)
'--------------------------
    Set Разряд_1 : Set Разряд_2 : Set Разряд_3 : Set Разряд_4 : Set Разряд_5 : Set Разряд_6 : Set Разряд_7 : Set Разряд_8       ' гасим индикаторы ОК
'    Reset Разряд_1 : Reset Разряд_2 : Reset Разряд_3 : Reset Разряд_4 : Reset Разряд_5 : Reset Разряд_6 : Reset Разряд_7 : Reset Разряд_8       ' гасим индикаторы ОА
'--------------------------
  Return  ' выход из обработчика прерывания
'-------------------------------------------------------------------------------
'*******************************************************************************

http://s5.uploads.ru/t/BczRI.jpg

Готовый нашёл только этот вариант, 4 разряда 7-seg led индикиции
Симуляция + исходник -  скачать      перезалито  17.12.2014

Эмуляция протеуса специально сильно замедленна, для ускорения, в настройках протеуса ( Система--> Опции анимации --> Фреймов в сек (поставить 50) --> Шагов в фрейме (поставить 25m) --> Шаг аннимации (поставить 4) --> ОK ). ,

0

5

Кнопки паралельно с разрядами 7-seg LED

Многие, рано или поздно, сталкиваются с проблемой нехватки свободных выводов МК. Ниже предлагается одно из решений проблемы.
Попутно получились часики.

Исходник

'*******************************************************************************
'*************************                             *************************
'*************************                             *************************
'*************************                             *************************
'*******************************************************************************
'* Revision    : 1.0                                                           *
'* Controller  : ATMEGA8A                                                      *
'* Compiler    : BASCOM-AVR 2.0.7.1                                            *
'* Author      : sasha_1973@mail.ru                                            *
'*******************************************************************************************************
'-------------------------------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 1000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32 : $baud = 4800       '1200     '2400     '4800     '9600     '19200     '38400     '57600     '115000
'-------------------------------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
Sim:
'  $sim
'-------------------------------------------------------------------------------
'*******************************************************************************************************
'-------------------------------------------------------------------------------
  $lib "mcsbyte.lbx"
  $lib "mcsbyteint.lib"
'-------------------------------------------------------------------------------
'**************************************************************************************************************************************************************************************************
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'  Config Adc = Single , Prescaler = Auto , Reference = Avcc       ' Prescaler может быть 2,4,8,16,32,64 или Auto, в случае Auto компилятор выбирает подходящую частоту работы АЦП.
'  Config Adc = Free , Prescaler = 32 , Reference = Avcc      ' Источник опорного напряжения Reference может быть: Aref – внешний источник, Avcc – напряжение питания схемы и Internal – внутренний
'  Режимы считывания: Single - единичное считывание, результаты заносятся в ADCL, ADCH; Free – постоянное считывание, результаты заносятся в ADCL, ADCH, но происходит всё автономно
'  Enable Adc                                      ' Разрешаем работу АЦП
'---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'***************************************************************************************************************************************************************************************************
'-------------------------------------------------------------------------------
'------------   Конфигурация TIMER0 - обработка 7-seg индикатора    ------------
'*******************************************************************************
'*************************     Конфигурация TIMER0     *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 0       ' конфигурируем таймер индикации    PRESCALE = 1|8|64|256|1024
'-------------------------------------------------------------------------------
  On Timer0 Обработка_прерывания_timer0       ' Nosave    'Подпрограмма обработка прерывания timer0
'-------------------------------------------------------------------------------
  Tcnt0 = 254       ' Делитель  1000/(1000000/1024/(256-251))= 1000/(976,5625/5)=1000/195,3125=5,12      5,12 ms
'*******************************************************************************
'*************************     Конфигурация TIMER2     *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Timer2 = Timer , Async = On , Prescale = 64       ' Делитель 32768 / 64 / 256 = 0,5 сек (прерывание TIMER2 = 2 раза в секунду)
'-------------------------------------------------------
  On Timer2 Обработка_прерывания_timer2       ' Nosave
'-------------------------------------------------------------------------------
'  Assr.3 = 1 : Wait 1                             ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды
'  При включении  бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима
' "Powersave" - разновидность спящего режима. Пробуждение от TIMER0, TIMER1
'  Mcucr = &B10000000                              ' Разрешаем режим пониженного энергопотребления  Power Idle
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'****************                                              *****************
'****************    Конфигурация семисегментных индикаторов   *****************
'****************                                              *****************
'*******************************************************************************
'-------------------------------------------------------------------------------
'-------   Назначаем переменные для сегментов (A, B, C, D, E, F, G, H)   -------
'-------------------------------------------------------------------------------
  A Alias Portb.0 : B Alias Portb.1 : C Alias Portb.2 : D Alias Portb.3 : E Alias Portb.4 : F Alias Portb.5 : G Alias Portd.6 : H Alias Portd.7       'порты, к которым подключены сегменты индикаторов
'-------------------------------------------------------------------------------
'-- Назначаем переменные для разрядов (Разряд_1, Разряд_2, Разряд_3, Разряд_4) --
'-------------------------------------------------------------------------------
  Разряд_1 Alias Portc.0 : Разряд_2 Alias Portc.1 : Разряд_3 Alias Portc.2 : Разряд_4 Alias Portc.3       ' : Разряд_5 Alias Portd.6 : Разряд_6 Alias Portd.7 : Разряд_7 Alias Portd.6 : Разряд_8 Alias Portd.7       '  порты, к которым подключены общие выводы индикаторов
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'-------------------  Определение индикаторов с ОА или ОК  ---------------------
'-------------------------------------------------------------------------------
'--------------   Заводим переменные для определения, ОА или ОК   --------------
'-------------------------------------------------------------------------------
  Dim Indicator_1 As Byte , Indicator_2 As Byte , Indicator_3 As Byte , Indicator_4 As Byte
'-------------------------------------------------------------------------------
'-------------   Ручной выбор ОА или ОК, используется для отладки   ------------
'-------------------------------------------------------------------------------
  Config Разряд_4 = Input : Config H = Output : Set H
'-------------------------------------------------------------------------------
'--   Автоматический выбор ОА или ОК, при наличии резистора ~47к, см.схему   ---
'-------------------------------------------------------------------------------
  Waitms 1
    If Pinc.3 = 1 Then       ' Смотрим уровень на Разряд_4
        Indicator_1 = 1       ' Если  Indicator_1 = 1, то ОК
        Indicator_2 = 1       ' Если  Indicator_2 = 1, то ОК
      Else
        Indicator_1 = 0       ' Иначе Indicator_1 = 0, то ОА
        Indicator_2 = 0       ' Иначе Indicator_2 = 0, то ОА
    End If
  Waitms 1
'-------------------------------------------------------------------------------
'-------------   Ручной выбор ОА или ОК, используется для отладки   ------------
'-------------------------------------------------------------------------------
'              Indicator_1 = 1 : Indicator_2 = 1 : Indicator_3 = 1
'              Indicator_1 = 0 : Indicator_2 = 0 : Indicator_3 = 0
'-------------------------------------------------------------------------------
'*******************************************************************************
'************    Окончательная настройка портов для LED индикации    ***********
'*******************************************************************************
'-------------------------------------------------------------------------------
  Ddrc = &B00001111 : Ddrd = &B11110010 : Ddrb = &B00111111
'-------------------------------------------------------------------------------
  Config Portd.4 = Output : Пищалка Alias Portd.4
  Config Portd.5 = Output : Двоеточие_led Alias Portd.5
'-------------------------------------------------------------------------------
'*******************************************************************************
'*********************    Конфигурация порта клавиатуры    *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Pind.3 = Input

  If Indicator_1 = 1 Then Set Portd.3 Else Reset Portd.3

  Клавиатура Alias Pind.3
'-------------------------------------------------------------------------------
'*******************************************************************************
'Настройка_часов:
'-----------------   Задействуем аппаратные часы контроллера   -----------------
'-------------------------------------------------------------------------------
'  Config Clock = Soft , Gosub = Sectic            ' Секундное_прерывание:
'  Config Date = Dmy , Separator = .               ' ANSI-Format    день. месяц. год
'  Date$ = "11.06.13"
'  Time$ = "21:02:00"
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************                                    ************************
'*******************         Конфигурация USART         ************************
'*******************                                    ************************
'*******************************************************************************
' RXCIE, TXCIE и UDRIE – биты, разрешающие прерывания по приему байта, окончанию передачи байта и пустом регистре UDR соответственно. Установкой их в 1 разрешаем прерывания.
' RXEN, TXEN – как я уже сказал, биты, включающие приёмник и передатчик соответственно. Установкой в 1 включаем приёмник или передатчик.
' TXC, RXC и UDRE – флаги прерываний по окончанию передачи, приёма и по опустошению регистра данных.
' U2X – если записать в этот бит 1, то скорость UART удвоится.
' UPE – флаг ошибки чётности. При ошибке он выставится в 1.

' Теперь UCSRC. Тут нас интересуют лишь биты, задающие размер одного байта – UCSZ0 и UCSZ1. Для стандартной посылки 8 бит, нужно записать в них единицы.

'  Name    Bit 7   Bit 6   Bit 5   Bit 4   Bit 3   Bit 2   Bit 1   Bit 0
'  UCSRA    RXC     TXC     UDRE    FE      DOR     PE      U2X    MPCM
'-------------------------------------------------------------------------------
'  Ucsra.1 = 1
'-------------------------------------------------------------------------------
  Config Pind.0 = Input       '> Конфигурация вывода RxD, приёмник UART
  Config Pind.1 = Output       '> Конфигурация вывода TxD, передатчик UART
'-----------------------------------------
'  On Udre Прерывание_буфер_uart_пуст              ' Переход на подпрограмму обработки прерывания после опустошения буфера передачи данных по UART
'  On Urxc Прерывание_прием_uart_закончен          ' Переход на подпрограмму обработки прерывания после окончания приёма данных по UART
'  On Utxc Прерыв_передача_uart_закончена          ' Переход на подпрограмму обработки прерывания после окончания передачи данных по UART
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'  Config Int0 = Low Level
'  On Int0 Обработка_прерывания_int0
'----------------------------------------
'  Кнопка_прерывание_int0 Alias Pind.2
'  Config Кнопка_прерывание_int0 = Input
'  Set Кнопка_прерывание_int0
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************    Определение переменных и констант    *******************
'*******************************************************************************
'-------------------------------------------------------------------------------
'--------------   Переменные для подпрограммы вывода на 7-seg LED   ------------
'-------------------------------------------------------------------------------
  Dim Цикл_led As Byte       ' переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды)
  Dim Цифра(4) As Byte       ' значения разрядов для 4-х разрядов
'                                        Dim Флаг_яркость As Bit       ' флаг для регулировки яркости LED дисплея
'                                        Dim Яркость_led As Byte       ' переменная, для регулировки яркости LED дисплея
  Dim Копия_цифра As Byte       ' переменная, для временного хранения выводимого разряда
  Dim Флаг_точка(4) As Byte       ' флаги точек для 4-х разрядов
  Dim Флаг_гашение(4) As Byte       ' флаги гашения нужного разряда для 4-х разрядов
  Dim Флаг_мигание(4) As Byte       ' флаги мигания нужного разряда для 4-х разрядов
  Dim Счетчик_миганий As Word       ' счетчик для обработки частоты и длительности мигания
  Dim Частота_мигания As Word       ' переменная, для хранения значения частоты мигания при  Флаг_мигание(n) = 1
  Dim Счетчик_разрядов As Byte       ' счетчик перебора разрядов
  Dim Выводимая_цифра_led As Byte       ' переменная, для загрузки цифр в порт
'                                        Dim Количество_разрядов As Byte       ' переменная, для хранения значения количества используемых разрядов
'                                        Dim Счетчик_яркость_led As Byte       ' переменная, для изменения яркости
  Dim Выводимые_данные_led As Byte       ' переменная, для хранения выводимых данных
  Dim Дополнительный_символ(4) As Byte       ' переменная, для хранения значения дополнительного символа при  Флаг_дополнительный_символ(n) = 1
  Dim Копия_выводимые_данные_led As Byte       ' переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды)
  Dim 1_канал_выводимые_данные_led As Byte       ' переменная, для хранения выводимых данных
  Dim 2_канал_выводимые_данные_led As Byte       ' переменная, для хранения выводимых данных
'                                        Dim 3_канал_выводимые_данные_led As Byte
  Dim Флаг_дополнительный_символ(4) As Byte       ' флаг сигнализирующий о выводе дополнительных символов
'                                        Dim Скорость_изменения_яркости_led As Byte       ' переменная, для хранения значения скорости изменения яркости LED дисплея
  Dim Длительность_горения_при_мигании As Word       ' переменная, для хранения значения длительности горения знакоместа при Флаг_мигание(n) = 1
'-------------------------------------------------------------------------------
'-----   Переменные для подпрограммы расчета времени и обработки кнопок   ------
'-------------------------------------------------------------------------------
  Dim Сон As Byte
  Dim Год As Word
  Dim Часы As Byte
  Dim Месяц As Byte
  Dim Минуты As Byte
  Dim Кнопка As Byte
  Dim Счетчик As Byte
  Dim Секунды As Byte
  Dim Число_месяца As Byte
  Dim Кнопка_нажата As Byte
  Dim Флаг_двоеточие As Byte
  Dim Счетчик_времени As Byte
  Dim Буфер_клавиатуры As Byte
  Dim Флаг_звук_включен As Byte
  Dim Флаг_есть_нажатие As Byte
  Dim Флаг_кнопка_нажата As Byte
  Dim Счетчик_нет_нажатия As Byte
  Dim Флаг_нажатие_кнопки As Byte
  Dim Флаг_горит_двоеточие As Byte
  Dim Длительность_пищалки As Byte
  Dim Флаг_показать_секунды As Byte
  Dim Счетчик_кнопка_нажата As Byte
  Dim Счетчик_времени_звонка As Byte
  Dim Флаг_произошло_нажатие As Byte
  Dim Флаг_обновить_индикатор As Byte
  Dim Время_горения_двоеточия As Byte
  Dim Счетчик_прерываний_int1 As Byte
  Dim Случайное_нажатие_кнопки As Byte
  Dim Счетчик_прерывания_timer0 As Byte
  Dim Счетчик_прерываний_timer0 As Byte
  Dim Счетчик_прерываний_timer2 As Byte
  Dim Флаг_есть_прерывание_timer0 As Byte
  Dim Флаг_есть_прерывание_timer2 As Byte
  Dim Флаг_обновить_данные_времени As Byte
  Dim Счет_времени_горения_двоеточия As Byte
  Dim Счетчик_времени_настройки_часов As Word
  Dim Счет_перем_временных_интервалов As Byte
  Dim Буфер_клавиатуры_предварительный As Byte
'-------------------------------------------------------------------------------

  Dim Первое_включение As Byte

  Dim Флаг_настраиваем_время As Byte

  Dim Пункт_настройки As Byte

  Dim Что_настраиваем As Byte

  Dim Флаг_меняем_часы As Byte

  Dim Флаг_меняем_минуты As Byte

  Dim Максимальное_значение As Byte

  Dim Минимальное_значение As Byte
'-------------------------------------------------------------------------------
'----------   Переменные для подпрограмм обработка аппаратного USART   ---------
'-------------------------------------------------------------------------------
  Dim B As Byte
  Dim Символ_из_буфера As Byte
  Dim Есть_данные_для_uart As Byte
  Dim Буфер_прием_uart As String * 20
  Dim Флаг_есть_сообщение_uart As Byte
  Dim Флаг_прием_uart_закончен As Byte
  Dim Принятое_сообщение As String * 20
  Dim Временный_буфер_uart As String * 1
  Dim Буфер_передача_uart As String * 20
  Dim Флаг_передача_uart_закончена As Byte
'-------------------------------------------------------------------------------
'*******************************************************************************
'************************    Определение подпрограмм    ************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Declare Sub Bip_bip()
  Declare Sub Del_buffer()       'очистка буфера
  Declare Sub Передача_uart()
  Declare Sub Настройка_часов()
  Declare Sub Обновить_данные()
  Declare Sub Регулировка_яркости_led()
  Declare Sub Обработка_нажатия_клавиатуры()
  Declare Sub Определение_индикаторов_оа_&_ок()
  Declare Sub Getline(временный_буфер_uart As String)       'чтение данных из буфера
'-------------------------------------------------------------------------------
'*******************************************************************************
'***********************    Первоначальные установки    ************************
'*******************************************************************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Readeeprom Первое_включение , 1 : Waitms 10

  If Первое_включение <> 50 Then
     rcall Начальные_настройки
  End If
'-------------------------------------------------------------------------------
  Readeeprom Часы , 100 : Waitms 10
  Readeeprom Минуты , 110 : Waitms 10
  Readeeprom Секунды , 120 : Waitms 10
  Readeeprom Число_месяца , 130 : Waitms 10
  Readeeprom Месяц , 140 : Waitms 10
  Readeeprom Год , 150 : Waitms 10
'-------------------------------------------------------------------------------
  Частота_мигания = 200 : Длительность_горения_при_мигании = 100       ' значение частоты мигания и длительности горения знакоместа на LED дисплее при Флаг_мигание(n) = 1
  Длительность_пищалки = 30
'-------------------------------------------------------------------------------
  Print "Секунды - " ; Секунды
  Print "Минуты - " ; Минуты
  Print "Часы - " ; Часы
  Print "Число - " ; Число_месяца
  Print "Месяц - " ; Месяц
  Print "Год - 2013"
  Print ""
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                            ******************
'****************    Разрешаем работу прерываний - Atmega8A     ****************
'*****************                                            ******************
'*******************************************************************************
'-------------------------------------------------------------------------------
'  Enable Adc
'  Enable Aci
'  Enable Urxc                                     ' Разрешаем прерывание после окончания приёма данных по UART
'  Enable Udre                                     ' Разрешаем прерывание после опустошения буфера UART
'  Enable Utxc                                     ' Разрешаем прерывание после окончания передачи по UART
'  Enable Oc1a
'  Enable Oc1b
'  Enable Int0
'  Enable Int1
  Enable Timer0
'  Enable Timer1
  Enable Timer2
'  Enable Compare2
'  Enable Compare1a
'  Enable Compare1b
'-------------------------------------------------------------------------------
'--------------------   Разрешаем работу всех прерываний   ---------------------
'-------------------------------------------------------------------------------
  Enable Interrupts
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************************    Начало программы    ****************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Do : Nop       ' крутимся здесь, ожидая прерывание
'-------------------------------------
    Главный_цикл:

    If Буфер_клавиатуры <> 0 Then
        Rcall Обработка_нажатия

        Print ""
        Print "Кнопка - " ; Кнопка
        Print ""

        Буфер_клавиатуры = 0
    End If

    If Есть_данные_для_uart = 1 Then
        Call Передача_uart
        Есть_данные_для_uart = 0
    End If

'--------------------
    Спящий_режим:
      Power Idle
'--------------------
    Goto Главный_цикл
'--------------------
  Loop
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                ******************************
'*****************          ПОДПРОГРАММЫ          ******************************
'*****************                                ******************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Настройка_времени:
'-------------------------------------------------------------------------------
    Настройка_часов:

      Флаг_настраиваем_время = 1
      Флаг_мигание(1) = 1 : Флаг_мигание(2) = 1
      Минимальное_значение = 0 : Максимальное_значение = 23

      Do

        Что_настраиваем = Часы

        If Буфер_клавиатуры <> 0 Then
            Rcall Обработка_нажатия
            Буфер_клавиатуры = 0
        End If

        Часы = Что_настраиваем

      Loop Until Флаг_настраиваем_время = 0

      Флаг_мигание(1) = 0 : Флаг_мигание(2) = 0

      Writeeeprom Часы , 100 : Waitms 10

      Goto Выход_настройка_времени

'--------------------------------------------------

    Настройка_минут:

      Флаг_настраиваем_время = 1
      Флаг_мигание(3) = 1 : Флаг_мигание(4) = 1
      Минимальное_значение = 0 : Максимальное_значение = 59

      Do

        Что_настраиваем = Минуты

        If Буфер_клавиатуры <> 0 Then
            Rcall Обработка_нажатия
            Буфер_клавиатуры = 0
        End If

        Минуты = Что_настраиваем

      Loop Until Флаг_настраиваем_время = 0

      Флаг_мигание(3) = 0 : Флаг_мигание(4) = 0

      Writeeeprom Минуты , 110 : Waitms 10

'-------------------------------------------------------------------------------
    Выход_настройка_времени:
    Goto Главный_цикл
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Сохранение_значений_ds1307:
'-------------------------------------------------------------------------------
    Disable Interrupts
'-------------------------------------------------------------------------------
'---------------------- Значения времени и даты --------------------------------
'-------------------------------------------------------------------------------
    Начальные_настройки:
'-------------------------------------------------------------------------------

      Первое_включение = 50
      Секунды = 0
      Минуты = 0
      Часы = 12
      Число_месяца = 1
      Месяц = 1
      Год = 2013

'---------------------------------------------------

      Writeeeprom Первое_включение , 1 : Waitms 10
      Writeeeprom Часы , 100 : Waitms 10
      Writeeeprom Минуты , 110 : Waitms 10
      Writeeeprom Секунды , 120 : Waitms 10
      Writeeeprom Число_месяца , 130 : Waitms 10
      Writeeeprom Месяц , 140 : Waitms 10
      Writeeeprom Год , 150 : Waitms 10

'-------------------------------------------------------------------------------
      Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 200 : Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 200 : Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 20
'-------------------------------------------------------------------------------
      Config Watchdog = 16
      Start Watchdog
      Waitms 150
'-------------------------
'    Goto Главный_цикл
'-------------------------
Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************   Подпрограмма обработки прерывания TIMER0   ****************
'*****************          происходит каждые 2,048 ms          ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_прерывания_timer0:
'-------------------------------------------------------------------------------
    Rcall Индикация_7seg_led

    Rcall Опрос_клавиатуры
'-------------------------------------------------------------------------------
' Делитель TIMER0 = 1000/(1000000/1024/(256-254))=1000/(976,5625/2) = 2,048 ms
'-------------------------------------------------------------------------------
    Tcnt0 = 254
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'********************    Подпрограмма опроса клавиатуры    *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Опрос_клавиатуры:
'-------------------------------------------------------------------------------

    If Indicator_1 = 0 Then
        If Клавиатура <> 0 Then
            Флаг_произошло_нажатие = 1
            Счетчик_нет_нажатия = 0
            Буфер_клавиатуры = Счетчик_разрядов
'            Goto Обработка_нажатия
          Else
            Incr Счетчик_нет_нажатия
            If Счетчик_нет_нажатия > 8 Then
                Счетчик_нет_нажатия = 0
                Флаг_произошло_нажатие = 0
            End If
        End If
      Else
        If Клавиатура = 0 Then
            Флаг_произошло_нажатие = 1
            Счетчик_нет_нажатия = 0
            Буфер_клавиатуры = Счетчик_разрядов
'            Goto Обработка_нажатия
          Else
            Incr Счетчик_нет_нажатия
            If Счетчик_нет_нажатия > 8 Then
                Счетчик_нет_нажатия = 0
                Флаг_произошло_нажатие = 0
            End If
        End If
     End If

    If Счетчик_нет_нажатия > 3 Then
        Буфер_клавиатуры = 0
        Счетчик_нет_нажатия = 0
        Счетчик_кнопка_нажата = 0
        Флаг_произошло_нажатие = 0
    End If

'-------------------------------------------------------------------------------
  Выход_опрос_клавиатуры:
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'********************    Подпрограмма обработки нажатия    *********************
'********************          кнопки клавиатуры           *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_нажатия:
'-------------------------------------------------------------------------------

    Incr Счетчик_кнопка_нажата

    If Счетчик_кнопка_нажата > 250 Then Счетчик_кнопка_нажата = 250

'-------------------------------------------------------------------------------

    Select Case Буфер_клавиатуры

      Case 1:
              If Счетчик_кнопка_нажата = 1 Then
                  Кнопка = 1
                  rcall Bip_Bip

                  If Флаг_настраиваем_время = 0 Then

                      If Флаг_показать_секунды = 0 Then
                          Флаг_показать_секунды = 1
                        Else
                          Флаг_показать_секунды = 0
                      End If

                    Else

                  End If

                Else
                  rcall Увеличение
                  Waitms 100
              End If

      Case 2:
              If Счетчик_кнопка_нажата = 1 Then
                  Кнопка = 2
                  rcall Bip_Bip

                  If Флаг_настраиваем_время = 0 Then
                      Флаг_настраиваем_время = 1
                      rcall Настройка_минут
                    Else
                      Флаг_настраиваем_время = 0
                  End If

                Else
              End If

      Case 3:
              If Счетчик_кнопка_нажата = 1 Then
                  Кнопка = 3
                  rcall Bip_Bip

                  If Флаг_настраиваем_время = 0 Then
                      Флаг_настраиваем_время = 1
                      rcall Настройка_часов
                    Else
                      Флаг_настраиваем_время = 0
                  End If

                Else
              End If

      Case 4:
              If Счетчик_кнопка_нажата = 1 Then
                  Кнопка = 4
                  rcall Bip_Bip

                  If Флаг_настраиваем_время = 0 Then

                      Секунды = 0

                    Else

                  End If

                Else

                  rcall Уменьшение

                  Waitms 100

              End If
      Case Else:
    End Select

'-------------------------------------------------------------------------------
  Выход_обработка_нажатия:
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
  Увеличение:
'-------------------------------------------------------------------------------
    Incr Что_настраиваем
    If Что_настраиваем > Максимальное_значение Then Что_настраиваем = Минимальное_значение
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
  Уменьшение:
'-------------------------------------------------------------------------------
    Decr Что_настраиваем
    If Что_настраиваем < Минимальное_значение Or Что_настраиваем = 255 Then Что_настраиваем = Максимальное_значение
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Bip_bip:
'-------------------------------------------------------------------------------
    Set Пищалка
    Waitms Длительность_пищалки
    Reset Пищалка
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'****************   Подпрограмма обработки прерывания TIMER2   *****************
'****************          происходит 2 раза в секунду         *****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_прерывания_timer2:
'-------------------------------------------------------------------------------
    Incr Счетчик_прерываний_timer2

    If Счетчик_прерываний_timer2 > 1 Then
        Счетчик_прерываний_timer2 = 0
        Флаг_обновить_данные_времени = 1
        rcall Обновить_данные_времени
    End If
'-------------------------------------------------------------------------------
'----------------   Каждые 0,5 сек. зажигаем двоеточие   -----------------------
'-------------------------------------------------------------------------------
    If Флаг_горит_двоеточие = 0 Then
        Флаг_горит_двоеточие = 1
      Else
        Флаг_горит_двоеточие = 0
    End If
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'******************       Подпрограмма обработки вывода       ******************
'****************   на 7-seg индикатор (вызывается по TIMER0)   ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Индикация_7seg_led:       ' прерывание таймера Т2 (индикация)
'-------------------------------------------------------------------------------
'   Stop Timer0
'-------------------------------------------------------------------------------

      If Флаг_показать_секунды = 1 Then
          1_канал_выводимые_данные_led = Минуты
          2_канал_выводимые_данные_led = Секунды
        Else
          1_канал_выводимые_данные_led = Часы
          2_канал_выводимые_данные_led = Минуты
      End If

      If Флаг_горит_двоеточие = 1 Then
          Set Двоеточие_led
          Флаг_точка(2) = 1
        Else
          Reset Двоеточие_led
          Флаг_точка(2) = 0
      End If

'-------------------------------------------------------------------------------

      Выводимые_данные_led = 1_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
      For Цикл_led = 2 To 1 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next

      Выводимые_данные_led = 2_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
      For Цикл_led = 4 To 3 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next
'-------------------------------------------------------------------------------
'----------------------   гасим все разряды индикатора   -----------------------
'-------------------------------------------------------------------------------
    Call Регулировка_яркости_led       ' в принципе, гашение тут без надобности, индикатор и так выключается в прерывании Регулировка_яркости_led. Если же индикация работает БЕЗ регулировки яркости, то гашение ОБЯЗАТЕЛЬНО.
'-------------------------------------------------------------------------------
'----   перебираем разряды, в каждом прерывании выводим следующий разряд   -----
'-------------------------------------------------------------------------------
    Incr Счетчик_разрядов : If Счетчик_разрядов > 4 Then Счетчик_разрядов = 1       ' выбираем разряд для загрузки в обработчик вывода на 7-seg LED
'------------------------------------------------------------------------------------
'участок кода отвечающий за мигание, тушение разрядов и выводит точку в нужном месте
'------------------------------------------------------------------------------------
    Incr Счетчик_миганий : If Счетчик_миганий > Частота_мигания Then Счетчик_миганий = 1       ' длительность мигания

    If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_миганий > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then       ' если флаг мигания этого разряда выставлен и счетчик > 200
        Select Case Счетчик_разрядов
          Case 1 To 2
            If Indicator_1 = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' выводим пустое место
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' выводим пустое место
            End If
          Case 3 To 4
            If Indicator_2 = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' выводим пустое место
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' выводим пустое место
            End If
        End Select
      Else       ' иначе (флаг не выставлен, либо счетчик < 200)
        If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then
            Select Case Счетчик_разрядов
              Case 1 To 2
                If Indicator_1 = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' выводим дополнительный_символ
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' выводим дополнительный_символ
                End If
              Case 3 To 4
                If Indicator_2 = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' выводим дополнительный_символ
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' выводим дополнительный_символ
                End If
            End Select
          Else
            Выводимая_цифра_led = Цифра(счетчик_разрядов)
              Select Case Счетчик_разрядов
                Case 1 To 2
                  If Indicator_1 = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)
                  End If
                Case 3 To 4
                  If Indicator_2 = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)
                  End If
              End Select
        End If

'-------------------------------------------------------------------------------
'---------------------   Если необходимо, добавляем точку   --------------------
'-------------------------------------------------------------------------------

      If Флаг_точка(счетчик_разрядов) = 1 Then
              Выводимая_цифра_led = Выводимая_цифра_led Xor &H80       '&H7F       ' или &B10000000  добавляем к выводимой цифре точку    Цифры_OA
      End If
'-------------------------------------------------------------------------------
    End If
'-------------------------------------------------------------------------------
'---------------------     загружаем в порт код цифры     ----------------------
'-------------------------------------------------------------------------------
             A = Выводимая_цифра_led.0       ' Сегмент "А"
             B = Выводимая_цифра_led.1       ' Сегмент "B"
             C = Выводимая_цифра_led.2       ' Сегмент "C"
             D = Выводимая_цифра_led.3       ' Сегмент "D"
             E = Выводимая_цифра_led.4       ' Сегмент "E"
             F = Выводимая_цифра_led.5       ' Сегмент "F"
             G = Выводимая_цифра_led.6       ' Сегмент "G"
             H = Выводимая_цифра_led.7       ' Сегмент "Точка"
'-------------------------------------------------------------------------------
'----------------   Включаем соответствующий разряд индикатора   ---------------
'-------------------------------------------------------------------------------
    Select Case Счетчик_разрядов
      Case 1 : If Indicator_1 = 1 Then Reset Разряд_1 Else Set Разряд_1
      Case 2 : If Indicator_1 = 1 Then Reset Разряд_2 Else Set Разряд_2
      Case 3 : If Indicator_1 = 1 Then Reset Разряд_3 Else Set Разряд_3
      Case 4 : If Indicator_1 = 1 Then Reset Разряд_4 Else Set Разряд_4
    End Select
'-------------------------------------------------------------------------------
'   Start Timer0
'-------------------------------------------------------------------------------
'--------------------   Выход из обработчика прерывания   ----------------------
'-------------------------------------------------------------------------------
  Return
'*******************************************************************************
'===============================================================================
'===========   Таблицы выводимых символов для индикаторов с ОК и ОА   ==========
'===============================================================================
  Цифры_ok:       ' цифры
'-----------
    Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F       '0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    Data &H40 , &H00 , &H63 , &H39 , &H78 , &H5C , &H38 , &H74 , &H5E , &H77       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
    Data &H58 , &H31 , &H76 , &H79 , &H50 , &H71 , &H1C , &H73 , &H37 , &H80       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П". "."
    Data &H54       ', &H , &H , &H , &H , &H , &H , &H , &H , &H       '"n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
  Цифры_oa:
'-----------
    Data &HC0 , &HF9 , &HA4 , &HB0 , &H99 , &H92 , &H82 , &HF8 , &H80 , &H90       '0,1,2,3,4,5,6,7,8,9
    Data &HBF , &HFF , &H9C , &HC6 , &H87 , &HA3 , &HC7 , &H8B , &HA1 , &H88       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
    Data &HA7 , &HCE , &H89 , &H86 , &HAF , &H8E , &HE3 , &H8C , &HC8 , &H7F       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П", "."
    Data &HAB       ', &H , &H , &H , &H , &H , &H , &H , &H , &H       '"n", "", "", "", "", "", "", "", "", "". ""
'===============================================================================
  Регулировка_яркости_led:       ' прерывание таймера Timer2 (регулировка яркости)
'--------------------------
    If Indicator_1 = 1 Then
        Set Разряд_1 : Set Разряд_2       ': Set Разряд_3 : Set Разряд_4       ': Set Разряд_5 : Set Разряд_6 : Set Разряд_7 : Set Разряд_8       ' гасим индикаторы ОК
      Else
        Reset Разряд_1 : Reset Разряд_2       ': Reset Разряд_3 : Reset Разряд_4       ': Reset Разряд_5 : Reset Разряд_6 : Reset Разряд_7 : Reset Разряд_8       ' гасим индикаторы ОА
    End If
'--------------------------
    If Indicator_2 = 1 Then
        Set Разряд_3 : Set Разряд_4       ': Set Разряд_7 : Set Разряд_8
      Else
        Reset Разряд_3 : Reset Разряд_4       ': Reset Разряд_7 : Reset Разряд_8       ' гасим индикаторы ОА
    End If
'--------------------------
  Return  ' выход из обработчика прерывания
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'********************    Подпрограмма расчета времени     **********************
'********************       часов, минут и секунд         **********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обновить_данные_времени:
'-------------------------------------------------------------------------------
    Incr Секунды       'плюс секунда

    If Секунды > 59 Then       'при необходимости
        Секунды = 0 : Goto Обновить_минуты       'скорректировать счетчик секунд
    End If

    Goto Обновить_индикатор
'======================================
   Обновить_минуты:
'======================================
    Incr Минуты       'плюс минута

    If Минуты > 59 Then       'при необходимости
        Минуты = 0 : Goto Обновить_часы       'скорректировать счетчик минут
    End If

      Goto Обновить_индикатор
'======================================
    Обновить_часы:
'======================================
      Incr Часы       'плюс час

      If Часы > 23 Then       'при необходимости
          Часы = 0 : Goto Обновить_число_месяца       'скорректировать счетчик часов
      End If
'======================================
    Обновить_число_месяца:
'======================================
      Incr Число_месяца       'плюс час

      If Число_месяца > 30 Then       'при необходимости
          Число_месяца = 1 : Goto Обновить_месяц       'скорректировать счетчик часов
      End If
'======================================
    Обновить_месяц:
'======================================
      Incr Месяц       'плюс час

      If Месяц > 12 Then       'при необходимости
          Месяц = 1 : Goto Обновить_год       'скорректировать счетчик часов
      End If
'======================================
    Обновить_год:
'======================================
      Incr Год       'плюс час

      If Год > 2020 Then       'при необходимости
          Год = 2013       'скорректировать счетчик часов
      End If

'======================================
    Обновить_индикатор:
'======================================
      Флаг_обновить_данные_времени = 0
      Есть_данные_для_uart = 1
'      Флаг_обновить_индикатор = 1                 ' поставить признак обновления индикации
'-------------------------------------------------------------------------------
   Выход_обновить_данные_времени:
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'******************       Подпрограмма обработки вывода       ******************
'******************      на компьютер (аппаратный USART)      ******************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Передача_uart:
'-------------------------------------------------------------------------------
    If Indicator_1 = 1 Then
        Print "Индикаторы с ОК"
      Else
        Print "Индикаторы с ОА"
    End If

    Print "Текущее время - " ;

    Print Часы ; ":" ;
    If Минуты < 10 Then Print "0" ;
    Print Минуты ; ":";
    If Секунды < 10 Then Print "0" ;
    Print Секунды

    Print "Текущая дата - " ;
    Print "Пятница " ;
    Print "28 июня 2013 года"
    Print ""
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************




'*******************************************************************************
'*******************************************************************************
'*******************************************************************************
'*********                                                              ********
'*********     П О К А          Н Е         И С П О Л Ь З У Ю Т С Я     ********
'*********                                                              ********
'*******************************************************************************
'*******************************************************************************
'*******************************************************************************
'*******************************************************************************
'*******************************************************************************

'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерыв_передача_uart_закончена:
'--------------------------------
    Флаг_передача_uart_закончена = 1
'----------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерывание_прием_uart_закончен:
'-------------------------------------------------------------------------------
    Флаг_прием_uart_закончен = 1
'----------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерывание_буфер_uart_пуст:
'--------------------------------
'    Disable Udre                                  '> Разрешаем прерывание после опустошения буфера UART

'    Set Флаг_буфер_uart_пуст
'  Waitus 100
'----------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************

'*******************************************************************************
'-------------------------------------------------------------------------------
  Опрос_буфера_uart:
'-------------------------------------------------------------------------------
   'Do
     Флаг_есть_сообщение_uart = Ischarwaiting()       'проверка наличия команды в буфере UART

     If Флаг_есть_сообщение_uart = 1 Then       'если в буфере что-то есть переменной R присвоится значение 1
         Getline Временный_буфер_uart       'вытаскиваем содержимое буфера в переменную S
         If Временный_буфер_uart = "A" Then       'если там символ "А"
             Print "Led ON"       'отошлем сообщение
'             Led = 1                              'и включим светодиод
           Elseif Временный_буфер_uart = "B" Then       'если там символ "В"
             Print "Led OFF"       'сообщим о выключении
'             Led = 0                              'выключаем светодиод
         End If
       Del_buffer       'если в буфере что-то другое очищаем его
     End If
   'Loop
   'End
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************

'подпрограмма для разбора сообщения c UART
'=========================================
'*******************************************************************************
'-------------------------------------------------------------------------------
Sub Getline(временный_буфер_uart As String)
'-------------------------------------------------------------------------------
Временный_буфер_uart = ""

Do
Символ_из_буфера = Inkey()       'берем символ из буфера в формате ASCII
Select Case Символ_из_буфера
  Case 0 :
           Exit Do       'если дальше буфер пуст - выходим из цикла
  Case 10 :
            If Временный_буфер_uart <> "" Then Exit Do       'конец строки, значит выходим из цикла
  Case Else :
               If Символ_из_буфера > 31 Then Временный_буфер_uart = Временный_буфер_uart + Chr(символ_из_буфера)       'составляем строку
End Select

Loop
End Sub
'-------------------------------------------------------------------------------
'*******************************************************************************

'очистка буфера UART
'===================
'*******************************************************************************
'-------------------------------------------------------------------------------
Sub Del_buffer()
'-------------------------------------------------------------------------------
Do
Символ_из_буфера = Inkey()       'кладем в переменную "В" данные из буфера
Loop Until Символ_из_буфера = 0       'выходим из цикла когда в переменную попадет 0 (буфер пуст)
End Sub
'-------------------------------------------------------------------------------
'*******************************************************************************

http://s5.uploads.ru/t/qrYCD.jpg     http://s4.uploads.ru/t/ewCT5.jpg
       

Симуляция + исходник  -  скачать    перезалито  17.12.2014

Обратите внимание, 7-seg LED можно ставить любые (с соответствующей коррекцией программы и схемы, что-бы соблюдались условия автовыбора типа индикатора), ОА и ОК с высотой символа до 38мм (проверялось в железе), желательно подобрать резисторы в цепи сегментов индикатора, по току, согласно документации на индикаторы ).

Сопротивление в цепи разряда индикатора, на корпус, ~47к.
Сопротивление в цепи клавиатуры 100к ±5к, подобранно эксперементально, в противном случае, не работает клавиатура при разных ( ОА, ОК ) индикаторах.

0

6

Будьте внимательны, от буквы в конце названия PCF8574x, зависит адресация микросхемы !!!

Ещё одно извращение, хотя, как знать, может кому и пригодится.

8-ми разрядная 7-seg LED индикация по шине I2c, через 2хPCF8574.

Адресация PCF8574, PCF8574N, PCF8574A, PCF8575

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------

! Обратите ВНИМАНИЕ, ULN2803 управляется лог. "0", а TD62783 лог. "1" !
В исходнике необходимо инвертировать сегменты или разряды, в зависимости от используемых индикаторов (ОА или ОК).

Если большие индикаторы не нужны, можно обойтись без ключей "Дарлингтона" (ULN2803, TD62783).
В этом случае подтяните "+" или "-" резисторами от 100 Ом выходы PCF8574 (разряды), в зависимости от применяемых 7-seg LED индикаторов.

Исходник. Общий, для ОА и ОК

'*******************************************************************************
'******************     Поразрядная 7-seg LED индикация     ********************
'*******************************************************************************

' Контроллер: ATMEGA8A или любой другой "AVR" с небольшими переделками исходника
' Версия компилятора: BASCOM-AVR 2.0.7.1
' Автор: sasha_1973

'*******************************************************************************
'-------------------------------------------------------------------------------
'---------------     Конфигурация используемого контроллера     ----------------
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 8000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                       ***********************
'*****************         Конфигурация шины I2c         ***********************
'*****************        микросхема часов DS1307        ***********************
'*****************                                       ***********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Sda = Portc.4       ' Конфигурация порта
  Config Scl = Portc.5       ' Конфигурация порта
  Config I2cdelay = 1       ' Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
  I2cinit           ' Инициализация i2c
  Dim Инициализация_i2c As Byte
'-------------------------------------------------------------------------------
'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------
'-------------------------------------------------------------------------------

  Const Чтение_сегменты_pcf8574 = &H7E
  Const Запись_сегменты_pcf8574 = &H7F

  Const Чтение_разряды_pcf8574 = &H70
  Const Запись_разряды_pcf8574 = &H71

  Const Разряды_set = &B11111111
  Const Разряды_reset = &B00000000

' ------------------------------------------------------------------------------

'  Немного отвлечемся.
'  Бытует мнение, что компилятор не дружит с кирилицей.
'  Исходя из личного опыта могу сказать, конфликтов не наблюдалось.
'  Единсвенное ограничение - количество символов в именах. Думаю Вам хватит с избытком.

'-------------------------------------------------------------------------------
'-----------------     Определение переменных и констант     -------------------
'-------------------------------------------------------------------------------
Начальные_настройки:       ' Просто метка, для удобства
'-------------------------------------------------------------------------------

  Dim Тип_индикатора_1_канал As Byte       ' Переменная, для хранения значения типа индикатора
  Тип_индикатора_1_канал = 0       ' Если тип_индикатора = 1 , то ОК , если Тип_индикатора = 0 , То ОA

  Dim Тип_индикатора_2_канал As Byte       ' Переменная, для хранения значения типа индикатора
  Тип_индикатора_2_канал = 0       ' Если тип_индикатора = 1 , то ОK , если Тип_индикатора = 0 , То ОA

'-------------------------------------

  Const Общее_количество_разрядов = 8       ' Переменная, для хранения значения общего количества используемых разрядов

  Const Скорость_изменения_переменной = 50       ' Переменная, для хранения значения задержки "Waitms"
  Const Значение_регистра_tcnt0_timer0 = 250       ' Переменная, для хранения значения регистра TCNT0

'-------------------------------------------------------------------------------
  Dim Разряд As Byte

  Dim Цикл_led As Byte       ' Переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды)
  Dim Счетчик_миганий As Word       ' Счетчик для обработки частоты и длительности мигания
  Dim Частота_мигания As Word       ' Переменная, для хранения значения частоты мигания при Флаг_мигание(n) = 1
  Dim Счетчик_разрядов As Byte       ' Счетчик перебора разрядов
  Dim Переменная_word_1 As Word       ' Переменная, которую будем менять
  Dim Переменная_word_2 As Word       ' Переменная, которую будем менять
  Dim Выводимая_цифра_led As Byte       ' Переменная, для загрузки цифр в порт
  Dim Выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim Копия_выводимые_данные_led As Word       ' Переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды)
  Dim 1_канал_выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim 2_канал_выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim Длительность_горения_при_мигании As Word       ' Переменная, для хранения значения длительности горения знакоместа при "Флаг_мигание(n) = 1"
  Dim Цифра(общее_количество_разрядов) As Byte       ' Значение разряда для 8-ми разрядов
  Dim Флаг_точка(общее_количество_разрядов) As Byte       ' Флаг точки для 8-ми разрядов
  Dim Флаг_гашение(общее_количество_разрядов) As Byte       ' Флаг гашения нужного разряда для 8-ми разрядов
  Dim Флаг_мигание(общее_количество_разрядов) As Byte       ' Флаг мигания нужного разряда для 8-ми разрядов
  Dim Дополнительный_символ(общее_количество_разрядов) As Byte       ' Переменная, для хранения значения дополнительного символа при Флаг_дополнительный_символ(n) = 1
  Dim Флаг_дополнительный_символ(общее_количество_разрядов) As Byte       ' Флаг сигнализирующий о выводе дополнительных символов для 8-ми разрядов

'-------------------------------------------------------------------------------
'----------------------     Определение подпрограмм     ------------------------
'-------------------------------------------------------------------------------

  Declare Sub Гашение_разрядов()
  Declare Sub Индикация_7seg_led()
  Declare Sub Обработка_прерывания_timer0()

'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'------------     Настройка таймера для обновления LED индикации     -----------
'-------------------------------------------------------------------------------

   Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0

'-------------------------------------------------------------------------------

' Даём понять компилятору, что будем использовать таймер в режиме таймера (простите за каламбур),
' с предварительным делителем "PRESCALE = 1024".
' и что же мы имеем: f(тактовая частота - 4МГц) / 1024(настраиваемый делитель таймера
' (возможные варианты - 1 , 8 , 64 , 256 , 1024)) = 3906.25 тактов МК будет проходить,
'пока сработает прерывание от переполнения таймера. так, как перед этим мы проштудировали Datasheet
'и выяснили, что "TIMER0" , считает до 256, то 3 906,25 / 256 ~ 15,26 раз в секунду
'будет обновлятся наша Led индикация (при 8-ми разрядной динамической индикации мы получим ~ 15,26 / 8 = "пшик",
'Это Просто Катастрофа). К нашей великой радости, разработчики "Atmel" продумали этот момент,
'у таймера есть различные регистры, которыми можно манипулировать.
'В данном, конкретном случае, нас интересует регистр "TCNT0". Tcnt0 - 8-ми разрядный(от 0 До 255) регистр таймера - счетчика(TIMER0).
'именно он используетя таймером для счета. Вот его мы, и будем использовать.

'-------------------------------------------------------------------------------
'    Настройка дополнительного делителя таймера для обновления LED индикации
'-------------------------------------------------------------------------------

'  Tcnt0 = Значение_регистра_tcnt0_timer0       ' Настройка дополнительного делителя таймера (значение = 250)

'--------------------------------------------------------------------------------

'И чего мы добились, да просто "TIMER0" будет считать не с "0", а с нашего значения.
'Посчитаем ещё раз: 4000000 / 1024 / (256-(значение Tcnt0)) =  3 906,25 / 6 ~ 651
'прерывание "TIMER0" в секунду, или 1000(ms) /  651 ~ 1,536 ms,
'это и будет частотой обновления нашей  7-seg LED индикации.

'Идем дальше.

'Итак, что мы имеем: порты настроены, периодичность обновления установлена,
'а вот, что будет происходить после прерывания "TIMER0", мы не написали,
'исправляемся.

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

'-------------------------------------------------------------------------------
'-----------     Подпрограмма выполняемая после прерывания TIMER0     ----------
'-------------------------------------------------------------------------------

   On Timer0 Обработка_прерывания_timer0       ' Переход на подпрограмму после каждого прерывания TIMER0

'-----------------------     Первоначальные установки    -----------------------
'-------------------------------------------------------------------------------

  Переменная_word_1 = 0       ' Значение, которое будем увеличивать
  Переменная_word_2 = 50       ' Значение, которое будем уменьшать

  Частота_мигания = 300       ' Значение частоты мигания знакоместа на LED дисплее при "Флаг_мигание(n) = 1"
  Длительность_горения_при_мигании = Частота_мигания / 2       ' Значение длительности горения знакоместа на LED дисплее при "Флаг_мигание(n) = 1"

'-------------------------------------------------------------------------------
'------------------------     Работа с прерываниями     ------------------------
'-------------------------------------------------------------------------------

    Enable Timer0   ' Разрешаем работу прерывания по ПЕРЕПОЛНЕНИЮ  таймера

    Enable Interrupts       ' Разрешаем работу всех прерываний

'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'--------------------------     Начало программы     ---------------------------
'-------------------------------------------------------------------------------

  Do : Nop          ' Крутимся между Do и Loop, ожидая прерывания TIMER0, для обновления LED индикации

'--------------------------

    Incr Переменная_word_1       ' Считаем, просто для примера
    If Переменная_word_1 > 9999 Then Переменная_word_1 = 0       ' Если досчитали до 9999, сбрасываем счетчик
    1_канал_выводимые_данные_led = Переменная_word_1       ' Будем выводить в 1 канал (первые 4 разряда)

    Decr Переменная_word_2       ' Уменьшаем переменную
    2_канал_выводимые_данные_led = Переменная_word_2       ' Будем выводить в 2 канал (первые 4 разряда)

    If Переменная_word_2 = 0 Then       ' Если досчитали до 0, выводим "stop", и мигаем
        Флаг_дополнительный_символ(5) = 1 : Дополнительный_символ(5) = 5       ' символ "S"
        Флаг_дополнительный_символ(6) = 1 : Дополнительный_символ(6) = 14       ' символ "t"
        Флаг_дополнительный_символ(7) = 1 : Дополнительный_символ(7) = 15       ' символ "o"
        Флаг_дополнительный_символ(8) = 1 : Дополнительный_символ(8) = 28       ' символ "P"

        Флаг_мигание(5) = 1       ' Мигаем 5 разрядом
        Флаг_мигание(6) = 1       ' Мигаем 6 разрядом
        Флаг_мигание(7) = 1       ' Мигаем 7 разрядом
        Флаг_мигание(8) = 1       ' Мигаем 8 разрядом

    End If

    Waitms Скорость_изменения_переменной       ' Задержка, для частоты смены показаний индикаторов

'--------------------------
  Loop
End
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************   Подпрограмма обработки прерывания TIMER0   ****************
'*****************          происходит каждые 1,536 ms          ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_прерывания_timer0:
'-------------------------------------------------------------------------------
'   Stop Timer0
    Rcall Индикация_7seg_led
'   Start Timer0
'-------------------------------------------------------------------------------
' Делитель TIMER0 = 1000/(4000000/1024/(256-250))=1000/(3 906,25 / 6) = 1,536 ms
'-------------------------------------------------------------------------------

'    Tcnt0 = Значение_регистра_tcnt0_timer0

'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************   Подпрограмма для обработки LED индикации   ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Индикация_7seg_led:
'-------------------------------------------------------------------------------
'----------   Смотрим, что будем выводить и делаем копию переменной    ---------
'-------------------------------------------------------------------------------
      Выводимые_данные_led = 1_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
'-------------------------------------------------------------------------------
'------------------   В цикле разбиваем на разряды, с 4 по 1   -----------------
'-------------------------------------------------------------------------------
      For Цикл_led = 4 To 1 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next
'-------------------------------------------------------------------------------
'----------   Смотрим, что будем выводить и делаем копию переменной    ---------
'-------------------------------------------------------------------------------
      Выводимые_данные_led = 2_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
'-------------------------------------------------------------------------------
'------------------   В цикле разбиваем на разряды, с 8 по 5   -----------------
'-------------------------------------------------------------------------------
      For Цикл_led = 8 To 5 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next
'-------------------------------------------------------------------------------
'----------------------   Гасим все разряды индикатора   -----------------------
'-------------------------------------------------------------------------------
    If Тип_индикатора_1_канал = 1 Then
        I2csend Запись_разряды_pcf8574 , Разряды_set       ' Переход к подпрограмме гашения индикаторов
      Else
        I2csend Запись_разряды_pcf8574 , Разряды_reset       ' Переход к подпрограмме гашения индикаторов
    End If

    If Тип_индикатора_2_канал = 1 Then
        I2csend Запись_разряды_pcf8574 , Разряды_set       ' Переход к подпрограмме гашения индикаторов
      Else
        I2csend Запись_разряды_pcf8574 , Разряды_reset       ' Переход к подпрограмме гашения индикаторов
    End If
'-------------------------------------------------------------------------------
'----   Перебираем разряды, в каждом прерывании выводим следующий разряд   -----
'-------------------------------------------------------------------------------
    Incr Счетчик_разрядов
'-------------------------------------------------------------------------------
'-----   Выбираем разряд для загрузки в обработчик вывода на 7-seg LED    ------
'-------------------------------------------------------------------------------
    If Счетчик_разрядов > Общее_количество_разрядов Then
        Счетчик_разрядов = 1
    End If
'------------------------------------------------------------------------------------
' Участок кода отвечающий за мигание, тушение разрядов и выводит точку в нужном месте
'------------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'----------------------------   Подготовка к миганию  --------------------------
'-------------------------------------------------------------------------------
    Incr Счетчик_миганий

    If Счетчик_миганий > Частота_мигания Then Счетчик_миганий = 1
'-------------------------------------------------------------------------------
'------------------   Если надо, то мигаем в нужных разрядах  ------------------
'-------------------------------------------------------------------------------
    If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_миганий > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then       ' Если флаг мигания этого разряда выставлен и счетчик > 200
        Select Case Счетчик_разрядов
          Case 1 To 4
            If Тип_индикатора_1_канал = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' Выводим пустое место в 1 - 4 разрядах
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' Выводим пустое место в 1 - 4 разрядах
            End If
          Case 5 To 8
            If Тип_индикатора_2_канал = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' Выводим пустое место в 5 - 8 разрядах
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' Выводим пустое место в 5 - 8 разрядах
            End If
        End Select
      Else
'-------------------------------------------------------------------------------
'-----------------------   Выводим дополнительные симвоы   ---------------------
'-------------------------------------------------------------------------------
        If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then
            Select Case Счетчик_разрядов
              Case 1 To 4
                If Тип_индикатора_1_канал = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                End If
              Case 5 To 8
                If Тип_индикатора_2_канал = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 5 - 8 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 5 - 8 разрядах
                End If
            End Select
          Else
'-------------------------------------------------------------------------------
'-------   Если не мигаем и ничего другого не выводим, выводим основное   ------
'-------------------------------------------------------------------------------
            Выводимая_цифра_led = Цифра(счетчик_разрядов)
              Select Case Счетчик_разрядов
                Case 1 To 4
                  If Тип_индикатора_1_канал = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                  End If
                Case 5 To 8
                  If Тип_индикатора_2_канал = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 5 - 8 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 5 - 8 разрядах
                  End If
              End Select
        End If
'-------------------------------------------------------------------------------
'-------------   Если необходимо, выводим точку в нужном разряде   -------------
'-------------------------------------------------------------------------------
      If Флаг_точка(счетчик_разрядов) = 1 Then
          Выводимая_цифра_led = Выводимая_цифра_led Xor &H80       '&H80 или &B10000000 добавляем к выводимой цифре точку
      End If
    End If
'-------------------------------------------------------------------------------
'---------------------     Загружаем в порт код цифры     ----------------------
'-------------------------------------------------------------------------------
    I2csend Запись_сегменты_pcf8574 , Выводимая_цифра_led
'-------------------------------------------------------------------------------
'---------------   Включаем соответствующий разряд индикатора   ----------------
'-------------------------------------------------------------------------------
    Select Case Счетчик_разрядов
      Case 1 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000001 Else Разряд = &B11111110
      Case 2 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000010 Else Разряд = &B11111101
      Case 3 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000100 Else Разряд = &B11111011
      Case 4 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00001000 Else Разряд = &B11110111
      Case 5 : If Тип_индикатора_2_канал = 0 Then Разряд = &B00010000 Else Разряд = &B11101111
      Case 6 : If Тип_индикатора_2_канал = 0 Then Разряд = &B00100000 Else Разряд = &B11011111
      Case 7 : If Тип_индикатора_2_канал = 0 Then Разряд = &B01000000 Else Разряд = &B10111111
      Case 8 : If Тип_индикатора_2_канал = 0 Then Разряд = &B10000000 Else Разряд = &B01111111
    End Select
'-------------------------------------------------------------------------------
'---------------------------   Загружаем в PCF8574   ---------------------------
'-------------------------------------------------------------------------------
    I2csend Запись_разряды_pcf8574 , Разряд       ' Короткий вариант записи данных в PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Цифры_ok:
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'----------------------------   Можно написать так   ---------------------------
'-------------------------------------------------------------------------------
'    Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F       '0, 1, 2, 3, 4, 5, 6, 7, 8, 9
'    Data &H40 , &H00 , &H63 , &H39 , &H78 , &H5C , &H38 , &H74 , &H5E , &H77       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
'    Data &H58 , &H31 , &H76 , &H79 , &H50 , &H71 , &H1C , &H73 , &H37 , &H80       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П". "."
'    Data &H54       ', &H , &H , &H , &H , &H , &H , &H , &H , &H '"n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
'-------   а можно так, выглядит нагляднее, но работать будет одинаково   ------
'-------------------------------------------------------------------------------
    Data &H3F       ' 0   "0"
    Data &H06       ' 1   "1"
    Data &H5B       ' 2   "2"
    Data &H4F       ' 3   "3"
    Data &H66       ' 4   "4"
    Data &H6D       ' 5   "5"
    Data &H7D       ' 6   "6"
    Data &H07       ' 7   "7"
    Data &H7F       ' 8   "8"
    Data &H6F       ' 9   "9"
    Data &H40       ' 10  "_"
    Data &H00       ' 11  "Пустое место"
    Data &H63       ' 12  "Значек градуса"
    Data &H39       ' 13  "С"
    Data &H78       ' 14  "t"
    Data &H5C       ' 15  "o"
    Data &H38       ' 16  "L"
    Data &H74       ' 17  "h"
    Data &H5E       ' 18  "d"
    Data &H77       ' 19  "A"
    Data &H58       ' 20  "c"
    Data &H31       ' 21  "Г"
    Data &H76       ' 22  "H"
    Data &H79       ' 23  "E"
    Data &H50       ' 24  "r"
    Data &H71       ' 25  "F"
    Data &H3E       ' 26  "U"
    Data &H1C       ' 27  "u"
    Data &H73       ' 28  "P"
    Data &H37       ' 29  "П"
    Data &H80       ' 30  "Точка"
    Data &H54       ' 31  "n"
'-------------------------------------------------------------------------------
  Цифры_oa:
'-------------------------------------------------------------------------------
'    Data &HC0 , &HF9 , &HA4 , &HB0 , &H99 , &H92 , &H82 , &HF8 , &H80 , &H90       '0,1,2,3,4,5,6,7,8,9
'    Data &HBF , &HFF , &H9C , &HC6 , &H87 , &HA3 , &HC7 , &H8B , &HA1 , &H88       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
'    Data &HA7 , &HCE , &H89 , &H86 , &HAF , &H8E , &HC1 , &HE3 , &H8C , &HC8       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П"
'    Data &H7F , &HAB       ', &H , &H , &H , &H , &H , &H , &H , &H , &H ' "." , "n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------   а можно так, выглядит нагляднее, но работать будет одинаково   ------
'-------------------------------------------------------------------------------
    Data &HC0       ' 0   "0"
    Data &HF9       ' 1   "1"
    Data &HA4       ' 2   "2"
    Data &HB0       ' 3   "3"
    Data &H99       ' 4   "4"
    Data &H92       ' 5   "5"
    Data &H82       ' 6   "6"
    Data &HF8       ' 7   "7"
    Data &H80       ' 8   "8"
    Data &H90       ' 9   "9"
    Data &HBF       ' 10  "_"
    Data &HFF       ' 11  "Пустое место"
    Data &H9C       ' 12  "Значек градуса"
    Data &HC6       ' 13  "С"
    Data &H87       ' 14  "t"
    Data &HA3       ' 15  "o"
    Data &HC7       ' 16  "L"
    Data &H8B       ' 17  "h"
    Data &HA1       ' 18  "d"
    Data &H88       ' 19  "A"
    Data &HA7       ' 20  "c"
    Data &HCE       ' 21  "Г"
    Data &H89       ' 22  "H"
    Data &H86       ' 23  "E"
    Data &HAF       ' 24  "r"
    Data &H8E       ' 25  "F"
    Data &HC1       ' 26  "U"
    Data &HE3       ' 27  "u"
    Data &H8C       ' 28  "P"
    Data &HC8       ' 29  "П"
    Data &H7F       ' 30  "Точка"
    Data &HAB       ' 31  "n"
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

http://s5.uploads.ru/t/ozwVK.jpg http://s4.uploads.ru/t/GtKD5.jpg

Симуляция в Протеус 7.10 sr0 + исходник Bascom 2.0.7.1 + схема + документация на микросхемы - скачать

0

7

Реализован вывод строковой переменной через функцию

Реализован вывод символов согласно таблицы кодов ASCII английского алфавита, первые 127 символов (выборочно, которые можно вывести на 7-seg) + символ "°" (176)

Реализованы: вывод точек и мигания разрядов


Индикаторы с общим анодом  -  скачать

http://sf.uploads.ru/t/2139c.jpg


Индикаторы с общим катодом  -  скачать

http://sf.uploads.ru/t/6jsNg.jpg


Индикаторы больших размеров через разнополярные ключи дарлингтона  -  скачать

http://sf.uploads.ru/t/FEZAR.jpg

+2

8

Дополнение к предыдущему посту, кому нужна скорость обработки прерываний.

Выводы МК, для индикаторов любые, назначаются в исходнике.

Обновление 7-seg LED индикации на ассемблере

$map       ' Получаем карту распределения памяти в отчёте компиляции
  $regfile = "m168pdef.dat"       ' Используемый контроллер
  $crystal = 1000000       ' Частота работы контроллера
  $framesize = 100       ' Размер области используемой для преобразований
  $hwstack = 100       ' Размер аппаратного стека
  $swstack = 100       ' Размер программного стека

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0       ' конфигурируем таймер индикации    PRESCALE= 1|8|64|256|1024
  On Compare0a Регулировка_яркости_led Nosave       ' Подпрограмма для обработки прерывания регулировки яркости индикатора
  On Timer0 Индикация_7seg_led Nosave       ' Подпрограмма для обработки прерывания
  Compare0a = 255
'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================

  A_seg_port Alias Portb : A_seg_pin Alias 4 : Config A_seg_port.a_seg_pin = Output       ' Cегмент A
  B_seg_port Alias Portb : B_seg_pin Alias 3 : Config B_seg_port.b_seg_pin = Output       ' Cегмент B
  C_seg_port Alias Portb : C_seg_pin Alias 2 : Config C_seg_port.c_seg_pin = Output       ' Cегмент C
  D_seg_port Alias Portb : D_seg_pin Alias 1 : Config D_seg_port.d_seg_pin = Output       ' Cегмент D
  E_seg_port Alias Portb : E_seg_pin Alias 0 : Config E_seg_port.e_seg_pin = Output       ' Cегмент E
  F_seg_port Alias Portd : F_seg_pin Alias 7 : Config F_seg_port.f_seg_pin = Output       ' Cегмент F
  G_seg_port Alias Portd : G_seg_pin Alias 6 : Config G_seg_port.g_seg_pin = Output       ' Cегмент G
  H_seg_port Alias Portd : H_seg_pin Alias 5 : Config H_seg_port.h_seg_pin = Output       ' Cегмент H

  1_razr_port Alias Portc : 1_razr_pin Alias 5 : Config 1_razr_port.1_razr_pin = Output       ' 1 знакоместо
  2_razr_port Alias Portd : 2_razr_pin Alias 0 : Config 2_razr_port.2_razr_pin = Output       ' 2 знакоместо
  3_razr_port Alias Portd : 3_razr_pin Alias 1 : Config 3_razr_port.3_razr_pin = Output       ' 3 знакоместо
  4_razr_port Alias Portd : 4_razr_pin Alias 2 : Config 4_razr_port.4_razr_pin = Output       ' 4 знакоместо

'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Timer0       ' Разрешаем работу прерывания по ПЕРЕПОЛНЕНИЮ
  Enable Compare0a       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:
'===============================================================================

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Индикация_7seg_led:       ' Прерывание TIMER0, обработка 7-seg LED индикации
'-------------------------------------------------------------------------------
   'Так, как есть логические операции, сохраняем SREG
   'Сохраняем данные из используемых регистров
    !push R16
    !in R16 , sreg
    !push R16
    !push R30
    !push R31

   'Смотрим какой разряд будем выводить, время выполнения фрагмента = 7 тактов
    !lds R30 , {Счетчик_разрядов}       ' Прямая загрузка  из переменной в регистр, время выполнения 2 такта
    !sBRC R30 , 2       ' &B00000100 = 4; Пропустить если 2 бит в регистре очищен, время выполнения 1 такт
    !clr R30       ' Очистить регистр, время выполнения 1 такт
    !inc R30       ' Инкременировать содержимое регистра, время выполнения 1 такт
    !sts {Счетчик_разрядов} , R30       ' Прямая загрузка  из регистра в переменную, время выполнения 2 такта

   'Считам длительность и частоту мигания разрядов 7-seg LED индикаторов
   'Счетчик_миганий = Счетчик_миганий + 1
    !lds R30 , {Счетчик_миганий}       ' Прямая загрузка  из переменной в регистр, время выполнения 2 такта
    !inc R30       ' Инкременировать содержимое регистра, время выполнения 1 такт

    !lds R31 , {Частота_мигания}
    !cp R30 , R31
    !BRLO Запись_счетчика_миганий       ' Перейти если меньше
    !ldi R30 , 1

   Запись_счетчика_миганий:
    !sts {Счетчик_миганий} , R30       ' Прямая загрузка  из регистра в переменную, время выполнения 2 такта

   'Собственно занимаемся миганием разрядов 7-seg LED индикаторов
    Loadadr Флаг_мигание_знакоместа(счетчик_разрядов) , Z
    !ld R16 , Z
    !cpi R16 , 1
    !BRNE Выводим_буфер       ' Перейти если не равно

    !lds R30 , {Счетчик_миганий}
    !lds R31 , {Длительность_горения_при_мигании}
    !cp R30 , R31
    !BRLO Выводим_буфер       ' Перейти если меньше
    !ldi R16 , 0       ' Выводим пустое место в соответствующем разряде
    !rjmp Мигание_1

   Выводим_буфер:
    Loadadr Buffer_7seg_led(счетчик_разрядов) , Z
    !ld R16 , Z

   Мигание_1:

   'Гасим разряды индикаторы ОА, время выполнения фрагмента = 8 тактов, если используем регулировку яркости в гашении нет необходимости
'    !cbi 1_razr_port , 1_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
'    !cbi 2_razr_port , 2_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
'    !cbi 3_razr_port , 3_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
'    !cbi 4_razr_port , 4_razr_pin       ' Очистить бит в порту, время выполнения 2 такта

   'Закидываем сегменты через виртуальные порты в порты контроллера, время выполнения 42 такта
    !SBRC R16 , 0       ' Пропустить если 0 бит в регистре очищен, время выполнения 1 такт
    !sbi A_seg_port , A_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 0       ' Пропустить если 0 бит в регистре установлен, время выполнения 1 такт
    !cbi A_seg_port , A_seg_pin       ' Очистить бит в порту, время выполнения 2 такта

    !SBRC R16 , 1       ' Пропустить если 1 бит в регистре очищен, время выполнения 1 такт
    !sbi B_seg_port , B_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 1       ' Пропустить если 1 бит в регистре установлен, время выполнения 1 такт
    !cbi B_seg_port , B_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 2       ' Пропустить если 2 бит в регистре очищен, время выполнения 1 такт
    !sbi C_seg_port , C_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 2       ' Пропустить если 2 бит в регистре установлен, время выполнения 1 такт
    !cbi C_seg_port , C_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 3       ' Пропустить если 3 бит в регистре очищен, время выполнения 1 такт
    !sbi D_seg_port , D_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 3       ' Пропустить если 3 бит в регистре установлен, время выполнения 1 такт
    !cbi D_seg_port , D_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 4       ' Пропустить если 4 бит в регистре очищен, время выполнения 1 такт
    !sbi E_seg_port , E_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 4       ' Пропустить если 4 бит в регистре установлен, время выполнения 1 такт
    !cbi E_seg_port , E_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 5       ' Пропустить если 5 бит в регистре очищен, время выполнения 1 такт
    !sbi F_seg_port , F_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 5       ' Пропустить если 5 бит в регистре установлен, время выполнения 1 такт
    !cbi F_seg_port , F_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 6       ' Пропустить если 6 бит в регистре очищен, время выполнения 1 такт
    !sbi G_seg_port , G_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 6       ' Пропустить если 6 бит в регистре установлен, время выполнения 1 такт
    !cbi G_seg_port , G_seg_pin       ' Установить бит в порту, время выполнения 2 такта

    !SBRC R16 , 7       ' Пропустить если 7 бит в регистре очищен, время выполнения 1 такт
    !sbi H_seg_port , H_seg_pin       ' Установить бит в порту, время выполнения 2 такта
    !SBRS R16 , 7       ' Пропустить если 7 бит в регистре установлен, время выполнения 1 такт
    !cbi H_seg_port , H_seg_pin       ' Очистить бит в порту, время выполнения 2 такта

   'Закидываем сегменты прямо в порт, если все сегменты на одном порту, время выполнения = 1 такт
   'Out Portd , R16       ' Время выполнения = 1 такт
   'Port_D = Буфер_знакоместа_byte(счетчик_разрядов)       ' Время выполнения 12 тактов

   'Включаем соответствующий разряд индикатора, время выполнения 11 - 17 тактов, в зависимости от выводимого разряда
    !LDs R16 , {Счетчик_разрядов}       ' Грузим в регистр номер выводимого разряда, время выполнения 2 такта

    !Cpi R16 , 1       ' (CPI) Сравнить с константой, время выполнения 1 такт
    !BREQ Led_1_знакоместо       ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт

    !Cpi R16 , 2       ' (CPI) Сравнить с константой, время выполнения 1 такт
    !BREQ Led_2_знакоместо       ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт

    !Cpi R16 , 3       ' (CPI) Сравнить с константой, время выполнения 1 такт
    !BREQ Led_3_знакоместо       ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт

    !cpi R16 , 4       ' (CPI) Сравнить с константой, время выполнения 1 такт
    !BREQ Led_4_знакоместо       ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт

    Led_1_знакоместо:
     !sbi 1_razr_port , 1_razr_pin       ' Установить бит в порту, время выполнения 2 такта
     !rjmp Выход_индикация_7seg_led       ' Идём на выход

    Led_2_знакоместо:
     !sbi 2_razr_port , 2_razr_pin       ' Установить бит в порту, время выполнения 2 такта
     !rjmp Выход_индикация_7seg_led       ' Идём на выход

    Led_3_знакоместо:
     !sbi 3_razr_port , 3_razr_pin       ' Установить бит в порту, время выполнения 2 такта
     !rjmp Выход_индикация_7seg_led       ' Идём на выход

    Led_4_знакоместо:
     !sbi 4_razr_port , 4_razr_pin       ' Установить бит в порту, время выполнения 2 такта
     !rjmp Выход_индикация_7seg_led       ' Идём на выход

   Выход_индикация_7seg_led:
     !pop R31
     !pop R30
     !pop R16
     !out sreg , R16
     !pop R16
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Регулировка_яркости_led:       ' подпрограмма гашения индикаторов
'-------------------------------------------------------------------------------
   'Гасим разряды индикаторы ОА, время выполнения фрагмента = 8 тактов, если используем регулировку яркости в гашении нет необходимости
    !cbi 1_razr_port , 1_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
    !cbi 2_razr_port , 2_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
    !cbi 3_razr_port , 3_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
    !cbi 4_razr_port , 4_razr_pin       ' Очистить бит в порту, время выполнения 2 такта
'-------------------------------------------------------------------------------
  Return
'===============================================================================

+1

9

Кто на маленького???
Для тех кому не хватает выводов или любят маленькие габариты

Наткнулся на статью 

Начало

Attiny13A + 8 разрядов 7-seg LED  через 1 вывод МК

Симуляция + кексик   -   скачать   (после теста в железе, выложу исходник)

http://s2.uploads.ru/t/t4P20.jpg

+1

10

Работа с 7 seg led индикаторами через 74HC595 на ASM AVR

Atmega328P + 4x7seg led + 2x74hc595  -  скачать

ОА

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       ' http://www.atmel.com/images/Atmel-8272- … asheet.pdf
  $crystal = 1000000       ' 1 МГц
  $framesize = 64       ' Размер области используемой и необходимой для преобразований
  $hwstack = 64       ' Размер аппаратного стека
  $swstack = 64       ' Размер программного стека

  Clk_74hc595 Alias Portb.0 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.1 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.2 : Config Load_74hc595 = Output : Load_74hc595 = 0

  Config Timer2 = Timer , Prescale = 8 , Clear Timer = 0
  Stop Timer2
  Timer2 = 0
  On Timer2 Obrabotka_preryvaniya_timer2 Nosave

  Dim Count_digit As Byte
  Dim Buf_74hc595(4) As Byte

  Declare Sub Print_7seg_led(byval Copy_str As String * 5)

  Dim Val_word As Word
  Dim Val_str As String * 5

'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Timer2 : Start Timer2
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================
  Main_loop:
'===============================================================================

      Incr Val_word

      If Val_word > 9999 Then
          Val_word = 0
      End If

      Val_str = Str(val_word)
      Val_str = Format(val_str , "   0")

      Print_7seg_led Val_str

      Waitms 100

'===============================================================================
  Goto Main_loop
End
'===============================================================================

'===============================================================================
  Sub Print_7seg_led(byval Copy_str As String * 5)
'-------------------------------------------------------------------------------
    !ldi R16 , 0
    !ldi R17 , 8

   Print_7seg_led_1:
    Loadadr Copy_str , X
    !add R26 , R17
    !adc R27 , R16
    !ld R18 , -X
    !subi R18 , 32

    !ldi R30 , Low(Code_7seg_led_oa * 2)
    !ldi R31 , High(Code_7seg_led_oa * 2)
    !add R30 , R18
    !adc R31 , R16
    !lpm R18 , Z

    Loadadr Copy_str , X
    !add R26 , R17
    !adc R27 , R16
    !st -X , R18

    !dec R17
    !brne Print_7seg_led_1

    !ld R16 , X+
    !ld R17 , X+
    !ld R18 , X+
    !ld R19 , X

    Loadadr Buf_74hc595(1) , X
    !st X+ , R16
    !st X+ , R17
    !st X+ , R18
    !st X , R19
   Exit_print_7seg_led:
'-------------------------------------------------------------------------------
  End Sub
'===============================================================================

'===============================================================================
  Obrabotka_preryvaniya_timer2:       ' Время выполнения прерывания 267 тактов МК + 8 тактов(вход в прерывание) + 4 такта(выход из прерывания)
'-------------------------------------------------------------------------------
   'Сохраняем используемые регистры
   'Т.к., используются логические операции, ОБЯЗАТЕЛЬНО СОХРАНЯЕМ SREG
    !push R16
    !in R16 , sreg
    !push R16
    !push R30
    !push R31

    !lds R16 , {Count_digit}       ' Забираем счётчик разрядов
    !inc R16       ' Считаем разряды
    !andi R16 , 3       ' Ограничение счётчика разрядов
    !sts {Count_digit} , R16       ' Сохраняемся

    Loadadr Buf_74hc595(1) , Z       ' Узнаём адрес массива с выводимым буфером
   'Вычисляем смещение данных в массиве
    !add R30 , R16
    !clr R16
    !adc R31 , R16
    !ld R16 , Z       ' Забираем данные из массива сегментов

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

    !lds R16 , {Count_digit}       ' Забираем выводимый разряд
    !ldi R30 , Low(Code_digit_oa * 2)       ' Младший байт адреса таблицы разрядов
    !ldi R31 , High(Code_digit_oa * 2)       ' Старший байт адреса таблицы разрядов
   'Вычисляем смещение данных в таблице
    !add R30 , R16
    !clr R16
    !adc R31 , R16
    !lpm R16 , Z       ' Забираем данные из таблицы разрядов

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

'============================
   Exit_preryvaniya_timer2:
   'Восстанавливаем используемые регистры и SREG
    !pop R31
    !pop R30
    !pop R16
    !out sreg , R16
    !pop R16
   'Выходим из прерывания
    !reti
'============================

   Write_74hc595:
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R16 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R16 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R16       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0

    !dec R31       ' Считаем биты
   !brne Next_Bit
  'Возврат из подпрограммы
   !ret
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Code_digit_oa:
'-------------------------------------------------------------------------------
    $asm
     .db &B00000001       ' 1
     .db &B00000010       ' 2
     .db &B00000100       ' 3
     .db &B00001000       ' 4
    $end Asm
'===============================================================================

'===============================================================================
  Code_7seg_led_oa:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
    $asm
     .db &HFF       ' 32 - "Пробел"
     .db 0       ' 33 - "!"
     .db 0 ' 34 - "" "
     .db 0       ' 35 - "#"
     .db 0       ' 36 - "$"
     .db 0       ' 37 - "%"
     .db 0       ' 38 - "&"
     .db 0       ' 39 - "'"
     .db 0       ' 40 - "("
     .db 0       ' 41 - ")"
     .db 0       ' 42 - "*"
     .db 0       ' 43 - "+"
     .db 0       ' 44 - ","
     .db &HBF       ' 45 - "-"
     .db &H7F       ' 46 - "."
     .db 0       ' 47 - "/"
     .db &HC0       ' 48 - "0"
     .db &HF9       ' 49 - "1"
     .db &HA4       ' 50 - "2"
     .db &HB0       ' 51 - "3"
     .db &H99       ' 52 - "4"
     .db &H92       ' 53 - "5"
     .db &H82       ' 54 - "6"
     .db &HF8       ' 55 - "7"
     .db &H80       ' 56 - "8"
     .db &H90       ' 57 - "9"
     .db 0       ' 58 - ":"
     .db 0       ' 59 - ";"
     .db 0       ' 60 - "<"
     .db 0       ' 61 - "="
     .db 0       ' 62 - ">"
     .db 0       ' 63 - "?"
     .db 0       ' 64 - "@"
     .db &H88       ' 65 - "A"
     .db 0       ' 66 - "B"
     .db &HC6       ' 67 - "C"
     .db 0       ' 68 - "D"
     .db &H86       ' 69 - "E"
     .db &H8E       ' 70 - "F"
     .db 0       ' 71 - "G"
     .db &H89       ' 72 - "H"
     .db &HF9       ' 73 - "I"
     .db &HF1       ' 74 - "J"
     .db 0       ' 75 - "K"
     .db &H7C       ' 76 - "L"
     .db 0       ' 77 - "M"
     .db 0       ' 78 - "N"
     .db &HC0       ' 79 - "O"
     .db &H8C       ' 80 - "P"
     .db 0       ' 81 - "Q"
     .db 0       ' 82 - "R"
     .db &H92       ' 83 - "S"
     .db 0       ' 84 - "T"
     .db &HC1       ' 85 - "U"
     .db 0       ' 86 - "V"
     .db 0       ' 87 - "W"
     .db 0       ' 88 - "X"
     .db &H91       ' 89 - "Y"
     .db 0       ' 90 - "Z"
     .db &HC6       ' 91 - "["
     .db 0       ' 92 - "\"
     .db &HF0       ' 93 - "]"
     .db 0       ' 94 - "^"
     .db &HF7       ' 95 - "_" - подчёркивание
     .db 0       ' 96 - "`"
     .db 0       ' 97 - "a"
     .db &H83       ' 98 - "b"
     .db &HA7       ' 99 - "c"
     .db &HA1       ' 100 - "d"
     .db 0       ' 101 - "e"
     .db 0       ' 102 - "f"
     .db 0       ' 103 - "g"
     .db &H8B       ' 104 - "h"
     .db 0       ' 105 - "i"
     .db 0       ' 106 - "j"
     .db 0       ' 107 - "k"
     .db 0       ' 108 - "l"
     .db 0       ' 109 - "m"
     .db &HAB       ' 110 - "n"
     .db &HA3       ' 111 - "o"
     .db 0       ' 112 - "p"
     .db 0       ' 113 - "q"
     .db &HAF       ' 114 - "r"
     .db 0       ' 115 - "s"
     .db &H87       ' 116 - "t"
     .db &HE3       ' 117 - "u"
    $end Asm
'===============================================================================

ОК

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       ' http://www.atmel.com/images/Atmel-8272- … asheet.pdf
  $crystal = 1000000       ' 1 МГц
  $framesize = 64       ' Размер области используемой и необходимой для преобразований
  $hwstack = 64       ' Размер аппаратного стека
  $swstack = 64       ' Размер программного стека

  Clk_74hc595 Alias Portb.0 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.1 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.2 : Config Load_74hc595 = Output : Load_74hc595 = 0

  Config Timer2 = Timer , Prescale = 8 , Clear Timer = 0
  Stop Timer2
  Timer2 = 0
  On Timer2 Obrabotka_preryvaniya_timer2 Nosave

  Dim Count_digit As Byte
  Dim Buf_74hc595(4) As Byte

  Declare Sub Print_7seg_led(byval Copy_str As String * 5)

  Dim Val_word As Word
  Dim Val_str As String * 5

'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Timer2 : Start Timer2
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================
  Main_loop:
'===============================================================================

      Incr Val_word

      If Val_word > 9999 Then
          Val_word = 0
      End If

      Val_str = Str(val_word)
      Val_str = Format(val_str , "   0")

      Print_7seg_led Val_str

      Waitms 100

'===============================================================================
  Goto Main_loop
End
'===============================================================================

'===============================================================================
  Sub Print_7seg_led(byval Copy_str As String * 5)
'-------------------------------------------------------------------------------
    !ldi R16 , 0
    !ldi R17 , 8

   Print_7seg_led_1:
    Loadadr Copy_str , X
    !add R26 , R17
    !adc R27 , R16
    !ld R18 , -X
    !subi R18 , 32

    !ldi R30 , Low(Code_7seg_led_ok * 2)
    !ldi R31 , High(Code_7seg_led_ok * 2)
    !add R30 , R18
    !adc R31 , R16
    !lpm R18 , Z

    Loadadr Copy_str , X
    !add R26 , R17
    !adc R27 , R16
    !st -X , R18

    !dec R17
    !brne Print_7seg_led_1

    !ld R16 , X+
    !ld R17 , X+
    !ld R18 , X+
    !ld R19 , X

    Loadadr Buf_74hc595(1) , X
    !st X+ , R16
    !st X+ , R17
    !st X+ , R18
    !st X , R19
   Exit_print_7seg_led:
'-------------------------------------------------------------------------------
  End Sub
'===============================================================================

'===============================================================================
  Obrabotka_preryvaniya_timer2:       ' Время выполнения прерывания 267 тактов МК + 8 тактов(вход в прерывание) + 4 такта(выход из прерывания)
'-------------------------------------------------------------------------------
   'Сохраняем используемые регистры
   'Т.к., используются логические операции, ОБЯЗАТЕЛЬНО СОХРАНЯЕМ SREG
    !push R16
    !in R16 , sreg
    !push R16
    !push R30
    !push R31

    !lds R16 , {Count_digit}       ' Забираем счётчик разрядов
    !inc R16       ' Считаем разряды
    !andi R16 , 3       ' Ограничение счётчика разрядов
    !sts {Count_digit} , R16       ' Сохраняемся

    Loadadr Buf_74hc595(1) , Z       ' Узнаём адрес массива с выводимым буфером
   'Вычисляем смещение данных в массиве
    !add R30 , R16
    !clr R16
    !adc R31 , R16
    !ld R16 , Z       ' Забираем данные из массива сегментов

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

    !lds R16 , {Count_digit}       ' Забираем выводимый разряд
    !ldi R30 , Low(Code_digit_ok * 2)       ' Младший байт адреса таблицы разрядов
    !ldi R31 , High(Code_digit_ok * 2)       ' Старший байт адреса таблицы разрядов
   'Вычисляем смещение данных в таблице
    !add R30 , R16
    !clr R16
    !adc R31 , R16
    !lpm R16 , Z       ' Забираем данные из таблицы разрядов

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

'============================
   Exit_preryvaniya_timer2:
   'Восстанавливаем используемые регистры и SREG
    !pop R31
    !pop R30
    !pop R16
    !out sreg , R16
    !pop R16
   'Выходим из прерывания
    !reti
'============================

   Write_74hc595:
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R16 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R16 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R16       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0

    !dec R31       ' Считаем биты
   !brne Next_Bit
  'Возврат из подпрограммы
   !ret
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Code_digit_ok:
'-------------------------------------------------------------------------------
    $asm
     .db &B11111110       ' 1
     .db &B11111101       ' 2
     .db &B11111011       ' 3
     .db &B11110111       ' 4
    $end Asm
'===============================================================================

'===============================================================================
  Code_7seg_led_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
    $asm
     .db 0       ' 32 - "Пробел"
     .db 0       ' 33 - "!"
     .db 0 ' 34 - "" "
     .db 0       ' 35 - "#"
     .db 0       ' 36 - "$"
     .db 0       ' 37 - "%"
     .db 0       ' 38 - "&"
     .db 0       ' 39 - "'"
     .db 0       ' 40 - "("
     .db 0       ' 41 - ")"
     .db 0       ' 42 - "*"
     .db 0       ' 43 - "+"
     .db 0       ' 44 - ","
     .db &H40       ' 45 - "-"
     .db &H80       ' 46 - "."
     .db 0       ' 47 - "/"
     .db &H3F       ' 48 - "0"
     .db &H06       ' 49 - "1"
     .db &H5B       ' 50 - "2"
     .db &H4F       ' 51 - "3"
     .db &H66       ' 52 - "4"
     .db &H6D       ' 53 - "5"
     .db &H7D       ' 54 - "6"
     .db &H07       ' 55 - "7"
     .db &H7F       ' 56 - "8"
     .db &H6F       ' 57 - "9"
     .db 0       ' 58 - ":"
     .db 0       ' 59 - ";"
     .db 0       ' 60 - "<"
     .db 0       ' 61 - "="
     .db 0       ' 62 - ">"
     .db 0       ' 63 - "?"
     .db 0       ' 64 - "@"
     .db &H77       ' 65 - "A"
     .db 0       ' 66 - "B"
     .db &H39       ' 67 - "C"
     .db 0       ' 68 - "D"
     .db &H79       ' 69 - "E"
     .db &H71       ' 70 - "F"
     .db 0       ' 71 - "G"
     .db &H76       ' 72 - "H"
     .db &H06       ' 73 - "I"
     .db &H0E       ' 74 - "J"
     .db 0       ' 75 - "K"
     .db &H38       ' 76 - "L"
     .db 0       ' 77 - "M"
     .db 0       ' 78 - "N"
     .db &H3F       ' 79 - "O"
     .db &H73       ' 80 - "P"
     .db 0       ' 81 - "Q"
     .db 0       ' 82 - "R"
     .db &H6D       ' 83 - "S"
     .db 0       ' 84 - "T"
     .db &H3E       ' 85 - "U"
     .db 0       ' 86 - "V"
     .db 0       ' 87 - "W"
     .db 0       ' 88 - "X"
     .db &H6E       ' 89 - "Y"
     .db 0       ' 90 - "Z"
     .db &H39       ' 91 - "["
     .db 0       ' 92 - "\"
     .db &H0F       ' 93 - "]"
     .db 0       ' 94 - "^"
     .db &H08       ' 95 - "_" - подчёркивание
     .db 0       ' 96 - "`"
     .db 0       ' 97 - "a"
     .db &H7C       ' 98 - "b"
     .db &H58       ' 99 - "c"
     .db &H5E       ' 100 - "d"
     .db 0       ' 101 - "e"
     .db 0       ' 102 - "f"
     .db 0       ' 103 - "g"
     .db &H74       ' 104 - "h"
     .db 0       ' 105 - "i"
     .db 0       ' 106 - "j"
     .db 0       ' 107 - "k"
     .db 0       ' 108 - "l"
     .db 0       ' 109 - "m"
     .db &H54       ' 110 - "n"
     .db &H5C       ' 111 - "o"
     .db 0       ' 112 - "p"
     .db 0       ' 113 - "q"
     .db &H50       ' 114 - "r"
     .db 0       ' 115 - "s"
     .db &H78       ' 116 - "t"
     .db &H1C       ' 117 - "u"
    $end Asm
'===============================================================================

http://s6.uploads.ru/t/gpRcG.png http://s7.uploads.ru/t/skA3B.png

+1

11

Готовый драйвер 7-seg LED ОА + Atmega8  -  скачать

http://s8.uploads.ru/t/7l5zN.jpg

Готовый драйвер 7-seg LED ОК + Atmega8 - скачать

http://sf.uploads.ru/t/R7qDV.jpg

+1

12

Ещё вариант на ASM для двух четырёхразрядных индикаторов

Почему ASM, меньше размер кода (bascom = ~3 kb, ASM = 620 byte) при идентичном функционале + скорость выполнения

Развёртка индикаторов осуществляется через 3 сдвиговых регистра 74hc595, задействовано 3 вывода МК.

В прерывании разворачивается сразу 8 разрядов 2х4, поэтому timer можно настраивать с меньшей частотой, вполне достаточно 4 ms

Исходник универсальный ОА + ОК (тип индикатора выбирается константой).

Реализована табличная регулировка яркости 7-seg led индикаторов в логарифмической зависимости (плавность нарастания для глаз) с разрядностью (количество градаций): 16; 32; 64; 128; 256 бит (выбирается константой)

===========
Пример вывода:
===========

Number_indicator = 1                               -  порядковый номер индикатора: 1 или 2
Buffer_7seg_str = "-2.3°"                         -  выводимая строковая переменная, поддерживаются символы (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu °(градус))
Brightness_7seg_led = 10                         -  уровень яркости, количество ступеней в зависимости от (Const Brightness_levels = 16 '16; 32; 64; 128; 256)
Attribute_blink_digit = &B_0000_0100       -  признак мигания разрядов, используется первый полубайт
Gosub String_to_code_7seg_led                -  подпрограмма для преобразования строки в коды символов 7-seg led индикаторов

==============
Пример применения:
==============
Attiny45_85,  size = 2522 byte
Частота МК 1 МГц
Измерение напряжения аккумулятора 12v
Измерение температуры с ds18b20
Вывод на 2х4 разрядных 7-seg led индикатора

Симуляция (Proteus 7.10) + исходник (Bascom 2.0.7.1)  -  Скачать с google disk


Исходник драйвера с пустым главным циклом size = 620 byte

'===============================================================================

  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "attiny85.dat"       ' Используемый контроллер
  $crystal = 1000000       '1 МГц
  $framesize = 64       'Размер области используемой и необходимой для преобразований
  $hwstack = 64       ' Размер аппаратного стека
  $swstack = 64       ' Размер программного стека

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0

  On Timer0 Indication_7seg_led Nosave       ' Подпрограмма для обработки прерывания
  On Compare0a Adjustment_brightness_7seg_led Nosave       ' Подпрограмма для обработки прерывания регулировки яркости индикатора

'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================
  Clk_74hc595 Alias Portb.4 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.1 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.3 : Config Load_74hc595 = Output : Load_74hc595 = 0

'===============================================================================
'            И С П О Л Ь З У Е М Ы Е     К О Н С Т А Н Т Ы
'===============================================================================
  Const Const_amount_digit = 8       'Количество разрядов

'Количество ступеней яркости в логарифмической зависимости (плавность нарастания для глаз)
  Const Brightness_levels = 16       'Количество ступеней яркости: 16; 32; 64; 128; 256

  Const Type_indication_oa_ok = 1       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом

  #if Type_indication_oa_ok = 0
      Const Sumbol_gradus_celsius = &HF0       'Кодировка значка "°" градус цельсия
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_gradus_celsius = &H0F       'Кодировка значка "°" градус цельсия
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_space = &H00       'Кодировка значка "Пробел"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_space = &HFF       'Кодировка значка "Пробел"
  #endif

  Const Dot_7seg_led = &B_0000_0100       'Расположение точки в коде знакоместа 7seg led

  Const Frequency_blink = 250       'Константа для хранения значения частоты мигания при  Flag_blink_digit(n) = 1
  Const Duration_blink = Frequency_blink / 2       'Константа для хранения значения длительности горения знакоместа при Flag_blink_digit(n) = 1

'===============================================================================
'--------------   И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е  -------------
'===============================================================================
  Dim Count_digit As Byte       'Используется в обработчике прерывания TIMER0
  Dim Count_blink As Byte       'Счетчик для обработки частоты и длительности мигания, используется в подпрограмме "Indication_7seg_led"
  Dim Number_indicator As Byte       'На какой индикатор выводится информация
  Dim 1_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 2_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim Brightness_7seg_led As Byte       'Переменная для значения яркости 7-seg led
  Dim 1_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 1 индикатора
  Dim 2_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 2 индикатора
  Dim Attribute_blink_digit As Byte       'Все флаги мигания в одном байте
  Dim Buffer_7seg_str As String * 12       ' Выводимый строковый буфер 7-seg LED

'===============================================================================
'--------------  Разрешаем работу необходимых прерываний  ----------------------
'===============================================================================
  Enable Timer0       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
  Enable Compare0a
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'===============================================================================

'         Предварительная проверка и запуск

'===============================================================================

'16 ступеней яркости в логарифмической зависимости (плавность нарастания для глаз)
  Brightness_7seg_led = 16
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

        !nop

   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Main
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  String_to_code_7seg_led:
'-------------------------------------------------------------------------------
  'R15-R20; 'R26-R31 - используемые регистры
    !push R15
    !push R16
    !push R17
    !push R18
    !push R19
    !push R20
    !push R26
    !push R27
    !push R30
    !push R31

    !lds R20 , {Number_indicator}
    !cpi R20 , 2
    !BREQ Load_2_Buffer_7seg_str       'Перейти если равно

   Load_1_buffer_7seg_str:
    Loadadr 1_buffer_7seg_led(1) , X
    !rjmp Next_loadadr

   Load_2_buffer_7seg_str:
    Loadadr 2_buffer_7seg_led(1) , X

   Next_loadadr:
    Loadadr Buffer_7seg_str , Y
    Loadwordadr Sumbol_7seg_led_oa_ok
    !movw R18 , R30       'Сохраняем адрес таблицы символов, далее он (адрес) понадобится '

    !clr  R15
    !clr  R17

   Next_sumbol:
    !ld   R16 , Y+
    !tst  R16
    !breq End_sumbol_buffer_7seg_str       'Перейти если все символы в переменной "Buffer_7seg_str" закончились

   Check_46:       'Проверка на точку "."
    !cpi  R16 , 46
    !BRNE Check_176       'Перейти если не равно
    !ldi  R17 , Dot_7seg_led       'Добавляем точку в предыдущем разряде
    !ld   R16 , -X
    !eor  R16 , R17
    !st     X , R16
    !subi R26 , -1
    !rjmp Next_sumbol_5

   Check_176:       'Проверка на значёк градуса "°"
    !cpi  R16 , 176
    !BRNE Next_sumbol_3       'Перейти если не равно
    !ldi  R16 , Sumbol_gradus_celsius       'Выводим символ "°", значек градуса Сельсия
    !rjmp Next_sumbol_4

   Next_sumbol_3:
    !clr  R17
    !subi R16 , 32       'Убираем незначащие значения
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R16 , Z       'Забираем значение в коде 7-seg led

   Next_sumbol_4:
    !st    X+ , R16
    !inc  R15       'Считаем количество символов (кроме точек), потом понадобится выставлять признаки мигания разрядов

   Next_sumbol_5:
    !movw R30 , R18       'Забираем ранее сохранённый начальный адрес таблицы кодов 7-seg led
    !rjmp Next_sumbol

   End_sumbol_buffer_7seg_str:
    !cpi R20 , 2
    !BREQ Load_2_flag_blink_digit       'Перейти если равно

   Load_1_flag_blink_digit:
    Loadadr 1_flag_blink_digit(1) , X
    !rjmp Load_attribute_blink_digit

   Load_2_flag_blink_digit:
    Loadadr 2_flag_blink_digit(1) , X

   Load_attribute_blink_digit:
    !clr  R16
    !ldi  R17 , 1
    !lds  R18 , {Attribute_blink_digit}
    !SWAP R18

   Next_flag_blink_digit:
    !ROl R18       'Циклический сдвиг влево через C
    !BRCS Save_Flag_blink_1       'Перейти если перенос установлен

   Save_flag_blink_0:
    !st    X+ , R16
    !rjmp Next_flag_blink_digit_1

   Save_flag_blink_1:
    !st    X+ , R17

   Next_flag_blink_digit_1:
    !tst R15
    !BREQ Exit_string_to_code_7seg_led       'Перейти если равно
    !dec R15
    !brne Next_flag_blink_digit

   Exit_string_to_code_7seg_led:
    !pop R31
    !pop R30
    !pop R27
    !pop R26
    !pop R20
    !pop R19
    !pop R18
    !pop R17
    !pop R16
    !pop R15
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Indication_7seg_led:       '5 + 2 + 303 + 4 = 314  тактов Прерывание TIMER0, обработка 7-seg LED индикации
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16
    !push R17
    !push R30
    !push R31

   'Перебираем разряды 7-seg LED индикации
    !lds R16 , {Count_digit}
    !inc R16
    !cpi R16 , 4       'Const_amount_digit
    !BRLO Save_count_digit       'Перейти если меньше
    !clr R16
   Save_count_digit:
    !sts {Count_digit} , R16

   'Считам длительность и частоту мигания разрядов 7-seg LED индикаторов
    !lds R17 , {Count_blink}
    !cpi R17 , Frequency_blink
    !BRLO Save_Count_blink       'Перейти если меньше
    !clr R17
   Save_count_blink:
    !inc R17
    !sts {Count_blink} , R17

   'Собственно занимаемся миганием разрядов 7-seg LED индикаторов
    Loadadr 1_flag_blink_digit(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z

    !cpi R17 , 1
    !BRNE Load_1_buffer_7seg       'Перейти если не равно
    !lds R17 , {Count_blink}
    !cpi R17 ,  Duration_blink
    !BRLO Load_1_buffer_7seg       'Перейти если меньше

  #if Type_indication_oa_ok = 0
    !ldi R17 , &H00
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &HFF
  #endif

    !rjmp Distribution_segment_1_indicator

   Load_1_buffer_7seg:
    Loadadr 1_buffer_7seg_led(1) , Z
    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led

   Distribution_segment_1_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

'    !rjmp Exit_indication_7seg_led

   'Собственно занимаемся миганием разрядов 7-seg LED индикаторов
    Loadadr 2_flag_blink_digit(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z

    !cpi R17 , 1
    !BRNE Load_2_buffer_7seg       'Перейти если не равно
    !lds R17 , {Count_blink}
    !cpi R17 ,  Duration_blink
    !BRLO Load_2_buffer_7seg       'Перейти если меньше

  #if Type_indication_oa_ok = 0
    !ldi R17 , &H00
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &HFF
  #endif

    !rjmp Distribution_segment_2_indicator

   Load_2_buffer_7seg:
    Loadadr 2_buffer_7seg_led(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led

  'Раскидываем сегменты по ножкам МК
   Distribution_segment_2_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   Exit_indication_7seg_led:
    Loadwordadr Table_digit_oa_ok
    !lds  R16 , {Count_digit}
    !clr  R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение в коде 7-seg led

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

    Loadwordadr Table_brightness_7seg_led
    !lds R16 , {Brightness_7seg_led}
    !clr R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение яркости 7-seg led
    !sts ocr0a , R17       'Закидываем значения яркости в регистр OCR0A

    !pop R31
    !pop R30
    !pop R17
    !pop R16
    !out sreg , R16
    !pop R16

   !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
   Write_74hc595:
'-------------------------------------------------------------------------------
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R17 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R17 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R17       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0

    !dec R31       ' Считаем биты
    !brne Next_Bit
'-------------------------------------------------------------------------------
   !ret
'===============================================================================

'===============================================================================
  Adjustment_brightness_7seg_led:       '5+2+...+4   'Подпрограмма гашения индикаторов
'-------------------------------------------------------------------------------
    !push R17
    !in R17 , sreg
    !push R17
    !push R31

  #if Type_indication_oa_ok = 0
    !ldi R17 , &B_0000_0000       'Сегменты 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !ldi R17 , &B_1111_1111       'Разряды 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &B_1111_1111       'Сегменты 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !ldi R17 , &B_0000_0000       'Разряды 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
  #endif

   Exit_brightness_7seg_led:
   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

    !pop R31
    !pop R17
    !out sreg , R17
    !pop R17

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Table_brightness_7seg_led:
'-------------------------------------------------------------------------------
#if Brightness_levels = 16
    Data 0 , 3 , 8 , 15 , 24 , 35 , 48 , 63 , 80 , 99 , 120 , 143 , 168 , 195 , 224 , 255
#endif
#if Brightness_levels = 32
    Data 0 , 0 , 2 , 3 , 6 , 8 , 12 , 15 , 20 , 24 , 30 , 35 , 42 , 48 , 56 , 63
    Data 71 , 80 , 89 , 99 , 109 , 120 , 131 , 143 , 155 , 168 , 181 , 195 , 209 , 224 , 239 , 255
#endif
#if Brightness_levels = 64
    Data 0 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 5 , 6 , 7 , 8 , 10 , 12 , 14 , 15
    Data 17 , 20 , 22 , 24 , 27 , 30 , 32 , 35 , 38 , 42 , 45 , 48 , 52 , 56 , 59 , 63
    Data 67 , 71 , 76 , 80 , 85 , 89 , 94 , 99 , 104 , 109 , 115 , 120 , 126 , 131 , 137 , 143
    Data 149 , 155 , 161 , 168 , 174 , 181 , 188 , 195 , 202 , 209 , 216 , 224 , 231 , 239 , 247 , 255
#endif
#if Brightness_levels = 128
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 3
    Data 4 , 5 , 5 , 6 , 6 , 7 , 8 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 14 , 15
    Data 16 , 17 , 19 , 20 , 21 , 22 , 23 , 24 , 26 , 27 , 28 , 30 , 31 , 32 , 34 , 35
    Data 37 , 38 , 40 , 42 , 43 , 45 , 47 , 48 , 50 , 52 , 54 , 56 , 57 , 59 , 61 , 63
    Data 65 , 67 , 69 , 71 , 74 , 76 , 78 , 80 , 82 , 85 , 87 , 89 , 92 , 94 , 97 , 99
    Data 102 , 104 , 107 , 109 , 112 , 115 , 117 , 120 , 123 , 126 , 128 , 131 , 134 , 137 , 140 , 143
    Data 146 , 149 , 152 , 155 , 158 , 161 , 165 , 168 , 171 , 174 , 178 , 181 , 184 , 188 , 191 , 195
    Data 198 , 202 , 205 , 209 , 213 , 216 , 220 , 224 , 227 , 231 , 235 , 239 , 243 , 247 , 251 , 255
#endif
#if Brightness_levels = 256
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
    Data 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3
    Data 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8
    Data 9 , 9 , 10 , 10 , 10 , 11 , 11 , 12 , 12 , 13 , 13 , 14 , 14 , 14 , 15 , 15
    Data 16 , 16 , 17 , 17 , 18 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 23 , 23 , 24 , 24
    Data 25 , 26 , 26 , 27 , 28 , 28 , 29 , 30 , 30 , 31 , 32 , 32 , 33 , 34 , 35 , 35
    Data 36 , 37 , 38 , 38 , 39 , 40 , 41 , 42 , 42 , 43 , 44 , 45 , 46 , 47 , 47 , 48
    Data 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63
    Data 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80
    Data 81 , 82 , 84 , 85 , 86 , 87 , 88 , 89 , 91 , 92 , 93 , 94 , 95 , 97 , 98 , 99
    Data 100 , 102 , 103 , 104 , 105 , 107 , 108 , 109 , 111 , 112 , 113 , 115 , 116 , 117 , 119 , 120
    Data 121 , 123 , 124 , 126 , 127 , 128 , 130 , 131 , 133 , 134 , 136 , 137 , 138 , 140 , 141 , 143
    Data 144 , 146 , 147 , 149 , 151 , 152 , 154 , 155 , 157 , 158 , 160 , 161 , 163 , 165 , 166 , 168
    Data 169 , 171 , 173 , 174 , 176 , 178 , 179 , 181 , 183 , 184 , 186 , 188 , 190 , 191 , 193 , 195
    Data 196 , 198 , 200 , 202 , 204 , 205 , 207 , 209 , 211 , 213 , 214 , 216 , 218 , 220 , 222 , 224
    Data 225 , 227 , 229 , 231 , 233 , 235 , 237 , 239 , 241 , 243 , 245 , 247 , 249 , 251 , 253 , 255
#endif
'===============================================================================

'===============================================================================
  Table_digit_oa_ok:
'-------------------------------------------------------------------------------
  'Кодировка разрядов
  '    8765_4321  -  разряды
  ' &B_0000_0000  -  расположение в байте
'------------------------------------------
#if Type_indication_oa_ok = 0
    Data &B_1110_1110       ' 1; 5
    Data &B_1101_1101       ' 2; 6
    Data &B_1011_1011       ' 3; 7
    Data &B_0111_0111       ' 4; 8
#endif

#if Type_indication_oa_ok = 1
    Data &B_0001_0001       ' 1; 5
    Data &B_0010_0010       ' 2; 6
    Data &B_0100_0100       ' 3; 7
    Data &B_1000_1000       ' 4; 8
#endif
'===============================================================================

'===============================================================================
  Sumbol_7seg_led_oa_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
  'Кодировка сегментов
  '    fbad_cghe      gfed cbah  -  сегменты
  ' &B_0000_0000  -  расположение в байте
  '
  'Выводимые символы  -  (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu)
#if Type_indication_oa_ok = 0
    $asm
     .db 0       '    32 - "Пробел"
     .db 0       '    33 - "!"
     .db 0 '''''''''' 34 - "" "
     .db 0       '    35 - "#"
     .db 0       '    36 - "$"
     .db 0       '    37 - "%"
     .db 0       '    38 - "&"
     .db 0       '    39 - "'"
     .db 0       '    40 - "("
     .db 0       '    41 - ")"
     .db 0       '    42 - "*"
     .db 0       '    43 - "+"
     .db 0       '    44 - ","
     .db &H10       ' 45 - "-"
     .db &H04       ' 46 - "."
     .db 0       '    47 - "/"
     .db &HEB       ' 48 - "0"
     .db &H28       ' 49 - "1"
     .db &HB3       ' 50 - "2"
     .db &HBA       ' 51 - "3"
     .db &H78       ' 52 - "4"
     .db &HDA       ' 53 - "5"
     .db &HDB       ' 54 - "6"
     .db &HA8       ' 55 - "7"
     .db &HFB       ' 56 - "8"
     .db &HFA       ' 57 - "9"
     .db 0       '    58 - ":"
     .db 0       '    59 - ";"
     .db 0       '    60 - "<"
     .db 0       '    61 - "="
     .db 0       '    62 - ">"
     .db 0       '    63 - "?"
     .db 0       '    64 - "@"
     .db &HF9       ' 65 - "A"
     .db 0       '    66 - "B"
     .db &HC3       ' 67 - "C"
     .db 0       '    68 - "D"
     .db &HD3       ' 69 - "E"
     .db &HD1       ' 70 - "F"
     .db &HCB       ' 71 - "G"
     .db &H79       ' 72 - "H"
     .db &H41       ' 73 - "I"
     .db &H2A       ' 74 - "J"
     .db 0       '    75 - "K"
     .db &H43       ' 76 - "L"
     .db 0       '    77 - "M"
     .db 0       '    78 - "N"
     .db &HEB       ' 79 - "O"
     .db &HF1       ' 80 - "P"
     .db 0       '    81 - "Q"
     .db 0       '    82 - "R"
     .db &HDA       ' 83 - "S"
     .db 0       '    84 - "T"
     .db &H6B       ' 85 - "U"
     .db 0       '    86 - "V"
     .db 0       '    87 - "W"
     .db 0       '    88 - "X"
     .db &H7A       ' 89 - "Y"
     .db 0       '    90 - "Z"
     .db &HC3       ' 91 - "["
     .db 0       '    92 - "\"
     .db &HAA       ' 93 - "]"
     .db 0       '    94 - "^"
     .db &H02       ' 95 - "_" - подчёркивание
     .db 0       '    96 - "`"
     .db 0       '    97 - "a"
     .db &H5B       ' 98 - "b"
     .db &H13       ' 99 - "c"
     .db &H3B       '100 - "d"
     .db 0       '   101 - "e"
     .db 0       '   102 - "f"
     .db 0       '   103 - "g"
     .db &H59       '104 - "h"
     .db &H01       '105 - "i"
     .db 0       '   106 - "j"
     .db 0       '   107 - "k"
     .db &H41       '108 - "l"
     .db 0       '   109 - "m"
     .db &H19       '110 - "n"
     .db &H1B       '111 - "o"
     .db 0       '   112 - "p"
     .db 0       '   113 - "q"
     .db &H11       '114 - "r"
     .db 0       '   115 - "s"
     .db &H53       '116 - "t"
     .db &H0B       '117 - "u"
    $end Asm
#endif

#if Type_indication_oa_ok = 1
    $asm
     .db &HFF       '    32 - "Пробел"
     .db 0       '    33 - "!"
     .db 0 '''''''''' 34 - "" "
     .db 0       '    35 - "#"
     .db 0       '    36 - "$"
     .db 0       '    37 - "%"
     .db 0       '    38 - "&"
     .db 0       '    39 - "'"
     .db 0       '    40 - "("
     .db 0       '    41 - ")"
     .db 0       '    42 - "*"
     .db 0       '    43 - "+"
     .db 0       '    44 - ","
     .db &HEF       ' 45 - "-"
     .db &HFB       ' 46 - "."
     .db 0       '    47 - "/"
     .db &H14       ' 48 - "0"
     .db &HD7       ' 49 - "1"
     .db &H4C       ' 50 - "2"
     .db &H45       ' 51 - "3"
     .db &H87       ' 52 - "4"
     .db &H25       ' 53 - "5"
     .db &H24       ' 54 - "6"
     .db &H57       ' 55 - "7"
     .db &H04       ' 56 - "8"
     .db &H05       ' 57 - "9"
     .db 0       '    58 - ":"
     .db 0       '    59 - ";"
     .db 0       '    60 - "<"
     .db 0       '    61 - "="
     .db 0       '    62 - ">"
     .db 0       '    63 - "?"
     .db 0       '    64 - "@"
     .db &H06       ' 65 - "A"
     .db 0       '    66 - "B"
     .db &H3C       ' 67 - "C"
     .db 0       '    68 - "D"
     .db &H2C       ' 69 - "E"
     .db &H2E       ' 70 - "F"
     .db &H34       ' 71 - "G"
     .db &H86       ' 72 - "H"
     .db &HBE       ' 73 - "I"
     .db &HD5       ' 74 - "J"
     .db 0       '    75 - "K"
     .db &HBC       ' 76 - "L"
     .db 0       '    77 - "M"
     .db 0       '    78 - "N"
     .db &H14       ' 79 - "O"
     .db &H0E       ' 80 - "P"
     .db 0       '    81 - "Q"
     .db 0       '    82 - "R"
     .db &H25       ' 83 - "S"
     .db 0       '    84 - "T"
     .db &H94       ' 85 - "U"
     .db 0       '    86 - "V"
     .db 0       '    87 - "W"
     .db 0       '    88 - "X"
     .db &H85       ' 89 - "Y"
     .db 0       '    90 - "Z"
     .db &H3C       ' 91 - "["
     .db 0       '    92 - "\"
     .db &H55       ' 93 - "]"
     .db 0       '    94 - "^"
     .db &HFD       ' 95 - "_" - подчёркивание
     .db 0       '    96 - "`"
     .db 0       '    97 - "a"
     .db &HA4       ' 98 - "b"
     .db &HEC       ' 99 - "c"
     .db &HC4       '100 - "d"
     .db 0       '   101 - "e"
     .db 0       '   102 - "f"
     .db 0       '   103 - "g"
     .db &HA6       '104 - "h"
     .db &HFE       '105 - "i"
     .db 0       '   106 - "j"
     .db 0       '   107 - "k"
     .db &HBE       '108 - "l"
     .db 0       '   109 - "m"
     .db &HE6       '110 - "n"
     .db &HE4       '111 - "o"
     .db 0       '   112 - "p"
     .db 0       '   113 - "q"
     .db &HEE       '114 - "r"
     .db 0       '   115 - "s"
     .db &HAC       '116 - "t"
     .db &HF4       '117 - "u"
    $end Asm
#endif
'===============================================================================

Исходник драйвера с примером применения

'===============================================================================

  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "attiny85.dat"       ' Используемый контроллер
  $crystal = 1000000       '1 МГц
  $framesize = 64       'Размер области используемой и необходимой для преобразований
  $hwstack = 64       ' Размер аппаратного стека
  $swstack = 64       ' Размер программного стека

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0

  On Timer0 Indication_7seg_led Nosave       ' Подпрограмма для обработки прерывания
  On Compare0a Adjustment_brightness_7seg_led Nosave       ' Подпрограмма для обработки прерывания регулировки яркости индикатора

'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================
  Clk_74hc595 Alias Portb.4 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.1 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.3 : Config Load_74hc595 = Output : Load_74hc595 = 0

'===============================================================================
'            И С П О Л Ь З У Е М Ы Е     К О Н С Т А Н Т Ы
'===============================================================================
  Const Const_amount_digit = 8       'Количество разрядов

'Количество ступеней яркости в логарифмической зависимости (плавность нарастания для глаз)
  Const Brightness_levels = 16       'Количество ступеней яркости: 16; 32; 64; 128; 256

  Const Type_indication_oa_ok = 1       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом

  #if Type_indication_oa_ok = 0
      Const Sumbol_gradus_celsius = &HF0       'Кодировка значка "°" градус цельсия
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_gradus_celsius = &H0F       'Кодировка значка "°" градус цельсия
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_space = &H00       'Кодировка значка "Пробел"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_space = &HFF       'Кодировка значка "Пробел"
  #endif

  Const Dot_7seg_led = &B_0000_0100       'Расположение точки в коде знакоместа 7seg led

  Const Frequency_blink = 250       'Константа для хранения значения частоты мигания при  Flag_blink_digit(n) = 1
  Const Duration_blink = Frequency_blink / 2       'Константа для хранения значения длительности горения знакоместа при Flag_blink_digit(n) = 1

'===============================================================================
'--------------   И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е  -------------
'===============================================================================
  Dim Count_digit As Byte       'Используется в обработчике прерывания TIMER0
  Dim Count_blink As Byte       'Счетчик для обработки частоты и длительности мигания, используется в подпрограмме "Indication_7seg_led"
  Dim Number_indicator As Byte       'На какой индикатор выводится информация
  Dim 1_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 2_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim Brightness_7seg_led As Byte       'Переменная для значения яркости 7-seg led
  Dim 1_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 1 индикатора
  Dim 2_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 2 индикатора
  Dim Attribute_blink_digit As Byte       'Все флаги мигания в одном байте
  Dim Buffer_7seg_str As String * 12       ' Выводимый строковый буфер 7-seg LED

'===============================================================================
'--------------  Разрешаем работу необходимых прерываний  ----------------------
'===============================================================================
  Enable Timer0       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
  Enable Compare0a
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'===============================================================================

'         Предварительная проверка и запуск

'===============================================================================

'16 ступеней яркости в логарифмической зависимости (плавность нарастания для глаз)
  Brightness_7seg_led = 16
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

        Number_indicator = 1
        Buffer_7seg_str = "--.-°"
       ' Brightness_7seg_led = 4
        Attribute_blink_digit = &B_0000_1110
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = "--.-°"
        'Brightness_7seg_led = 6
        Attribute_blink_digit = &B_0000_0000
        Gosub String_to_code_7seg_led
        Wait 2

        Number_indicator = 1
        Buffer_7seg_str = "--.-°"
       ' Brightness_7seg_led = 4
        Attribute_blink_digit = &B_0000_0000
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = "--.-°"
        'Brightness_7seg_led = 6
        Attribute_blink_digit = &B_0000_1110
        Gosub String_to_code_7seg_led
        Wait 2

        Number_indicator = 1
        Buffer_7seg_str = "-2.3°"
        'Brightness_7seg_led = 4
        Attribute_blink_digit = &B_0000_0100
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = "12.3U"
        'Brightness_7seg_led = 6
        Attribute_blink_digit = &B_0000_0010
        Gosub String_to_code_7seg_led
        Wait 2

        Number_indicator = 1
        Buffer_7seg_str = "12.3°"
       ' Brightness_7seg_led = 8
        Attribute_blink_digit = &B_0000_1000
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = " 0.0U"
       ' Brightness_7seg_led = 8
        Attribute_blink_digit = &B_0000_0001
        Gosub String_to_code_7seg_led
        Wait 2

        Number_indicator = 1
        Buffer_7seg_str = "Err°"
       ' Brightness_7seg_led = 10
        Attribute_blink_digit = &B_0000_1110
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = "ErrU"
       ' Brightness_7seg_led = 10
        Attribute_blink_digit = &B_0001_1110
        Gosub String_to_code_7seg_led
        Wait 2

        Number_indicator = 1
        Buffer_7seg_str = "Abcd"
       ' Brightness_7seg_led = 12
        Attribute_blink_digit = &B_0000_1111
        Gosub String_to_code_7seg_led

        Number_indicator = 2
        Buffer_7seg_str = "EFHJ"
       ' Brightness_7seg_led = 12
        Attribute_blink_digit = &B_0000_1111
        Gosub String_to_code_7seg_led
        Wait 2

        !nop

   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Main
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  String_to_code_7seg_led:
'-------------------------------------------------------------------------------
  'R15-R20; 'R26-R31 - используемые регистры
    !push R15
    !push R16
    !push R17
    !push R18
    !push R19
    !push R20
    !push R26
    !push R27
    !push R30
    !push R31

    !lds R20 , {Number_indicator}
    !cpi R20 , 2
    !BREQ Load_2_Buffer_7seg_str       'Перейти если равно

   Load_1_buffer_7seg_str:
    Loadadr 1_buffer_7seg_led(1) , X
    !rjmp Next_loadadr

   Load_2_buffer_7seg_str:
    Loadadr 2_buffer_7seg_led(1) , X

   Next_loadadr:
    Loadadr Buffer_7seg_str , Y
    Loadwordadr Sumbol_7seg_led_oa_ok
    !movw R18 , R30       'Сохраняем адрес таблицы символов, далее он (адрес) понадобится '

    !clr  R15
    !clr  R17

   Next_sumbol:
    !ld   R16 , Y+
    !tst  R16
    !breq End_sumbol_buffer_7seg_str       'Перейти если все символы в переменной "Buffer_7seg_str" закончились

   Check_46:       'Проверка на точку "."
    !cpi  R16 , 46
    !BRNE Check_176       'Перейти если не равно
    !ldi  R17 , Dot_7seg_led       'Добавляем точку в предыдущем разряде
    !ld   R16 , -X
    !eor  R16 , R17
    !st     X , R16
    !subi R26 , -1
    !rjmp Next_sumbol_5

   Check_176:       'Проверка на значёк градуса "°"
    !cpi  R16 , 176
    !BRNE Next_sumbol_3       'Перейти если не равно
    !ldi  R16 , Sumbol_gradus_celsius       'Выводим символ "°", значек градуса Сельсия
    !rjmp Next_sumbol_4

   Next_sumbol_3:
    !clr  R17
    !subi R16 , 32       'Убираем незначащие значения
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R16 , Z       'Забираем значение в коде 7-seg led

   Next_sumbol_4:
    !st    X+ , R16
    !inc  R15       'Считаем количество символов (кроме точек), потом понадобится выставлять признаки мигания разрядов

   Next_sumbol_5:
    !movw R30 , R18       'Забираем ранее сохранённый начальный адрес таблицы кодов 7-seg led
    !rjmp Next_sumbol

   End_sumbol_buffer_7seg_str:
    !cpi R20 , 2
    !BREQ Load_2_flag_blink_digit       'Перейти если равно

   Load_1_flag_blink_digit:
    Loadadr 1_flag_blink_digit(1) , X
    !rjmp Load_attribute_blink_digit

   Load_2_flag_blink_digit:
    Loadadr 2_flag_blink_digit(1) , X

   Load_attribute_blink_digit:
    !clr  R16
    !ldi  R17 , 1
    !lds  R18 , {Attribute_blink_digit}
    !SWAP R18

   Next_flag_blink_digit:
    !ROl R18       'Циклический сдвиг влево через C
    !BRCS Save_Flag_blink_1       'Перейти если перенос установлен

   Save_flag_blink_0:
    !st    X+ , R16
    !rjmp Next_flag_blink_digit_1

   Save_flag_blink_1:
    !st    X+ , R17

   Next_flag_blink_digit_1:
    !tst R15
    !BREQ Exit_string_to_code_7seg_led       'Перейти если равно
    !dec R15
    !brne Next_flag_blink_digit

   Exit_string_to_code_7seg_led:
    !pop R31
    !pop R30
    !pop R27
    !pop R26
    !pop R20
    !pop R19
    !pop R18
    !pop R17
    !pop R16
    !pop R15
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Indication_7seg_led:       '5 + 2 + 303 + 4 = 314  тактов Прерывание TIMER0, обработка 7-seg LED индикации
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16
    !push R17
    !push R30
    !push R31

   'Перебираем разряды 7-seg LED индикации
    !lds R16 , {Count_digit}
    !inc R16
    !cpi R16 , 4       'Const_amount_digit
    !BRLO Save_count_digit       'Перейти если меньше
    !clr R16
   Save_count_digit:
    !sts {Count_digit} , R16

   'Считам длительность и частоту мигания разрядов 7-seg LED индикаторов
    !lds R17 , {Count_blink}
    !cpi R17 , Frequency_blink
    !BRLO Save_Count_blink       'Перейти если меньше
    !clr R17
   Save_count_blink:
    !inc R17
    !sts {Count_blink} , R17

   'Собственно занимаемся миганием разрядов 7-seg LED индикаторов
    Loadadr 1_flag_blink_digit(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z

    !cpi R17 , 1
    !BRNE Load_1_buffer_7seg       'Перейти если не равно
    !lds R17 , {Count_blink}
    !cpi R17 ,  Duration_blink
    !BRLO Load_1_buffer_7seg       'Перейти если меньше

  #if Type_indication_oa_ok = 0
    !ldi R17 , &H00
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &HFF
  #endif

    !rjmp Distribution_segment_1_indicator

   Load_1_buffer_7seg:
    Loadadr 1_buffer_7seg_led(1) , Z
    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led

   Distribution_segment_1_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

'    !rjmp Exit_indication_7seg_led

   'Собственно занимаемся миганием разрядов 7-seg LED индикаторов
    Loadadr 2_flag_blink_digit(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z

    !cpi R17 , 1
    !BRNE Load_2_buffer_7seg       'Перейти если не равно
    !lds R17 , {Count_blink}
    !cpi R17 ,  Duration_blink
    !BRLO Load_2_buffer_7seg       'Перейти если меньше

  #if Type_indication_oa_ok = 0
    !ldi R17 , &H00
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &HFF
  #endif

    !rjmp Distribution_segment_2_indicator

   Load_2_buffer_7seg:
    Loadadr 2_buffer_7seg_led(1) , Z

    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led

  'Раскидываем сегменты по ножкам МК
   Distribution_segment_2_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   Exit_indication_7seg_led:
    Loadwordadr Table_digit_oa_ok
    !lds  R16 , {Count_digit}
    !clr  R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение в коде 7-seg led

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

    Loadwordadr Table_brightness_7seg_led
    !lds R16 , {Brightness_7seg_led}
    !clr R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение яркости 7-seg led
    !sts ocr0a , R17       'Закидываем значения яркости в регистр OCR0A

    !pop R31
    !pop R30
    !pop R17
    !pop R16
    !out sreg , R16
    !pop R16

   !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
   Write_74hc595:
'-------------------------------------------------------------------------------
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R17 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R17 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R17       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0

    !dec R31       ' Считаем биты
    !brne Next_Bit
'-------------------------------------------------------------------------------
   !ret
'===============================================================================

'===============================================================================
  Adjustment_brightness_7seg_led:       '5+2+...+4   'Подпрограмма гашения индикаторов
'-------------------------------------------------------------------------------
    !push R17
    !in R17 , sreg
    !push R17
    !push R31

  #if Type_indication_oa_ok = 0
    !ldi R17 , &B_0000_0000       'Сегменты 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !ldi R17 , &B_1111_1111       'Разряды 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
  #endif
  #if Type_indication_oa_ok = 1
    !ldi R17 , &B_1111_1111       'Сегменты 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
    !ldi R17 , &B_0000_0000       'Разряды 7seg_led
    !rCALL Write_74hc595       ' Закидываем данные в 74HC595
  #endif

   Exit_brightness_7seg_led:
   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

    !pop R31
    !pop R17
    !out sreg , R17
    !pop R17

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Table_brightness_7seg_led:
'-------------------------------------------------------------------------------
#if Brightness_levels = 16
    Data 0 , 3 , 8 , 15 , 24 , 35 , 48 , 63 , 80 , 99 , 120 , 143 , 168 , 195 , 224 , 255
#endif
#if Brightness_levels = 32
    Data 0 , 0 , 2 , 3 , 6 , 8 , 12 , 15 , 20 , 24 , 30 , 35 , 42 , 48 , 56 , 63
    Data 71 , 80 , 89 , 99 , 109 , 120 , 131 , 143 , 155 , 168 , 181 , 195 , 209 , 224 , 239 , 255
#endif
#if Brightness_levels = 64
    Data 0 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 5 , 6 , 7 , 8 , 10 , 12 , 14 , 15
    Data 17 , 20 , 22 , 24 , 27 , 30 , 32 , 35 , 38 , 42 , 45 , 48 , 52 , 56 , 59 , 63
    Data 67 , 71 , 76 , 80 , 85 , 89 , 94 , 99 , 104 , 109 , 115 , 120 , 126 , 131 , 137 , 143
    Data 149 , 155 , 161 , 168 , 174 , 181 , 188 , 195 , 202 , 209 , 216 , 224 , 231 , 239 , 247 , 255
#endif
#if Brightness_levels = 128
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 3
    Data 4 , 5 , 5 , 6 , 6 , 7 , 8 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 14 , 15
    Data 16 , 17 , 19 , 20 , 21 , 22 , 23 , 24 , 26 , 27 , 28 , 30 , 31 , 32 , 34 , 35
    Data 37 , 38 , 40 , 42 , 43 , 45 , 47 , 48 , 50 , 52 , 54 , 56 , 57 , 59 , 61 , 63
    Data 65 , 67 , 69 , 71 , 74 , 76 , 78 , 80 , 82 , 85 , 87 , 89 , 92 , 94 , 97 , 99
    Data 102 , 104 , 107 , 109 , 112 , 115 , 117 , 120 , 123 , 126 , 128 , 131 , 134 , 137 , 140 , 143
    Data 146 , 149 , 152 , 155 , 158 , 161 , 165 , 168 , 171 , 174 , 178 , 181 , 184 , 188 , 191 , 195
    Data 198 , 202 , 205 , 209 , 213 , 216 , 220 , 224 , 227 , 231 , 235 , 239 , 243 , 247 , 251 , 255
#endif
#if Brightness_levels = 256
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
    Data 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3
    Data 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8
    Data 9 , 9 , 10 , 10 , 10 , 11 , 11 , 12 , 12 , 13 , 13 , 14 , 14 , 14 , 15 , 15
    Data 16 , 16 , 17 , 17 , 18 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 23 , 23 , 24 , 24
    Data 25 , 26 , 26 , 27 , 28 , 28 , 29 , 30 , 30 , 31 , 32 , 32 , 33 , 34 , 35 , 35
    Data 36 , 37 , 38 , 38 , 39 , 40 , 41 , 42 , 42 , 43 , 44 , 45 , 46 , 47 , 47 , 48
    Data 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63
    Data 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80
    Data 81 , 82 , 84 , 85 , 86 , 87 , 88 , 89 , 91 , 92 , 93 , 94 , 95 , 97 , 98 , 99
    Data 100 , 102 , 103 , 104 , 105 , 107 , 108 , 109 , 111 , 112 , 113 , 115 , 116 , 117 , 119 , 120
    Data 121 , 123 , 124 , 126 , 127 , 128 , 130 , 131 , 133 , 134 , 136 , 137 , 138 , 140 , 141 , 143
    Data 144 , 146 , 147 , 149 , 151 , 152 , 154 , 155 , 157 , 158 , 160 , 161 , 163 , 165 , 166 , 168
    Data 169 , 171 , 173 , 174 , 176 , 178 , 179 , 181 , 183 , 184 , 186 , 188 , 190 , 191 , 193 , 195
    Data 196 , 198 , 200 , 202 , 204 , 205 , 207 , 209 , 211 , 213 , 214 , 216 , 218 , 220 , 222 , 224
    Data 225 , 227 , 229 , 231 , 233 , 235 , 237 , 239 , 241 , 243 , 245 , 247 , 249 , 251 , 253 , 255
#endif
'===============================================================================

'===============================================================================
  Table_digit_oa_ok:
'-------------------------------------------------------------------------------
  'Кодировка разрядов
  '    8765_4321  -  разряды
  ' &B_0000_0000  -  расположение в байте
'------------------------------------------
#if Type_indication_oa_ok = 0
    Data &B_1110_1110       ' 1; 5
    Data &B_1101_1101       ' 2; 6
    Data &B_1011_1011       ' 3; 7
    Data &B_0111_0111       ' 4; 8
#endif

#if Type_indication_oa_ok = 1
    Data &B_0001_0001       ' 1; 5
    Data &B_0010_0010       ' 2; 6
    Data &B_0100_0100       ' 3; 7
    Data &B_1000_1000       ' 4; 8
#endif
'===============================================================================

'===============================================================================
  Sumbol_7seg_led_oa_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
  'Кодировка сегментов
  '    fbad_cghe      gfed cbah  -  сегменты
  ' &B_0000_0000  -  расположение в байте
  '
  'Выводимые символы  -  (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu)
#if Type_indication_oa_ok = 0
    $asm
     .db 0       '    32 - "Пробел"
     .db 0       '    33 - "!"
     .db 0 '''''''''' 34 - "" "
     .db 0       '    35 - "#"
     .db 0       '    36 - "$"
     .db 0       '    37 - "%"
     .db 0       '    38 - "&"
     .db 0       '    39 - "'"
     .db 0       '    40 - "("
     .db 0       '    41 - ")"
     .db 0       '    42 - "*"
     .db 0       '    43 - "+"
     .db 0       '    44 - ","
     .db &H10       ' 45 - "-"
     .db &H04       ' 46 - "."
     .db 0       '    47 - "/"
     .db &HEB       ' 48 - "0"
     .db &H28       ' 49 - "1"
     .db &HB3       ' 50 - "2"
     .db &HBA       ' 51 - "3"
     .db &H78       ' 52 - "4"
     .db &HDA       ' 53 - "5"
     .db &HDB       ' 54 - "6"
     .db &HA8       ' 55 - "7"
     .db &HFB       ' 56 - "8"
     .db &HFA       ' 57 - "9"
     .db 0       '    58 - ":"
     .db 0       '    59 - ";"
     .db 0       '    60 - "<"
     .db 0       '    61 - "="
     .db 0       '    62 - ">"
     .db 0       '    63 - "?"
     .db 0       '    64 - "@"
     .db &HF9       ' 65 - "A"
     .db 0       '    66 - "B"
     .db &HC3       ' 67 - "C"
     .db 0       '    68 - "D"
     .db &HD3       ' 69 - "E"
     .db &HD1       ' 70 - "F"
     .db &HCB       ' 71 - "G"
     .db &H79       ' 72 - "H"
     .db &H41       ' 73 - "I"
     .db &H2A       ' 74 - "J"
     .db 0       '    75 - "K"
     .db &H43       ' 76 - "L"
     .db 0       '    77 - "M"
     .db 0       '    78 - "N"
     .db &HEB       ' 79 - "O"
     .db &HF1       ' 80 - "P"
     .db 0       '    81 - "Q"
     .db 0       '    82 - "R"
     .db &HDA       ' 83 - "S"
     .db 0       '    84 - "T"
     .db &H6B       ' 85 - "U"
     .db 0       '    86 - "V"
     .db 0       '    87 - "W"
     .db 0       '    88 - "X"
     .db &H7A       ' 89 - "Y"
     .db 0       '    90 - "Z"
     .db &HC3       ' 91 - "["
     .db 0       '    92 - "\"
     .db &HAA       ' 93 - "]"
     .db 0       '    94 - "^"
     .db &H02       ' 95 - "_" - подчёркивание
     .db 0       '    96 - "`"
     .db 0       '    97 - "a"
     .db &H5B       ' 98 - "b"
     .db &H13       ' 99 - "c"
     .db &H3B       '100 - "d"
     .db 0       '   101 - "e"
     .db 0       '   102 - "f"
     .db 0       '   103 - "g"
     .db &H59       '104 - "h"
     .db &H01       '105 - "i"
     .db 0       '   106 - "j"
     .db 0       '   107 - "k"
     .db &H41       '108 - "l"
     .db 0       '   109 - "m"
     .db &H19       '110 - "n"
     .db &H1B       '111 - "o"
     .db 0       '   112 - "p"
     .db 0       '   113 - "q"
     .db &H11       '114 - "r"
     .db 0       '   115 - "s"
     .db &H53       '116 - "t"
     .db &H0B       '117 - "u"
    $end Asm
#endif

#if Type_indication_oa_ok = 1
    $asm
     .db &HFF       '    32 - "Пробел"
     .db 0       '    33 - "!"
     .db 0 '''''''''' 34 - "" "
     .db 0       '    35 - "#"
     .db 0       '    36 - "$"
     .db 0       '    37 - "%"
     .db 0       '    38 - "&"
     .db 0       '    39 - "'"
     .db 0       '    40 - "("
     .db 0       '    41 - ")"
     .db 0       '    42 - "*"
     .db 0       '    43 - "+"
     .db 0       '    44 - ","
     .db &HEF       ' 45 - "-"
     .db &HFB       ' 46 - "."
     .db 0       '    47 - "/"
     .db &H14       ' 48 - "0"
     .db &HD7       ' 49 - "1"
     .db &H4C       ' 50 - "2"
     .db &H45       ' 51 - "3"
     .db &H87       ' 52 - "4"
     .db &H25       ' 53 - "5"
     .db &H24       ' 54 - "6"
     .db &H57       ' 55 - "7"
     .db &H04       ' 56 - "8"
     .db &H05       ' 57 - "9"
     .db 0       '    58 - ":"
     .db 0       '    59 - ";"
     .db 0       '    60 - "<"
     .db 0       '    61 - "="
     .db 0       '    62 - ">"
     .db 0       '    63 - "?"
     .db 0       '    64 - "@"
     .db &H06       ' 65 - "A"
     .db 0       '    66 - "B"
     .db &H3C       ' 67 - "C"
     .db 0       '    68 - "D"
     .db &H2C       ' 69 - "E"
     .db &H2E       ' 70 - "F"
     .db &H34       ' 71 - "G"
     .db &H86       ' 72 - "H"
     .db &HBE       ' 73 - "I"
     .db &HD5       ' 74 - "J"
     .db 0       '    75 - "K"
     .db &HBC       ' 76 - "L"
     .db 0       '    77 - "M"
     .db 0       '    78 - "N"
     .db &H14       ' 79 - "O"
     .db &H0E       ' 80 - "P"
     .db 0       '    81 - "Q"
     .db 0       '    82 - "R"
     .db &H25       ' 83 - "S"
     .db 0       '    84 - "T"
     .db &H94       ' 85 - "U"
     .db 0       '    86 - "V"
     .db 0       '    87 - "W"
     .db 0       '    88 - "X"
     .db &H85       ' 89 - "Y"
     .db 0       '    90 - "Z"
     .db &H3C       ' 91 - "["
     .db 0       '    92 - "\"
     .db &H55       ' 93 - "]"
     .db 0       '    94 - "^"
     .db &HFD       ' 95 - "_" - подчёркивание
     .db 0       '    96 - "`"
     .db 0       '    97 - "a"
     .db &HA4       ' 98 - "b"
     .db &HEC       ' 99 - "c"
     .db &HC4       '100 - "d"
     .db 0       '   101 - "e"
     .db 0       '   102 - "f"
     .db 0       '   103 - "g"
     .db &HA6       '104 - "h"
     .db &HFE       '105 - "i"
     .db 0       '   106 - "j"
     .db 0       '   107 - "k"
     .db &HBE       '108 - "l"
     .db 0       '   109 - "m"
     .db &HE6       '110 - "n"
     .db &HE4       '111 - "o"
     .db 0       '   112 - "p"
     .db 0       '   113 - "q"
     .db &HEE       '114 - "r"
     .db 0       '   115 - "s"
     .db &HAC       '116 - "t"
     .db &HF4       '117 - "u"
    $end Asm
#endif
'===============================================================================

Картинки

https://upforme.ru/uploads/0000/25/b8/1217/t970993.jpg
https://upforme.ru/uploads/0000/25/b8/1217/t715654.jpg

+3

13

Антикризисный вариант !

Attiny13 + 2x Ds18b20 + 2x 7seg led через 3x 74hc595

Симуляция + исходник  -  Скачать с google disk

Исходник

'===============================================================================
'
'  Размер исходника 954 byte, 93 %
'
'===============================================================================
  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "attiny13.dat"       ' Используемый контроллер
  $crystal = 1200000       '1.2 МГц
  $framesize = 10       'Размер области используемой и необходимой для преобразований
  $hwstack = 10       ' Размер аппаратного стека
  $swstack = 10       ' Размер программного стека

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0

  On Timer0 Indication_7seg_led Nosave       ' Подпрограмма для обработки прерывания

'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================
  Clk_74hc595 Alias Portb.4 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.2 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.3 : Config Load_74hc595 = Output : Load_74hc595 = 0

'===============================================================================
'            И С П О Л Ь З У Е М Ы Е     К О Н С Т А Н Т Ы
'===============================================================================
  Const Type_indication_oa_ok = 1       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом

  #if Type_indication_oa_ok = 0
      Const Sumbol_gradus_celsius = &HF0       'Кодировка значка "°" градус цельсия
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_gradus_celsius = &H0F       'Кодировка значка "°" градус цельсия
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_space = &H00       'Кодировка значка "Пробел"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_space = &HFF       'Кодировка значка "Пробел"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_minus = &H10       'Кодировка значка  "-"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_minus = &HEF       'Кодировка значка  "-"
  #endif

'===============================================================================
'--------------   И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е  -------------
'===============================================================================
  Dim Div_2_timer0 As Byte       'Программное деление частоты  TIMER0
  Dim Count_digit As Byte       'Используется в обработчике прерывания TIMER0
  Dim Number_indicator As Byte       'На какой индикатор выводится информация
  Dim 1_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 2_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 1_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 1 индикатора
  Dim 2_flag_blink_digit(4) As Byte       'Поразрядные флаги мигания разрядов 2 индикатора
  Dim Attribute_blink_digit As Byte       'Все флаги мигания в одном байте

'===============================================================================
'--------------   НАСТРОЙКА  МК  ДЛЯ   Ds18b20  --------------------------------
'===============================================================================
  Port_ds18b20 Alias Pinb
'-----------------------  Используемые переменные  -----------------------------
  Dim Flag_minus As Byte
  Dim Count_ds18b20 As Byte
  Dim Temp_ds18b20_byte As Byte
  Dim Data_ds18b20(2) As Byte       'Массив данных от DS18B20

'===============================================================================
'--------------  Разрешаем работу необходимых прерываний  ----------------------
'===============================================================================
  Enable Timer0       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'===============================================================================

'         Предварительная проверка и запуск

'===============================================================================
  !ldi R17 , Sumbol_gradus_celsius
  !sts {1_buffer_7seg_led(4)} , R17
  !sts {2_buffer_7seg_led(4)} , R17

'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

      Count_ds18b20 = 0       'Номер датчика
      Gosub Ready_ds18b20

      Number_indicator = 1       'Номер индикатора
      Gosub Byte_to_code_7seg_led

      Count_ds18b20 = 1       'Номер датчика
      Gosub Ready_ds18b20

      Number_indicator = 2       'Номер индикатора
      Gosub Byte_to_code_7seg_led

      Waitms 700

'   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Main
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  Wait_tcnt0:
'-------------------------------------------------------------------------------
    If Tcnt0 < 150 Then
        Goto Wait_tcnt0
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
'  Подпрограмма расчета и вывода температур
'===============================================================================
  Ready_ds18b20:
'-------------------------------------------------------------------------------
    Gosub Preparing_reading

    Gosub Wait_tcnt0
    1wwrite &HBE , 1 , Port_ds18b20 , Count_ds18b20

    If Err > 0 Then
        Goto Start_measuring_ds18b20
    End If

    Gosub Wait_tcnt0
    Data_ds18b20(1) = 1wread(1 , Port_ds18b20 , Count_ds18b20)

    Gosub Wait_tcnt0
    Data_ds18b20(2) = 1wread(1 , Port_ds18b20 , Count_ds18b20)

    !ldi  R18 , 4
    !lds  R16 , {Data_ds18b20(1)}       '{Temp_ds18b20}
    !lds  R17 , {Data_ds18b20(2)}       '{Temp_ds18b20 + 1}
    !clr  R23
    !sbrc R17 , 7
    !ldi  R23 , &B_1000_0000
   Next_shift:
    !ror  R17
    !ror  R16
    !dec  R18
    !brne Next_shift
    !OR   R17 , R23

    !clr R21
    !cpi R16 , 0
    !cpc R17 , R21
    !brge Save_plus_data_ds18b20       'Перейти если больше или равно (со знаком)
    !rjmp Save_minus_data_ds18b20

   Save_plus_data_ds18b20:
    !clr R17
    !sts {Flag_minus} , R17
    !rjmp Exit_ready_ds18b20

   Save_minus_data_ds18b20:
    !ldi R20 , &HFF
    !clr R21
    !ldi R31 , 8

    !lsr R20
   Next_shift_integer:
    !brcc Next_shift_integer_1
    !add R21 , R16
   Next_shift_integer_1:
    !ror R21
    !ror R20
    !dec R31
    !brne Next_shift_integer

    !ldi R17 , 1
    !sts {Flag_minus} , R17
    !mov R16 , R20
   Exit_ready_ds18b20:
    !sts {Temp_ds18b20_byte} , R16

'===============================================================================
'  Запуск измерения температур датчиками Ds18b20
'===============================================================================
  Start_measuring_ds18b20:
'-------------------------------------------------------------------------------
    Gosub Preparing_reading
    1wwrite &H44 , 1 , Port_ds18b20 , Count_ds18b20
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Preparing_reading:
    Gosub Wait_tcnt0
    1wreset Port_ds18b20 , Count_ds18b20
    Gosub Wait_tcnt0
    1wwrite &HCC , 1 , Port_ds18b20 , Count_ds18b20
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Byte_to_code_7seg_led:       ' Время выполнения с заходом и выходом 210 тактов МК
'-------------------------------------------------------------------------------
  'R0  - "0"
  'R15 - копия номера индикатора
  'R16 - делимое
  'R17 - сначала номер индикатора, затем остаток делимого
  'R18 - количество разрядов в байте
  'R19 - копия делимого
  'R20:R21 - копия адреса таблицы символов
  'R26:R27 - адрес массива
  'R30:R31 - адрес таблицы символов
'-------------------------------------------------------------------------------
    !lds  R16 , {temp_ds18b20_byte}
    !lds  R17 , {Number_indicator}
    !mov  R19 , R16
    !ldi  R30 , low(Sumbol_7seg_led_oa_ok * 2)
    !ldi  R31 , high(Sumbol_7seg_led_oa_ok * 2)
    !movw R20 , R30
    !cpi  R17 , 2
    !mov  R15 , R17
    !BREQ Load_2_Buffer_7seg_str       'Перейти если равно
   Load_1_buffer_7seg_str:
    Loadadr 1_buffer_7seg_led(4) , X
    !rjmp Load_reg_sbci_7seg_led
   Load_2_buffer_7seg_str:
    Loadadr 2_buffer_7seg_led(4) , X
   Load_reg_sbci_7seg_led:
    !clr  R0
    !clr  R17
    !ldi  R18 , 3       'Необходимое количество разрядов
   Next_sbci_7seg_led:
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !inc  R17       'Считаем проходы "-10"
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !SBCI R16 , 10       'Вычитание константы с переносом
    !rjmp Next_sbci_7seg_led
   Next_byte_code_7seg_led:
   'Забираем значение кода 7-SEG LED выводимой цифры, текущего разряда
    !add  R30 , R16
    !ADC  R31 , R0
    !lpm  R16 , Z
    !st    -X , R16
    !mov  R16 , R17       'Забираем остаток делимого
    !movw R30 , R20       'Забираем адрес таблицы символов
    !clr  R17
    !dec  R18
    !BREQ Exit_byte_to_code_7seg_led
   !rjmp Next_sbci_7seg_led
   Exit_byte_to_code_7seg_led:
    !mov R18 , R15       'Забираем номер индикатора

    !cpi R19 , 100
    !BRLO Clean_digit_1       'Перейти если меньше

   Cpi_0:
    !cpi R19 , 10
    !BRLO Clean_digit_2       'Перейти если меньше

   Exit_byte_to_code_7seg_led_1:
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Clean_digit_1:
    !lds R16 , {Flag_minus}
    !tst R16
    !BREq Load_sumbol_space_1       'Перейти если не равно

   Load_sumbol_minus_1:
    !ldi R17 , Sumbol_minus
    !rjmp Save_2_buffer_7seg_led_1

   Load_sumbol_space_1:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_1:
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_1       'Перейти если равно

    !sts  {2_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

   Save_1_buffer_7seg_led_1:
    !sts  {1_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

  Clean_digit_2:
    !lds R16 , {Flag_minus}
    !tst R16
    !BREq Load_sumbol_space_2       'Перейти если не равно

   Load_sumbol_minus_2:
    !ldi R17 , Sumbol_minus
    !rjmp Save_2_buffer_7seg_led_2

   Load_sumbol_space_2:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_2:
    !ldi R16 , Sumbol_space
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_2       'Перейти если равно

    !sts {2_buffer_7seg_led(1)} , R16
    !sts {2_buffer_7seg_led(2)} , R17
    !rjmp Exit_byte_to_code_7seg_led_1

   Save_1_buffer_7seg_led_2:
    !sts {1_buffer_7seg_led(1)} , R16
    !sts {1_buffer_7seg_led(2)} , R17

  !rjmp Exit_byte_to_code_7seg_led_1
'===============================================================================

'===============================================================================
  Indication_7seg_led:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16
    !push R17
    !push R30
    !push R31

    !lds R16 , {Div_2_timer0}
    !com R16
    !sts {Div_2_timer0} , R16
    !tst R16
    !brne Start_indication_7seg_led       'Count_timer_read_ds18b20
    !rjmp Exit_indication_7seg_led

   Start_indication_7seg_led:
   'Перебираем разряды 7-seg LED индикации
    !lds R16 , {Count_digit}
    !inc R16
    !cpi R16 , 4       'Const_amount_digit
    !BRLO Save_count_digit       'Перейти если меньше
    !clr R16
   Save_count_digit:
    !sts {Count_digit} , R16

   Load_1_buffer_7seg:
    Loadadr 1_buffer_7seg_led(1) , Z
     !rcall Add_adc_lpm

   Distribution_segment_1_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   Load_2_buffer_7seg:
    Loadadr 2_buffer_7seg_led(1) , Z
     !rcall Add_adc_lpm

  'Раскидываем сегменты по ножкам МК
   Distribution_segment_2_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

    Loadwordadr Table_digit_oa_ok
    !clr  R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение в коде 7-seg led

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

   Exit_indication_7seg_led:
    !pop R31
    !pop R30
    !pop R17
    !pop R16
    !out sreg , R16
    !pop R16

   !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Add_adc_lpm:
'-------------------------------------------------------------------------------
    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led
   !ret
'===============================================================================
   Write_74hc595:
'-------------------------------------------------------------------------------
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R17 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R17 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R17       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0
    !dec R31       ' Считаем биты
    !brne Next_Bit
'-------------------------------------------------------------------------------
   !ret
'===============================================================================

'===============================================================================
  Table_digit_oa_ok:
'-------------------------------------------------------------------------------
  'Кодировка разрядов
  '    8765_4321  -  разряды
  ' &B_0000_0000  -  расположение в байте
'------------------------------------------
#if Type_indication_oa_ok = 0
    Data &B_1110_1110       ' 1; 5
    Data &B_1101_1101       ' 2; 6
    Data &B_1011_1011       ' 3; 7
    Data &B_0111_0111       ' 4; 8
#endif

#if Type_indication_oa_ok = 1
    Data &B_0001_0001       ' 1; 5
    Data &B_0010_0010       ' 2; 6
    Data &B_0100_0100       ' 3; 7
    Data &B_1000_1000       ' 4; 8
#endif
'===============================================================================

'===============================================================================
  Sumbol_7seg_led_oa_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
  'Кодировка сегментов
  '    fbad_cghe      gfed cbah  -  сегменты
  ' &B_0000_0000  -  расположение в байте
  '
  'Выводимые символы  -  (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu)
#if Type_indication_oa_ok = 0
    $asm
     .db &HEB       ' 48 - "0"
     .db &H28       ' 49 - "1"
     .db &HB3       ' 50 - "2"
     .db &HBA       ' 51 - "3"
     .db &H78       ' 52 - "4"
     .db &HDA       ' 53 - "5"
     .db &HDB       ' 54 - "6"
     .db &HA8       ' 55 - "7"
     .db &HFB       ' 56 - "8"
     .db &HFA       ' 57 - "9"
    $end Asm
#endif

#if Type_indication_oa_ok = 1
    $asm
     .db &H14       ' 48 - "0"
     .db &HD7       ' 49 - "1"
     .db &H4C       ' 50 - "2"
     .db &H45       ' 51 - "3"
     .db &H87       ' 52 - "4"
     .db &H25       ' 53 - "5"
     .db &H24       ' 54 - "6"
     .db &H57       ' 55 - "7"
     .db &H04       ' 56 - "8"
     .db &H05       ' 57 - "9"
    $end Asm
#endif
'===============================================================================

https://upforme.ru/uploads/0000/25/b8/1217/t681843.png

+5

14

Очередной антикризисный вариант !

Attiny13 + 2хADC + 2х7seg led

Симуляция (Proteus 7/10) + исходник (Bascom 2.0.7.1)  -  Скачать с google disk


Настройки функционала выбираются константами, далее компиляция и можно заливать в МК.


Const Type_indication_oa_ok = 0       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом 

'Варианты отображения на 7-seg led, = 0 целое или = 1 с десятыми
  Const Whole_tenths_2_adc = 0
  Const Whole_tenths_3_adc = 1

'Требуемая шкала в попугайчиках, не более 250
  Const Scale_in_volts_2_adc = 100
  Const Scale_in_volts_3_adc = 20

'Количество измерений одного канала АЦП для получения выборки
'Варианты 4, 8, 16, 32, 64
  Const Sample_adc = 64

'Варианты опорного напряжения
  Voltage_reference_avcc Alias &B_0000_0000
  Voltage_reference_1_1v Alias &B_0100_0000

'Варианты выводимых символов в крайнем правом разряде
  !ldi R16 , Sumbol_U
'  !ldi R17 , Sumbol_I
'  !ldi R17 , Sumbol_t
'  !ldi R17 , Sumbol_P
'  !ldi R17 , Sumbol_space  'Пробел
'  !ldi R17 , Sumbol_minus
'  !ldi R17 , Sumbol_gradus_celsius  '°

Исходник

'===============================================================================
'
'  Размер исходника 1012 byte, 98 %
'
'===============================================================================
  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "attiny13.dat"       ' Используемый контроллер
  $crystal = 1200000       '1.2 МГц
  $framesize = 10       'Размер области используемой и необходимой для преобразований
  $hwstack = 10       ' Размер аппаратного стека
  $swstack = 10       ' Размер программного стека

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0

  On Timer0 Indication_7seg_led Nosave       ' Подпрограмма для обработки прерывания

'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================
  Clk_74hc595 Alias Portb.2 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.0 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.1 : Config Load_74hc595 = Output : Load_74hc595 = 0

'===============================================================================
'            И С П О Л Ь З У Е М Ы Е     К О Н С Т А Н Т Ы
'===============================================================================
  Const Type_indication_oa_ok = 0       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом

'Расположение точки в коде знакоместа 7seg led
  Const Dot_7seg_led = &B_0000_0100       'Расположение точки в коде знакоместа 7seg led

  #if Type_indication_oa_ok = 0
      Const Sumbol_gradus_celsius = &HF0       'Кодировка значка "°" градус цельсия
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_gradus_celsius = &H0F       'Кодировка значка "°" градус цельсия
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_space = &H00       'Кодировка значка "Пробел"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_space = &HFF       'Кодировка значка "Пробел"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_minus = &H10       'Кодировка значка  "-"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_minus = &HEF       'Кодировка значка  "-"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_i = &H41       'Кодировка значка  "I"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_i = &HBE       'Кодировка значка  "I"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_u = &H6B       'Кодировка значка  "U"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_u = &H94       'Кодировка значка  "U"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_t = &H53       'Кодировка значка  "t"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_t = &HAC       'Кодировка значка  "t"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_p = &HF1       'Кодировка значка  "P"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_p = &H0E       'Кодировка значка  "P"
  #endif

'===============================================================================
'--------------   И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е  -------------
'===============================================================================
  Dim Div_2_timer0 As Byte       'Программное деление частоты  TIMER0
  Dim Count_digit As Byte       'Используется в обработчике прерывания TIMER0
  Dim Number_indicator As Byte       'На какой индикатор выводится информация
  Dim 1_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 2_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0

'===============================================================================
'                     Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (1 МГц / 128 = 9375 Гц)
  Config Adc = Single , Prescaler = 128 , Reference = Avcc       'INTERNAL_1.1

'Ссылка на подпрограмму обработчика прерывания АЦП
  On Adc Interrupt_processing_adc Nosave

'Варианты отображения на 7-seg led, = 0 целое или = 1 с десятыми
  Const Whole_tenths_2_adc = 0
  Const Whole_tenths_3_adc = 1

'Требуемая шкала в вольтах, не более 250 вольт
  Const Scale_in_volts_2_adc = 100
  Const Scale_in_volts_3_adc = 20

'Множитель для пересчёта данных АЦП
  '20  / 1024 * 10000 = 196
  '25  / 1024 * 10000 = 244
  '50  / 1024 * 1000 = 48
  '100 / 1024 * 1000 = 97
  '250 / 1024 * 1000 = 244
  #if Scale_in_volts_2_adc <= 25
      Const Factor_data_2_adc = Scale_in_volts_2_adc / 1024 * 10000 + 1
  #else
      Const Factor_data_2_adc = Scale_in_volts_2_adc / 1024 * 1000 + 1
  #endif
  #if Scale_in_volts_3_adc <= 25
      Const Factor_data_3_adc = Scale_in_volts_3_adc / 1024 * 10000 + 1
  #else
      Const Factor_data_3_adc = Scale_in_volts_3_adc / 1024 * 1000 + 1
  #endif

'Количество измерений одного канала АЦП для получения выборки
'Варианты 4, 8, 16, 32, 64
  Const Sample_adc = 64

  #if Sample_adc = 4
      Const Const_averaging = 2
  #endif
  #if Sample_adc = 8
      Const Const_averaging = 3
  #endif
  #if Sample_adc = 16
      Const Const_averaging = 4
  #endif
  #if Sample_adc = 32
      Const Const_averaging = 5
  #endif
  #if Sample_adc = 64
      Const Const_averaging = 6
  #endif

  Adcsra.aden = 1       'Включаем АЦП

  Voltage_reference_avcc Alias &B_0000_0000
  Voltage_reference_1_1v Alias &B_0100_0000

'Номера каналов АЦП с Ref = Avcc
  Channel_adc_2 Alias &B_0000_0010       'Опорное Avcc, 2 канал
  Channel_adc_3 Alias &B_0000_0011       'Опорное Avcc, 3 канал
'Номера каналов АЦП с Ref = internal 1.1V
'  Channel_adc_2 Alias &B_0100_0010       'Опорное internal 1.1V, 2 канал
'  Channel_adc_3 Alias &B_0100_0011       'Опорное internal 1.1V, 3 канал

  Admux = Channel_adc_2

  Dim Count_adc As Byte
  Dim Sum_data_adc As Word
  Dim Skip_1_measurement As Byte
  Dim Flag_data_adc_ready As Byte

  Dim Data_adc_2_word As Word
  Dim Data_adc_3_word As Word
  Dim Data_adc_long As Long

'===============================================================================
'--------------  Разрешаем работу необходимых прерываний  ----------------------
'===============================================================================
  Adcsra.adif = 1       'Сброс флага прерывания
  Adcsra.adsc = 1       'Запуск измерения
  Enable Adc       'Разрешение прерываний АЦП

  Enable Timer0       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'===============================================================================

'         Предварительная проверка и запуск

'===============================================================================
  !ldi R16 , Sumbol_u
'  !ldi R17 , Sumbol_i
'  !ldi R17 , Sumbol_t
'  !ldi R17 , Sumbol_p
'  !ldi R17 , Sumbol_space
'  !ldi R17 , Sumbol_minus
'  !ldi R17 , Sumbol_gradus_celsius

'  !sts {1_buffer_7seg_led(1)} , R17
'  !sts {1_buffer_7seg_led(2)} , R17
'  !sts {1_buffer_7seg_led(3)} , R17
  !sts {1_buffer_7seg_led(4)} , R16

'  !sts {2_buffer_7seg_led(1)} , R17
'  !sts {2_buffer_7seg_led(2)} , R17
'  !sts {2_buffer_7seg_led(3)} , R17
  !sts {2_buffer_7seg_led(4)} , R16

'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

     If Flag_data_adc_ready = 0 Then
         Goto Wait_ms_1
     End If

           !ldi R17 , 2            'Number_indicator
           Gosub Calculate_data_adc
           !ldi R17 , 2       '   'Number_indicator
           Gosub Byte_to_code_7seg_led

           !ldi R17 , 1            'Number_indicator
           Gosub Calculate_data_adc
           !ldi R17 , 1             'Number_indicator
           Gosub Byte_to_code_7seg_led

           Flag_data_adc_ready = 0

   Wait_ms_1:
'      Waitms 700

'   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Main
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  Calculate_data_adc:
'-------------------------------------------------------------------------------
'    !lds R17 , {Number_indicator}
    !cpi R17 , 2
    !BREQ Load_data_adc_2       'Перейти если равно

   Load_data_adc_3:
    Data_adc_long = Data_adc_3_word * Factor_data_3_adc
    !rjmp Calculate_data_adc_1

   Load_data_adc_2:
    Data_adc_long = Data_adc_2_word * Factor_data_2_adc

   Calculate_data_adc_1:
    Data_adc_long = Data_adc_long / 1000

    !lds R16 , {Data_adc_long}
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Byte_to_code_7seg_led:       ' Время выполнения с заходом и выходом 210 тактов МК
'-------------------------------------------------------------------------------
  'R0  - "0"
  'R15 - копия номера индикатора
  'R16 - делимое
  'R17 - сначала номер индикатора, затем остаток делимого
  'R18 - количество разрядов в байте
  'R19 - копия делимого
  'R20:R21 - копия адреса таблицы символов
  'R26:R27 - адрес массива
  'R30:R31 - адрес таблицы символов
'-------------------------------------------------------------------------------
'    !lds  R16 , {Temp_buffer_7seg_byte}
'    !lds  R17 , {Number_indicator}
    !mov  R19 , R16
    !ldi  R30 , low(Sumbol_7seg_led_oa_ok * 2)
    !ldi  R31 , high(Sumbol_7seg_led_oa_ok * 2)
    !movw R20 , R30
    !cpi  R17 , 2
    !mov  R15 , R17
    !BREQ Load_2_Buffer_7seg_str       'Перейти если равно
   Load_1_buffer_7seg_str:
    Loadadr 1_buffer_7seg_led(4) , X
    !rjmp Load_reg_sbci_7seg_led
   Load_2_buffer_7seg_str:
    Loadadr 2_buffer_7seg_led(4) , X
   Load_reg_sbci_7seg_led:
    !clr  R0
    !clr  R17
    !ldi  R18 , 3       'Необходимое количество разрядов
   Next_sbci_7seg_led:
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !inc  R17       'Считаем проходы "-10"
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !SBCI R16 , 10       'Вычитание константы с переносом
    !rjmp Next_sbci_7seg_led
   Next_byte_code_7seg_led:
   'Забираем значение кода 7-SEG LED выводимой цифры, текущего разряда
    !add  R30 , R16
    !ADC  R31 , R0
    !lpm  R16 , Z
    !st    -X , R16
    !mov  R16 , R17       'Забираем остаток делимого
    !movw R30 , R20       'Забираем адрес таблицы символов
    !clr  R17
    !dec  R18
    !BREQ Exit_byte_to_code_7seg_led
   !rjmp Next_sbci_7seg_led

   Exit_byte_to_code_7seg_led:
    !mov R18 , R15       'Забираем номер индикатора

    !cpi R19 , 100
    !BRLO Clean_digit_1       'Перейти если меньше

   Cpi_0:
    !cpi R19 , 10
    !BRLO Clean_digit_2       'Перейти если меньше

   Exit_byte_to_code_7seg_led_1:

    !ldi  R17 , Dot_7seg_led       'Добавляем точку в предыдущем разряде
    !cpi R18 , 2
    !BRNE Exit_byte_to_code_7seg_led_2       'Перейти если не равно

    !lds  R16 , {2_buffer_7seg_led(2)}
    !eor  R16 , R17
#if Whole_tenths_2_adc = 1
    !sts {2_buffer_7seg_led(2)} , R16
#endif
    !rjmp Exit_byte_to_code_7seg_led_3

   Exit_byte_to_code_7seg_led_2:
    !lds  R16 , {1_buffer_7seg_led(2)}
    !eor  R16 , R17
#if Whole_tenths_3_adc = 1
    !sts {1_buffer_7seg_led(2)} , R16
#endif

   Exit_byte_to_code_7seg_led_3:

'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Clean_digit_1:
   Load_sumbol_space_1:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_1:
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_1       'Перейти если равно

    !sts  {2_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

   Save_1_buffer_7seg_led_1:
    !sts  {1_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

  Clean_digit_2:
   Load_sumbol_space_2:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_2:
    !ldi R16 , Sumbol_space
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_2       'Перейти если равно

    !sts {2_buffer_7seg_led(1)} , R16

  #if Whole_tenths_2_adc = 0
    !sts {2_buffer_7seg_led(2)} , R17
  #endif

    !rjmp Exit_byte_to_code_7seg_led_1

   Save_1_buffer_7seg_led_2:
    !sts {1_buffer_7seg_led(1)} , R16

  #if Whole_tenths_3_adc = 0
    !sts {1_buffer_7seg_led(2)} , R17
  #endif

  !rjmp Exit_byte_to_code_7seg_led_1
'===============================================================================

'===============================================================================
  Interrupt_processing_adc_1:
'-------------------------------------------------------------------------------
    !clr R26
    !sts {Skip_1_measurement} , R26
    !rjmp Start_measurement_adc
'===============================================================================
  Interrupt_processing_adc:
'-------------------------------------------------------------------------------
   'Сохраняем регистры
   'Т.к., используются логические операции, обязательно сохраняем SREG
    !push R26
    !in R26 , sreg
    !push R26
    !push R27

   'Если сменили канал, пропускаем первое измерение
    !lds R26 , {Skip_1_measurement}
    !tst R26
    !brne Interrupt_processing_adc_1

   'Набираем сумму из 64 измерений, для усреднения показаний
    !lds R26 , {Sum_data_adc}
    !in R27 , adcl
    !add R26 , R27
    !sts {Sum_data_adc} , R26

    !lds R26 , {Sum_data_adc + 1}
    !in R27 , adch
    !adc R26 , R27
    !sts {Sum_data_adc + 1} , R26

   'Считаем количество измерений
    !lds R26 , {count_adc}
    !inc R26
    !sts {count_adc} , R26
   'Если набрали 64 измерения
    !cpi R26 , Sample_adc
    !BREQ Mean
    !rjmp Start_measurement_adc

  'Усреднение из 64 измерений
   Mean:
    !push R16
    !push R17
    !Push R30
    !Push R31

    !ldi R30 , Const_averaging
    !lds R26 , {Sum_data_adc}
    !lds R27 , {Sum_data_adc + 1}
  'Сдвиг вправо на 6 бит, или деление на 64
   More_shift:
    !lsr R27
    !ror R26
    !dec R30
    !brne More_shift

   'Читаем текущий номер канала АЦП
    !lds R16 , admux
    !andi R16 , &B_0001_1111

   '13 тактов МК, самый быстрый вариант (аналог Goto Переменная Label)
    !clr R17
    !ldi R30 , low(_Save_data_adc_0)
    !ldi R31 , high(_Save_data_adc_0)
    !add R30 , R16
    !adc R31 , R17
    !ijmp

    _save_data_adc_0:
                     !rjmp Save_data_adc_0
    _save_data_adc_1:
                     !rjmp Save_data_adc_1
    _save_data_adc_2:
                     !rjmp Save_data_adc_2
    _save_data_adc_3:
                     !rjmp Save_data_adc_3

    !rjmp Change_channel_adc

   Save_data_adc_0:
    !rjmp Change_channel_adc
   Save_data_adc_1:
    !rjmp Change_channel_adc

   Save_data_adc_2:
    !sts {Data_adc_2_word} , R26
    !sts {Data_adc_2_word + 1} , R27
    !ldi R30 , Channel_adc_3
    !rjmp Change_channel_adc

   Save_data_adc_3:
    !sts {Data_adc_3_word} , R26
    !sts {Data_adc_3_word + 1} , R27
    !ldi R30 , Channel_adc_2

    !ldi R26 , 1
    !sts {Flag_data_adc_ready} , R26
    !rjmp Change_channel_adc

  'Переключаем канал АЦП
   Change_channel_adc:
    !lds R31 , admux
    !andi R31 , &B_0100_0000
    !or R31 , R30
    !sts admux , R30

    !pop R31
    !pop R30
    !pop R17
    !pop R16

   'Обнуляем переменные для следующего измерения
    !ldi R26 , 0
    !ldi R27 , 1
    !sts {Count_adc} , R26
    !sts {Sum_data_adc} , R26
    !sts {Sum_data_adc + 1} , R26
   'Подымаем флаг смены канала, что бы пропустить первое измерение
    !sts {Skip_1_measurement} , R27

  'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
   Start_measurement_adc:
    !lds R26 , ADCSRA
    !ori R26 , &B_0100_0000
    !sts ADCSRA , R26

  'Восстанавливаем регистры и SREG
   Exit_interrupt_adc:
    !pop R27
    !pop R26
    !out sreg , R26
    !pop R26

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Indication_7seg_led:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16
    !push R17
    !push R30
    !push R31

    !lds R16 , {Div_2_timer0}
    !com R16
    !sts {Div_2_timer0} , R16
    !tst R16
    !brne Start_indication_7seg_led       'Count_timer_read_ds18b20
    !rjmp Exit_indication_7seg_led

   Start_indication_7seg_led:
   'Перебираем разряды 7-seg LED индикации
    !lds R16 , {Count_digit}
    !inc R16
    !cpi R16 , 4       'Const_amount_digit
    !BRLO Save_count_digit       'Перейти если меньше
    !clr R16
   Save_count_digit:
    !sts {Count_digit} , R16

   Load_1_buffer_7seg:
    Loadadr 1_buffer_7seg_led(1) , Z
    !rcall Add_adc_lpm

   Distribution_segment_1_indicator:
    !rcall Write_74hc595       'Закидываем данные в 74HC595

   Load_2_buffer_7seg:
    Loadadr 2_buffer_7seg_led(1) , Z
    !rcall Add_adc_lpm

  'Раскидываем сегменты по ножкам МК
   Distribution_segment_2_indicator:
    !rcall Write_74hc595       'Закидываем данные в 74HC595

    Loadwordadr Table_digit_oa_ok
    !clr  R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение в коде 7-seg led

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

   Exit_indication_7seg_led:
    !pop R31
    !pop R30
    !pop R17
    !pop R16
    !out sreg , R16
    !pop R16

   !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Add_adc_lpm:
'-------------------------------------------------------------------------------
    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led
   !ret
'===============================================================================
   Write_74hc595:
'-------------------------------------------------------------------------------
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R17 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R17 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R17       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0
    !dec R31       ' Считаем биты
    !brne Next_Bit
'-------------------------------------------------------------------------------
   !ret
'===============================================================================

'===============================================================================
  Table_digit_oa_ok:
'-------------------------------------------------------------------------------
  'Кодировка разрядов
  '    8765_4321  -  разряды
  ' &B_0000_0000  -  расположение в байте
'------------------------------------------
#if Type_indication_oa_ok = 0
    Data &B_1110_1110       ' 1; 5
    Data &B_1101_1101       ' 2; 6
    Data &B_1011_1011       ' 3; 7
    Data &B_0111_0111       ' 4; 8
#endif

#if Type_indication_oa_ok = 1
    Data &B_0001_0001       ' 1; 5
    Data &B_0010_0010       ' 2; 6
    Data &B_0100_0100       ' 3; 7
    Data &B_1000_1000       ' 4; 8
#endif
'===============================================================================

'===============================================================================
  Sumbol_7seg_led_oa_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
  'Кодировка сегментов
  '    fbad_cghe      gfed cbah  -  сегменты
  ' &B_0000_0000  -  расположение в байте
  '
  'Выводимые символы  -  (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu)
#if Type_indication_oa_ok = 0
    $asm
     .db &HEB       ' 48 - "0"
     .db &H28       ' 49 - "1"
     .db &HB3       ' 50 - "2"
     .db &HBA       ' 51 - "3"
     .db &H78       ' 52 - "4"
     .db &HDA       ' 53 - "5"
     .db &HDB       ' 54 - "6"
     .db &HA8       ' 55 - "7"
     .db &HFB       ' 56 - "8"
     .db &HFA       ' 57 - "9"
    $end Asm
#endif

#if Type_indication_oa_ok = 1
    $asm
     .db &H14       ' 48 - "0"
     .db &HD7       ' 49 - "1"
     .db &H4C       ' 50 - "2"
     .db &H45       ' 51 - "3"
     .db &H87       ' 52 - "4"
     .db &H25       ' 53 - "5"
     .db &H24       ' 54 - "6"
     .db &H57       ' 55 - "7"
     .db &H04       ' 56 - "8"
     .db &H05       ' 57 - "9"
    $end Asm
#endif
'===============================================================================

https://upforme.ru/uploads/0000/25/b8/1217/t783901.jpg
https://upforme.ru/uploads/0000/25/b8/1217/t10908.jpg

+5

15

Доработка этого до Attiny25

Исходник

'===============================================================================

  $map    ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "attiny25.dat"       ' Используемый контроллер
  $crystal = 1000000       '1 МГц
  $framesize = 16       'Размер области используемой и необходимой для преобразований
  $hwstack = 16       ' Размер аппаратного стека
  $swstack = 16       ' Размер программного стека

'===============================================================================
'                     Конфигурация АЦП
'===============================================================================
'tiny25,tiny45,tiny85
'AVCC
'EXTERNAL or OFF
'INTERNAL_1.1
'INTERNAL_2.56_NOCAP
'INTERNAL_2.56_EXTCAP
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (1 МГц / 128 = 7812 Гц)
  Config Adc = Single , Prescaler = 128 , Reference = Avcc

'Ссылка на подпрограмму обработчика прерывания АЦП
  On Adc Interrupt_processing_adc Nosave

'Количество измерений одного канала АЦП для получения выборки
'Варианты 4, 8, 16, 32, 64
  Const Sample_adc = 4

  #if Sample_adc = 4
      Const Const_averaging = 2
  #endif
  #if Sample_adc = 8
      Const Const_averaging = 3
  #endif
  #if Sample_adc = 16
      Const Const_averaging = 4
  #endif
  #if Sample_adc = 32
      Const Const_averaging = 5
  #endif
  #if Sample_adc = 64
      Const Const_averaging = 6
  #endif

  Adcsra.aden = 1       'Включаем АЦП
'  Waitms 10       'Ждём когда всё запустится и выйдет на рабочие уровни

'Номера каналов АЦП
  Channel_adc_1 Alias &B_0000_0001       'Опорное Avcc, 1 канал

  Admux = Channel_adc_1

  Dim Count_adc As Byte
  Dim Sum_data_adc As Word
'  Dim Skip_1_measurement As Byte
  Dim Flag_data_adc_ready As Byte

  Dim Data_adc_1_byte As Byte

  Dim Data_adc_1_word As Word
  Dim Temp_data_adc_1_word As Word
  Dim Data_adc_1_long As Long
'  Dim Data_adc_1_str As String * 10

'===============================================================================
'           Настройка таймера для работы 7-seg LED индикации
'===============================================================================
  Config Timer0 = Timer , Prescale = 8 , Clear Timer = 0

  On Timer0 Indication_7seg_led Nosave       ' Подпрограмма для обработки прерывания

'===============================================================================
'           Настройка портов МК для работы 7-seg LED индикации
'===============================================================================
  Clk_74hc595 Alias Portb.4 : Config Clk_74hc595 = Output : Clk_74hc595 = 0
  Data_74hc595 Alias Portb.1 : Config Data_74hc595 = Output : Data_74hc595 = 0
  Load_74hc595 Alias Portb.3 : Config Load_74hc595 = Output : Load_74hc595 = 0

'===============================================================================
'            И С П О Л Ь З У Е М Ы Е     К О Н С Т А Н Т Ы
'===============================================================================
  Const Type_indication_oa_ok = 1       '0-индикаторы с общим катодом, 1-индикаторы с общим анодом

  #if Type_indication_oa_ok = 0
      Const Sumbol_gradus_celsius = &HF0       'Кодировка значка "°" градус цельсия
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_gradus_celsius = &H0F       'Кодировка значка "°" градус цельсия
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_space = &H00       'Кодировка значка "Пробел"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_space = &HFF       'Кодировка значка "Пробел"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_minus = &H10       'Кодировка значка  "-"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_minus = &HEF       'Кодировка значка  "-"
  #endif

  #if Type_indication_oa_ok = 0
      Const Sumbol_u = &H6B       'Кодировка значка  "U"
  #endif
  #if Type_indication_oa_ok = 1
      Const Sumbol_u = &H94       'Кодировка значка  "U"
  #endif

  Const Dot_7seg_led = &B_0000_0100       'Расположение точки в коде знакоместа 7seg led

'===============================================================================
'--------------   И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е  -------------
'===============================================================================
  Dim Div_2_timer0 As Byte       'Программное деление частоты на /2   TIMER0
  Dim Count_digit As Byte       'Используется в обработчике прерывания TIMER0
  Dim Number_indicator As Byte       'На какой индикатор выводится информация

  Dim 1_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0
  Dim 2_buffer_7seg_led(4) As Byte       'Выводимый буфер 7-seg LED, используется в обработчике прерывания TIMER0

'===============================================================================
'           Настройка портов МК для работы ds18b20
'===============================================================================
  Config 1wire = Portb.0       ' Ножка МК для подключения датчика Ds18b20
'-----------------------  Используемые переменные  -----------------------------
  Dim Flag_minus As Byte
  Dim Count_ds18b20 As Byte
  Dim Flag_read_ds18b20 As Byte
  Dim Temp_ds18b20_byte As Byte
  Dim Temp_buffer_7seg_byte As Byte
  Dim Data_ds18b20(2) As Byte       'Массив данных от DS18B20

'===============================================================================
'--------------  Разрешаем работу необходимых прерываний  ----------------------
'===============================================================================
  Adcsra.adif = 1       'Сброс флага прерывания
  Adcsra.adsc = 1       'Запуск измерения
  Enable Adc       'Разрешение прерываний АЦП

  Enable Timer0       ' Разрешаем работу прерывания по СОВПАДЕНИЮ
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'===============================================================================

'         Предварительная проверка и запуск

'===============================================================================
  !ldi R16 , Sumbol_u
  !ldi R17 , Sumbol_minus
  !ldi R18 , Sumbol_gradus_celsius

  !sts {1_buffer_7seg_led(1)} , R17
  !sts {1_buffer_7seg_led(2)} , R17
  !sts {1_buffer_7seg_led(3)} , R17
  !sts {1_buffer_7seg_led(4)} , R18

  !sts {2_buffer_7seg_led(1)} , R17
  !sts {2_buffer_7seg_led(2)} , R17
  !sts {2_buffer_7seg_led(3)} , R17
  !sts {2_buffer_7seg_led(4)} , R16

'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

     If Flag_read_ds18b20 > 0 Then
         Goto Wait_ms
     End If

           Gosub Ready_ds18b20

           Number_indicator = 1
           Temp_buffer_7seg_byte = Temp_ds18b20_byte
           Flag_read_ds18b20 = 5

           Gosub Byte_to_code_7seg_led

   Wait_ms:
     If Flag_data_adc_ready = 0 Then
         Goto Wait_ms_1
     End If

           Temp_data_adc_1_word = Data_adc_1_word
           Data_adc_1_long = Temp_data_adc_1_word * 196       '20 вольт / 1024 (разрядность АЦП)
           Data_adc_1_long = Data_adc_1_long / 1000
           Data_adc_1_byte = Data_adc_1_long
           Number_indicator = 2
           Temp_buffer_7seg_byte = Data_adc_1_byte
           Flag_data_adc_ready = 0

           Gosub Byte_to_code_7seg_led

   Wait_ms_1:

       Decr Flag_read_ds18b20

       Waitms 200

'   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Main
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  Byte_to_code_7seg_led:       ' Время выполнения с заходом и выходом 210 тактов МК
'-------------------------------------------------------------------------------
  'R0  - "0"
  'R15 - копия номера индикатора
  'R16 - делимое
  'R17 - сначала номер индикатора, затем остаток делимого
  'R18 - количество разрядов в байте
  'R19 - копия делимого
  'R20:R21 - копия адреса таблицы символов
  'R26:R27 - адрес массива
  'R30:R31 - адрес таблицы символов
'-------------------------------------------------------------------------------
'    !push R0
'    !push R15
'    !push R16
'    !push R17
'    !push R18
'    !push R19
'    !push R20
'    !push R21
'    !push R26
'    !push R27
'    !push R30
'    !push R31

    !lds  R16 , {Temp_buffer_7seg_byte}
    !mov  R19 , R16
    !lds  R17 , {Number_indicator}
    !mov  R15 , R17
    !ldi  R30 , low(Sumbol_7seg_led_oa_ok * 2)
    !ldi  R31 , high(Sumbol_7seg_led_oa_ok * 2)
    !movw R20 , R30
    !cpi  R17 , 2
    !BREQ Load_2_Buffer_7seg_str       'Перейти если равно
   Load_1_buffer_7seg_str:
    Loadadr 1_buffer_7seg_led(4) , X
    !rjmp Load_reg_sbci_7seg_led
   Load_2_buffer_7seg_str:
    Loadadr 2_buffer_7seg_led(4) , X
   Load_reg_sbci_7seg_led:
    !clr  R0
    !clr  R17
    !ldi  R18 , 3       'Необходимое количество разрядов
   Next_sbci_7seg_led:
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !inc  R17       'Считаем проходы "-10"
    !cpi  R16 , 10
    !BRLO Next_byte_code_7seg_led       'Перейти если меньше
    !SBCI R16 , 10       'Вычитание константы с переносом
    !rjmp Next_sbci_7seg_led
   Next_byte_code_7seg_led:
   'Забираем значение кода 7-SEG LED выводимой цифры, текущего разряда
    !add  R30 , R16
    !ADC  R31 , R0
    !lpm  R16 , Z
    !st    -X , R16
    !mov  R16 , R17       'Забираем остаток делимого
    !movw R30 , R20       'Забираем адрес таблицы символов
    !clr  R17
    !dec  R18
    !BREQ Exit_byte_to_code_7seg_led
   !rjmp Next_sbci_7seg_led
   Exit_byte_to_code_7seg_led:
    !mov R18 , R15       'Забираем номер индикатора

    !cpi R19 , 100
    !BRLO Clean_digit_1       'Перейти если меньше

   Cpi_0:
    !cpi R19 , 10
    !BRLO Clean_digit_2       'Перейти если меньше

   Exit_byte_to_code_7seg_led_1:
    !cpi R18 , 2
    !BRNE Exit_byte_to_code_7seg_led_2       'Перейти если не равно
    !lds  R16 , {2_buffer_7seg_led(2)}
    !ldi  R17 , Dot_7seg_led       'Добавляем точку в предыдущем разряде
    !eor  R16 , R17
    !sts {2_buffer_7seg_led(2)} , R16

   Exit_byte_to_code_7seg_led_2:
'    !pop R31
'    !pop R30
'    !pop R27
'    !pop R26
'    !pop R21
'    !pop R20
'    !pop R19
'    !pop R18
'    !pop R17
'    !pop R16
'    !pop R15
'    !pop R0
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Clean_digit_1:
    !cpi R18 , 2
    !breq Load_sumbol_space_1
    !lds R16 , {Flag_minus}
    !tst R16
    !BREq Load_sumbol_space_1       'Перейти если не равно

   Load_sumbol_minus_1:
    !ldi R17 , Sumbol_minus
    !rjmp Save_2_buffer_7seg_led_1

   Load_sumbol_space_1:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_1:
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_1       'Перейти если равно

    !sts  {2_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

   Save_1_buffer_7seg_led_1:
    !sts  {1_buffer_7seg_led(1)} , R17
    !rjmp cpi_0

  Clean_digit_2:
    !lds R16 , {Flag_minus}
    !tst R16
    !BREq Load_sumbol_space_2       'Перейти если не равно

   Load_sumbol_minus_2:
    !ldi R17 , Sumbol_minus
    !rjmp Save_2_buffer_7seg_led_2

   Load_sumbol_space_2:
    !ldi R17 , Sumbol_space

   Save_2_buffer_7seg_led_2:
    !ldi R16 , Sumbol_space
    !cpi R18 , 1
    !BREQ Save_1_buffer_7seg_led_2       'Перейти если равно

    !sts {2_buffer_7seg_led(1)} , R16
    !rjmp Exit_byte_to_code_7seg_led_1

   Save_1_buffer_7seg_led_2:
    !sts {1_buffer_7seg_led(1)} , R16
    !sts {1_buffer_7seg_led(2)} , R17

  !rjmp Exit_byte_to_code_7seg_led_1
'===============================================================================

'===============================================================================
  Interrupt_processing_adc:
'-------------------------------------------------------------------------------
   'Сохраняем регистры
   'Т.к., используются логические операции, обязательно сохраняем SREG
    !push R26
    !in R26 , sreg
    !push R26
    !push R27

   'Набираем сумму из 64 измерений, для усреднения показаний
    !lds R26 , {Sum_data_adc}
    !in R27 , adcl
    !add R26 , R27
    !sts {Sum_data_adc} , R26

    !lds R26 , {Sum_data_adc + 1}
    !in R27 , adch
    !adc R26 , R27
    !sts {Sum_data_adc + 1} , R26

   'Считаем количество измерений
    !lds R26 , {count_adc}
    !inc R26
    !sts {count_adc} , R26
   'Если набрали 64 измерения
    !cpi R26 , Sample_adc
    !BREQ Mean
    !rjmp Start_measurement_adc

  'Усреднение из 64 измерений
   Mean:
    !push R16
    !push R17
    !Push R30
    !Push R31

    !ldi R30 , Const_averaging
    !lds R26 , {Sum_data_adc}
    !lds R27 , {Sum_data_adc + 1}
  'Сдвиг вправо на 6 бит, или деление на 64
   More_shift:
    !lsr R27
    !ror R26
    !dec R30
    !brne More_shift

   Save_data_adc_1:
    !sts {Data_adc_1_word} , R26
    !sts {Data_adc_1_word + 1} , R27
    !ldi R27 , 1
    !sts {Flag_data_adc_ready} , R27

    !ldi R31 , Channel_adc_1       'admux
'    !andi R31 , &B_0100_0000
'    !or R31 , R30
    !sts admux , R31

    !pop R31
    !pop R30
    !pop R17
    !pop R16

   'Обнуляем переменные для следующего измерения
    !ldi R26 , 0
    !sts {Count_adc} , R26
    !sts {Sum_data_adc} , R26
    !sts {Sum_data_adc + 1} , R26

  'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
   Start_measurement_adc:
    !lds R26 , ADCSRA
    !ori R26 , &B_0100_0000
    !sts ADCSRA , R26

  'Восстанавливаем регистры и SREG
   Exit_interrupt_adc:
    !pop R27
    !pop R26
    !out sreg , R26
    !pop R26

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Indication_7seg_led:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16
    !push R17
    !push R30
    !push R31

    !lds R16 , {Div_2_timer0}
    !com R16
    !sts {Div_2_timer0} , R16
    !tst R16
    !brne Start_indication_7seg_led       'Count_timer_read_ds18b20
    !rjmp Exit_indication_7seg_led

   Start_indication_7seg_led:
   'Перебираем разряды 7-seg LED индикации
    !lds R16 , {Count_digit}
    !inc R16
    !cpi R16 , 4       'Const_amount_digit
    !BRLO Save_count_digit       'Перейти если меньше
    !clr R16
   Save_count_digit:
    !sts {Count_digit} , R16

   Load_1_buffer_7seg:
    Loadadr 1_buffer_7seg_led(1) , Z
     !rcall Add_adc_lpm

   Distribution_segment_1_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   Load_2_buffer_7seg:
    Loadadr 2_buffer_7seg_led(1) , Z
     !rcall Add_adc_lpm

  'Раскидываем сегменты по ножкам МК
   Distribution_segment_2_indicator:
    !rcall Write_74hc595       ' Закидываем данные в 74HC595

    Loadwordadr Table_digit_oa_ok
    !clr  R17
    !add  R30 , R16
    !adc  R31 , R17
    !lpm  R17 , Z       'Забираем значение в коде 7-seg led

    !rcall Write_74hc595       ' Закидываем данные в 74HC595

   'Защёлкиваем данные, непосредственный вывод на 7-seg LED
    Load_74hc595 = 1
    Load_74hc595 = 0

   Exit_indication_7seg_led:
    !pop R31
    !pop R30
    !pop R17
    !pop R16
    !out sreg , R16
    !pop R16

   !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Add_adc_lpm:
'-------------------------------------------------------------------------------
    !clr R17
    !add R30 , R16
    !adc R31 , R17
    !ld  R17 , Z       'Забираем значение в коде 7-seg led
   !ret
'===============================================================================
   Write_74hc595:
'-------------------------------------------------------------------------------
    !ldi R31 , 8       ' 8 бит в байте
   Next_bit:       ' Загоняем данные в 74HC595
    !SBRC R17 , 7       ' Пропустить если бит в регистре очищен
    Data_74hc595 = 1
    !SBRs R17 , 7       ' Пропустить если бит в регистре установлен
    Data_74hc595 = 0
    !rol R17       ' Сдвигаем влево биты в байте
   Write_clk:       ' Передаём тактовые импульсы
    Clk_74hc595 = 1
    Clk_74hc595 = 0

    !dec R31       ' Считаем биты
    !brne Next_Bit
'-------------------------------------------------------------------------------
   !ret
'===============================================================================

'===============================================================================
  Wait_tcnt0:
'-------------------------------------------------------------------------------
    If Tcnt0 < 150 Then
        Goto Wait_tcnt0
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
'  Подпрограмма расчета и вывода температур
'===============================================================================
  Ready_ds18b20:
'-------------------------------------------------------------------------------
    Gosub Preparing_reading

    Gosub Wait_tcnt0
    Disable Interrupts
    1wwrite &HBE       ', 1 , Port_ds18b20 , Count_ds18b20
    Enable Interrupts

    If Err > 0 Then
        Goto Start_measuring_ds18b20
    End If

    Gosub Wait_tcnt0
    Disable Interrupts
    Data_ds18b20(1) = 1wread(1)
    Enable Interrupts

    Gosub Wait_tcnt0
    Disable Interrupts
    Data_ds18b20(2) = 1wread(1)
    Enable Interrupts

    !ldi  R18 , 4
    !lds  R16 , {Data_ds18b20(1)}       '{Temp_ds18b20}
    !lds  R17 , {Data_ds18b20(2)}       '{Temp_ds18b20 + 1}
    !clr  R23
    !sbrc R17 , 7
    !ldi  R23 , &B_1000_0000
   Next_shift:
    !ror  R17
    !ror  R16
    !dec  R18
    !brne Next_shift
    !OR   R17 , R23

    !clr R21
    !cpi R16 , 0
    !cpc R17 , R21
    !brge Save_plus_data_ds18b20       'Перейти если больше или равно (со знаком)
    !rjmp Save_minus_data_ds18b20

   Save_plus_data_ds18b20:
    !clr R17
    !sts {Flag_minus} , R17
    !rjmp Exit_ready_ds18b20

   Save_minus_data_ds18b20:
    !ldi R20 , &HFF
    !clr R21
    !ldi R31 , 8

    !lsr R20
   Next_shift_integer:
    !brcc Next_shift_integer_1
    !add R21 , R16
   Next_shift_integer_1:
    !ror R21
    !ror R20
    !dec R31
    !brne Next_shift_integer

    !ldi R17 , 1
    !sts {Flag_minus} , R17
    !mov R16 , R20
   Exit_ready_ds18b20:
    !sts {Temp_ds18b20_byte} , R16

'===============================================================================
'  Запуск измерения температур датчиками Ds18b20
'===============================================================================
  Start_measuring_ds18b20:
'-------------------------------------------------------------------------------
    Gosub Preparing_reading
    Disable Interrupts
    1wwrite &H44       ', 1 , Port_ds18b20 , Count_ds18b20
    Enable Interrupts
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Preparing_reading:
    Gosub Wait_tcnt0
    1wreset       'Port_ds18b20 , Count_ds18b20
    Gosub Wait_tcnt0
    Disable Interrupts
    1wwrite &HCC       ', 1 , Port_ds18b20 , Count_ds18b20
    Enable Interrupts
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Table_digit_oa_ok:
'-------------------------------------------------------------------------------
  'Кодировка разрядов
  '    8765_4321  -  разряды
  ' &B_0000_0000  -  расположение в байте
'------------------------------------------
#if Type_indication_oa_ok = 0
    Data &B_1110_1110       ' 1; 5
    Data &B_1101_1101       ' 2; 6
    Data &B_1011_1011       ' 3; 7
    Data &B_0111_0111       ' 4; 8
#endif

#if Type_indication_oa_ok = 1
    Data &B_0001_0001       ' 1; 5
    Data &B_0010_0010       ' 2; 6
    Data &B_0100_0100       ' 3; 7
    Data &B_1000_1000       ' 4; 8
#endif
'===============================================================================

'===============================================================================
  Sumbol_7seg_led_oa_ok:       ' Таблица для 7-seg LED с общим анодом
'-------------------------------------------------------------------------------
  'Кодировка сегментов
  '    fbad_cghe      gfed cbah  -  сегменты
  ' &B_0000_0000  -  расположение в байте
  '
  'Выводимые символы  -  (-.[]_  0123456789  ACEFGHIJLOPSUY   bcdhnortu)
#if Type_indication_oa_ok = 0
    $asm
     .db &HEB       ' 48 - "0"
     .db &H28       ' 49 - "1"
     .db &HB3       ' 50 - "2"
     .db &HBA       ' 51 - "3"
     .db &H78       ' 52 - "4"
     .db &HDA       ' 53 - "5"
     .db &HDB       ' 54 - "6"
     .db &HA8       ' 55 - "7"
     .db &HFB       ' 56 - "8"
     .db &HFA       ' 57 - "9"
    $end Asm
#endif

#if Type_indication_oa_ok = 1
    $asm
     .db &H14       ' 48 - "0"
     .db &HD7       ' 49 - "1"
     .db &H4C       ' 50 - "2"
     .db &H45       ' 51 - "3"
     .db &H87       ' 52 - "4"
     .db &H25       ' 53 - "5"
     .db &H24       ' 54 - "6"
     .db &H57       ' 55 - "7"
     .db &H04       ' 56 - "8"
     .db &H05       ' 57 - "9"
    $end Asm
#endif
'===============================================================================

https://upforme.ru/uploads/0000/25/b8/1217/t310947.jpg

+3


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » ! Исследование 7-seg LED индикации !