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

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык украинский
Дата добавления 10.10.2013
Размер файла 268,7 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

1. відправлення першим МК пакету даних з 4-х байтів (власна адреса, секунди, хвилини, години) другому МК для їхнього запису в буфер даних;

2. читання першим МК тестових значень та значення з перемикача «піаніно» з буфера даних другого МК.

Для забезпечення обміну даними між мікроконтролерами простір буферів даних розмічений таким чином:

0 - тестове значення 1;

1 - тестове значення 2;

2 - тестове значення 3;

3 - значення для вибору;

4 - зовнішній майстер;

5 - секунди;

6 - хвилин;

7 - години.

Програмний код основної програми розроблений таким чином, щоб могти бути використаним для обох мікроконтролерів одночасно.

Відмінність полягає лише у тому, що для одного з них макровизначення Master приймає значення 0, а для іншого 1.

Таким чином для них забезпечуються I2C-адреси 0x78 та 0x79.

У функції Initializer() при виклику функції ініціалізації модуля TWI необхідно передати їй 2 параметри: I2C-адресу та дозвіл/заборону загальних викликів, а також організувати вивід I2C-адреси на LCD.

// Ініціалізація I2C

I2C_Init(adressI2c, 0);

// вивід адреси МК на дисплей

LCD_GotoYX(1,15);

LCD_WriteStr( utoa(adressI2c ,Sbuf,16) );

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

Для одночасного зчитування даних клієнтською програмою з мікроконтролерів я задіяв два конвертора USB-UART на основі мікросхеми FT232RL.

Для візуалізації даних був розроблений клієнтський модуль мовою С++.

Кнопка з надписом «Відіслати штамп часу до A/B» ініціалізує передачу власної I2C-адреси та поточного часу, отриманого з мікросхеми годинника, іншому МК та вказівки для передачі через UART інтерфейс до комп'ютера записаного у буфер даних штампу часу. Кнопка з надписом «Прочитати значення з А/В» ініціалізує зчитування тестових значень та значення перемикача «піаніно», що записані у буфері даних іншого МК, та передача цих значень клієнтській програмі на комп'ютері.

Для даного прикладу була проведена експериментальна апробація роботи I2C-інтерфейсу в мультимайстерному режимі на фізичному обладнанні. Також протестовано функції арбітражу, що відповідають кодам статусу модуля TWI 0x68, 0x78, 0xB0 (втрата пріоритету та перехід у режим роботи slave) при одночасній посилці даних мікроконтолерами один одному. Для цього були об'єднані однакові виводи PB6 та PB7.

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

4. ЕКОНОМІЧНА ЧАСТИНА

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

4.1 Розрахунок витрат на виконання дослідної роботи

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

витрати на оплату праці;

відрахування на соціальні заходи;

матеріали;

витрати на використання комп'ютерної техніки;

витрати на використання спец обладнання для наукових (експериментальних) робіт;

накладні витрати;

інші витрати.

4.1.1 Розрахунок витрат на оплату праці

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

Таблиця 4.1. Вихідні дані для розрахунку витрат на оплату праці

№ п/п

Посада виконавців

Місячний оклад, грн.

Середньоденна ставка, грн/дн

1

Керівник ДР, доцент

2500

119,05

2

Консультант з економіки, доцент

2500

119,05

3

Студент

600

28,57

Витрати на оплату праці розробників роботи визначаються за формулою

де nij - чисельність розробників і-ої спеціальності j-го тарифного розряду, які приймають участь в проектуванні, чол.; tij - час, котрий затрачений на розробку проекту співробітника і-ої спеціальності j-го тарифного розряду, днів; Cij - денна заробітна плата і-ої спеціальності j-го тарифного розряду, грн., яка визначається за формулою:

де Cij - основна місячна заробітна плата розробника і-ої спеціальності j-го тарифного розряду, грн.; h - коефіцієнт, що визначає розмір додаткової заробітної плати (при умові наявності доплат); р - середня кількість робочих днів у місяці (приймаємо 21 р.д.).

4.1.2 Відрахування на соціальні заходи

Величну відрахувань у спеціальні державні фонди визначають у відсотковому співвідношенні від суми основної та додаткової заробітної плати. Згідно діючого нормативного законодавства сума відрахувань у спеціальні державні фонди складає 36,2% від суми заробітної плати

грн.

Таблиця 4.2. Розрахунок витрат на оплату праці

№ п/п

Посада виконавців

Час розробки, дні

Денна заробітна плата, грн

Витрати на розробку, грн

1

Керівник ДР, доцент

5

119,05

595,25

2

Консультант з економіки, Доцент

0,25

119,05

29,76

3

Студент

60

28,57

1714,29

Разом

2339,21

4.1.3 Розрахунок витрат на матеріали

У таблиці 4.3 наведено перелік купованих виробів і розраховані витрати на них.

Таблиця 4.3. Розрахунок витрат на куповані вироби

№ п/п

Найменування купованих виробів

Одиниця виміру

Ціна на одиницю виміру, грн

Кількість купованих виробів

Сума, грн

Транспортні витрати (10% від суми)

Загальна сума, грн

1

Папір (формат А4)

уп

45,0

2

90,00

9,0

99,0

2

Ручка кулькова

шт

2,0

2

4,00

0,4

4,40

3

