Статья №8


     Рассмотрим  ещё  один  пример  применения  шины  I2C. Это  работа  часов  реального  времени  DS1307  совместно  с  микроконтроллером  ATtiny2313. 
     DS1307  - это  малопотребляющие  полные  двоично – десятичные  часы – календарь, включающие  56  байтов  энергонезависимой  статической  ОЗУ. Адреса  и  данные  передаются  по  двухпроводной  двунаправленной  шине. Часы – календарь  отсчитывают  секунды, минуты, часы, день, дату, месяц  и  год. Последняя  дата  месяца  автоматически  корректируется  для  месяцев  с  количеством  дней  меньше  31, включая  коррекцию  високосного  года. Часы  работают  как  в  24 –часовом, так  и  в  12 – часовом  режиме  с  индикатором  АМ/РМ. DS1307  имеет  встроенную  систему  наблюдения  за  питанием , которая  обнаруживает  перебои  питания  и  автоматически  переключается  на  питание  от  батареи. Устройство  работоспособно  при  напряжении  питания  выше  1,25 В. Однако, когда  к  часам  подключена  батарея  3 В, при  напряжении  питания  ниже  1,25 В  чтение  и  запись  запрещены, но  функция  отсчёта  продолжает  работать. Частота  подключаемого  к  контактам  Х1  и  Х2  кварца – 32,768 КГц.
     DS1307  работает  на  двухпроводной  последовательной  шине  как  ведомое  устройство. Доступ  к  нему  достигается  установкой  условия  START  и  передачей  устройству  идентификационного  кода, за  которым  следует  адрес  регистра. К  следующим  за  ним  регистрам  доступ  может  осуществляться  последовательно, пока  не  будет  выполнено  условие  STOP. 
     Информация   от  часов  и  календаря  получается  чтением  соответствующих  байтов  регистра. Регистры  показаны  в  табл.1:
 

     Бит  7  регистра секунды (адрес 00Н) – это  бит  останова  часов  (1 – тактовый  генератор  выключен, 0 – включён). Поскольку  при  включении  питания  состояние  регистров  не определено, необходимо  принудительно  включать  тактовый  генератор  (СН=0)  во  время  начальной  инициализации.
     Бит  6  регистра  часов  (адрес  02Н)  отвечает  за  выбор  режима  работы  1 – 12 часовой  режим  работы  0 – 24 часовой  режим  работы. В  12 – часовом  режиме  бит  5 – это  бит  АМ/РМ, в  24 – часовом  режиме   бит  5 – это  бит  второго  десятка  часов.
     Управляющий  регистр  (адрес  07Н)  используется  для  управления  выводом  SQW/OUT  (Scuare  Wave/Output Driver – сигнал  с  прямоугольными  импульсами).   Бит  OUT  управляет  логическим  уровнем  на  выводе  SQW/OUT:  если  OUT=1,  то SQW/OUT=1;  если  OUT=0 , то  SQW/OUT=0.
     Бит  SQWE  (=1)  включает  генерацию  прямоугольных  импульсов, частота  которых  зависит  от  состояния  битов  RS1, RS0  регистра  управления  (адрес  07H).
     Адрес  DS1307  -  1101000. В  режиме  приёма  часы  декодируют  адресный  байт  и  выдают  в  линию  SDA  подтверждение, после  чего  ведущий  передаёт  в  устройство  адрес  регистра.  Это  установит  регистровый  указатель. Затем  ведущий  начинает  передачу  байтов  данных, каждый  из  которых  будет  подтверждаться  DS1307. Чтобы  завершить  запись  данных, ведущий  генерирует  условие  окончания.
     В  режиме  ведомого  передатчика  DS1307  начинает  передавать  данные,  начиная  с  указанного  адреса, находящегося  в  регистровом  указателе. Если  перед  началом  чтения  указатель  регистра  не  записан, то  первым  читаемым  адресом  будет  тот, который  был  сохранён  в  нём  последним. 
     На  Рис.1  представлена  схема  подключения  DS1307  к  ATtiny2313. Индикация  значений  часов  и  календаря  происходит  с  помощью  ЖКИ  типа  МТ-16S2H  (фирма – изготовитель  МЭЛТ). 

 
      Регистр  управления  DS1307  сконфигурирован  таким  образом, что  на  контакте  SQW/OUT  генерируется  токовые  импульсы  частотой  1 Гц, заставляющие  мигать  светодиод  HL1, что  позволяет  контролировать  работу  часов. Шины  SDA  и  SDL  имеют  подтяжку  резисторами  R2, R3 – 10 КОм. Резистор  R1  и  конденсатор  С1  образуют  цепь  сброса  микроконтроллера. 
     Основная  программа  ATtiny2313  cчитывает  из  часов  и  индуцирует  на  дисплее  в  цикле  значения   часов  и  минут.
     Для  установки  часов   необходимо  нажать  кнопку  «Установка»  (S2), тогда  включится  прерывание  INT0, при  обработке  которого  с  помощью  кнопок  «Увеличение»  (S5)  и  «Продолжение»  (S4). Блок – схема  программы  “Clock”  приведена  на  Рис.2, где  основной  цикл  заключается  в  считывании  значений  часов  и  минут  по  I2C  из  DS1307
