Статья №19

 

     В  этой  статье  будут  рассмотрены  вопросы  работы  и  программирования  модуля  TWI. 
     Модуль  двухпроводного  последовательного  интерфейса  (Two – Wire  serial  Interface – TWI)  имеется  практически  во  всех  микроконтроллерах  семейства  AVR – MEGA.

     Интерфейс  TWI  является  полным  аналогом  базовой  версии  интерфейса  I2C  фирмы  Philips  (см. статью  №7).  Он  также,  как  I2C,  позволяет  объединить  до  128  различных  устройств  с  помощью  двунаправленной  шины,  состоящей  из  линии  тактового  сигнала – SCL  и  линии  данных – SDA,  для  работы  которых  требуются  (по  аналогии  с  I2C)  два  подтягивающих  резистора,  по  одному  на  каждую  линию.  Устройство,  инициирующее  и  завершающее  передачу  данных  по  шине,  а  также  генерирующее   тактовый  сигнал  SCL,  называется  ведущим  (Master).  Устройство,  адресуемое  ведущим,  называется  ведомым  (Slave).

     Конфигурирование  TWI  осуществляется  подобно  кофигурированию  I2C,  например:

Сonfig  TWI = 100000   'частота = 100КГц                                                                                 
Config  Sda = Portc.1                                                                                                                    
Config  Scl = Portc.0

     В  отличии  от  команд  I2C  команды  TWI  имеют  комплексный  характер,  т. е.  включают  в  себя  несколько  команд  шины  I2C,  что  сокращает  код  программы.

     Команда  отсылки  в  Slave:  I2csend  Save,  var      ‘Slave – адрес  ведомого  устройства;  var – посылаемая  переменная. Данная  команда  содержит  три  команды:  I2cstart,  I2cwbyte,  I2cstop. 

     С  помощью  команды  I2csend  Slave,  var,  bytes  можно  отсылать  массивы  данных,  например:

X = &H10                      ‘адрес  ведомого  устройства                                                            
Z =1                               ’адрес  регистра  Slave,  с  которого  начинается  запись                                                             
For  I = 1  To  5            ‘создание  массива                                                                                  
A(i) = I                                                                                                                                               
Next  I                                                                                                                                               
Bytes = 5                                 ’в  массиве  5  байтов                                                                                                                                          
I2csend  X,  Z                          ’отсыл  адреса  начала  записи  в  Slave                                                                            
I2csend  X,  A(1),  Bytes        ‘запись  в  Slave  пяти  байтов,  по  адресуначиная  с  байта  A(1).

     Cчитывание  из  ведомого  устройства  осуществляется  с  помощью  команды:
I2creceive  Slave,  var
     Эта  команда  включает  в  себя:  I2cstart,  I2crbyte,  I2cstop,  но  может  выполнять  и  I2cwbyte:

I2creceive  Slave,  var,  bw,  br    ‘bw – количество  байтов  для  записи  в  Slave;  br – количество  байтов  считывания

     Возьмём  адреса  и  массив  предыдущего  примера.  Считаем  из  Slave  с  адреса  Z  один  байт  и  запишем  по  этому  же  адресу  два  байта:

I2creceive  X,  Z                                                                                                                                
I2creceive  X,  A(2),  2,  1 ‘по  адресу  Z  будут  записаны  два  байта - А(2)  и  А(3)  и  считан  один  байт - А(2).

     Ещё  один  способ  записи  и  чтения  массивов  с  помощью  оператора  FOR…NEXT  будет  описан  в  приведённой  ниже  программе  для  микроконтроллера  устанавливаемых  с  терминала  Bascom  часов,  схема  которых  приведена  на  Рис.1.

 

 

 Рис.1 - Схема часов, устанавливаемых с ПК

      Устройство  состоит  из  микроконтроллера  ATmega8535  (DD1),  тактовая  частота  которого  4МГц  получена  от  внутреннего  генератора,  интерфейса  RS-232  (XP1,DD2,C3,C4C5,C6),  микросхемы  часов  реального  времени  (DD3),   разъёма  для  распайки  ленточного  кабеля  (контакты  Х2…Х11)  для соединения  с  жидко – кристаллическим  индикатором  (ЖКИ)  типа  MT-16S2H  (производитель  МЭЛТ),  который  расположен  вне  платы,  разъёма  для  внутрисхемного  программирования  (ХР2),  цепи  сброса  микроконтроллера  (DD4.1,  DD4.2,  R1,  C1)  и  стабилизатора  напряжения  5В  (DA1).  Работа  всех  этих  составляющих  узлов  была  неоднократно  подробно  описана  в  предыдущих  статьях  по  Bascom.    

     Данные  для  работы  часов  вводятся  с  персонального  компьютера  (ПК)  при  помощи  терминала  Bascom. При  нажатии  любой  клавиши  на  клавиатуре  ПК  на  экране  терминала  появляется  надпись,  например:  «ввод  единиц  минут  (0 – 9):».  Далее  необходимо  набрать  значение и  нажать  клавишу  «Enter».  Значение  секунд  вводится  программно  (0).  После  ввода  данных  происходит  запуск  часов, и  светодиод  HL1  начинает  мигать  с  частотой  1Гц. Частота  генератора  микросхемы  часов  задаётся  и  стабилизируется  кварцевым  резонатором  (ZQ1)  на  32,768 КГц   типа  НС49/S,  AA, DT-38T  и  др..

     На  ЖКИ – индикаторе  отображается  следующая  информация:  часы,  минуты,  секунды - в  первой  строке;   день  недели,  число, месяц  и  год – во  второй  строке  (см. Рис.2).

 

 

Рис. 2

     Программа  микроконтроллера  «UHR»  состоит  из  основного  цикла,  где  происходит   считывание  данных  из  микросхемы  часов  (Slave)  и  отображение  их  на  ЖКИ,  и  подпрограммы  обработки  прерывания  по  приёму,  где  осуществляется  ввод  данных  с  терминала  Bascom  при  помощи  функции  «эхо».

     В  программе  запись  и  считывание  данных  претворены  в  жизнь  с  помощью  оператора  FOR…NEXT.  Но  может  быть  удобнее,  применив  описанные  выше  способы  записи  и  чтения,  представить  эти  процессы  в  следующем  виде:

Dim  D(8)  As  Byte     ‘определение  массива                                                                           
.  .  .  .  .  .  .  .  .  .  .  .                                                                                                                         
I2csend  Write1307,  X     ‘произвести  запись,  начиная  с  адреса  Х  (секунды)          
I2csend  Write1307,  D(1),  8     ‘запись  восьми  байтов,  начиная  с  D(1)  (сек)       
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .                                                                                                       
I2csend  Write1307,  X     ‘произвести  чтение,  начиная  с  адреса  Х  (сек)                                
I2creceive  Read1307,  D(1),  0,  7     ‘чтение  семи  байтов  (восьмой  байт  –       
 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .’регистр  управления),  начиная  с  D(1)
   

     Попробуйте  и  этот  вариант.
     Текст программы  «UHR»:

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

Config Twi = 100000                'блок TWI,частота 100 КГц
Config Sda = Portc.1
Config Scl = Portc.0
Config Pind.0 = Input              'UART-RXD
Config Pind.1 = Output             'UART-TXD
'определение переменных:
Dim Esec As Byte                   'единицы секунд
Dim Dsec As Byte                   'десятки секунд
Dim Osec As Byte                   'объединённый файл секунд
Dim Emin As Byte                   'минуты
Dim Dmin As Byte
Dim Eheoer As Byte                 'часы
Dim Dheoer As Byte
Dim Day As Byte                    'день недели
Dim Edata As Byte                  'день недели
Dim Ddata As Byte
Dim Emon As Byte                   'месяц
Dim Dmon As Byte
Dim Eyear As Byte                  'год
Dim Dyear As Byte
Dim I As Byte
Dim D(8) As Byte                   'массив объединённых файлов
Dim J As Byte

Const Read1307 = &B11010001        'адреса считывания и записи DS1307
Const Write1307 = &B11010000

Declare Sub Readuhr                'подпрограмма считывания из DS1307

On Urxc Rxd                        'подпрограмма обработки прерывания по приёму

Enable Interrupts                  'разрешение прерываний
Enable Urxc                        'разрешение прерываний по приёму