Олівець простий

шт

1,50

2

3,00

0,3

3,30

4

Диски DWD-R

шт

2,0

2

4,00

0,4

4,40

5

Зошит, 96 арк

шт

3,50

1

3,50

0,35

3,85

6

Тонер для принтера

уп

40

1

40

4,0

44,0

Разом

158,95

4.1.4 Витрати на використання комп'ютерної техніки

Витрати на використання комп'ютерної техніки включають витрати на амортизацію комп'ютерної техніки, витрати на користування програмним забезпеченням, витрати на електроенергію, що споживається комп'ютером. За даними обчислювального центру НУ «Львівська політехніка» для ЕОМ типу ІВМ РС/АТХ вартість години роботи становить 4,5 грн. Середній щоденний час роботи на комп'ютері - 4 години. Розрахунок витрат на використання комп'ютерної техніки приведений в таблиці 4.4.

Таблиця 4.4. Розрахунок витрат на використання комп'ютерної техніки

№ п/п

Назва етапів робіт, при виконанні яких використовується комп'ютер

Час використання комп'ютера

Витрати на використання комп'ютера, грн

днів

годин

1

Проведення досліджень та оформлення їх результатів

30

120

540

2

Оформлення розділу “Економіка”

2

8

36

3

Оформлення ДР

16

64

288

Разом

48

192

864

4.1.5 Накладні витрати

Накладні витрати проектних організацій включають три групи видатків: витрати на управління, загальногосподарські витрати, невиробничі витрати. Вони розраховуються за встановленими відсотками до витрат на оплату праці. Середньостатистичний відсоток накладних витрат в організації складає 150%.

(грн.)

4.1.6 Інші витрати.

Інші витрати є витратами, які не враховані в інших статтях. Вони становлять 10% від заробітної плати:

(грн.)

На основі отриманих даних складається калькуляція планової собівартості загалом по дослідній роботі і зводиться в таблицю 4.5.

Таблиця 4.5. Кошторис витрат на виконання НДР

№ п/п

Найменування елементів витрат

Сума витрат, грн

1

Витрати на оплату праці

2339,21

2

Відрахування у спеціальні державні фонди

846,79

3

Витрати на куповані вироби

158,95

4

Витрати на використання комп'ютерної техніки

864

5

Накладні витрати

3508,82

6

Інші витрати

233,92

Разом

7951,69

4.2 Розрахунок договірної ціни та прибутку дослідної роботи

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

Ц=С*(1 + р)

де Ц - договірна ціна, С - собівартість проведення роботи, р - рівень рентабельності витрат у виконавця робти.

Тоді очікуваний прибуток від реалізації дослідної роботи розраховують за формулою:

П = Ц - С ( грн)

де П - очікуваний прибуток від виконання роботи.

Для даної дослідної роботи ціна визначена як:

1,3*С = 10337,2 грн.

Тоді прибуток буде рівним:

П=1,3*С-С = 0,3*С=0,3*7951,69=2385,51 (грн).

4.3 Оцінка результативності дослідної роботи

Результатом дослідної роботи є досягнення технічного, економічного або соціального ефекту. У даному підрозділі оцінено рівень ефектів від проведеної дослідної роботи.

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

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

де , коефіцієнт науково-технічної результативності; - коефіцієнт значимості і-го фактору, використовуваного для оцінки; - коефіцієнт досягнутого рівня і-го фактору; m - кількість факторів науково-технічної результативності.

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

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

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

З таблиці 4.6 слід вибрати фактори та ознаки, які характеризують, науково-технічну результативності дослідної роботи .

Таблиця 4.6 Характеристики факторів та ознак науково-технічної результативності дослідної роботи

Фактор науково-технічної результативності

Коефіцієнт значимості фактору

Якість фактора

Характеристика фактора

Коефіцієнт досягнутого рівня

Перспективність використання результатів

0,5

Важлива

Результати будуть використані в конкретному науковому напрямі при розробці нових технічних рішень, націлених на суттєве підвищення продуктивності праці

0,8

Масштаб можливої реалізації результатів

0,3

Галузевий

Час реалізації: до трьох років

0,8

Завершеність отриманих результатів

0,2

Середня

Технічне завдання на прикладні НДР чи ДКР

0,8

Згідно із наведенеми даними розраховуємо коефіцієнт науково-технічної ефективності:

Висновки

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

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

Розробивши план проведення дослідної роботи, було підраховано кошторис витрат: витрати на заробітну плату, відрахування у спеціальні державні фонди, витрати на куповані вироби, витрати на використання комп'ютерної техніки, накладні витрати. Загалом кошторис витрат на проведення дослідної склав 7951,69 грн.

Коефіцієнт науково-технічної ефективності 0,8, що є хорошим показником. Економічний ефект від використання проектного рішення полягає у зниженні фінансових, ресурсних та часових витрат при використанні сучасних контролерів та давачів.

ВИСНОВКИ

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

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

2. Розроблена структура дає можливість у повній мірі реалізувати усі функції арбітражу для I2C-шини.

3. Розроблені алгоритми для реалізації мультимайстерного режиму з використанням апаратних переривань просимулювані та протестовані в пакеті Proteus.

4. Усі отримані результати експериментально апробовані на фізичному обладнанні.

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

СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ

