

'--------------------   Конфигурация используемого МК   ------------------------
  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

'------------------------  Настройка таймера  ----------------------------------
  Const Const_доп_делитель_timer2 = 131

  Config Timer2 = Timer , Prescale = 64 , Clear Timer = 0       ' PRESCALE= 1|8|64|256|1024
  On Timer2 Обработка_прерывания_timer2 Nosave       ' Подпрограмма для обработки прерывания
  Stop Timer2
  Timer2 = Const_доп_делитель_timer2       ' Закидываем значение дополнительного делителя в TIMER2

  Const Const_счетчик_timer2 = 1000
  Dim Const_счетчик_timer2_low As Byte : Const_счетчик_timer2_low = Low(const_счетчик_timer2)
  Dim Const_счетчик_timer2_high As Byte : Const_счетчик_timer2_high = High(const_счетчик_timer2)


  Dim Счетчик_timer2 As Word
  Dim Флаг_прерывание_timer2 As Byte

  Dim Время_работы_часы As Byte
  Dim Время_работы_минуты As Byte
  Dim Время_работы_секунды As Byte

  Dim Время_работы_str As String * 8 : Время_работы_str = " 0:00:00"
  Dim Время_работы_часы_str As String * 2 : Время_работы_часы_str = " 0"
  Dim Время_работы_минуты_str As String * 2 : Время_работы_минуты_str = "00"
  Dim Время_работы_секунды_str As String * 2 : Время_работы_секунды_str = "00"

'------------------------   Подключаемые библиотеки   --------------------------
  $lib "lcd_HD44780_pcf8574.lib"

'-----------------------   Конфигурация шины I2c   -----------------------------
  Config Scl = Portc.5       ' Конфигурация I2c Scl
  Config Sda = Portc.4       ' Конфигурация I2c Sda
  Config I2cdelay = 20       ' Частота I2c = частота МК / I2cdelay  (работает в железе начиная с 20, меньше работает через раз)
  I2cinit
  Waitms 50       ' Инициализируем шину I2c, ждем


  Const Const_буфер_lcd = 16
  Config Lcd = 16 * 2

'-----------------------  Дополнительные_символы--------------------------------
 Deflcdchar 1 , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32       'значек градуса

'--------------------   Переменные для работы библиотеки   ---------------------
  Dim _backlight As Byte : _backlight = 1       ' Переменная для управления подсветкой
  Dim _lcd_e As Byte : _lcd_e = 192       ' !!! Не трогать, не будет работать !!!

'------------------   Переменная для адресации PCF8574х   ----------------------
  Const Pcf8574_lcd = &H4E       ' Адрес PCF8574A первого LCD

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Write   |     Read     |    Write  |   Read   |
'|-------------|-------------|--------------|-----------|----------|
'|  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   |
'------------------------------------------------------------------

'----------------   Конфигурация выводов PCF8574x   ----------------------------
  Const Pcf_rs = 0       ' RS
  Const Pcf_bl = 3       ' Подсветка
  Const Pcf_e2 = 2       ' Е
  Const Pcf_e1 = 1       ' Висит в воздухе
 '------------------------------------
  Const Pcf_d4 = 4       ' D4
  Const Pcf_d5 = 5       ' D5
  Const Pcf_d6 = 6       ' D6
  Const Pcf_d7 = 7       ' D7

  Initlcd       ' Обязательно инициализируем LCD
  Cursor Off       ' Выключаем курсор
  Cls       ' Чистим экран, на всякий случай, можно не делать
  Wait 1

  Dim Флаг_обновить_lcd As Byte

  Dim Буфер_lcd_1_строка_str As String * Const_буфер_lcd
  Dim Буфер_lcd_2_строка_str As String * Const_буфер_lcd
  Dim Буфер_lcd_3_строка_str As String * Const_буфер_lcd
  Dim Буфер_lcd_4_строка_str As String * Const_буфер_lcd

'-------------------------------------------------------------------------------
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'    З А П У С К    И    П Р Е Д В А Р И Т Е Л Ь Н Ы Е    Н А С Т Р О Й К И
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  Dim Val_long As Long
  Dim Val_long_str As String * 10

'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

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

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:
'###############################################################################


    If Флаг_прерывание_timer2 <> 0 Then
        Gosub Время_работы
        Флаг_прерывание_timer2 = 0
        Флаг_обновить_lcd = 1
        Goto Главный_цикл
    End If


    Буфер_lcd_1_строка_str = Время_работы_str
    Буфер_lcd_2_строка_str = Val_long_str
    Locate 1 , 1
    Lcd Буфер_lcd_1_строка_str
    Locate 2 , 1
    Lcd Буфер_lcd_2_строка_str


    Incr Val_long
    Val_long_str = Str(val_long)
    Val_long_str = Format(val_long_str , "       0")


    Waitms 100

'===============================================================================
  Goto Главный_цикл
 End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================


'===============================================================================
  Обработка_прерывания_timer2:       ' Время обработки прерывания 55 тактов + 8 тактов вход + 5 тактов выход
'-------------------------------------------------------------------------------
   'Т.к. будем использовать логические операции, !!! ОБЯЗАТЕЛЬНО сохраняем SREG !!!
    !push R16
    !in R16 , sreg
    !push R16
    !push R26
    !push R27

    !lds R26 , {Счетчик_timer2}
    !lds R27 , {Счетчик_timer2 + 1}
    !ADIW R26 , 1

    !lds R16 , {Const_счетчик_timer2_low}
    !cp  R26 , R16
    !lds R16 , {Const_счетчик_timer2_high}
    !cpc R27 , R16
    !breq Прошла_секунда
    !rjmp Выход_прерывания_timer2

   Прошла_секунда:
    !clr R26
    !clr R27
    !ldi R16 , 1
    !sts {Флаг_прерывание_timer2} , R16

   Выход_прерывания_timer2:
    !sts {Счетчик_timer2} , R26
    !sts {Счетчик_timer2 + 1} , R27

    !ldi R16 , Const_доп_делитель_timer2
    !out tcnt2 , R16

   'Восстанавливаем ранее сохранённые регистры и SREG
    !pop R27
    !pop R26
    !pop R16
    !out sreg , R16
    !pop R16
    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
  Время_работы:
'-------------------------------------------------------------------------------
    Incr Время_работы_секунды
    If Время_работы_секунды > 59 Then
        Время_работы_секунды = 0
        Incr Время_работы_минуты
        Время_работы_минуты_str = Str(время_работы_минуты)
        If Время_работы_минуты < 10 Then Время_работы_минуты_str = "0" + Время_работы_минуты_str
        If Время_работы_минуты > 59 Then
            Время_работы_минуты = 0
            Incr Время_работы_часы
            If Время_работы_часы > 23 Then
                Время_работы_часы = 0
            End If       ' If Время_работы_часы > 23 Then
            Время_работы_часы_str = Str(время_работы_часы)
            If Время_работы_часы < 10 Then Время_работы_часы_str = " " + Время_работы_часы_str
        End If       ' If Время_работы_минуты > 59 Then
    End If       ' If Время_работы_секунды > 59 Then
    Время_работы_секунды_str = Str(время_работы_секунды)
    If Время_работы_секунды < 10 Then Время_работы_секунды_str = "0" + Время_работы_секунды_str

    Время_работы_str = Время_работы_часы_str + ":" + Время_работы_минуты_str + ":" + Время_работы_секунды_str
'-------------------------------------------------------------------------------
  Return
'===============================================================================