декодировании  их  из  двоично – десятичного  кода  и  отображении  на  ЖКИ.
    Подпрограмма  установки  состоит  из  кодирования  значений  часов  и  минут  в  двоично – десятичный  код  и  отправки  их  по  I2C  в  DS1307. Текст  программы  приводится  ниже:

$regfile = "attiny2313a.dat"       'настройки
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Config Sda = Portb.5               'конфигурация I2C
Config Scl = Portb.7
Config I2cdelay = 10

Config Int0 = Falling              'прерывание по спаду импульса

Config Debounce = 75
Config Pind.4 = Input
Config Pind.5 = Input

Const Adressr = &B11010001         'cчитывание
Const Adressw = &B11010000         'запись
Const Secadress = &H00             'адреса регистров часов
Const Minadress = &H01
Const Clockadress = &H02
Const Datadress = &H04
Const Uprbyte = &B00010000
Const Upradress = &H07
Const Sec1 = &B00000000

Dim Sec As Byte                    'объявления переменных
Dim Minut As Byte
Dim Eminut As Byte
Dim Clock As Byte
Dim Eclock As Byte
Dim Z As Integer
Dim Ones As Byte
Dim Tens As Byte

Declare Sub Ed                     'определение подпрограммы-выделение десятков и единиц

On Int0 Button                     'определение подпрограмм прерываний

I2cstart                           'запись в регистр упрaвления
I2cwbyte Adressw
I2cwbyte Upradress
I2cwbyte Uprbyte
I2cstop

Enable Interrupts                  'разрешение прерываний
Enable Int0

I2cstart                           'Запуск Часов
I2cwbyte Adressw
I2cwbyte Secadress
I2cwbyte Sec1
I2cstop

Do                                 'считывание минут и  часов из DS1307
  I2cstart
  I2cwbyte Adressr
  I2cwbyte Minadress
  I2crbyte Minut , Ack             'считывание минут
  I2crbyte Clock , Nack            'считывание часов
  I2cstop
‘декодирование значений часов и минут
  Eminut = Minut And &B00001111    ' единицы минут
  Minut = Minut And &B11110000
  Shift Minut , Right , 4          'десятки минут
  Eclock = Clock And &B00001111    'единицы часов
  Clock = Clock And &B11110000
  Shift Clock , Right , 4          'десятки часов

  Cls
  Lcd "     " ; Clock ; Eclock ; ":" ; Minut ; Eminut       'индикация часов и минут
  Wait 1
Loop

Button:                            'установка 
Waitms 75
Do                                 'установка  минут
  If Portd.4 = 0 Then              'кнопка "далее" нажата?-переход к переводу минут в двоич.-дес.код
  Exit Do
  End If
  If Portd.5 = 0 Then              'кнопка "увеличить" нажата?
  Waitms 75
  Minut = Minut + 1
  End If
  If Minut = 60 Then              ’проверка по  предельному  значению
  Minut = 0
  End If
  Cls
  Lcd "Minut=" ; Minut
Loop
  Waitms 75
  Z = Minut                        'выделение десятков и единиц минут
  Call Ed
  Eminut = Ones
  Minut = Tens
  Shift Minut , Left , 4
  Minut = Minut + Eminut           'получение знач. минут в двоич.- десятичном коде

  Do                               'установка часов
  If Portd.4 = 0 Then
  Exit Do
  End If
  If Portd.5 = 0 Then
  Waitms 75
  Clock = Clock + 1
  End If
  If Clock = 24 Then
  Clock = 0
  End If
  Cls
  Lcd "Clock=" ; Clock
Loop
Waitms 75
I2cstart                           'установка 24-хчасового режима
I2cwbyte Adressw
I2cwbyte Clockadress
I2cwbyte Sec1
I2cstop

Z = Clock
Call Ed
Eclock = Ones
Clock = Tens
Shift Clock , Left , 4
Clock = Clock + Eclock             'получение знач.часов в двоич.- десятичном коде
 
I2cstart                           'запись минут и часов в DS1307
I2cwbyte Adressw
I2cwbyte Minadress
I2cwbyte Minut
I2cwbyte Clock
I2cstop

Return

Sub Ed                             'подпрограмма выделения единиц и десятков
Tens = 0
Ones = 0                           
Do                                 'выделение десятков
  Z = Z - 10
  If Z < 0 Then Exit Do
  Tens = Tens + 1
Loop
  Z = Z + 10                       'выделение единиц
  Ones = Z
End Sub
End                                'end program
 
            Блок – схема  программы  “Clok”  приведена  на  Рис.2.  
 