1. Рюмик, С. М. 1000 и одна микроконтроллерная схема Вып. 1//С. М. Рюмик. - Додэка-21, 2010.-356 с.

2. Шпак. Ю. А. Программирование на языке С для AVR и PIC микроконтроллеров. Изд. 2-е, переработанное и дополненное.// Сост. Ю. А. Шпак - К.: “МК-Пресс”. СП.: “КОРОНА-ВЕК”, 2011 - 544с.

3. Евстифеев А. В. Микроконтроллеры AVR семейства Tiny и Mega фирми ATMEL, 5-е изд., стер. - М.: Издательский дом “Додэка-21”, 2008. - 560с.

4. Лапин А.А. Интерфейсы. Выбор и реализация. М.: Техносфера, 2005. - 168 с.

5. ATmega32A. Datasheets - Atmel Corporation. - 353 pages.

6. Роман Абраш. Книга по работе с WinAVR и AVR Studio. - Підбірка статей у журналі «Радиолюбитель» за період 01/2010-05/2011. - 88 стр.

7. AVR Libc Development Pages. - http://www.nongnu.org/avr-libc.

8. Anil Kumar Maini. Digital Electronics: Principles, Devices and Applications. John Wiley & Sons, Ltd. - 2007. - 727 pages.

9. AVR311: Using the TWI module as I2C slave. Application Note - Atmel Corporation. - 12 pages.

10. AVR315: Using the TWI module as I2C master. Application Note - Atmel Corporation. - 14 pages.

11. UM10204. I2C-bus specification and user manual. - NXP Semicon¬ductors. 2012. - 64 pages.

12. PCF8583. Clock and calendar with 240 x 8-bit RAM. Datasheets - NXP Semiconductors. - 2010. - 37 pages.

13. Иди Ф. Сетевой и межсетевой обмен данными с микроконтроллерами. - М.: Издательский дом «Додэка XXI», 2007. - 376 с.

14. Парк Д., Маккей С., Райт Э. Передача данных в системах контроля и управления. - М.: ООО «Группа ИДТ», 2007. - 480 с.

ДОДАТКИ

Додаток А

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

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

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

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

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

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

#define NOCONTROL 0 //зворотній контроль виконання пакету

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

#define I2C_BUF_SIZE_OUT 64

#define I2C_BUF_MASK_OUT (I2C_BUF_SIZE_OUT-1)

#define I2C_BUF_SIZE_IN 64

#define I2C_BUF_MASK_IN (I2C_BUF_SIZE_IN-1)

unsigned char I2C_BufOUT[I2C_BUF_SIZE_OUT], I2C_StartBufOUT=0, I2C_EndBufOUT=0;

unsigned char I2C_BufIN[I2C_BUF_SIZE_IN], I2C_StartBufIN=0, I2C_EndBufIN=0;

unsigned char I2C_StartBufOUTtemp; //зберігає поч. буфера на випадок втрати пріоритету

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

unsigned char I2C_status=0; //0bit-NACKer, 1bit-BufOUTer, 2bit-BufINer, 3bit-BUFinfEr

//5bit-Proccess, 6bit-Control, 7bit-адреса+W

#define I2C_NACKer 0 // slave не відповів NACK

#define I2C_BufOUTer 1 // буфер OUT заповнений

#define I2C_BufINer 2 // буфер IN заповнений

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

#define I2C_Proccess 5 // вказує, чи відбувається зараз передача на I2-шині

#define I2C_Control 6 // вказує, чи необх. звітуватися про викон.

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

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

// №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;

void WriteI2C_BUFinf(unsigned char value) // запис в інформаційний буфер

{

I2C_BUFinf[I2C_EndBUFinf++] = value;

I2C_EndBUFinf &= I2C_BUFinfMASK;

//перевіряємо на переповнення буфера

//if(I2C_StartBUFinf==I2C_EndBUFinf)

// I2C_status |= 1<<I2C_BUFinfEr; // помилка: буфер заповнений

} // розкоментувати при необхідності

unsigned char ReadI2C_BUFinf() // читання з інформаційного буфера

{

unsigned char value = I2C_BUFinf[I2C_StartBUFinf++];

I2C_StartBUFinf &= I2C_BUFinfMASK;

return value;

}

#define I2C_Task_1 (1<<1)

#define I2C_Task_2 (2<<1)

#define I2C_Task_3 (3<<1)

#define I2C_Task_4 (4<<1)

#define I2C_Task_5 (5<<1)

#define I2C_Task_Slave_command (126<<1)

#define I2C_Task_Slave_byte (127<<1)

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

#define I2C_BUFdataSIZE 16

#define I2C_BUFdataMASK (I2C_BUFdataSIZE-1)

unsigned char I2C_BUFdata[I2C_BUFdataSIZE], I2C_AutoincBUFdata=0, I2C_AutoincBUFdataLib=0;

unsigned char I2C_commandtemp;

// запис у буфер даних

void WriteI2C_BUFdata_adr(unsigned char address,unsigned char value) //address=[0, I2C_BUFdataSIZE-1]

{

if(address<I2C_BUFdataSIZE)

{

I2C_AutoincBUFdata=address;

I2C_BUFdata[I2C_AutoincBUFdata++] = value;

I2C_AutoincBUFdata &= I2C_BUFdataMASK;

}

}