Do                                 'основной цикл
  Call Readuhr                     'считывание из DS1307
  Cls                              'очистка дисплея
  Locate 1 , 2                     'строка 1,знакоместо 2
  Lcd ; Dheoer ; Eheoer ; ":" ; Dmin ; Emin;       'индикация часов
  Locate 1 , 11
  Lcd "Sec:" ; Dsec ; Esec         'индикация секунд
  Locate 2 , 1
  Lcd ; Day                        'индикация дня недели
  Locate 2 , 5
  Lcd ; Ddata ; Edata ; "." ; Dmon ; Emon ; "." ; Dyear ; Eyear       'индикация числа,месяца и года
Loop

Sub Readuhr:                       'чтение из часов
For I = 1 To 7
J = I - 1
I2csend Write1307 , J , 1
I2creceive Read1307 , D(i) , 0 , 1 'блок TWI-считывание объединённых файлов остальных данных из DS1307
Next I
Esec = Osec And &B00001111         'выделение единиц
Dsec = Osec And &B11110000         'маскирование единиц
Shift Dsec , Right , 4             'сдвиг десятков на 4 знака вправо
Emin = D(1) And &B00001111         'выделение единиц и десятков из объединенных файлов данных
Dmin = D(1) And &B11110000
Shift Dmin , Right , 4
Eheoer = D(2) And &B00001111
Dheoer = D(2) And &B11110000
Shift Dheoer , Right , 4
Day = D(3)
Edata = D(4) And &B00001111
Ddata = D(4) And &B11110000
Shift Ddata , Right , 4
Emon = D(5) And &B00001111
Dmon = D(5)and &B11110000
Shift Dmon , Right , 4
Eyear = D(6) And &B00001111
Dyear = D(6)and &B11110000
Shift Dyear , Right , 4
End Sub

Rxd:                               'запись в часы
   Osec = 0
   D(1) = Osec
   Input "ввод единиц минут (0-9):" , Emin
   Input "ввод десятков минут (0-5):" , Dmin
   Cls
   Lcd ; Dmin ; Emin
   Shift Dmin , Left , 4           'сдвиг единиц на 4 знака влево
   D(2) = Dmin + Emin              'объединение полубайтов в байт для посылки в DS1307
   Input "ввод единиц часов (0-9):" , Eheoer
   Input "ввод десятков часов (0-2):" , Dheoer
   Cls
   Lcd ; Dheoer ; Eheoer
   Shift Dheoer , Left , 4
   D(3) = Dheoer + Eheoer
   Input "ввод дня недели (1-7):" , Day
   D(4) = Day
   Input "ввод единиц числа (0-9):" , Edata
   Input "ввод десятков числа (0-3):" , Ddata
   Cls
   Lcd ; Ddata ; Edata
   Shift Ddata , Left , 4
   D(5) = Ddata + Edata
   Input "ввoд единиц мес:" , Emon
   Input "ввод десят мес:" , Dmon
   Cls
   Lcd ; Dmon ; Emon
   Shift Dmon , Left , 4
   D(6) = Dmon + Emon
   Input "ввод единиц года (0-9):" , Eyear
   Input "ввoд десят года (0-9):" , Dyear
   Cls
   Lcd ; Dyear ; Eyear
   Shift Dyear , Left , 4
   D(7) = Dyear + Eyear
   D(8) = &B10010000               'конфиг.регистра управления
   For I = 1 To 8
   J = I - 1
   I2csend Write1307 , J           'отсыл адреса для записи
   I2csend Write1307 , D(i) , 1    'блок TWI-запись в DS1307  данных
   Next I
Return

End                                'end program

     Печатная  плата  устройства  имеет размеры  76х60 мм.  Расположение  компонентов  представлено  на  Рис.3. Все  компоненты  кроме  микроконтроллера  и  стабилизатора  напряжения  имеют  исполнение  SMD.  Резисторы  типа  РН1 -12  и  керамические  чип – конденсаторы  выбраны  типоразмером  12-06.  Электролитический  конденсатор  танталовый – тип D.  Микроконтроллер  желательно  установить  в  панели  DIP  для  микросхем  типа  TRL (SCL) - 40. 

 

  Рис.3 - Плата часов

      Проект  устройства  находится  в  папке  «FILE  PCAD»,  которая  прилагается  к  данной  статье. Печатную  плату  вы  можете  заказать  на  сайте  http://newservice.rezonit.ru.

     Программа находится в Приложении 1.