Побудова модуля управління системи контролю доступу на AVR-мікроконтролерах. Робота з інтерфейсами 1-Wire, I2C, SPI

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Кафедра захисту інформації

Інформація про роботу

Рік:
2010
Тип роботи:
Лабораторна робота
Предмет:
Інші
Група:
ІБ-43
Варіант:
29

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА» Кафедра ЗІ  Лабороторна робота №5 Побудова модуля управління системи контролю доступу на AVR-мікроконтролерах. Робота з інтерфейсами 1-Wire, I2C, SPI з курсу "МІКРОПРОЦЕСОРНІ ПРИСТРОЇ" Варіант № 29 Виконала: ст. гр. ІБ-43 Прийняла: - Львів-2010 Мета роботи: – ознайомитись з принципами побудови модулів управління систем контролю доступу. Вивчити правила обміну інформацією через інтерфейси 1-Wire, I2C, SPI та ознайомитися з їх програмною реалізацією для AVR-мікроконтролерів на мові С в середовищі CodeVisionAVR. Завдання: Вивчити теоретичний матеріал. Вивчити основні властивості інтерфейсів 1-Wire, I2C, SPI та правила обміну даними по них, принципи роботи з мікросхемами DS1990A, DS1307, 25LC256, принципи побудови та функціонування СКД необхідні для виконання лабораторної роботи. Підготовити програму функціонування модуля управління СКД згідно індивідуального завдання в табл. 8. Алгоритм функціонування модуля управління СКД аналогічний описаному в пункті 2. - 90 5 6 Номер ключа, число, година, хвилина, тип події (вхід/вихід) 22.09.09 11:45:19   Текст програми #include <90S2313.h> #include <delay.h> // Підтримка 1-Wire інтерфейсу #asm .equ __w1_port=0x18 // Для підкл. iButton викор. PORTB .equ __w1_bit=5 // Вивід 5 - РВ5 #endasm #include <1wire.h> // Підтримака І2С інтерфейсу #asm .equ __i2c_port=0x18 // Для інтерфейсу I2C використовується PORTB .equ __sda_bit=1 // SDA = PB1 .equ __scl_bit=2 // SCL = PB2 #endasm #include <i2c.h> // SPI Settings //#define SPI PORTD #define NCS 3 //PD3 #define SCLK 4 //PD4 #define MOSI 5 //PD5 #define MISO 6 //PD6 // адреса масиву легальних ключів #define REG_KEY_ADDR 16 // адрера початку журналу #define EVENT_LIST 0x60 // максимальна кількість записів в журналі #define MAX_EVENTS 95 // маска для вибору необхідних даних з ГРЧ #define MASK 0b01110000 // час відкриття дверей (cек.) #define OPEN_TIME 10 typedef unsigned char BYTE; // структура одного запису реєстраційного журналу struct RegRec { unsigned char ID[8]; // ідентифікатор користувача BYTE date[3]; // 0 - дата, 1 - місяць, 2 - рік unsigned char type; // 1 - вхід, 0 - вихід } event; // передача одного байту через SPI // повертає отриманий байт BYTE SPI_SendByte(BYTE data) { BYTE temp, res = 0, mask = 0x80; while(mask) { // зберігаємо біт що поступив на вхід temp = PIND & (1<<MISO); if(temp) res|=mask; // формуємо вихідний біт PORTD.MOSI = (data & mask) && 1; #asm("nop"); delay_ms(10); PORTD.SCLK = 1; mask>>=1; PORTD.SCLK = 0; } return res; } // запис блоку даних через SPI void SPI_Write(const BYTE *buf, BYTE size, unsigned int addr) { if(!buf || !size || size>64) return ; PORTD.SCLK = 0; PORTD.NCS = 0; SPI_SendByte(0b00000110); // дозволити запис в пам'ять PORTD.NCS = 1; // завершити команду #asm("nop"); PORTD.NCS = 0; // розпочати команду SPI_SendByte(0b00000010); // код операції запису в пам'ять SPI_SendByte(addr>>8); // старший байт адреси SPI_SendByte((BYTE)addr); // молодший байт адреси // запис самих даних while(size) SPI_SendByte(*buf++), --size; PORTD.NCS = 1; } // запис блоку даних через SPI BYTE SPI_Read(BYTE *buf, BYTE size, unsigned int addr) { if(!buf || !size || size>64) return 1; PORTD.SCLK = 0; PORTD.NCS = 0; // розпочати команду SPI_SendByte(0b00000011); // код операції читання з пам'яті SPI_SendByte(addr>>8); // старший байт адреси SPI_SendByte((BYTE)addr); // молодший байт адреси // читання самих даних while(size) *buf++=SPI_SendByte(0), --size; PORTD.NCS = 1; return 0; } BYTE FindKey(const BYTE key[8]) { BYTE key_count; BYTE rKey[8],k; int addr = REG_KEY_ADDR; SPI_Read(&key_count, sizeof(key_count), REG_KEY_ADDR-1); while(key_count--) { SPI_Read(rKey, sizeof(rKey), addr); for(k=0;k<sizeof(rKey);k++) if(rKey[k]!=key[k]) break; if(k==sizeof(rKey)) return 1; addr+=sizeof(rKey); } return 0; } void RegisterEvent(BYTE key[8], BYTE type) { BYTE ev_count; // кількість записів в журналі BYTE tmp, mask; int addr = EVENT_LIST; // адреса нового запису SPI_Read(&ev_count, sizeof(ev_count), EVENT_LIST - sizeof(ev_count)); if(ev_count==MAX_EVENTS) ev_count=0; tmp = ev_count++; // знаходимо адресу для нового запису while(tmp--) addr+=sizeof(event); // записуємо кількість записів SPI_Write(&ev_count, sizeof(ev_count), EVENT_LIST-sizeof(ev_count)); // формуємо запис, копіюємо ключ for (ev_count=0;ev_count<sizeof(key);ev_count++) event.ID[ev_count]=key[ev_count]; // запитаємо рік, місяць і дату в ГРЧ while(!i2c_start()); // звертаємося до годинника реального часу while(!i2c_write(0b11010000)); while(!i2c_write(0)); // читаємо з 0 адреси while(!i2c_start()); // repeat start while(!i2c_write(0b11010001)); for(mask=1, ev_count=0; mask; mask<<=1) { tmp = i2c_read(1); if(mask & MASK) // вибираємо тільки необхідні дані event.date[ev_count++]=tmp; } i2c_stop(); // задаємо тип event.type = type; // записуємо дані в журнал SPI_Write((BYTE*)&event, sizeof(event), addr); } // Ініціалізація годинника реального часу void InitRealTimeClock() { i2c_init(); // ініціалізація I2C інтерфейсу // очікуємо на звільнення шини і формуємо умову початку передачі даних while(!i2c_start()); // звертаємося до годинника реального часу while(!i2c_write(0b11010000)); // починаємо запис з нульової комірки пам'яті while(!i2c_write(0)); // необхідно записати дату/час 13.01.09 02:58:51 while(!i2c_write(0b01010001)); // секунди 51 while(!i2c_write(0b01011000)); // хвилини 58 while(!i2c_write(0b01000010)); // години 02/24 while(!i2c_write(0b01000011)); // день тижня while(!i2c_write(0b00001001)); // дата 09 while(!i2c_write(0b00000001)); // місяць 01 while(!i2c_write(0b00001001)); // рік 09 while(!i2c_write(0)); // інші налаштування по замовчуванню i2c_stop(); //закінчуємо обмін даними } void main() { unsigned char item_key[9]; // ID поточного пристрою BYTE out_h=1; PORTD.NCS = 1; DDRD.NCS = DDRD.SCLK = DDRD.MOSI = 1; DDRB.6 = PORTB.6= 1; // вимикаємо світлодіод InitRealTimeClock(); while(1) { // опитуємо кнопку виходу if(!PIND.2 && out_h) { // оскільки при виході не стоїть зчитувач ключів // ми не можемо ідентифікувати особу - обнуляємо ключ for(out_h=0;out_h<sizeof(item_key);out_h++) item_key[out_h]=0; out_h=0; PORTB.6 = 0; // вмикаємо світлодіод // реєструємо запис в журналі RegisterEvent(item_key, 0); delay_ms(OPEN_TIME*1000); // відкриваємо двері. PORTB.6 = 1; // вимикаємо світлодіод } if(PIND.2) out_h=1; // очікуємо на підключення пристрою 1-Wire if(!w1_init()) continue; // посилаємо команду зчитування ID if(!w1_search(0xF0, item_key)) continue; // шукаємо ключ в базі доступних ключів if(!FindKey(item_key)) continue; // користувач легальний, вмикаємо світлодіод PORTB.6 = 0; // Реєструємо його в журналі RegisterEvent(item_key, 1); delay_ms(OPEN_TIME*1000); // відкриваємо двер. PORTB.6 = 1; // вимикаємо світлодіод } } Схема роботи 
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

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

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!