void WriteI2C_BUFdata(unsigned char value)

{

I2C_BUFdata[I2C_AutoincBUFdata++] = value;

I2C_AutoincBUFdata &= I2C_BUFdataMASK;

}

// запис у буфер даних (бібліотечне)

void WriteI2C_BUFdataLib(unsigned char value)

{

I2C_BUFdata[I2C_AutoincBUFdataLib++] = value;

I2C_AutoincBUFdataLib &= I2C_BUFdataMASK;

}

// запис у буфер даних без автоінкременту

void WriteI2C_BUFdata_noinc(unsigned char address,unsigned char value)

{

if(address<I2C_BUFdataSIZE)

{

I2C_BUFdata[address] = value;

}

}

// читання з буфера даних

unsigned char ReadI2C_BUFdata_adr(unsigned char address) //address=[0, I2C_BUFdataSIZE-1]

{

if(address<I2C_BUFdataSIZE)

{

I2C_AutoincBUFdata=address;

unsigned char value = I2C_BUFdata[I2C_AutoincBUFdata++];

I2C_AutoincBUFdata &= I2C_BUFdataMASK;

return value;

}

else

return 0;

}

unsigned char ReadI2C_BUFdata()

{

unsigned char value = I2C_BUFdata[I2C_AutoincBUFdata++];

I2C_AutoincBUFdata &= I2C_BUFdataMASK;

return value;

}

// читання з буфера даних (бібліотечне)

unsigned char ReadI2C_BUFdataLib()

{

unsigned char value = I2C_BUFdata[I2C_AutoincBUFdataLib++];

I2C_AutoincBUFdataLib &= I2C_BUFdataMASK;

return value;

}

inline void I2C_Init(unsigned char address, unsigned char generalcall)

{

TWBR = TWBRcalc; //Bit Rate

TWSR = 0; //подільник TWPS=0

I2CDDR &= ~(1<<SCLpin | 1<<SDApin); //на вхід

I2CPORT |= 1<<SCLpin | 1<<SDApin; //підтягуючі резистори

TWAR = address<<1|generalcall; //адреса у режимі slave

TWCR = 1<<TWEA|1<<TWEN|1<<TWIE;

}

void WriteI2C_BufOUT(unsigned char value) // запис у буфер передачі I2C

{

I2C_BufOUT[I2C_EndBufOUT++] = value;

I2C_EndBufOUT &= I2C_BUF_MASK_OUT;

//перевіряємо на переповнення буфера

//if(I2C_StartBufOUT==I2C_EndBufOUT)

// I2C_status |= 1<<I2C_BufOUTer; // помилка: буфер заповнений

} // розкоментувати при необхідності

void WriteI2C_BufIN(unsigned char value) // запис у буфер прийому I2C

{

I2C_BufIN[I2C_EndBufIN++] = value;

I2C_EndBufIN &= I2C_BUF_MASK_IN;

//перевіряємо на переповнення буфера

//if(I2C_StartBufIN==I2C_EndBufIN)

// I2C_status |= 1<<I2C_BufINer; // помилка: буфер заповнений

} // розкоментувати при необхідності

unsigned char ReadI2C_BufOUT() // читання з буфера передачі I2C

{

unsigned char value = I2C_BufOUT[I2C_StartBufOUT++];

I2C_StartBufOUT &= I2C_BUF_MASK_OUT;

return value;

}

unsigned char ReadI2C_BufIN() // читання з буфера передачі I2C

{

unsigned char value = I2C_BufIN[I2C_StartBufIN++];

I2C_StartBufIN &= I2C_BUF_MASK_IN;

return value;

}

void I2C_SearchStartStop()

{

unsigned char temp=1, I2C_StartBufOUTtemp;

do

{

I2C_StartBufOUTtemp=I2C_StartBufOUT;

switch(ReadI2C_BufOUT())

{

case 0x20: //якщо команда адреси

case 0x40: //якщо команда відправки байта

ReadI2C_BufOUT(); break; //то зчитуємо ще й наст. байт

case 0x80: break; //якщо команда читатння байта

case 0x04: //якщо команда Stop

case 0x10: //якщо комадна ReStart

temp=0; //пошук завершений

I2C_StartBufOUT=I2C_StartBufOUTtemp; //відновл. адресу у буфері

break;

}

}

while(temp==1) ;

}

inline void I2C_Start(unsigned char control)

{

cli(); //заборона глобальних переривань

WriteI2C_BufOUT(control); //вказує чи потрібно звітуватися про виконання

}

inline void I2C_ReStart()

{

WriteI2C_BufOUT(0x10); //вказуємо, що Повторний СТАРТ

}

inline void I2C_Address(unsigned char address, unsigned char direction)

{

WriteI2C_BufOUT(0x20); //вказує, що далі піде передача адреси

WriteI2C_BufOUT(address<<1 | direction); //адреса + напрям передачі

}

inline void I2C_SendByte(unsigned char byte)

{

WriteI2C_BufOUT(0x40); //вказує, що далі піде передача байту даних

WriteI2C_BufOUT(byte); //байт даних

}

inline void I2C_ReadByte(unsigned char ack)

{

WriteI2C_BufOUT(0x80+ack); //вказує, що далі піде читання байту даних

} //та вказує стан ACK/NACK у мол. біті

inline void I2C_Stop()

