Дослідження та реалізація мультимайстерного режиму для I2C-інтерфейсу

Тип работы:
Дипломная
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

АНОТАЦІЯ

У дипломній роботі проведено дослідження можливостей організації мікроконтролерних мереж на основі I2C-інтерфейсу. Детально проаналізовано особливості роботи I2C-інтерфейсу, фізичного середовища для його реалізації, а також функціональні можливості модуля TWI мікроконтролерів AVR для забезпечення обміну даними за I2C-протоколом.

Найважливіша частина дипломної роботи стосується програмної підтримки мультимайстерного режиму роботи мікроконтролерної мережі за I2C-інтерфейсом з використанням апаратних переривань модуля TWI мікроконтролерів AVR.

Для мультимайстерного режиму реалізовані функції арбітражу. Усі розроблені програмні алгоритми для обміну даними за I2C-протоколом експериментально апробовані на фізичному обладнанні.

ANNOTATION

In the work our study were divided into several stages. The first stage was a detailed analysis of the characteristics of the I2C-interface, the physical environment for its implementation and the functionality of the module TWI AVR Microcontroller for data exchange for I2C-protocol. The next stage was studied implementation of data exchange for multy-master mode. For multy-master mode implemented features arbitration.

All examples of communication for I2C-protocol experimentally tested.

ВСТУП

Будь-який мікроконтролер призначений для виконання функцій по керуванню або контролю фізичними параметрами конкретних об'єктів керування. Функції керування або контролю зводяться до оброблення і наступного використання цифрової двійкової інформації, що надходить від об'єктів керування по лініях зв’язку від різних пристроїв сполучення мікроконтролера з об'єктом. У якості таких пристроїв можуть бути датчики різних аналогових фізичних параметрів та пов’язані з ними нормуючі перетворювачі електричних сигналів, аналого-цифрові перетворювачі, датчики цифрової інформації та ін. З боку виведення інформації мікроконтролер взаємодіє з цифровими індикаторами, виконавчими механізмами, дисплеями, цифродрукуючими пристроями та іншими засобами запам’ятовування, зберігання і використання результатів обробки інформації.

З'єднання всього різноманіття зовнішніх пристроїв з шинами мікроконтролера здійснюється за допомогою інтерфейсів, які слід розуміти як уніфікований засіб об'єднання різних пристроїв в єдину систему. Будь-який інтерфейс повинен забезпечити вирішення наступних двох завдань.

По-перше, інтерфейс у своїй апаратній частині повинен забезпечити електричне з'єднання різних зовнішніх пристроїв з різними електричними і конструктивними параметрами з єдиною системою шин конкретного мікроконтролера. При цьому мають бути враховані такі параметри, як кількість ліній зв’язку, рівні і потужності електричних сигналів, довжина і завадозахищеність ліній зв’язку.

По-друге, інтерфейс повинен забезпечити гнучке програмне керування всіма підключеними зовнішніми пристроями. У цій частині інтерфейс повинен забезпечити не тільки працездатність зовнішніх пристроїв, але й узгодження по швидкодії різних зовнішніх пристроїв та центрального мікропроцесора.

Таким чином, під інтерфейсом слід розуміти уніфікований програмно-апаратний пристрій, який призначений для організації обміну інформацією між мікропроцесором та зовнішніми пристроями, об'єднаними в єдину систему.

За своїм призначенням інтерфейси бувають внутрішніми і зовнішніми. Внутрішній інтерфейс об'єднує ВІС мікропроцесора, модулі пам’яті і засоби управління вводом-виводом. Зовнішній інтерфейс забезпечує сполучення інформаційних шин МК з зовнішніми пристроями.

Сучасні мікроконтролери деякі зовнішні інтерфейси обміну даними можуть підтримувати на програмному рівні, а для деякий, набагато складніших за своєю структурою, у них є передбачені окремі периферійні модулі. Серед найбільш популярних інтерфейсів можна відзначити такі: USB, Ethernet, САN, UART, I2S, I2C, SSI/SPI.

Ethernet — один з найпоширеніших на сьогоднішній день стандартів організації локальних мереж. Модуль Ethernet, переважно є апаратно реалізований в мікроконтролерах типу ARM.

Шина USB (Universal Serial Bus) з’явилася порівняно недавно — версія першого затвердженого варіанту стандарту з’явилася 15 січня 1996 року. Розробка стандарту була ініційована авторитетними фірмами — Intel, DEC, IBM, NEC, Northen Telecom і Compaq. На сьогоднішній день USB є одним з найбільш затребуваних інтерфейсів передачі даних. Шина строго орієнтована, має поняття «головний пристрій» (Host) і «периферійні пристрої» (Device).

Існує декілька версій специфікації USB: USB 1. 0, USB 1. 1, USB 2. 0, USB 3.0.

Для пристроїв USB 2.0 регламентовано три режими роботи:

* Low-speed, 10 … 1500 Кбіт/cек (використовується для інтерактивних пристроїв: клавіатури, миші, джойстики);

* Full-speed, 0,5 … 12 Мбіт/сек (аудіо-, відеопристрої);

* Hi-speed, 25 … 480 Мбіт/сек (відеопристрої, пристрої зберігання інформації).

Мережевий протокол CAN (Controller Area Network) був розроблений в 1987 році фірмою Bosch для мультипроцесорних автомобільних систем реального часу. CAN оптимізований для систем, в яких передається порівняно невеликий обсяг інформації зі швидкістю до 1 Мбіт/сек. Основні переваги CAN-протоколу — висока завадостійкість, надійність, можливість отримання повідомлень всіма вузлами (контролерами даних) із синхронізацією за часом, неруйнівний арбітраж доступу до шини, мала ймовірність пропуску помилки. Прийнята в CAN-інтерфейсі схема передачі повідомлень дозволяє її розширювати і модернізувати: нові пристрої прийому даних можна додавати до мережі без зміни існуючих програмних засобів і порушення роботи старої системи. Все це привернуло увагу розробників і користувачів різних розподілених систем керування, що використовуються, окрім транспортних засобів, у промисловості, енергетиці, медичному приладобудуванні.

UART (Universal Asynchronous Receiver / Transmitter) — напевно, найвідоміший інтерфейс. Можливо, зв’язок через асинхронний послідовний порт відходить у минуле, проте складно знайти контролер, який не має в складі периферії UART.

IrDA являє собою абревіатуру Infrared Data Association — асоціації, яка займається розробкою специфікацій для обміну даними по оптичному інтерфейсу за допомогою інфрачервоного світла. Така технологія також згодом отримала назву IrDA.

Досвід показує, що серед інших бездротових ліній передачі інформації інфрачервоний (ІЧ) відкритий оптичний канал є недорогим і зручним способом передачі даних на невеликі відстані (до декількох десятків метрів). Зокрема, він ефективний для забезпечення бездротового зв’язку між персональним комп’ютером і периферійними пристроями.

