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

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

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

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

Рік:
2015
Тип роботи:
Лабораторна робота
Предмет:
Інші
Група:
ІБ-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; // вимикаємо світлодіод } } Схема роботи 
Антиботан аватар за замовчуванням

2015

Коментарі

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

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

Нічого не вибрано
0%

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

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

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

Admin

26.02.2023 12:38

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