{

WriteI2C_BufOUT(0x04); //вказуємо, що СТОП

if( (I2C_status&(1<<I2C_Proccess)) == 0) // якщо передача на I2C-шині відсутня

{

I2C_status |= 1<<I2C_Proccess; // TWI зайнятий

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE; // Start

I2C_StartBufOUTtemp=I2C_StartBufOUT;

unsigned char temp = ReadI2C_BufOUT();

if(temp & 0x01) I2C_status |= 1<<I2C_Control;

else I2C_status &= ~(1<<I2C_Control);

I2C_infoNtask = 0xFE & temp;

I2C_infoNbytes = 0;

}

sei(); //дозвіл глобальних переривань

}

void I2C_Action()

{

switch(ReadI2C_BufOUT())

{

case 0x04: //команда СТОП

if(I2C_status & (1<<I2C_Control))

{

I2Ctask++;

if(I2C_infoNtask!=0) // якщо адреса задачі не 0

{

WriteI2C_BUFinf(I2C_infoNtask); // запис в інфобуфер №задачі

WriteI2C_BUFinf(I2C_infoNbytes);// запис в інфобуфер к-сть прийнятих байт

}

}

// перевіряємо на спорожнення буфера

if(I2C_StartBufOUT==I2C_EndBufOUT)

{

I2C_status &= ~(1<<I2C_Proccess); // TWI вільний

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTO|1<<TWEN|1<<TWIE; // Stop

}

else

{

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTO|1<<TWEN; //команда Stop

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE; //Start

I2C_StartBufOUTtemp=I2C_StartBufOUT;

unsigned char temp = ReadI2C_BufOUT();

if(temp & 0x01) I2C_status |= 1<<I2C_Control;

else I2C_status &= ~(1<<I2C_Control);

I2C_infoNtask = 0xFE & temp;

I2C_infoNbytes = 0;

}

break;

case 0x10: //команда ReStart

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE; break;

case 0x20: //передача адреси на шину I2C

case 0x40: //запис байту даних на шину I2C

TWDR = ReadI2C_BufOUT();

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE; break;

//читання байту даних на шині I2C

case 0x80: TWCR = 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE; break;

case 0x81: TWCR = 1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE; break;

}

}

ISR(TWI_vect)

{

switch(TWSR & 0b11111000)

{

//================== у режимі Master =====================================

case 0x08: //був сформований СТАРТ

case 0x10: //був сформований Повторний СТАРТ

case 0x18: //була передана адреса+Write та отримано ACK

case 0x28: //була переданий байт даних та отримано ACK

case 0x40: //була передана адреса+Read та отримано ACK

I2C_Action(); break;

case 0x50: //був прочитаний байт та передано ACK

case 0x58: //був прочитаний байт та передано NACK

WriteI2C_BufIN(TWDR); I2C_infoNbytes++; I2C_Action(); break;

case 0x20: //була передана адреса+Write та отримано NACK

case 0x30: //був переданий байт даних та отримано NACK

case 0x48: //була передана адреса+Read та отримано NACK

I2C_status |= 1<<I2C_NACKer; // помилка: NACK

I2C_SearchStartStop(); I2C_Action(); break;

case 0x38: //втрата пріоритету

I2C_StartBufOUT=I2C_StartBufOUTtemp; //відновл. поч. у буфері

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE;

ReadI2C_BufOUT();

break;

//================== у режимі Slave =====================================

case 0x68: //втрата пріоритету ->прийн. власну адресу+W та відісл. ACK

case 0x78: //втрата пріоритету ->прийн. заг. виклик+W та відісл. ACK

I2C_StartBufOUT=I2C_StartBufOUTtemp; //відновл. поч. у буфері

case 0x60: //прийнято власну адресу+W та відіслано ACK

case 0x70: //прийнято загальний виклик+W та відіслано ACK

I2C_status |= 1<<I2C_Proccess; // TWI зайнятий

I2C_status |= 1<<I2C_AddressW; // прийнято адресу+W

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE; //Slave готовий

break;

case 0x88: //прийнято байт даних та відіслано NACK

case 0x98: //прийнято байт даних та відіслано NACK (загальний виклик)

case 0x80: //прийнято байт даних та відіслано ACK

case 0x90: //прийнято байт даних та відіслано ACK (загальний виклик)

if( I2C_status & (1<<I2C_AddressW) )

{ //якщо попередньою була адреса МК

I2C_status &= ~(1<<I2C_AddressW); //скид біта

I2C_commandtemp=TWDR;

if(I2C_commandtemp>=I2C_BUFdataSIZE)

{

WriteI2C_BUFinf(I2C_Task_Slave_command);

WriteI2C_BufIN(TWDR);

I2Ctask++;

}

else

I2C_AutoincBUFdataLib=I2C_commandtemp;

}

else // прийом байту даних

{

if(I2C_commandtemp>=I2C_BUFdataSIZE)

{

WriteI2C_BUFinf(I2C_Task_Slave_byte); WriteI2C_BufIN(TWDR);

I2Ctask++;

}

else WriteI2C_BUFdataLib(TWDR);

}

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE;

break;

case 0xA0: // Stop або ReStart у режимі slave

if(I2C_StartBufOUT!=I2C_EndBufOUT) //якщо вих. буфер не порожн

{

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE;

}

else

{

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE; //Slave готовий

I2C_status &= ~(1<<I2C_Proccess); // TWI вільний

}

break;

case 0xB0: // втрата пріоритету ->прийн власну адресу+R та відісл ACK

I2C_StartBufOUT=I2C_StartBufOUTtemp; //відновл. поч. у буфері

case 0xA8: // прийнято власну адресу+R та відіслано ACK

I2C_status |= 1<<I2C_Proccess; // TWI зайнятий

TWDR = ReadI2C_BUFdataLib();

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE;

break;

case 0xB8: // був переданий байт даних та отрим. ACK

TWDR = ReadI2C_BUFdataLib();

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE;

break;

case 0xC0: // був переданий байт даних та отрим. NACK

if(I2C_StartBufOUT!=I2C_EndBufOUT) //якщо вих буфер не порожній

{

TWCR = 1<<TWEA|1<<TWINT|1<<TWSTA|1<<TWEN|1<<TWIE;

}

else

{

TWCR = 1<<TWEA|1<<TWINT|1<<TWEN|1<<TWIE; //Slave готовий

I2C_status &= ~(1<<I2C_Proccess); // TWI вільний

}

break;

}

}