LIN (Local Interconnect Network) — стандарт промислової мережі розроблений консорціумом європейських автовиробників та інших відомих компаній, включаючи Audi AG, BMW AG, Daimler Chrysler AG, Motorola Inc.

Протокол LIN призначений для створення недорогих локальних мереж обміну даними на коротких відстанях. Він служить для передачі вхідних впливів, станів перемикачів на панелях управління, а також для відповідних дій різних пристроїв, що з'єднані в одну систему через LIN і відбуваються в так званому «людському» часовому діапазоні (порядку сотень мілісекунд).

I2S (Inter-Integrated Circuit Sound) — інтерфейс призначений для передачі цифрових аудіоданих.

SSI (Synchronous Serial Interface) — популярний інтерфейс для послідовного обміну даними між мікросхемами. Поряд з I2C він належить до найбільш широко використовуваних інтерфейсів для з'єднання мікросхем. SSI дозволяє підключати до контролера різного роду мікросхеми, в т. ч. запам’ятовуючі пристрої (EEPROM, Flash-пам'ять, SRAM), годинник реального часу (RTC), АЦП / ЦАП, цифрові потенціометри, спеціалізовані контролери та ін.

На відміну від стандартного послідовного порту, SSI є синхронним інтерфейсом, тобто будь-яка передача в ньому синхронізована із загальним тактовим сигналом, що генерується головним пристроєм. Приймаюча периферія синхронізує отримання бітової послідовності з тактовим сигналом. До одного послідовного периферійного інтерфейсу провідного пристрою-мікросхеми може приєднуватися кілька мікросхем. Головний пристрій вибирає підлеглий пристрій для передачі, активуючи сигнал «вибір кристалу» на підлеглій мікросхемі.

Найбільшої популярності для мікроконтролерних систем набув I2C-інтерфейс завдяки своїй простоті реалізації, низької собівартості та відносно непоганої швидкості роботи.

Список можливих застосувань I2C-інтерфейсу:

— доступ до модулів пам’яті RAM;

— доступ до модулів пам’яті EEPROM;

— доступ до низькошвидкісних ЦАП/АЦП;

— доступ до найрізноманітніших давачів;

— регулювання контрастності, насиченості і колірного балансу моніторів;

— регулювання звуку в динаміках;

— управління світлодіодами, в тому числі в мобільних телефонах;

— читання інформації з датчиків моніторингу і діагностики устаткування, наприклад, термостат центрального процесора або швидкість обертання вентилятора охолодження;

— читання інформації з годинника реального часу (кварцових генераторів);

— управління включенням/виключенням живлення системних компонент;

— інформаційний обмін між мікроконтролерами.

На сьогоднішній день лише асортимент продукції Philips включає більше 150 КМОП і біполярних I2C-сумісних пристроїв. Усі ці пристрої мають вбудований інтерфейс, який дозволяє їм зв’язуватися один з одним по I2C-шині. Це конструкторське рішення вирішує безліч проблем з'єднання різних пристроїв, які зазвичай виникають при розробці цифрових систем.

Переваги використання I2C-інтерфейсу:

— необхідно лише один мікроконтролер для керування ряду пристроїв;

— використовується лише дві лінії вводу/виводу загального призначення;

— стандарт передбачає «гаряче» підключення і відключення пристроїв у процесі роботи системи;

— вбудований у мікросхеми фільтр фільтрує сплески, забезпечуючи цілісність даних.

Переваги для конструкторів при використанні I2C-інтерфейсу:

— оскільки такі мікросхеми підключаються безпосередньо до шини без будь-яких додаткових електричних кіл, з’являється можливість модифікації і модернізації системи прототипу шляхом підключення і відключення пристроїв від шини;

- блоки на функціональній схемі відповідають мікросхемам, перехід від функціональної схеми до принципової відбувається швидко;

- немає потреби розробляти шинні інтерфейси, так як шина вже інтегрована в мікросхеми;

- інтегровані адресація пристроїв і протокол передачі даних дозволяють системі бути повністю програмно обумовленою;

- одні і ті ж типи мікросхем можуть бути часто використані в різних додатках;

- час розробки знижується, так як конструктори швидко знайомляться з часто використовуваними функціональними блоками і відповідними мікросхемами;

- мікросхеми можуть бути додані або зняті зі системи без впливу на інші мікросхеми, що підключені до шини (якщо їхня робота незалежна);

- проста діагностика збоїв та відлагодження; порушення в роботі легко відслідковуються;

- час розробки програмного забезпечення може бути зменшене за рахунок повторного використання розробленої бібліотеки для роботи з пристроями на I2C-шині.

Мета та завдання дипломної роботи: дослідити та алгоритмічно забезпечити роботу мультимайстерного режиму мікроконтролерної мережі на основі I2C-інтерфейсу.

Практичне значення отриманих результатів: розроблений програмний код мовою високого рівня Сі може використовуватися як готова бібліотека при роботі з пристроями та мережами, що працюють за I2C-інтерфейсом.

Запропонована алгоритмічна реалізація мультимайстерного режиму роботи I2C-шини апробована шляхом натурного експерименту.

1. АНАЛІЗ ПИТАННЯ

1.1 Огляд літературних джерел

1.1.1 Аналіз особливостей роботи I2C-інтерфейсу

Інтерфейс I2C (IIC, Inter-Integrated Circuit) розроблений ще на початку 1980-х компанією Philips (зараз NXP Semiconductors) та представляє собою двонаправлену 2-провідну шину, що використовується для контролю та обміну даними з інтегральними схемами.

I2C складається з двох ліній: SDA (даних) та SCL (тактування), які підтягнуті через резистори до напруги живлення та керуються з боку пристроїв через відкритий колектор чи відкритий стік (рис. 1. 1).

Інтерфейс передбачає різний набір швидкостей обміну з 7-ми і 10-ти бітною адресацією пристроїв на I2C-шині (розширення можливостей інтерфейсу здійснювалися у різні роки):

— Стандартний режим (Standard-mode): двонаправлена передача даних зі швидкістю до 100 кбіт/сек. Адреса — 7 біт, адресація до 112 пристроїв на I2C-шині (1982 р. Оригінал).

— Швидкісний режим (Fast-mode, Fm): двонаправлена передача даних зі швидкістю до 400 кбіт/сек. Розширення адресного простору до 10 біт, адресація до 1008 пристроїв на I2C-шині (1992 р. V.1. 0).

— Високошвидкісний режим (High-speed mode, Hs): двонаправлена передача даних зі швидкістю до 3,4 Мбіт/сек. (1998 р. V.2. 0).

— Швидкісний режим плюс (Fast-mode plus, Fm+): двонаправлена передача даних зі швидкістю до 1 Мбіт/сек. (2007 р. V.3. 0).

