


'===============================================================================
'      К О Н Ф И Г У Р А Ц И Я   К О Н Т Р О Л Л Е Р А     ATMEGA_328P
'===============================================================================
  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf
  $crystal = 8000000
  $framesize = 64       ' Размер области используемой и необходимой для преобразований
  $hwstack = 64       ' Размер аппаратного стека
  $swstack = 64       ' Размер программного стека

'===============================================================================
'               К О Н Ф И Г У Р А Ц И Я   Ш И Н Ы   i2c
'===============================================================================
 '1 - аппаратная реализация (МК - выводы аппаратные)
 '2 - программная реализация (МК - выводы любые)
  Const Variant_realizacii_i2c = 1

  #if Variant_realizacii_i2c = 1
      $lib "i2c_twi.lbx"       ' Без этой библиотеки реализация работы с шиной I2c будет программной, с библиотекой реализация шины I2c происходит на уровне аппаратных средств МК
      ' SCL и SDA, аппаратные выводы МК!!!
      Config Sda = Portc.4       ' Конфигурация вывода Sda
      Config Scl = Portc.5       ' Конфигурация вывода Scl
      Config Twi = 20000       ' Скорость работы шины I2c на аппаратном уровне
  #endif

  #if Variant_realizacii_i2c = 2
      Config Sda = Portc.4       ' Конфигурация вывода Sda
      Config Scl = Portc.5       ' Конфигурация вывода Scl
      Config I2cdelay = 10       ' Скорость работы шины I2c на программном уровне
  #endif

  I2cinit       ' Инициализация шины I2c
  Waitms 50

'===============================================================================
'           П О Д К Л Ю Ч Е Н И Е     Б И Б Л И О Т Е К
'===============================================================================
  $lib "lcd_HD44780_pcf8574.lib"

  Config Lcd = 20 * 4       ' Конфигурация используемого LCD

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

  Const Pcf8574_lcd = &H40       ' Адрес PCF8574х

'+-----------------------------------------------------------------+
'|             |  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 = 6       ' RS
  Const Pcf_bl = 7       ' Подсветка
  Const Pcf_e2 = 4       ' Е
  Const Pcf_e1 = 5       ' Висит в воздухе
 '-----------------------------------------
  Const Pcf_d4 = 0       ' D4
  Const Pcf_d5 = 1       ' D5
  Const Pcf_d6 = 2       ' D6
  Const Pcf_d7 = 3       ' D7


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

'-----------------------  Дополнительные_символы--------------------------------
 Deflcdchar 1 , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32       'значек градуса
' Deflcdchar 5 , 14 , 10 , 10 , 10 , 14 , 31 , 31 , 14       'термометр
'  Deflcdchar 6 , 4 , 5 , 15 , 20 , 4 , 14 , 10 , 27           'человечек
'  Deflcdchar 7 , 232 , 244 , 232 , 227 , 228 , 228 , 227 , 224       'градус Цельсия
'  Deflcdchar 8 , 2 , 6 , 30 , 30 , 30 , 6 , 2 , 32            'динамик
'  Deflcdchar 9 , 32 , 25 , 11 , 4 , 26 , 19 , 32 , 32        'значек вентилятора
'  Deflcdchar 10 , 9 , 26 , 28 , 27 , 28 , 26 , 9 , 32         'пищалка или пъезик
'  Deflcdchar 1 , 31 , 27 , 19 , 27 , 27 , 17 , 31 , 31       'инверсная 1
'  Deflcdchar 2 , 31 , 17 , 29 , 27 , 23 , 17 , 31 , 31       'инверсная 2
'  Deflcdchar 3 , 31 , 17 , 29 , 27 , 29 , 17 , 31 , 31       'инверсная 3
'  Deflcdchar 4 , 31 , 21 , 21 , 17 , 29 , 29 , 31 , 31       'инверсная 4
'  Deflcdchar 5 , 31 , 17 , 23 , 17 , 29 , 17 , 31 , 31       'инверсная 5
'  Deflcdchar 6 , 31 , 17 , 23 , 17 , 21 , 17 , 31 , 31       'инверсная 6
'  Deflcdchar 7 , 31 , 17 , 29 , 27 , 23 , 23 , 31 , 31       'инверсная 7
'  Deflcdchar 8 , 31 , 17 , 21 , 17 , 21 , 17 , 31 , 31       'инверсная 8
'  Deflcdchar 9 , 31 , 17 , 21 , 17 , 29 , 17 , 31 , 31       'инверсная 9
'  Deflcdchar 0 , 31 , 17 , 21 , 21 , 21 , 17 , 31 , 31       'инверсная 0