Додаток Б

Лістинг програми МК ATmega32A для дослідження роботи

I2C-інтерфейсу в мультимайстерному режимі

//=========== LCD Define ======================================

#define LCDPORT PORTA // LCD Data Port 0..3

#define LCDPIN PINA

#define LCDDDR DDRA

//=========== I2C Define ======================================

#define I2CPORT PORTC

#define I2CDDR DDRC

#define SCLpin PC0

#define SDApin PC1

//#define F_CPU 8000000L

//100KHz (8MHz)

#define I2Cspeed 100000L

//=============================================================

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#include <stdlib.h>

#include "LCD_4.h"

#include "I2Cmultimaster.h"

void Initializer();

void BCDplus1(unsigned char *bcd);

void LCDout();

void TimeStampToLCD();

void TestValueToLCD();

char Sbuf[10];

unsigned char second, minute, hour, logicEdit=0, change=0, temp_minute;

unsigned char tenchar[10] ={'0','1','2','3','4','5','6','7','8','9'};

#define Master 0

#define adressEEPROM (0b1010100|Master)

#define adressI2c (0x78|Master)

unsigned char test1, test2, test3, switchvalue;

//-------------Вектор переривань таймера 1 ----------------------------------

ISR(TIMER1_COMPA_vect)

{

if(logicEdit==0)

{

I2C_Start(I2C_Task_1|CONTROL);

I2C_Address(0b1010000, I2C_W);

I2C_SendByte(0x02);

I2C_ReStart();

I2C_Address(0b1010000, I2C_R);

I2C_ReadByte(ACK); //читаємо секунди

I2C_ReadByte(ACK); //читаємо хвилини

I2C_ReadByte(NACK); //читаємо годину

I2C_Stop();

}

}

void main()