— Ультрависокошвидкісний режим (Ultra Fast-mode, UFm): однонаправлена передача даних зі швидкістю до 5 Мбіт/сек. для нових USDA та USCL ліній, що використовують двотактну логіку без підтягуючих резисторів. Пристрої для однонаправленої UFm-шини не є сумісними з пристроями для двонаправленої I2C-шини. (2012 р. V.4. 0).

Максимальна кількість пристроїв, що приєднуються до одної I2C-шини, обмежується максимальною ємкістю шини у 400 пФ та здатністю адресації цих пристроїв.

Рис. 1.1 Під'єднання пристроїв до I2C-шини

У вільному стані (коли ніхто нічого не передає) на шині присутній високий рівень «1», що забезпечують підтягуючі резистори до напруги живлення. Пристрої до I2C-шини під'єднуються за принципом монтажного «І»: коли вихідний транзистор (рис. 1. 1) виводу SDA чи SCL пристрою закритий, тоді плив з боку пристрою на лінію відсутній, і на лінії присутній високий рівень «1» через підтягуючий резистор до живлення, якщо ж вихідний транзистор відкритий — він підтягує відповідну лінію до землі, і на ній встановлюється низький рівень «0». Тобто, передача/прийом сигналів здійснюється пристроями шляхом подачі/зняття «землі» на/з відповідної лінії I2C-шини (подали на лінію землю — на лінії «0»; відпустили лінію — «1» за рахунок підтягуючих резисторів до живлення).

На рис. 1.1 трикутники на вході вказують, що входи високоомні і не впливають на рівні сигналів на лініях, і лише зчитують значення цих рівнів. Переважно використовуються рівні 5 В та 3,3 В напруги живлення VDD. Для більшості пристроїв рівні розпізнаються як: високий рівень «1» — від 0,7·VDD, низький рівень «0» — до 0,3·VDD.

Підтягуючі резистори мають номінали від декількох кОм до декількох десятків кОм. Чим вища швидкість, тим менший номінал резистора необхідно встановити. При більшому номіналі резистора лінія буде довше встановлюватися в «1» (за рахунок перезаряду паразитної ємності між дротами). Оптимально вибирають 4,7 або 10 кОм.

Більшість популярних мікросхем (давачі, годинники, АЦП, мікроконтролери AVR і т.п.) працюють на швидкості 100 чи/та 400 кГц та мають 7-бітну адресацію. Тому розглянемо I2C-протокол саме для цього формату.

Керуючі сигнали та формат посилки. Обмін даними на I2C-шині здійснюється у чітко визначеному порядку. За керування обміном даними на шині відповідає головний пристрій (master), хоча на шині може бути присутні декілька головних пристроїв, але керувати передачею у певний момент може лише один з них. Для цього він має «захопити» шину, виконати обмін даними з необхідними пристроями на шині та «відпустити» шину. Трішки далі ми детально розглянемо одномастерний та мультимастерний режими.

Розберемо основні сигнали, що можуть бути присутні на шині.

Передача даних на лінії SDA відбувається послідовно біт за бітом, згідно поданих імпульсів на лінії SCL. Читання біту на лінії SDA здійснюється у момент, коли на синхролінії SCL присутній високий рівень «1». Тому протокол вимагає, щоб поки присутня «1» на синхролінії, сигнал даних SDA не змінювався. Передача байту даних здійснюється, починаючи зі старшого біту. Синхронізацію на шині забезпечує головний пристрій, той що проявив ініціативу для обміну даних.

Для початку передачі даних та її завершення головний пристрій формує на шині відповідні сигнали START та STOP. Між цими сигналами шина вважається занятою, тобто інші головні пристрої не намагаються нічого передавати та чекають поки шина не звільниться.

Сигнал START (S) розпізнається на шині за спадаючим фронтом сигналу SDA при високому рівні «1» на синхролінії SCL.

Сигнал STOP (P), навпаки, розпізнається за зростаючим фронтом сигналу SDA при високому рівні «1» на синхролінії SCL. Сигнал STOP обов’язково має слідувати після сигналу START.

Ще одним керуючим сигналом є «повторний старт» REPEAT START (Sr). За своєю формою він ідентичний сигналу START. Після сигналу START головний пристрій повинен передати адресний байт (7-бітна адреса + 1 біт напряму обміну) підлеглому пристрою, з яким він хоче виконати обмін даними. Якщо головний пристрій хоче змінити напрям передачі чи звернутися до іншого пристрою, то він має видати на шину сигнал REPEAT START та продовжити передачу. Це дає йому можливість виконувати обмін даними з різними пристроями, не втрачаючи контроль за шиною (інші головні пристрої не будуть його перебивати). Як тільки він видасть сигнал STOP, інший головний пристрій може забрати керування шиною собі. Нюанси, що стосуються одночасного захоплення шини декількома головними пристроями та визначення пріоритету надання контролю за шиною, будуть викладені при розгляді мультимастерного режиму.

Після кожного переданого байту (адреси чи даних) слідує 9-й біт підтвердження ACK (від слова acknowledge). Той, хто прийняв байт, має видати на лінію даних SDA підтвердження ACK (A), тобто подати «0» на лінію. Наприклад, ми видали на лінію адресу пристрою, з яким хочемо здійснювати обмін. Якщо пристрій присутній, і він розпізнав свою адресу, тоді він це підтвердить (A), притиснувши лінію до землі («0»). Якщо пристрій відсутній, тоді на лінії ніхто не відгукнеться, і на ній буде присутній NACK (N), тобто високий рівень «1».

Якщо підлеглий пристрій не встигає обробити отриману від головного пристрою інформацію, тоді він може вносити паузи, виставляючи на синхролінії SCL низький рівень «0».

Будь-яка I2C-посилка складається зі старту, адресного пакету, пакету даних, (рестарту, адресного пакету, пакету даних і т.д.) та стопу. Усі пакети завжди є 9-ти бітними.

Адресний пакет формується головним пристроєм та завжди слідує після сигналу старту (рестарту). Він містить 7-бітний адрес підлеглого пристрою (першим передається старший біт), біт напряму обміну W=0 (передача) чи R=1 (прийом) та біт підтвердження ACK від підлеглого пристрою. Підлеглі пристрої можуть мати довільний 7-бітний адрес, за винятком нульового та адресів із діапазону 1111ххх, які є зарезервованими. Нульовий адрес використовується для виконання загальних викликів, тобто передачі даних для усіх підлеглих пристроїв на шині, для яких є дозволені загальні виклики.

Пакет даних містить 8 біт даних (першим передається старший біт) та біт підтвердження ACK від підлеглого пристрою. Якщо пакет даних завершується NACK, тоді передача даних має бути припинена, і має слідувати або повторний старт, або стоп.

Розглянемо типові I2C-посилки.

Якщо головний пристрій (master) націлений лише на передачу даних, то посилка має складатися зі сигналу START, адресного пакету з бітом напряму W (передача) та довільної кількості пакетів з даними, що передаються для підлеглого пристрою (slave). Посилка обов’язково завершується сигналом STOP. Якщо підлеглий пристрій не підтвердить якийсь з пакетів (NACK), тоді подальший прийом зупиняється, а на шину видається сигнал STOP.