'===============================================================================
'             И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е
'===============================================================================
  Dim Флаг_обновить_lcd As Byte

'===============================================================================
'       И С П О Л Ь З У Е М Ы Е     П О Д П Р О Г Р А М М Ы
'===============================================================================
  Declare Sub Print_lcd(byval Copy_строка As Byte , Byval Copy_знакоместо As Byte , Byval Copy_buffer_lcd As String)       ' Подпрограмма вывода русского текста на LCD HD44780

'--------  Настройка прерывания поступающего с вывода "SQW/OUT" Ds3231  --------

  Config Pind.2 = Input       ' Настраиваем вывод на вход
  Config Int0 = Rising       ' Прерывание срабатывает по спаду уровня   Rising (по переднему фронту) ; Falling (по заднему фронту) ; Low Level (по низкому уровню)

' Ссылка на подпрограмму обработчика прерывания INT0, поступают секундные импульсы с Ds3231

  On Int0 Обработка_прерывания_ds3231 Nosave       ' После прерывания идем в подпрограмму обработки прерывания с Ds3231

'-----------------  Адресация микросхемы часов Ds3231  -------------------------

  Const Запись_ds3231 = &HD0       ' Адрес записи в ОЗУ Ds3231
  Const Чтение_ds3231 = &HD1       ' Адрес чтения из ОЗУ Ds3231

'------------  Константы для работы с микросхемой часов Ds3231  ----------------

  Const Const_секунды = 0       ' Регистр секунды
  Const Const_минуты = 1       ' Регистр минуты
  Const Const_часы = 2       ' Регистр часы
  Const Const_день_недели = 3       ' Регистр день_недели
  Const Const_число_месяца = 4       ' Регистр число_месяца
  Const Const_месяц = 5       ' Регистр месяц
  Const Const_год = 6       ' Регистр год

  Const Const_alarm_1_seconds = 7       ' Регистр секунды будильника 1
  Const Const_alarm_1_minutes = 8       ' Регистр минуты будильника 1
  Const Const_alarm_1_hours = 9       ' Регистр часы будильника 1
  Const Const_alarm_1_day = 10       ' Первые 4 бита, регистр день недели будильника 1
  Const Const_alarm_1_date = 10       ' Последние 4 бита, регистр день недели будильника 1

  Const Const_alarm_2_minutes = 11       ' Регистр минуты будильника 2
  Const Const_alarm_2_hours = 12       ' Регистр часы будильника 2
  Const Const_alarm_2_day = 13       ' Первые 4 бита, регистр день недели будильника 2
  Const Const_alarm_2_date = 13       ' Последние 4 бита, регистр день недели будильника 2

  Const Control_register = 14
  Const Status_register = 15
  Const Const_aging_offset = 16

  Const Const_температура_high = 17       ' Целая часть температуры со знаком
  Const Const_температура_low = 18       ' Дробная часть температуры
  Const Const_коррекция_температуры = 2.65       ' Корректирующая константа



  Const Const_stop_часы = &B10000000       ' Значение переменной для остановки часов
  Const Const_start_часы = &B00000000       ' Значение переменной для запуска часов

'  Управляющий регистр используется для управления работой вывода SQW/OUT      &B00100000
'        BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
'NAME:    EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
'Por : 0 0 0 1 1 1 0 0
  Const Const_разрешение_sout_ds3231 = &B00000000       ' Разрешение импульсов с частотой 1 Гц на выходе SQW/OUT - (выходной сигнал с прямоугольными импульсами)
'                                        ||||||||
'                                        |||||||+--- 0 - A1IE - Alarm 1 Interrupt Enable (A1IE)
'                                        ||||||+---- 1 - A2IE - Alarm 2 Interrupt Enable (A2IE)
'                                        |||||+----- 2 - INTCN - Interrupt Control (INTCN)
'                                        ||||+------ 3 - RS1   - Rate Select (RS2 and RS1)
'                                        |||+------- 4 - RS2   - Rate Select (RS2 and RS1)
'                                        ||+-------- 5 - CONV  - Convert Temperature (CONV)
'                                        |+--------- 6 - BBSQW - Battery-Backed Square-Wave Enable
'                                        +---------- 7 - EOSC  - Enable Oscillator (EOSC), 0 - запущен, 1 остановлен
' Примечание:
'  Const Const_разрешение_sout_ds1307 = &B00000000       ' Разрешение импульсов с частотой 1 Гц на выходе SQW/OUT
'  Const Const_разрешение_sout_ds1307 = &B00001000       ' Разрешение импульсов с частотой 1,024 кГц на выходе SQW/OUT
'  Const Const_разрешение_sout_ds1307 = &B00010000       ' Разрешение импульсов с частотой 4,096 кГц на выходе SQW/OUT
'  Const Const_разрешение_sout_ds1307 = &B00011000       ' Разрешение импульсов с частотой 8,192 кГц на выходе SQW/OUT