{

Initializer();

// заповнення буфера даних

WriteI2C_BUFdata_adr(0,0x12); //testvalue1

WriteI2C_BUFdata(0x34); //testvalue2

WriteI2C_BUFdata(0x56); //testvalue3

sei();

// зчитування поточного часу з EEPROM

I2C_Start(CONTROL);

I2C_Address(adressEEPROM, I2C_W);

I2C_SendByte(0x80);

I2C_ReStart();

I2C_Address(adressEEPROM, I2C_R);

I2C_ReadByte(ACK); //читаємо секунди

I2C_ReadByte(ACK); //читаємо хвилини

I2C_ReadByte(NACK); //читаємо годину

I2C_Stop();

// очікуємо кінця сеансу читання з I2C-шини

while(I2Ctask==0) { }

I2Ctask--;

// читаємо з вхідного буфера значення часу

second=ReadI2C_BufIN();

minute=ReadI2C_BufIN();

hour=ReadI2C_BufIN();

if( (second&0xF0) >= 0x60 || (second&0x0F) >= 0x0A )

second = 0;

if( (minute&0xF0) >= 0x60 || (minute&0x0F) >= 0x0A )

minute = 0;

if( (hour&0xE0) == 0 && (hour&0x0F) >= 0x0A || hour == 2 && (hour&0x0F) >= 0x04 || (hour&0xF0) >= 0x30)

hour = 0;

temp_minute = minute;

// запис у годинник значення часу з EEPROM

I2C_Start(NOCONTROL);

I2C_Address(0b1010000, I2C_W);

I2C_SendByte(0x02);

I2C_SendByte(second);

I2C_SendByte(minute);

I2C_SendByte(hour);

I2C_Stop();

unsigned char freePIN=1, key=1, edit=0;

unsigned char Ntask, Nbytes;

unsigned char SlaveCommand;

while (1) //основний робочий цикл

{

WriteI2C_BUFdata_noinc(3,PIND&0x7F);// занесення в буфер даних значення switch

if(I2Ctask)

{

I2Ctask--;

// розбирання поточної задачі у вхідному буфері TWI

Ntask = ReadI2C_BUFinf();

if(Ntask==I2C_Task_1)

{

second=ReadI2C_BufIN();

minute=ReadI2C_BufIN();

hour=ReadI2C_BufIN();

LCDout();

Nbytes= ReadI2C_BUFinf();

}

else

if(Ntask==I2C_Task_2)

{

test1=ReadI2C_BufIN();

test2=ReadI2C_BufIN();

test3=ReadI2C_BufIN();

switchvalue=ReadI2C_BufIN();

TestValueToLCD();

Nbytes= ReadI2C_BUFinf();

}

else

if( Ntask == I2C_Task_Slave_command )

{

SlaveCommand=ReadI2C_BufIN();

if(SlaveCommand==51)

{

TimeStampToLCD();

}

//else ...

}

else

if( Ntask == I2C_Task_Slave_byte )

{

}

}

if(edit) {LCDout(); edit=0;}

if(temp_minute != minute)

{ // запис в EEPROM поточного часу

temp_minute = minute;

I2C_Start(NOCONTROL);

I2C_Address(adressEEPROM, I2C_W);

I2C_SendByte(0x80);

I2C_SendByte(second);

I2C_SendByte(minute);

I2C_SendByte(hour);

I2C_Stop();

}

if(freePIN == 1) //перевірка чи була натиснута кнопка

{ //якщо =1, тоді ще не натисалася

if(PINB != 0xFF)

{

freePIN = 0;

PORTD |= 1<<7; //включаємо бузер

if(bit_is_clear(PINB,0)) //у режим редагування

{

logicEdit^=1;

LCD_GotoYX(1,10);

if(logicEdit==1)

LCD_WriteStr("Edit");

else

{

LCD_WriteStr(" ");

if(change==1)

{ // запис у годинник

I2C_Start(NOCONTROL);

I2C_Address(0b1010000, I2C_W);

I2C_SendByte(0x02);

I2C_SendByte(second);

I2C_SendByte(minute);

I2C_SendByte(hour);

I2C_Stop();

// запис в EEPROM поточного часу

temp_minute = minute;

I2C_Start(NOCONTROL);

I2C_Address(adressEEPROM, I2C_W);

I2C_SendByte(0x80);

I2C_SendByte(second);

I2C_SendByte(minute);

I2C_SendByte(hour);

I2C_Stop();

}

}

change=0;

}

else

if(bit_is_clear(PINB,1)) //змінюємо години

{

if(logicEdit==1)

{

change=1;

BCDplus1(&hour);

if(hour==0x24) hour=0;

edit=1;

}

}

else

if(bit_is_clear(PINB,2)) //змінюємо хвилини

{

if(logicEdit==1)

{

change=1;

BCDplus1(&minute);

if(minute==0x60) minute=0;

edit=1;

}

}

else

if(bit_is_clear(PINB,3)) //обнулюємо секунди

{

if(logicEdit==1)

{

change=1;

second=0;

edit=1;

}

}

else

if(bit_is_clear(PINB,6)) // відправити іншому МК часовий штамп

{

I2C_Start(NOCONTROL);

I2C_Address(adressI2c^1, I2C_W);

I2C_SendByte(4);

I2C_SendByte(adressI2c);

I2C_SendByte(second);

I2C_SendByte(minute);

I2C_SendByte(hour);

I2C_ReStart();

I2C_Address(adressI2c^1, I2C_W);

I2C_SendByte(51); // команда для виводу на LCD

I2C_Stop();

}

else

if(bit_is_clear(PINB,7)) // прочитати з іншого МК значення з буфера даних

{

I2C_Start(I2C_Task_2|CONTROL);

I2C_Address(adressI2c^1, I2C_W);

I2C_SendByte(0x00);

I2C_ReStart();

I2C_Address(adressI2c^1, I2C_R);

I2C_ReadByte(ACK); //читаємо testvalue1

I2C_ReadByte(ACK); //читаємо testvalue2

I2C_ReadByte(ACK); //читаємо testvalue3

I2C_ReadByte(NACK); //читаємо switchvalue

I2C_Stop();

}

_delay_ms(300); //затримка для бузера

PORTD &= ~(1<<7); //виключаємо бузер

key=1;

}

}

else

if(PINB == 0xFF) //перевіряємо чи кнопка відпущена

{

_delay_ms(200);

freePIN=1;

}

}

}

void Initializer() //Ініціалізація заліза

{

//Ініціалізація портів

//Порт A

DDRA = 0x00;

PORTA = 0xFF;

//Порт B

DDRB = 0x00;

PORTB = 0xFF;

//Порт С -- I2C

DDRC = 0x00;

PORTC = 0xFF;

//Порт D

DDRD = 0b10000000;

PORTD = 0b01111111;

//Ініціалізація LCD

InitLCD();

//Ініціалізація Таймера#1

//Режим: Скид При Співпадінні OCR1A (0.5sec) + дільник=256

OCR1AH = 0x3D;

OCR1AL = 0x08;

TCCR1A = 0x00;

TCCR1B = (1<<WGM12)|(1<<CS12);

//дозвіл на переривання по співпадінню T1

TIMSK |= 1<<OCIE1A;

//Ініціалізація I2C

//100KHz (8MHz)

I2C_Init(adressI2c,0);

// вивід адреси МК на дисплей

LCD_GotoYX(1,15);

LCD_WriteStr( utoa(adressI2c ,Sbuf,16) );

}

void BCDplus1(unsigned char *bcd)