Якщо головний пристрій (master) націлений лише на прийом даних, то посилка має складатися зі сигналу START, адресного пакету з бітом напряму R (прийом) та довільної кількості пакетів з даними, що передаються підлеглим пристроєм. Посилка обов’язково завершується сигналом STOP. Після кожного прийнятого головним пристроєм байту даних він виставляє біт підтвердження ACK. Якщо головний пристрій не хоче далі приймати дані, то він обов’язково виставляє NACK та завершує посилку сигналом STOP.

в) Комбінований формат передбачає, що головний пристрій в межах однієї посилки буде як приймати, так і передавати дані до підлеглого пристрою чи навіть здійснювати обмін даними з декількома підлеглими пристроями. Наприклад, для зчитування поточного часу з мікросхеми годинника PCF8583 мікроконтролер формує на шині сигнал START, передає адресу пристрою + W, далі передає пристрою байт даних, що містить адресу регістра з якого потрібно читати дані. Потім для зміни напряму обміну даними формує на шині REPEAT START, передає адресу пристрою + R, а далі читає з регістрів годинника необхідні байти (секунди, хвилини і т.п.). Мікросхема годинника автоматично збільшує на одиницю адресу регістра, з якого необхідно буде далі зчитувати дані. Якщо М К зчитав необхідні йому байти з даними, то для останнього зчитаного байту він обов’язково має видати NACK та завершити посилку сигналом STOP.

10-бітна адресація представляє собою розширення для 7-бітної, і полягає у тому, що спершу передається стандартний адресний пакет, що містить п’ять бітів 11 110, які вказують, що це 10-розрядний адрес, два старших біти адреси та біт W/R. У другому байті передаються 8 молодших біти адреси. Передача даних передбачає 2 байти з адресою за якими слідують байти з даними. Прийом ж даних передбачає сигнал повторного старту, оскільки перший адресний байт спершу вказує на передачу (W) другого адресного байту, а потім змушений переключитися на прийом, відіславши при цьому лише перший адресний байт з бітом на прийом ®.

В одній посилці також можуть поєднуватися як передача, так і прийом даних, а також і обмін даними з декількома пристроями.

1.1. 2 Аналіз TWI-модуля мікроконтролерів AVR

I2C-інтерфейс для МК AVR має назву TWI (Two-wire Serial Interface, двопровідний послідовний інтерфейс).

Він реалізує базову версію I2C-інтерфейсу та підтримує швидкість обміну до 400 кГц. МК можуть мати лише 7-бітну адресу.

Обмін даними по I2C-протоколу здійснюється через відповідні виводи SDA та SCL, що суміщені з виводами одного з портів вводу/виводу. При використанні цих виводів модулем TWI до них можуть бути підключені внутрішні підтягуючі резистори, що дає можливість у деяких випадках обійтися без зовнішніх резисторів, що вимагаються інтерфейсом. Для цих виводів в модулі встановлені обмежувачі швидкості наростання фронтів сигналів, а також фільтри, що відсікають паразитні імпульси тривалістю менше 50 нсек.

Функціонування модуля TWI забезпечується п’ятьма регістрами:

TWBR — регістр швидкості передачі. Він задає частоту сигналів на виводі SCL. Значення регістра для вказаної швидкості може бути обчислене за такою формулою

де TWPS — значення 2-х молодших розрядів регістра TWSR, що виконують функцію подільника. Значення швидкості має бути, як мінімум, меншим у 16 разів за тактову частоту МК. Також значення TWBR має бути не меншим за 10, бо інакше під час передачі байта можуть генеруватися некоректні сигнали на виводах SDA та SCL.

TWAR — регістр адреси. Старші 7 біт містять I2C-адресу для МК для його роботи у режимі Slave. Молодший розряд TWGCE вказує, чи для МК дозволені загальні виклики (за адресою 0×00). Контроль адресних пакетів виконується навіть у сплячому режиму МК, що дає можливість переводити МК у робочий режим у випадку його адресації.

TWDR — регістр даних.

Для передачі по I2C-шині у цей регістр заносяться як адреса+R/W підлеглого пристрою, так і байти даних, що мають бути йому передані.

Також звідси зчитуються і отримані модулем TWI байти з I2C-шини. TWCR — регістр керування модулем TWI. Усі маніпуляції, що необхідно здійснити на I2C-шині виконуються за рахунок виставлення відповідних бітів (табл. 1. 1) цього регістра.

Таблиця 1.1 Розряди регістра керування TWCR

№біта

Назва

Призначення

7

TWINT

Прапорець переривання від модуля TWI

6

TWEA

Дозвіл на підтвердження ACK («1» — ACK,

«0» — NACK і у режимі slave модуль TWI неактивний)

5

TWSTA

Прапорець стану START

4

TWSTO

Прапорець стану STOP

3

TWWC

Прапорець конфлікту запису (виставляється при записі у регістр TWDR, коли прапорець переривання TWINT скинутий)

2

TWEN

Дозвіл на роботу модуля TWI

1

-

Зарезервовано, читається як «0»

0

TWIE

Дозвіл на переривання від модуля TWI

TWSR — регістр статусу. Виставлення прапорця TWINT регістра керування TWCR сигналізує, що модуль TWI виконав поточну задачу і очікує подальших дій програми.

У цей час у регістрі статусу у його старших п’яти розрядах міститься певний код, згідно якого можна визначити стан I2C-шини. Тому програма повинна зчитати у проміжну змінну байт значення регістра TWSR, числовою маскою встановити нулі у трьох молодших розрядах та, порівнюючи отриманий код зі таблицею значень в інструкції виробника на МК, вибрати подальші дії TWI-модуля.

1.2 Постановка задачі

Підсумувавши огляд літературних джерел, можна дійти наступного висновку. Для нашого дослідження необхідно підняти та вирішити такі питання:

1) Аналіз роботи модуля TWI мікроконтролера AVR з послідовною шиною за I2C-інтерфейсом.

2) Аналіз роботи модуля TWI МК AVR з I2C-шиною в мультимайстерному режимі.

3) Розробити структуру даних для забезпечення обміну даними за I2C-протоколом, що передбачає використання апаратних переривань модуля TWI мікроконтролера AVR.

4) Розробити мікроконтролерну мережу на основі I2C-інтерфейсу.

Перше питання передбачає аналіз модуля TWI для обміну даними з підлеглими пристроями та розроблення бібліотечних функцій, що будуть забезпечувати роботу модуля з I2C-шиною у звичайному режимі (наявний лише один головний пристрій).

Друге питання передбачає аналіз модуля TWI для обміну даними як з підлеглими пристроями, так і з іншими мікроконтролерами, тобто функціонування I2C-шини в мультимайстерному режимі. Це питання потребує також дослідження функції арбітражу для мікроконтролерів.