'  Const Const_настройка_ds1307 = 7       ' Регистр для настройки Ds1307
'  Const Const_stop_часы = &B10000000       ' Значение константы для остановки часов
'  Const Const_start_часы = &B00000000       ' Значение константы для запуска часов
'  Const Const_разрешение_sout_ds1307 = &B10010000       ' Значение константы для старта секундных импульсов

'===============================================================================
'             И С П О Л Ь З У Е М Ы Е     П Е Р Е М Е Н Н Ы Е
'===============================================================================

  Dim Флаг_опросить_ds3231 As Byte

  Dim Год As Byte
  Dim Часы As Byte
  Dim Месяц As Byte
  Dim Минуты As Byte
  Dim Секунды As Byte
  Dim День_недели As Byte
  Dim Число_месяца As Byte

  Dim Год_str As String * 4
  Dim Часы_str As String * 2
  Dim Месяц_str As String * 8
  Dim Минуты_str As String * 2
  Dim Секунды_str As String * 2
  Dim День_недели_str As String * 11
  Dim Число_месяца_str As String * 2


  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"


  Dim Время_str As String * 8
  Dim Дата_str As String * 32

  Dim Температура_low As Byte
  Dim Температура_high As Byte

  Dim Сигнатура_температуры As Byte
  Dim Целые_температуры As Byte
  Dim Десятые_температуры_sin As Single

  Dim Готовая_температура_single As Single
  Dim Temp_температура_single_1 As Single

  Dim Готовая_температура_str As String * 10


  Dim Данные_status_register As Byte
  Dim Данные_control_register As Byte

  Dim 1_буд_секунды As Byte
  Dim 1_буд_минуты As Byte
  Dim 1_буд_часы As Byte
  Dim 1_буд_число_месяца As Byte
  Dim 1_буд_месяц As Byte
  Dim 1_буд_год As Byte

  Dim 2_буд_минуты As Byte
  Dim 2_буд_часы As Byte
  Dim 2_буд_число_месяца As Byte
  Dim 2_буд_месяц As Byte
  Dim 2_буд_год As Byte


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

'===============================================================================
'       И С П О Л Ь З У Е М Ы Е     П О Д П Р О Г Р А М М Ы
'===============================================================================

'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'    З А П У С К    И    П Р Е Д В А Р И Т Е Л Ь Н Ы Е    Н А С Т Р О Й К И
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

  1_буд_секунды = 0
  1_буд_минуты = 0
  1_буд_часы = 17
  1_буд_число_месяца = 25
  1_буд_месяц = 10
  1_буд_год = 14

  2_буд_минуты = 2
  2_буд_часы = 17
  2_буд_число_месяца = 25
  2_буд_месяц = 10
  2_буд_год = 14

  1_буд_год = Makebcd(1_буд_год)       ' Год
  1_буд_часы = Makebcd(1_буд_часы)       ' Часы
  1_буд_месяц = Makebcd(1_буд_месяц)       ' Месяц
  1_буд_минуты = Makebcd(1_буд_минуты)       ' Минуты
  1_буд_секунды = Makebcd(1_буд_секунды)       ' Секунды
  1_буд_число_месяца = Makebcd(1_буд_число_месяца)       ' Число

  2_буд_год = Makebcd(2_буд_год)       ' Год
  2_буд_часы = Makebcd(2_буд_часы)       ' Часы
  2_буд_месяц = Makebcd(2_буд_месяц)       ' Месяц
  2_буд_минуты = Makebcd(2_буд_минуты)       ' Минуты
  2_буд_число_месяца = Makebcd(2_буд_число_месяца)       ' Число

  I2cstart       ' Подготовка к работа шины I2c
  I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
  I2cwbyte Const_alarm_1_seconds       ' Адрес регистра, в который будет производиться запись
  I2cwbyte 1_буд_секунды       ' Записываемая переменная
  I2cwbyte 1_буд_минуты       ' Записываемая переменная
  I2cwbyte 1_буд_часы       ' Записываемая переменная
  I2cwbyte 1_буд_число_месяца       ' Записываемая переменная
  I2cwbyte 1_буд_месяц       ' Записываемая переменная
  I2cwbyte 1_буд_год       ' Записываемая переменная
  I2cwbyte 2_буд_минуты       ' Записываемая переменная
  I2cwbyte 2_буд_часы       ' Записываемая переменная
  I2cwbyte 2_буд_число_месяца       ' Записываемая переменная
  I2cwbyte 2_буд_месяц       ' Записываемая переменная
  I2cwbyte 2_буд_год       ' Записываемая переменная
  I2cstop       ' Освобождаем шину I2c