{

unsigned char bcdl=(*bcd)&0x0F, bcdh=(*bcd)>>4;

bcdl++;

if(bcdl==10)

{ bcdl=0; bcdh++; }

*bcd = (bcdh<<4) | bcdl;

}

void LCDout()

{

LCD_GotoYX(1,1);

LCD_WriteLetter(tenchar[hour >> 4]);

LCD_WriteLetter(tenchar[hour & 0x0F]);

LCD_WriteLetter(':');

LCD_WriteLetter(tenchar[minute >> 4]);

LCD_WriteLetter(tenchar[minute & 0x0F]);

LCD_WriteLetter(':');

LCD_WriteLetter(tenchar[second >> 4]);

LCD_WriteLetter(tenchar[second & 0x0F]);

}

void TimeStampToLCD()

{

unsigned char second_buf, minute_buf, hour_buf, master_buf;

master_buf=ReadI2C_BUFdata_adr(4);

second_buf=ReadI2C_BUFdata();

minute_buf=ReadI2C_BUFdata();

hour_buf=ReadI2C_BUFdata();

LCD_GotoYX(2,1);

LCD_WriteStr( utoa(master_buf ,Sbuf,16) );

LCD_WriteLetter('>');

LCD_WriteLetter(tenchar[hour_buf >> 4]);

LCD_WriteLetter(tenchar[hour_buf & 0x0F]);

LCD_WriteLetter(':');

LCD_WriteLetter(tenchar[minute_buf >> 4]);

LCD_WriteLetter(tenchar[minute_buf & 0x0F]);

LCD_WriteLetter(':');

LCD_WriteLetter(tenchar[second_buf >> 4]);

LCD_WriteLetter(tenchar[second_buf & 0x0F]);

LCD_WriteLetter(' ');

LCD_WriteLetter(' ');

LCD_WriteLetter(' ');

LCD_WriteLetter(' ');

LCD_WriteLetter(' ');

}

void TestValueToLCD()

{

LCD_GotoYX(2,1);

LCD_WriteStr( utoa(test1 ,Sbuf,16) );

LCD_WriteLetter('-');

LCD_WriteStr( utoa(test2 ,Sbuf,16) );

LCD_WriteLetter('-');

LCD_WriteStr( utoa(test3 ,Sbuf,16) );

LCD_WriteLetter('-');

LCD_WriteStr( utoa(switchvalue ,Sbuf,2) );

}

Размещено на Allbest.ru


Подобные документы

  • Проектування та реалізація бази даних на фізичному рівні. Формування сутності з їх атрибутами. Вибір засобів розробки даного програмного забезпечення. Створення інтерфейсу для роботи з базою даних. Інструкція користувача, головне функціональне вікно.

    курсовая работа [1,7 M], добавлен 26.09.2013

  • Аналіз технічного забезпечення, вибір інструментального програмного забезпечення та середовища розробки програм. Створення класів для реалізації необхідних функцій для роботи програмного засобу. Розробка інтерфейсу для користувача та лістинг програми.

    курсовая работа [343,9 K], добавлен 24.08.2012

  • Порядок обміну даними через порт принтера (інтерфейсу Centronics). Розряди паралельного порту. Особливості протоколів та типів паралельного порту. Фізичні характеристики передавачів і приймачів сигналів. Проектування апаратури для спряження з Centronics.

    реферат [204,3 K], добавлен 19.06.2010

  • Характеристика та відмінні ознаки динамічних структур даних, особливості та умови їх застосування. Переваги роботи з даними такого типу. Опис структури даних "двохзв’язний список", етапи її розробки, функціональні особливості, інструкція з використання.

    контрольная работа [28,3 K], добавлен 24.09.2010

  • Визначення вимог до програмного забезпечення. Проектування архітектури програми, структури даних та інтерфейсу. Програмування графічного редактора, специфікація його класів та алгоритм роботи. Зміна архітектури редактора згідно нових вимог замовника.

    дипломная работа [1,2 M], добавлен 05.01.2014

  • Теоретичні відомості про пакет ІЗВП Borland Delphi та СУБД MS Access, оцінка їх функціональних особливостей. Опис структури бази даних. Проектування інтерфейсу програми, опис її логічної структури та функцій. Контроль коректності вхідних, вихідних даних.

    курсовая работа [4,5 M], добавлен 03.01.2014

  • Системний аналіз бази даних за вхідною та вихідною документацією, визначення сутностей, атрибутів, зв’язків. Створення логічної моделі бази даних із застосуванням нормалізації, алгоритм її роботи. Розробка програмного забезпечення та інтерфейсу СУБД.

    курсовая работа [946,8 K], добавлен 02.07.2015

  • Побудова інформаційно-математичної моделі задачі. Визначення структури даних. Розробка інтерфейсу програми з користувачем. Реалізація проекту у візуальному середовищі. Аналіз та тестування програми. Розгляд результатів та інструкція з експлуатації.

    курсовая работа [4,2 M], добавлен 07.05.2009

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

    курсовая работа [594,1 K], добавлен 09.04.2013

  • Загальна характеристика існуючих методів обміну даними між компонентами MS Office, їх властивості та напрямки використання. Формат даних, що вставляються з буфера обміну. Відмінності у властивостях створених, впроваджених та вставлених даних.

    курсовая работа [190,2 K], добавлен 07.02.2003

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.