Третє питання передбачає забезпечення функціонування модуля TWI з використанням декількох кільцевих буферів. Для цього необхідно розробити структуру внутрішнього протоколу для формування I2C-посилки та її запису у вихідний буфер. Також слід передбачити ще декілька додаткових буферів для прийому даних, оброблення поточних задач, а також для функціонування модуля TWI в режимі slave.

Четверте питання стосується вже виключно реалізації розроблених програмних бібліотек для роботи за I2C-протоколом з конкретними прикладами мікросхем.

модуль мікроконтролер інтерфейс протокол

2. ДОСЛІДЖЕННЯ РОБОТИ I2C-ІНТЕРФЕЙСУ AVR-МІКРОКОНТРОЛЕРА

2.1 Реалізація I2C-протоколу модулем TWI

Звичайний режим передбачає, що на I2C-шині присутній лише один головний пристрій (мікроконтролер), який виконує обмін даними з підлеглими пристроями (рис. 2. 1).

Рис. 2.1 Одномайстерна I2C-шина

Роботу з модулем TWI мікроконтролера можемо організувати як програмно (постійно перевіряти прапорець TWINT на факт завершення поточної задачі), так і в режимі переривання від модуля TWI. У режимі апаратного переривання ми зможемо використати обчислювальні потужності МК для інших поточних задач і лише час від часу перериватися, щоб керувати роботою модуля TWI на I2C-шині. Тому ми будемо розглядати роботу модуля TWI саме з використанням апаратного переривання.

Керування модулем TWI виконується через регістр TWCR. Тут є одна особливість, яка полягає у тому, що ми мусимо повністю перезаписувати його значення, а не виставляти окремі його біти за допомогою присвоєння з логічним АБО (|=).

Як тільки у регістр TWCR заноситься одна з команд керування (рис. 2. 2), то модуль TWI починає одразу її реалізовувати, а по завершенню виконання виставляє прапорець TWINT, і програма переходить на підпрограму переривання модуля TWI. У підпрограмі переривання необхідно зчитати значення статусу (табл. 2. 1) у регістрі TWSR для виконаної команди та прийняти подальші дії для обміну даними.

Рис. 2.2 Формати команд для модуля TWІ у режимі master

Таблиця 2.1. Коди статусів для модуля TWI у режимі master

Код

Стан I2C-шини та модуля TWI

0x08

Був сформований START

0x10

Був сформований REPEAT START

0x18

Було передано адреса+Write та отримано ACK

0x20

Було передано адреса+Write та отримано NACK

0x28

Був переданий байт даних та отримано ACK

0x30

Був переданий байт даних та отримано NACK

0x40

Було передано адреса+Read та отримано ACK

0x48

Було передано адреса+Read та отримано NACK

0x50

Був прочитаний байт даних та передано ACK

0x58

Був прочитаний байт даних та передано NACK

2.2 Алгоритмічна реалізація роботи з I2C-шиною через апаратні переривання

Для забезпечення роботи з I2C-шиною через апаратні переривання потрібно задіяти 2 кільцеві буфери: один на передачу, а другий на прийом даних з I2C-шини, та реалізувати для буфера передачі чітку послідовність кодів для запису у нього I2C-посилки. Згідно переривань модуля TWI коди з даними будуть послідовно зчитуватися з буфера та буде виконуватися обмін даними з підлеглими пристроями на I2C-шині.

Введемо такі псевдокоди для форматування I2C-посилки у вихідному буфері для модуля TWI:

0x04 — код для команди STOP;

0x10 — код для команди REPEAT START;

0x20 — код адреси (вказує, що у наступній комірці буфера буде адреса пристрою);

0x40 — код передачі байту даних (вказує, що у наступній комірці буфера буде байт даних, який потрібно відправити на I2C-шину);

0x80 — код для читання байту даних з I2C-шини з підтвердженням МК про прийнятий байт (ACK);

0x81 — код для читання останнього байту даних з I2C-шини без підтвердження (NACK).

Окремі сегменти посилки заносяться у буфер через виклики набору функцій (рис. 2. 3), які вже безпосередньо заносять псевдокоди з даними у буфер, а також забезпечують додаткову функціональність. Наприклад, при виклику функції Start () ми маємо передати у неї параметр CONTROL чи NOCONTROL, який вказує чи потрібно по завершенню передачі I2C-посилки звітуватися про виконання. Також функція Start () здійснює заборону на глобальні переривання, яка знімається аж у кінці форматування посилки функцією Stop (). Такий крок необхідний для того, щоб передача посилки не здійснювалася, до поки не буде повністю занесена у буфер.

Перед кожним байтом адреси чи даних завжди слідує відповідний псевдокод, за яким можна розпізнати, що міститься у наступній комірці. Формально, передача як адреси, так і даних є однотипна, але окремі коди дають можливість відслідковувати при відладці, що ми передаємо.

Для читання даних введено псевдокод 0×80 з 0 чи 1 у молодшому розряді (якщо 1, тоді код буде 0×81). Якщо 0, то МК підтверджує про прийнятий байт і очікує прийому наступного. Якщо 1, тоді МК виставляє на шину NACK та завершує прийом даних.

У вихідному буфері може бути одночасно записано декілька I2C-посилок. Запуск першої посилки (сигнал START) виконує функція Stop (), а наступні у буфері за нею посилки виконуються вже згідно підпрограми переривання модуля TWI.

Якщо модуль TWI повинен прозвітуватися про виконану посилку, тоді введена нами змінна I2Ctask буде збільшена на 1 (на початку вона рівна 0). Це означає, що у вхідному буфері є прийняті дані, які програма має зчитати. Після цього програма повинна буде зменшити змінну I2Ctask назад на 1.

Для уніфікації даних, що мають передаватися в основні функції, які відповідають за формування I2C-посилки, необхідно також здійснити наступний ряд макровизначень:

#define ACK 0 // підтвердження активне

#define NACK 1 // підтвердження відсутнє

#define I2C_W 0 // запит на запис

#define I2C_R 1 // запит на читання

#define CONTROL 1 // зворотній контроль виконання посилки

#define NOCONTROL 0 // виконання посилки без підтвердження

//розрахунок швидкості TWI

#define TWBRcalc (F_CPU/I2Cspeed-16)/2

Вхідний та вихідний буфер модуля TWI може бути довільної довжини, тому для кожного з них ми забезпечуємо можливість встановлення свого розміру:

#define I2C_BUF_SIZE_OUT 32

#define I2C_BUF_MASK_OUT (I2C_BUF_SIZE_OUT-1)

#define I2C_BUF_SIZE_IN 32

#define I2C_BUF_MASK_IN (I2C_BUF_SIZE_IN-1)

unsigned char I2C_BufOUT[I2C_BUF_SIZE_OUT], I2C_StartBufOUT=0,

I2C_EndBufOUT=0, I2C_BufOUTer=0;