'Активируем выход часовой микросхемы на 1Гц для светодиода и прерывания
  I2cstart       ' Запись регистра упрaвления
  I2cwbyte Запись_ds3231
  I2cwbyte Control_register
  I2cwbyte &B_0000_0011       ' Const_разрешение_sout_ds3231
  I2cstop

  I2cstart       ' Запись статус регистра
  I2cwbyte Запись_ds3231
  I2cwbyte Status_register
  I2cwbyte &B_0000_0000
  I2cstop

'' ###################################################################################################################
'' ###################################################################################################################
'' ###################################################################################################################

'Готовим данные для записи в Ds3231

'' ###################################################################################################################
'' ###################################################################################################################
'' ###################################################################################################################


'  Секунды = 0
'  Минуты = 21
'  Часы = 15
'  День_недели = 1
'  Число_месяца = 8
'  Месяц = 3
'  Год = 15

'  Год = Makebcd(год)       ' Год
'  Часы = Makebcd(часы)       ' Часы
'  Месяц = Makebcd(месяц)       ' Месяц
'  Минуты = Makebcd(минуты)       ' Минуты
'  Секунды = Makebcd(секунды)       ' Секунды
'  День_недели = Makebcd(день_недели)       ' День недели
'  Число_месяца = Makebcd(число_месяца)       ' Число

' 'Запись подготовленных данных в регистры Ds3231
'  I2cstart       ' Подготовка к работа шины I2c
'  I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
'  I2cwbyte Const_секунды       ' Адрес регистра, в который будет производиться запись
'  I2cwbyte Секунды       ' Записываемая переменная
'  I2cwbyte Минуты       ' Записываемая переменная
'  I2cwbyte Часы       ' Записываемая переменная
'  I2cwbyte День_недели       ' Записываемая переменная
'  I2cwbyte Число_месяца       ' Записываемая переменная
'  I2cwbyte Месяц       ' Записываемая переменная
'  I2cwbyte Год       ' Записываемая переменная
'  I2cstop       ' Освобождаем шину I2c



'' ###################################################################################################################
'' ###################################################################################################################
'' ###################################################################################################################



  Gosub Опрос_all_ds3231
  Gosub Получение_температуры_ds3231

  Reset Подсветка       ' Включаем подсветку, именно Reset, т.к., на плате с PCF8574 стоит транзистор
  Print_lcd 1 , 1 , "Тестирование вывода "
  Print_lcd 2 , 1 , "на LCD по шине  i2c "
  Print_lcd 3 , 1 , "Atmega328P + Ds3231 "
  Print_lcd 4 , 1 , "   через PCF8574    "
  Wait 2
  Cls

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

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


     If Флаг_опросить_ds3231 <> 0 Then
         Gosub Опрос_all_ds3231
         If Минуты = 0 Then       ' Согласно документации на Ds3231, опрашивать температуру чаще 1 раза в минуту нет смысла
             Gosub Получение_температуры_ds3231
         End If
         Gosub Чтение_status_register
         Gosub Чтение_control_register
         Gosub Время_работы
         Флаг_обновить_lcd = 1
         Флаг_опросить_ds3231 = 0
         Goto Главный_цикл
     End If



     If Флаг_обновить_lcd <> 0 Then
         Gosub Обновить_lcd
         Флаг_обновить_lcd = 0
         Goto Главный_цикл
     End If



     nop

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

'===============================================================================
  Обновить_lcd:
'-------------------------------------------------------------------------------
    Время_работы_str = Время_работы_часы_str + ":" + Время_работы_минуты_str + ":" + Время_работы_секунды_str
    Время_str = Часы_str + ":" + Минуты_str + ":" + Секунды_str
    Дата_str = Число_месяца_str + " " + Месяц_str


    Буфер_lcd_1_строка_str = Время_str + "    " + Время_работы_str
    Буфер_lcd_2_строка_str = "    " + День_недели_str
    Буфер_lcd_3_строка_str = "     " + Дата_str
    Буфер_lcd_4_строка_str = " t Ds3231: " + Готовая_температура_str

    Print_lcd 1 , 1 , Буфер_lcd_1_строка_str
    Print_lcd 2 , 1 , Буфер_lcd_2_строка_str
    Print_lcd 3 , 1 , Буфер_lcd_3_строка_str
    Print_lcd 4 , 1 , Буфер_lcd_4_строка_str
    Locate 4 , 18
    Lcd Chr(1) ; "C"