Рис.2 - Блок-схема программы "Clock"   

      До  сих  пор  для  отображения  информации  мы  использовали   жидкокристаллический  индикатор. Однако, это  же  можно  сделать  и  с  помощью  семисегментного  светодиодного  индикатора. Используя  для  управления  данным  индикатором  микроконтроллер  AVR, а  не  отдельную  микросхему  дешифратора, с  помощью  них  можно  отображать   очень  многое, например: латинские  буквы  (c, C, d, E, F, G, h, H, I, P, и  др.).
     Общепринятые  обозначения  сегментов  индикаторов  приведены  во  многих  учебниках, отметим  только, что  сегменты  индикатора  являются  светодиодами  и  могут  быть  подключены  по  схеме  либо  с  общим  катодом,  либо -  с   общим  анодом.
     Если  вы, например, используете  индикаторы  с  общим  катодом, то  для  включения  сегментов  нужно  подать  на  их  аноды  напряжение  высокого  уровня, а  управление  организовать  через  ключи, подключающие  катоды  индикаторов  к  земле. Выводы  семисегментных  индикаторов  желательно  подключать  к  одному  порту. Это  облегчит  программирование  и  упростит  топологию  печатной  платы.
     На  Рис.3  представлена  схема  подключения  двухсекционного  семисегментного  светодиодного  индикатора  типа  DC56-11SRWA  (с  общим  катодом)  к  микроконтроллеру  ATtiny2313. Как  видно  из  схемы  сегменты  индикаторов  подключены  к  порту В  через  токоограничивающие  резисторы  430 Ом. Управление  индикаторами  осуществляется  с  помощью  контактов  PD6 (индикация  десятков),  PD5  (индикация  единиц), которые  управляют  ключами  транзисторной  сборки  DA2  (IRF7103), подключающими  катоды  индикаторов  К1  и  К2  к  земле. 

 

  Рис.3 - Схема подключения семисегментного светодиодного индикатора
 
     Микроконтроллер  с  персонального   компьютера  через  RS-232  принимает  числа   от  0  до  99.  Принятое  число  разделяется  на  количество  десятков  и  количество  единиц. Далее    количество  десятков  и  количество  единиц  идентифицируются  с  кодами  семисегментного  индикатора. Затем  семисегментный  код  десяток  помещается  в     порт В  и  индуцируется  на  первом  индикаторе. Потом  первый  индикатор  выключается, в  порт В  помещается  семисегментный   код  единиц  и  включается  второй  индикатор  (а  первый  выключается). Поочередное  быстрое  включение  и  выключение  индикаторов  создаёт  для  человеческого  глаза  впечатление  одновременной  индикации  десятков  и  единиц.  Такое  включение  индикаторов  называется  динамическим.
     На  Рис.4  приведена  блок – схема  программы  “Ledindi”. Как  видно  из  блок – схемы, программа  содержит  основной  цикл, в  котором  происходит  индикация  принятого  по RS-232  числа,  и  подпрограммы  обработки  прерывания  по  завершению  приёма, в которой происходит  обработка  принятого  числа. Ниже  приведен  текст  программы. 


Рис.4 - Блок-схема программы "Ledindi"
     
 
 Программа  “Ledindi”:

$regfile = "attiny2313a.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Ddrb = &B11111111                  'PORTB - все выхода
Portb = 0                          'PORTB - на всех выходах низкий уровень
Config Pind.5 = Output             'общий катод - единицы
Config Pind.6 = Output             'общий катод - десятки
Config Pind.0 = Input              'RxD

Dim Tens As Byte                   'объявление переменных
Dim Ones As Byte
Dim Cod(10) As Byte
Dim Index As Byte
Dim Codd As Byte
Dim Code As Byte
Dim Z As Integer

On Urxc Rx                         'определение подпрограммы прерывания по приёму

Enable Interrupts                  'разрешение прерываний
Enable Urxc

Do                                 'основная программа
  Portb = Codd                     'индикация десятков
  Reset Portd.5
  Set Portd.6
  Waitms 100                       'задержка 100 мс
  Portb = Code                     'индикация единиц
  Reset Portd.6
  Set Portd.5
  Waitms 100
Loop

Rx:                                'подпрограмма обработки  прерываний по приёму
Input , Z                       'приём числа
Tens = 0
Ones = 0                           
Do                                 'выделение десятков
  Z = Z - 10
  If Z < 0 Then Exit Do
  Tens = Tens + 1
  Loop
  Z = Z + 10                       'выделение единиц
  Ones = Z

Tens = Tens + 1                    'определение кода индикатора для десятков
Restore M1
For Index = 1 To 10
Read Cod(index)
If Index = Tens Then
Codd = Cod(index)
End If
Next Index

Ones = Ones + 1                    'определение кода индикатора для единиц
Restore M1
For Index = 1 To 10
Read Cod(index)
If Index = Ones Then
Code = Cod(index)
End If
Next Index
Return

End                                'end program

M1:
Data &B00111111 , &B00000110 , &B00011011 , &B01001111 , &B00100100 , &B01101101 , &B01111101 , &B00000111 , &B01111111 , &B01101111

     Данную  программу  вы  можете  симулировать, не  собирая  схемы. Но  не  забудьте   для  отключения  задержек  после  настроек  поставить  оператор  $sim. 
     Программы   “Clok” и  “Ledini”   находятся  в  приложении 1  данной  статьи.