unsigned char I2C_BufIN[I2C_BUF_SIZE_IN], I2C_StartBufIN=0,

I2C_EndBufIN=0, I2C_BufINer=0;

Для забезпечення певної функціональності програмного коду для роботи з I2C-шиною слід оголосити ряд додаткових змінних:

unsigned char I2Cproccess=0; // вказує, чи є зараз передача на I2С-шині

unsigned char I2Ccontrol; // вказує, чи необх. звітув. про викон.

volatile unsigned char I2Ctask=0; //вказує, скільки опрац. пакетів start-stop

Остання змінна оголошена з директивою volatile, оскільки вона одночасно використовується як в підпрограмі переривання, так і в основній програмі. Функції запису/читання буферів працюють за логікою роботи FIFO-буферів, їхня конкретна реалізація для буферів прийомо-передачі модуля TWI.

Також варто звернути увагу на функцію I2C_SearchStartStop (). У випадку, коли підлеглий пристрій не відгукнувся на свою адресу, чи попросту він відсутній на шині, або під час прийому даних він не хоче їх більше приймати, тоді на шині у момент підтвердження буде присутній NACK.

Головний пристрій (master), отримавши NACK, змушений відмовитися від подальшого обміну з цим пристроєм. І тому ця функція у вихідному буфері модуля TWI шукає найближчу команду REPEAT START чи STOP, пропускаючи команди обміну даними з поточним пристроєм.

Основна робота модуля TWI організована через підпрограму переривання. Логічний перемикач отримує значення з регістра статуса TWSR (маскуючи при цьому три молодших біти) та згідно цього коду виконує одну з трьох типових дій, яка обов’язково завершується функцією I2C_Action ():

— якщо прочитано байт даних, то він з регістра TWDR заноситься у вхідний буфер;

— якщо передача завершилася не успішно (NACK з боку підлеглого пристрою), тоді шукаємо у вихідному буфері найближчу команду повторного старту чи стопу;

— для решта типових команд лише викликається функція I2C_Action (), яка виконає наступну команду для I2C-шини, що записана у вихідному буфері модуля TWI.

Функція I2C_Action () призначена для зчитування з вихідного буфера модуля TWI поточної команди чи даних та виводу їх на I2C-шину.

2.3 Практичне застосування розробленої алгоритмічної бібліотеки для обміну даними з периферією за I2C-протоколом

До I2C-шини в нас підключені: мікроконтролер ATmega32A, годинник реального часу (RTC) PCF8583 та пам’ять EEPROM M24C08. Значення, зчитані з мікросхеми годинника, будемо передавати для візуалізації на персональний комп’ютер.

Зв’язок з ПК реалізований на основі мікросхеми FT232RL.

Мікросхема FT232RL — міст між інтерфейсами USB і UART. З боку ПК, за допомогою додаткових комп’ютерних драйверів, мікросхема ідентифікується як COM-порт, а з боку пристрою має інтерфейс UART. Завдяки мікросхемі FT232RL можна дуже просто підключити свій пристрій до ПК через інтерфейс USB, не вникаючи в його особливості. Дана мікросхема дуже надійна, стабільна, підтримується всіма операційними системами.

Характеристики та особливості мікросхеми FT232RL:

— одночіповий перехідник з USB в асинхронний послідовний інтерфейс передачі даних (UART);

— протокол USB повністю реалізований у мікросхемі;

— інтерфейс UART підтримує режими передачі 7 або 8 біт даних, 1 або 2 стопових біта, різні режими контролю парності;

— швидкості передачі від 300 бод до 3 мегабод для RS422 / RS485 / TTL та від 300 бод до 1 мегабод для RS-232;

— налаштовувані виводи CBUS;

— можливість виведення стану прийому/передачі на зовнішні світлодіоди;

— можливість подачі тактового сигналу на зовнішні мікросхеми, контролери, ПЛІС (частоти 6, 12, 24 і 48 МГц);

— висока здатність навантаження виходів;

— вбудована енергонезалежна пам’ять EEPROM об'ємом 1024 байт.

Мікросхеми постачаються із запрограмованою EEPROM, тому не потрібно програмувати EEPROM для початку роботи.

При роботі з годинником реального часу PCF8583 виставлення значень часу здійснюється за допомогою додаткових кнопок, підключених до порту B. Спершу необхідно натиснути кнопку «Редагування», потім за допомогою інших кнопок виставити години та хвилини (кнопка «Секунди» буде лише обнулювати значення), та ще раз натиснути кнопку «Редагування» для передачі зміненого значення часу до мікросхеми годинника.

PCF8583 являє собою оперативну пам’ять, ємністю 256 байт, у якій перші 8 байт використовуються для годинника, календаря і функцій лічильника. Наступні 8 байт можуть бути запрограмовані на використання в якості регістрів сигналізації. Решта 240 байт відносяться до оперативної пам’яті. Вбудований регістр адреси автоматично нарощується після читання або запису кожного байта даних. Усі числа в регістрах годин за замовчуванням зберігаються в BCD форматі.

Адреса пристрою на I2C-шині встановлена виробником як 10 1000A0. Вивід А0 ми подали на землю, отже цей біт дорівнює 0.

Зчитування поточного часу з мікросхеми PCF8583 виконується у підпрограмі переривання таймера № 1, який налаштований на інтервал 0,5 сек. У підпрограмі за допомогою відповідних функцій формується I2C- посилка, при цьому логічна змінна logicEdit повинна дорівнювати нулю. За допомогою цієї змінної блокується зчитування часу з годинника у момент, коли ми редагуємо поточні значення часу.

Отримані значення з годинника заносяться у вхідний буфер та по завершенню посилки (про це сигналізує змінна I2Ctask) в основній програмі зчитуються з буфера у змінні second, minute, hour та передаються для візуалізації через UART до персонального комп’ютера.

У режимі редагування (один раз натиснута перша кнопка) ми відповідними кнопками кожним натисканням збільшуємо на 1 значення цих змінних.

Оскільки значення змінних second, minute, hour зберігаються у BCD форматі, то для цього ми використовуємо відповідну функцію BCDplus1(), та після інкременту значення перевіряємо його на переповнення, відповідно, 0×60 та 0×24, і у разі чого обнулюємо.

Повторне натискання кнопки редагування формує I2C-посилку для занесення змінених значень часу у годинник, та встановлює логічну змінну logicEdit в нуль, що переводить програму у режим відображення поточного часу.

Мікросхема пам’яті EEPROM M24C08 додає певну функціональність у нашу програму. Для збереження поточного часу у випадку пропажі напруги живлення значення часу заноситься щохвилини у мікросхему пам’яті.

Об'єм пам’яті M24C08 становить 8 кбіт (1024 байти). Ця мікросхема підтримує швидкість I2C-шини 400 кбіт/сек, працює при напрузі від 2,5 до 5 В, побайтний або сторінковий (до 16 байт) запис даних, автоматичне збільшення адреси при читанні та запису даних, більше 1 мільйона операцій запису, можливість захисту від перезапису, максимальний час запису 5 мсек (як для побайтного, так і сторінкового режиму).