'-------------------------------------------------------------------------------
  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
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
  Опрос_all_ds3231:
'-------------------------------------------------------------------------------
  'Читаем значениия всех регистров Ds3231
    I2cstart       ' Подготовка к работе шины I2c
    I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
    I2cwbyte Const_секунды       ' Регистр с которого будем считывать данные
    I2crepstart       ' Повторная подготовка к работе шины I2c
    I2cwbyte Чтение_ds3231       ' Адресное обращение к используемому чипу i2c, для чтения
    I2crbyte Секунды , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte Минуты , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte Часы , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte День_недели , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte Число_месяца , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte Месяц , Ack       ' Читаем значение из регистра чипа i2c
    I2crbyte Год , Nack       ' Читаем значение из регистра чипа i2c
    I2cstop       ' Освобождаем шину I2c

    Год = Makedec(год)       ' Год
    Часы = Makedec(часы)       ' Часы
    Месяц = Makedec(месяц)       ' Месяц
    Минуты = Makedec(минуты)       ' Минуты
    Секунды = Makedec(секунды)       ' Секунды
    День_недели = Makedec(день_недели)       ' День недели
    Число_месяца = Makedec(число_месяца)       ' Число

    Год_str = "20" + Str(год)
    Месяц_str = Lookupstr(месяц , Название_месяца)
    День_недели_str = Lookupstr(день_недели , Название_дня_недели)
    If Часы < 10 Then Часы_str = " " + Str(часы) Else Часы_str = Str(часы)
    If Минуты < 10 Then Минуты_str = "0" + Str(минуты) Else Минуты_str = Str(минуты)
    If Секунды < 10 Then Секунды_str = "0" + Str(секунды) Else Секунды_str = Str(секунды)
    If Число_месяца < 10 Then Число_месяца_str = " " + Str(число_месяца) Else Число_месяца_str = Str(число_месяца)

    Время_str = Часы_str + ":" + Минуты_str + ":" + Секунды_str
    Дата_str = День_недели_str + " " + Число_месяца_str + " " + Месяц_str + " " + Год_str + " года"

'-------------------------------------------------------------------------------
  Return
'===============================================================================



'===============================================================================
'--  Подпрограмма для опроса Ds3231, почему так, потому, что так БЫСТРЕЕ !!!  --
'===============================================================================
  Опрос_ds3231:
'-------------------------------------------------------------------------------
    I2cstart       ' Подготовка к работе шины I2c
    I2cwbyte Запись_ds3231       ' Команда начало записи
    I2cwbyte Const_секунды       ' Команда начального адреса куда пишем - 0
    I2cstart       ' Подготовка к работа шины I2c
    I2cwbyte Чтение_ds3231       ' Адресное обращение к Ds3231
    I2crbyte Секунды , Nack       ' Читаем значение секунд (двоично-десятичное форматирование)
    I2cstop       ' Освобождаем шину I2c

    Секунды = Makedec(секунды)       ' Секунды
    If Секунды < 10 Then Секунды_str = "0" + Str(секунды) Else Секунды_str = Str(секунды)

    If Секунды = 0 Then
        I2cstart       ' Подготовка к работе шины I2c
        I2cwbyte Запись_ds3231       ' Команда начало записи
        I2cwbyte Const_минуты       ' Команда начального адреса куда пишем - 0
        I2cstart       ' Подготовка к работа шины I2c
        I2cwbyte Чтение_ds3231       ' Адресное обращение к Ds3231
        I2crbyte Минуты , Nack       ' Читаем значение секунд (двоично-десятичное форматирование)
        I2cstop       ' Освобождаем шину I2c

        Минуты = Makedec(минуты)       ' Минуты
        If Минуты < 10 Then Минуты_str = "0" + Str(минуты) Else Минуты_str = Str(минуты)


        Gosub Получение_температуры_ds3231


        If Минуты = 0 Then
            I2cstart       ' Подготовка к работе шины I2c
            I2cwbyte Запись_ds3231       ' Команда начало записи
            I2cwbyte Const_часы       ' Команда начального адреса куда пишем - 0
            I2cstart       ' Подготовка к работа шины I2c
            I2cwbyte Чтение_ds3231       ' Адресное обращение к Ds3231
            I2crbyte Часы , Nack       ' Читаем значение секунд (двоично-десятичное форматирование)
            I2cstop       ' Освобождаем шину I2c

            Часы = Makedec(часы)       ' Часы
            If Часы < 10 Then Часы_str = " " + Str(часы) Else Часы_str = Str(часы)

            If Часы = 0 Then
                I2cstart       ' Подготовка к работе шины I2c
                I2cwbyte Запись_ds3231       ' Команда начало записи
                I2cwbyte Const_день_недели       ' Команда начального адреса куда пишем - 0
                I2cstart       ' Подготовка к работа шины I2c
                I2cwbyte Чтение_ds3231       ' Адресное обращение к Ds3231
                I2crbyte День_недели , Ack
                I2crbyte Число_месяца , Ack
                I2crbyte Месяц , Ack
                I2crbyte Год , Nack
                I2cstop       ' Освобождаем шину I2c

                Год = Makedec(год)       ' Год
                Месяц = Makedec(месяц)       ' Месяц
                День_недели = Makedec(день_недели)       ' День недели
                Число_месяца = Makedec(число_месяца)       ' Число

                День_недели_str = Lookupstr(день_недели , Название_дня_недели)
                If Число_месяца < 10 Then Число_месяца_str = "0" + Str(число_месяца) Else Число_месяца_str = Str(число_месяца)
                Месяц_str = Lookupstr(месяц , Название_месяца)
                Год_str = "20" + Str(год)
            End If       ' If Часы = 0 Then
        End If       ' If Минуты = 0 Then
    End If       ' If Секунды = 0 Then
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
  Чтение_status_register:
'-------------------------------------------------------------------------------

    I2cstart       ' Подготовка к работе шины I2c
    I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
    I2cwbyte Status_register       ' Регистр с которого будем начинать считывать данные
    I2crepstart       ' Повторная подготовка к работе шины I2c
    I2cwbyte Чтение_ds3231       ' Адресное обращение к используемому чипу i2c, для чтения
    I2crbyte Данные_status_register , Nack       ' Читаем значение из регистра чипа i2c, и даём понять, что чтение завершено
    I2cstop       ' Освобождаем шину I2c

'-------------------------------------------------------------------------------
  Return
'===============================================================================



'===============================================================================
  Чтение_control_register:
'-------------------------------------------------------------------------------

    I2cstart       ' Подготовка к работе шины I2c
    I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
    I2cwbyte Control_register       ' Регистр с которого будем начинать считывать данные
    I2crepstart       ' Повторная подготовка к работе шины I2c
    I2cwbyte Чтение_ds3231       ' Адресное обращение к используемому чипу i2c, для чтения
    I2crbyte Данные_control_register , Nack       ' Читаем значение из регистра чипа i2c, и даём понять, что чтение завершено
    I2cstop       ' Освобождаем шину I2c

'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
  Получение_температуры_ds3231:
'-------------------------------------------------------------------------------

    I2cstart       ' Подготовка к работе шины I2c
    I2cwbyte Запись_ds3231       ' Адресное обращение к используемому чипу i2c, для записи
    I2cwbyte &H11       ' Регистр с которого будем начинать считывать данные
    I2crepstart       ' Повторная подготовка к работе шины I2c
    I2cwbyte Чтение_ds3231       ' Адресное обращение к используемому чипу i2c, для чтения
    I2crbyte Температура_high , Ack       ' Читаем значение из регистра чипа i2c и даём понять, что будем читать ещё
    I2crbyte Температура_low , Nack       ' Читаем значение из регистра чипа i2c, и даём понять, что чтение завершено
    I2cstop       ' Освобождаем шину I2c

    Gosub Расчет_готовой_температуры

    Готовая_температура_str = Fusing(готовая_температура_single , "&.&")
    Готовая_температура_str = Format(готовая_температура_str , "+   0")
    Готовая_температура_str = Готовая_температура_str

'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
' Расчёт готовой температуры полученной от RTC Ds3231
'===============================================================================
  Расчет_готовой_температуры:
'-------------------------------------------------------------------------------
    Сигнатура_температуры = Температура_high And &B_1000_0000       ' Берём значение 7-го битика, где хранится сигнатура температуры
    Целые_температуры = Температура_high And &B_0111_1111       ' Берём значение 6-ти битиков, где хранится целое значение температуры

    Shift Температура_low , Right , 6       ' Берём значение последних 2-х битиков, где хранятся десятые температуры
    Десятые_температуры_sin = Температура_low * 0.25       ' Получаем десятые и сотые температуры


    If Сигнатура_температуры = 128 Then
        Temp_температура_single_1 = Целые_температуры + Десятые_температуры_sin
        Готовая_температура_single = Temp_температура_single_1 - 128
        Готовая_температура_single = Готовая_температура_single + Const_коррекция_температуры
      Else
        Готовая_температура_single = Целые_температуры + Десятые_температуры_sin
        Готовая_температура_single = Готовая_температура_single - Const_коррекция_температуры
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
' Обработка прерываний от RTC Ds3231
'===============================================================================
  Обработка_прерывания_ds3231:
'-------------------------------------------------------------------------------
    !push R16
    !ldi R16 , 1
    !sts {Флаг_опросить_ds3231} , R16
    !pop R16
    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
 Название_дня_недели:       ' Раскомментировать нужное
'-------------------------------------------------------------------------------
'    Data "" , "Понедельник" , "Вторник" , "Среда" , "Четверг" , "пятница" , "Суббота" , "Воскресенье"
'-------------------------------------------------------------------------------

    Data " "       '          0
    Data "Воскресенье"       ' 1
    Data "Понедельник"       ' 2
    Data "Вторник"       '          3
    Data "Среда"       '          4
    Data "Четверг"       '          5
    Data "Пятница"       '          6
    Data "Суббота"       '          7

' Это не кракозябли, это может кому понадобится, вывод русских названий дней недели на LCD с контроллером HD44780

'    Data " "        '          0
'    Data "BocєpeceЅДe"       ' 1
'    Data "ЁoЅeгe»ДЅёє"       ' 2
'    Data "BїopЅёє"  '          3
'    Data "Cpeгa"    '          4
'    Data "«eїіepґ"  '          5
'    Data "ЁЗїЅёеa"  '          6
'    Data "CyІІoїa"  '          7

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


'===============================================================================
  Название_месяца:       ' Раскомментировать нужное
'-------------------------------------------------------------------------------
'    Data "" , "Января" , "Февраля" , "Марта" , "Апреля" , "Мая" , "Июня" , "Июля" , "Августа" , "Сентября" , "Октября" , "Ноября" , "Декабря"
'-------------------------------------------------------------------------------

    Data " "       ' 0
    Data "Января"       ' 1
    Data "Февраля"       ' 2
    Data "Марта"       ' 3
    Data "Апреля"       ' 4
    Data "Мая"       ' 5
    Data "Июня"       ' 6
    Data "Июля"       ' 7
    Data "Августа"       ' 8
    Data "Сентября"       ' 9
    Data "Октября"       ' 10
    Data "Ноября"       ' 11
    Data "Декабря"       ' 12

' Это не кракозябли, это может кому понадобится, вывод русских названий месяцев на LCD с контроллером HD44780

'    Data " "        ' 0
'    Data "±ЅіapЗ"   ' 1
'    Data "Єeіpa»З"  ' 2
'    Data "Mapїa"    ' 3
'    Data "Aѕpe»З"   ' 4
'    Data "MaЗ"      ' 5
'    Data "ҐЖЅЗ"     ' 6
'    Data "ҐЖ»З"     ' 7
'    Data "Aіґycїa"  ' 8
'    Data "CeЅїЗІpЗ" ' 9
'    Data "OєїЗІpЗ"  ' 10
'    Data "HoЗІpЗ"   ' 11
'    Data "аeєaІpЗ"  ' 12

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


'===============================================================================
'           Подпрограмма вывода русского текста на LCD HD44780
'===============================================================================
  Sub Print_lcd(byval Copy_строка As Byte , Byval Copy_знакоместо As Byte , Byval Copy_buffer_lcd As String)       ' Подпрограмма вывода русского текста на LCD HD44780
'-------------------------------------------------------------------------------
    Local Длина_строки As Byte , Цикл_lcd_print As Byte , Код_символа As Byte , Код_символа_lcd As Byte
    Local Строка As Byte , Знакоместо As Byte
    Local Символ_str As String * 1 , Символ_lcd_str As String * 1 , Вывод_на_lcd_str As String * 20

    Строка = Copy_строка
    Знакоместо = Copy_знакоместо
    Вывод_на_lcd_str = ""

    Длина_строки = Len(copy_buffer_lcd)       ' Узнаем количество выводимых символов
    If Длина_строки = 0 Then       ' Ecли длина строки "0", выходим из подпрограммы
        Exit Sub       ' Узнаем количество выводимых символов
    End If

    For Цикл_lcd_print = 1 To Длина_строки       ' В цикле занимаемся кодировкой символов
        Символ_str = Mid(copy_buffer_lcd , Цикл_lcd_print , 1)       ' Вынимаем по 1 символу из выводимого текста
        Код_символа = Asc(символ_str)       ' Узнаем код вынутого символа

        If Код_символа > 191 Then
            Код_символа_lcd = Lookup(код_символа , Cp1251_to_lcd_hd44780)       ' Берем код символа из таблицы (смотреть внизу исходника)
            Символ_lcd_str = Chr(код_символа_lcd)       ' Берем код символа знакогенератора LCD из таблицы (смотреть внизу исходника)
          Else
            Символ_lcd_str = Символ_str
        End If

        Вывод_на_lcd_str = Вывод_на_lcd_str + Символ_lcd_str       ' Собираем выводимый текст в формате LCD
    Next Цикл_lcd_print       ' Повторяем для всех символов выводимого текста

    Locate Строка , Знакоместо       ' Указываем координаты для вывода текста
    Lcd Вывод_на_lcd_str       ' Непосредственный вывод текста на LCD
'-------------------------------------------------------------------------------
  End Sub
'===============================================================================



'===============================================================================
'           Таблица для перекодировки из символов Cp1251
'                в символы знакосинтезирующего LCD
'===============================================================================
  Cp1251_to_lcd_hd44780:
'---------------  первые 128 знаков  -------------------------------------------
    Data &H00 , &H01 , &H02 , &H03 , &H04 , &H05 , &H06 , &H07 , &H08 , &H09
    Data &H0A , &H0B , &H0C , &H0D , &H0E , &H0F , &H10 , &H11 , &H12 , &H13
    Data &H14 , &H15 , &H16 , &H17 , &H18 , &H19 , &H1A , &H1B , &H1C , &H1D
    Data &H1E , &H1F , &H20 , &H21 , &H22 , &H23 , &H24 , &H25 , &H26 , &H27
    Data &H28 , &H29 , &H2A , &H2B , &H2C , &H2D , &H2E , &H2F , &H30 , &H31
    Data &H32 , &H33 , &H34 , &H35 , &H36 , &H37 , &H38 , &H39 , &H3A , &H3B
    Data &H3C , &H3D , &H3E , &H3F , &H40 , &H41 , &H42 , &H43 , &H44 , &H45
    Data &H46 , &H47 , &H48 , &H49 , &H4A , &H4B , &H4C , &H4D , &H4E , &H4F
    Data &H50 , &H51 , &H52 , &H53 , &H54 , &H55 , &H56 , &H57 , &H58 , &H59
    Data &H5A , &H5B , &H20 , &H5D , &H5E , &H5F , &H60 , &H61 , &H62 , &H63
    Data &H64 , &H65 , &H66 , &H67 , &H68 , &H69 , &H6A , &H6B , &H6C , &H6D
    Data &H6E , &H6F , &H70 , &H71 , &H72 , &H73 , &H74 , &H75 , &H76 , &H77
    Data &H78 , &H79 , &H7A , &H5B , &H20 , &H5D , &HE9 , &H7F
'---------------  вторые 128 знаков  -------------------------------------------
    Data &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20
    Data &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20
    Data &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20 , &H20
    Data &H20 , &H20 , &HCB , &H20 , &H49 , &H69 , &H04 , &H20 , &HFE , &HEF
    Data &HA2 , &HCC , &H00 , &HC9 , &H20 , &H20 , &H20 , &H02 , &H00 , &H00
    Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &HB5 , &H4E , &H00 , &H00
    Data &H00 , &H00 , &H00 , &H00 , &H41 , &HA0 , &H42 , &HA1 , &HE0 , &H45
    Data &HA3 , &HA4 , &HA5 , &HA6 , &H4B , &HA7 , &H4D , &H48 , &H4F , &HA8
    Data &H50 , &H43 , &H54 , &HA9 , &HAA , &H58 , &HE1 , &HAB , &HAC , &HE2
    Data &HAD , &HAE , &H62 , &HAF , &HB0 , &HB1 , &H61 , &HB2 , &HB3 , &HB4
    Data &HE3 , &H65 , &HB6 , &HB7 , &HB8 , &HB9 , &HBA , &HBB , &HBC , &HBD
    Data &H6F , &HBE , &H70 , &H63 , &HBF , &H79 , &HE4 , &H78 , &HE5 , &HC0
    Data &HC1 , &HE6 , &HC2 , &HC3 , &HC4 , &HC5 , &HC6 , &HC7
'===============================================================================