I2C-адреса M24C08 має такий вигляд:

1 0 1 0 E2 A9 A8

де E2 представляє собою фізичний вивід мікросхеми і за допомогою нього можемо підключити 2 EEPROM до I2C-шини. А9 та А8 визначають старші біти адреси для внутрішньої пам’яті.

Вивід E2 ми підключили до високого рівня для уникнення конфлікту адреси з мікросхемою годинника. Таким чином адреса мікросхеми пам’яті має таке значення 1 0 1 0 1 A9 A8.

При старті мікроконтролера (перед основним робочим циклом) з EEPROM зчитується значення часу, та одразу ж заноситься у годинник.

В основному робочому циклі постійно перевіряється чи поточне значення хвилин не змінилося, у разі чого відбувається запис в EEPROM. Аналогічний код розміщений і для кнопки «редагування».

3. ДОСЛІДЖЕННЯ ТА РЕАЛІЗАЦІЯ МУЛЬТИМАЙСТЕРНОГО РЕЖИМУ РОБОТИ I2C-ШИНИ

3.1 Організація структури даних для мультимайстерного режиму

Цей режим передбачає, що на I2C-шині можуть одночасно бути присутніми декілька головних пристроїв (мікроконтролерів), які виконуватимуть обмін даними з підлеглими пристроями (рис. 3. 1). Кожен з мікроконтролерів може бути як головним (master), так і підлеглим (slave) пристроєм. Тобто, він може адресувати інші пристрої, а може і сам бути адресованим.

Рис. 3.1 Мультимайстерна I2C-шина

У мультимайстерному режимі вести передачу на I2C-шині в певний момент часу може лише один пристрій, тобто, хто перший займе шину (виставить сигнал старт), той і зможе виконувати обмін даними з підлеглими пристроями аж до кінця своєї посилки (сигналу стоп). Якщо ж сигнали старт виставлять одночасно декілька пристроїв, тоді між ними проводиться арбітраж (набір правил для керування пріоритетом доступу до шини конкуруючими головними пристроями).

Рис. 3.2 Процедура арбітражу між двома головними пристроями

Арбітраж виконується на лінії SDA при високому рівні сигналу на SCL (рис. 3. 2). Пристрій, що формує на лінії SDA високий рівень, а в той час інший пристрій формує низький рівень, тоді перший втрачає право бути головним і повинен перейти у режим підлеглого. Тобто, арбітраж виграє той, що виставляє на лінії SDA «0» в той момент, коли інші виставляють «1». Спершу арбітраж проводиться для байту адреси. Якщо ж конкуруючі пристрої адресують цей самий підлеглий пристрій, тоді арбітраж проводиться для наступних за адресою байтів даних, і аж до сигналу стоп чи повторного старту. Може бути ситуація, коли головні пристрої виконують однотипний обмін даними з підлеглим пристроєм. Тоді вони не зможуть виявити конфлікт на шині.

Оскільки МК AVR можуть працювати з I2C-шиною як в режимі master, так і в режимі slave, то може виникнути ситуація, що вони, окрім того, що можуть втратити арбітраж, то ще й можуть бути в цей момент адресованими іншими мікроконтролерами.

Модуль TWI відпрацьовує усі ці ситуації, як функції арбітражу, так і роботу в slave-режимі, та виставляє у регістрі статусу TWSR відповідні коди для цих ситуацій. Таблиця 3.1 є доповненням до таблиці 2.1.

Таблиця 3.1. Коди статусів для модуля TWI у режимі slave

Код

Стан I2C-шини та модуля TWI

0x38

Втрата пріоритету в режимі master

0x60

Прийнято власну адресу+Write та відіслано ACK

0x68

Втрата пріоритету: прийнято власну адресу+Write та відіслано ACK

0x70

Прийнято загальний виклик+Write та відіслано ACK

0x78

Втрата пріоритету: прийнято загальний виклик+Write та відіслано ACK

0x80

Прийнято байт даних та відіслано ACK

0x88

Прийнято байт даних та відіслано NACK

0x90

Прийнято байт даних та відіслано ACK (заг. виклик)

0x98

Прийнято байт даних та відіслано NACK (заг. виклик)

0xA0

Отримано сигнал stop чи repeat start у режимі slave

0xA8

Прийнято власну адресу+Read та відіслано ACK

0xB0

Втрата пріоритету: прийнято власну адресу+Read та відіслано ACK

0xB8

Був переданий байт даних та отримано ACK

0xC0

Був переданий байт даних та отримано NACK

Оскільки мультимайстерний режим передбачає оброблення більшої кількості задач та ситуацій, що можуть виникати при передачі на I2C-шині, то для забезпечення необхідної функціональності додамо ще два буфери: інфобуфер та буфер даних.

Найперше, ми введемо можливість контролю за виконанням I2C-посилок згідно присвоєних їм номерів задач.

Номер задачі буде присвоюватися посилці під час її формування, а саме: при виклику функції I2C_Start (). Оскільки молодший біт значення, що передається цій функції, відповідає за контроль за виконанням посилки, то, відповідно, адреса може займати лише старші 7 бітів.

Для цього найкраще передбачити ряд макровизначень:

#define I2C_Task1 (1< <1)

#define I2C_Task2 (2< <1)

// … і т.д.

#define I2C_Task_Slave_command (126< <1)

#define I2C_Task_Slave_byte (127< <1)

Тоді виклик функції буде виглядати таким чином:

I2C_Start (I2C_Task1|CONTROL);

Останні два макровизначення дають можливість сигналізувати про прийом даних у режимі slave (по одному прийнятому байту на кожну задачу). При цьому розрізняються командні (ті, що отримуються після власної адреси+Write) та звичайні байти даних.

Виконані задачі записуються в інфобуфер. У режимі master формат даних містить 2 байти: номер виконаної задачі та кількість прийнятих байтів (для контролю). У режимі slave записуються лише по 1 байту (виконана задача прийнятого командного чи звичайного байта). Отримані байти вже безпосередньо зчитуються з буфера IN у порядку запису виконаних задач в інфобуфері. Якщо командний байт містить адресу в буфері даних, тоді інформація про такі задачі не заноситься в інфобуфер, а отримані байти даних записуються безпосередньо вже у буфер даних підпрограмою переривання модуля TWI.

Аналіз виконаних задач здійснюється в основній програмі за допомогою розгалуженого умовного блоку.

unsigned char Ntask, Nbytes;

if (I2Ctask) // якщо є необроблені задачі

{

I2Ctask--;

Ntask = ReadI2C_BUFinf ();

if (Ntask == I2C_Task1)

{ // оброблення даних + контроль за кількістю прийнятих байтів

Nbytes= ReadI2C_BUFinf ();

}

else

if (Ntask == I2C_Task_Slave_command)

{ // аналіз прийнятого командного байта

}

else

if (Ntask == I2C_Task_Slave_byte)

{ // аналіз прийнятого байта даних

}

}

У процесі арбітражу через втрату пріоритету виконання поточної I2C-посилки може бути перерване. Тому необхідно постійно тримати у тимчасовій змінній розміщення початку в буфері OUT поточної посилки, і при необхідності відновлювати.

Від МК у режимі slave зовнішній пристрій може вимагати здійснити такі три дії:

— виконати певну задачу (включити світло, запустити процес оцифрування даних модуля АЦП і т.п.);

— прийняти байт даних;

— вислати байт даних з визначеною інформацією (наприклад, отримані результати від модуля АЦП).

Для цього, на зразок периферійних пристроїв, для режиму slave виділяємо окремий буфер даних (рис. 3. 3), у якому за кожною коміркою буде закріплено певна величина. Наприклад, сюди можуть записуватися оцифровані значення з АЦП і при потребі зчитуватися зовнішнім пристроєм. Можуть міститися конфігураційні комірки для функціонування МК, значення яких будуть змінюватися іншими пристроями тощо.

Читання та запис даних здійснюється згідно вказаної адреси розміщення даних у буфері. Адреса при цьому автоматично інкрементується, щоб можна було виконувати операції з послідовними даними, наприклад, зчитати I2C-посилкою одразу декілька байтів. Тобто, МК у режимі slave функціонує за правилами, що визначені I2C-протоколом. Для розділення доступу до даних підпрограмою переривання TWI та основною програмою ми передбачили дві змінні: I2C_AutoincBUFdata (основна програма) та I2C_AutoincBUFdataLib (підпрограма переривання).

Програмний код бібліотеки для роботи з I2C-шиною в мультимайстерному режимі є фактично розширенням попередньої бібліотеки для одномайстерного режиму. Тому представимо лише ті частини коду, що відсутні для одномайстерного режиму чи є модифіковані.

До програмного коду необхідно додати два макровизначення для змінної I2C_status, а також тимчасову змінну для відновлення початку I2C- посилки у буфері OUT:

#define I2C_BUFinfEr 3 // буфер inf заповнений

#define I2C_AddressW 7 // прийнято адресу+W

// зберігає початок I2C-посилки (буфер OUT) на випадок втрати пріоритету

unsigned char I2C_StartBufOUTtemp;

Код для буфера даних інфобуфера:

// Буфер даних для режиму Slave

#define I2C_BUFdataSIZE 16

#define I2C_BUFdataMASK (I2C_BUFdataSIZE-1)

unsigned char I2C_BUFdata[I2C_BUFdataSIZE], I2C_commandtemp;

unsigned char I2C_AutoincBUFdata=0, I2C_AutoincBUFdataLib=0;

// Організація інформаційного буфера про виконані задачі

// № 126−127 slave режим; № 1−125 master режим;

// № 0 не вказано номер задачі

#define I2C_BUFinfSIZE 16

#define I2C_BUFinfMASK (I2C_BUFinfSIZE-1)

unsigned char I2C_BUFinf[I2C_BUFinfSIZE], I2C_StartBUFinf=0, I2C_EndBUFinf=0;

unsigned char I2C_infoNtask, I2C_infoNbytes;

Буфер даних має більшу кількість функцій, що працюють з його даними. Як вже згадувалося, це пов’язано з його структурою, яка хоч і є зацикленою, однак для буфера даних є виділені два незалежні вказівники на комірки з даними.

Певної модифікації зазнає функція I2C_Action (), а от основний функціональний програмний код, що забезпечує роботу в режимі slave та відслідковує функцію арбітражу на I2C-шині прописується у підпрограмі переривання модуля TWI.

Функція ініціалізації повинна приймати значення I2C-адреси для модуля TWI у режимі slave, а також вказівку «1» чи «0» для дозволу/заборони загальних викликів (з адресою 0×00).

Повний програмний код бібліотеки для роботи з I2C-шиною в мультимайстерному режимі наведено у додатку А.

3.2 Реалізація арбітражу на I2C-шині

Тестування та відлагодження розробленої бібліотеки при роботі з I2C-шиною у мультимайстерному режимі для функцій арбітражу виконувалося безпосередньо на фізичному макеті, оскільки у пакеті Proteus виявлено їхню некоректну роботу для МК AVR.

А. Код статусу 0×38 (втрата пріоритету в режимі master). Для цього тесту функцій арбітражу ми змушуємо мікроконтролери одночасно виконувати звертання до пам’яті EEPROM.

Одна кнопка під'єднана одразу до двох МК, а її натиск ініціалізує запуск процедури запису в пам’ять EEPROM. Кожен з МК звертається до своєї області пам’яті в EEPROM. Очікування натиску кнопки ми зациклили у конструкції while{}. Як тільки кнопка буде натиснутою, мікроконтролери одночасно почнуть змагатися за доступ до пам’яті EEPROM. Хто перший видасть на лінію «0», той і отримає пріоритет для доступу, а інший буде очікувати звільнення шини.

Зауважимо, що оскільки запис у пам’ять EEPROM триває деякий час (5−10 мсек.), то мікросхема почне відповідати на свою адресу лише після циклу запису, а до цього на лінії буде NACK.

Для аналізу результатів арбітражу дані з мікроконтролерів передаються через UART-порт до персонального комп’ютера у клієнтську програму. Клієнтська програма працює одночасно з двома СОМ-портами, через які вона отримує дані з конкуруючих мікроконтолерів.

Перший мікроконтролер програє арбітраж, оскільки в адресі EEPROM сьомий біт рівний одиниці, а в другого мікроконтролера — нуль. Далі перший мікроконтролер намагається отримати доступ до пам’яті EEPROM, а остання не відповідає (5−10 мсек.), бо здійснюється запис. По закінчення запису в EEPROM перший мікроконтролер успішно записує дані.

Б. Коди статусів 0×68, 0×78, 0xB0 (втрата пріоритету та перехід у режим роботи slave). Ці коди сигналізують, що МК при спробі вийти зі спробою передачі даних на шині був перерваний іншим МК для його адресації та обміну з ним даними.

3.3 Практичне застосування мультимайстерного режиму

Для дослідження функціональності розробленої програмної бібліотеки для роботи з TWI модулем через апаратні переривання ми розробили мікроконтролерну мережу на основі I2C-інтерфейсу.

Мікроконтролерна мережа складається з двох головних пристроїв мікроконтролерів ATMega32A, та двох периферійних пристроїв годинника реального часу PCF8583 та пам’яті EEPROM М24C08. Обидва мікроконтролери паралельно працюють з годинником та пам’яттю EEPROM, а також обмінюються даними між собою. У цьому прикладі ми реалізували 2 ситуації обміну даними мікроконтролерами між собою по I2C-шині:

ПоказатьСвернуть
Заполнить форму текущей работой