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

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

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

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

Рік:
2024
Тип роботи:
Звіт до лабораторної роботи
Предмет:
Мікропроцесори

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

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”  ЗВІТ ДО ЛАБОРАТОРНОЇ РОБОТИ № 5 З КУРСУ “МІКРОПРОЦЕСОРНІ ПРИСТРОЇ” «Побудова модуля управління системи контролю доступу на AVR – мікро контролерах. Робота з інтерфейсами 1 – Wire, IC, SPI» Мета роботи: ознайомитись з принципами побудови модулів управління системи контролю доступу. Вивчити правила обміну інформацією через інтерфейси 1 – Wire, IC, SPI та ознайомитися з їх програмною реалізацією для AVR – мікроконтролерів на мові С в середовищі Code VISION AVR Завдання : 1. Створити проект в Code VISION AVR, ввести свою програму, провести її компіляцію. 2. відкрити файл LR_5.dsn в програмі Proteus, внести у схему відповідно до свого індивідуального завдання, підключити до МК отриманий в Code VISION AVR hex – файл. 3. запустити режим симуляції схеми та перевірити правильність функціонування модуля управління СКД у всіх режимах роботи: очікування, пред’явлення зареєстрованого ключа, пред’явлення незареєстрованого ключа, натискання кнопки виходу. № Кількість запитів N Кількість зареєстрованих ключів Час відкриття дверей t, сек Формат реєстраційного запису Початкова дата та час  2 40 3 5 Номер ключа, число, година, тип події (вхід/вихід) 02.02.09 13:15:27   Текст програми у Code VISION AVR // Блок управління системи контролю доступу на МК АТ90S2313 з iButton DS1990, I2C-RTC DS1307 та SPI-EEPROM 25LC256 (32Kx8) // 20.05.2009 р. // Тактова частота МК 7.3728 МГц //////////////////////////////////////////////////////////////////////////////////// // Порт для підключення iButton DS1990 #asm .equ __w1_port = 0x18 .equ __w1_bit = 5 #endasm //////////////////////////////////////////////////////////////////////////////////// // Порт для підключення I2C-RTC DS1307 #asm .equ __i2c_port = 0x18 .equ __scl_bit = 2 .equ __sda_bit = 1 #endasm //////////////////////////////////////////////////////////////////////////////////// #include <90S2313.h> #include <1wire.h> #include <i2c.h> #include <delay.h> //////////////////////////////////////////////////////////////////////////////////// // Оголошення типу даних - байт typedef unsigned char byte; //////////////////////////////////////////////////////////////////////////////////// // Структура дати і часу typedef struct { byte Second; byte Minute; byte Hour; byte Day; byte Date; byte Month; byte Year; } DS1307_Data; //////////////////////////////////////////////////////////////////////////////////// // Глобальні змінні // Оголошення змінної для збереження поточного часу і дати DS1307_Data DS1307_1; // Оголошення змінної для збереження ідентифікаційного номера iButton DS1990A byte ROM_Code[9]; //////////////////////////////////////////////////////////////////////////////////// //******************************************************************// // Виводи SPI-EEPROM 25LC256 #define PORT_EEPROM PORTD #define DDR_EEPROM DDRD #define PIN_EEPROM PIND #define CS 3 #define SCK 4 #define SI 5 #define SO 6 //******************************************************************// // Виводи I2C-RTC DS1307 #define PORT_RTC PORTB #define DDR_RTC DDRB #define PIN_RTC PINB #define SDA 1 #define SCL 2 //******************************************************************// // Виводи iButton DS1990A #define PORT_iButton PORTB #define DDR_iButton DDRB #define PIN_iButton PINB #define Data_iButton 5 //******************************************************************// // Виводи електронного замка #define PORT_Switch PORTB #define DDR_Switch DDRB #define PIN_Switch PINB #define Switch 7 //******************************************************************// // Виводи світлодіоду #define PORT_Led PORTB #define DDR_Led DDRB #define PIN_Led PINB #define Led 6 //******************************************************************// // Виводи кнопки виходу #define PORT_Out_Key PORTD #define DDR_Out_Key DDRD #define PIN_Out_Key PIND #define Out_Key 2 //******************************************************************// // Коди команд EEPROM 25LC256 #define EEPROM_READ 0x03 #define EEPROM_WRITE 0x02 #define EEPROM_WRDI 0x04 #define EEPROM_WREN 0x06 #define EEPROM_RDSR 0x05 #define EEPROM_WRSR 0x01 //******************************************************************// // Коди команд iButton DS1990 #define SEARCH_ROM 0xF0 //******************************************************************// // Адреса сімейства iButton #define DS1990_FAMILY_CODE 0x01 //******************************************************************// // Кількість подій в системі #define N_Record 55 //******************************************************************// // Розмір одного запису в байтах #define Record_Size 16 //******************************************************************// // Адреса початку записів в EEPROM 25LC256 #define Record_Addr 0x40 //******************************************************************// // Адреса лічильника записів в EEPROM #define Record_Count_Addr 0x30 //******************************************************************// // Час відкривання дверей в мілісекундах #define T_msec 5000 //******************************************************************// // Кількість зареєстрованих ключів #define N_Key 3 //******************************************************************// // Тип запису #define Input_Record 0 #define Output_Record 1 //******************************************************************// // E8C52A // 3D2C90 /*----------------------------------------------------------------*/ // Підпрограма обслуговування зовнішнього переривання по виводу INT0 interrupt [2] void ext_interrupt0(void); /*----------------------------------------------------------------*/ void Pin_Init(void); // Функції нижнього рівня роботи з РКД void DS1307_Init(void); void DS1307_Read(DS1307_Data* arg1); void DS1307_Write(DS1307_Data* arg1); byte SPI_Send_Byte(byte data); void SPI_Send_CMD1(byte cmd); byte SPI_Read_SR(void); byte SPI_Read_Data(int address, byte* buffer, byte n); byte SPI_Write_Data(int address, byte* buffer, byte n); void Save_Record(DS1307_Data* arg1, byte* code, byte type); //////////////////////////////////////////////////////////////////////////////////////////// void main(void) { byte temp, ii, jj, temp1; byte iButton_Arrary[N_Key][8]; Pin_Init(); DS1307_1.Second = 0x27; //02-02-09 13:15:27 DS1307_1.Minute = 0x15; DS1307_1.Hour = 0x13; DS1307_1.Day = 0x01; DS1307_1.Date = 0x02; DS1307_1.Month = 0x02; DS1307_1.Year = 0x09; DS1307_Init(); DS1307_Write(&DS1307_1); // Прочитати зареєстровані ключі з EEPROM-пам'ті for(ii = 0; ii < N_Key; ii++) temp = SPI_Read_Data(0x0000 + ii * 8, &iButton_Arrary[ii][0], 8); // Налаштувати зовнішнє переривання INT0 від кнопки виходу GIMSK = GIMSK | 0x40; MCUCR = MCUCR | 0x02; while(1) { #asm("cli") temp = w1_search(SEARCH_ROM, &ROM_Code[0]); if (temp == 0) { #asm("sei") } else { // Пошук for(ii = 0; ii < N_Key; ++ii) { temp1 = 0; for(jj = 0; jj < 8; ++jj) { if(ROM_Code[jj] != iButton_Arrary[ii][jj]) { temp1 = 1; break; } } if(temp1 == 0) break; } if(temp1 == 0) { DS1307_Read(&DS1307_1); Save_Record(&DS1307_1, &ROM_Code[0], Input_Record); PORT_Led.Led = 0; PORT_Switch.Switch = 1; delay_ms(T_msec); PORT_Led.Led = 1; PORT_Switch.Switch = 0; } else #asm("sei"); } delay_ms(1); }; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void DS1307_Init(void) { // Ініціалізація І2С шини та режиму роботи годинника реального часу (RTC) byte temp; temp = i2c_start(); temp = i2c_write(0xd0); temp = i2c_write(0x07); temp = i2c_write(0b00000000); i2c_stop(); }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void DS1307_Read(DS1307_Data* arg1) { // Зчитування часу та дати з RTC byte temp2; temp2 = i2c_start(); temp2 = i2c_write(0xd0); temp2 = i2c_write(0x00); i2c_stop(); temp2 = i2c_start(); temp2 = i2c_write(0xd1); arg1->Second = i2c_read(1) & 0x7F; arg1->Minute = i2c_read(1) & 0x7F; arg1->Hour = i2c_read(1) & 0x3F; arg1->Day = i2c_read(1) & 0x07; arg1->Date = i2c_read(1) & 0x3F; arg1->Month = i2c_read(1) & 0x1F; arg1->Year = i2c_read(0); i2c_stop(); }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void DS1307_Write(DS1307_Data* arg1) { // Запич часу та дати в RTC byte temp2; temp2 = i2c_start(); temp2 = i2c_write(0xd0); temp2 = i2c_write(0x00); temp2 = i2c_write(arg1->Second); temp2 = i2c_write(arg1->Minute); temp2 = i2c_write(arg1->Hour | 0b00000000); temp2 = i2c_write(arg1->Day); temp2 = i2c_write(arg1->Date); temp2 = i2c_write(arg1->Month); temp2 = i2c_write(arg1->Year); i2c_stop(); }; //////////////////////////////////////////////////////////////////////////////////////////////////////// byte SPI_Send_Byte(byte data) { byte ii, temp, result = 0, temp1 = 0x80; for(ii = 0; ii < 8; ++ii) { temp = PIN_EEPROM; temp = temp & (1<<SO); if(temp != 0) result = result | temp1; PORT_EEPROM.SI = (data & temp1) && 1; #asm("nop"); PORT_EEPROM.SCK = 1; temp1 = temp1 >> 1; PORT_EEPROM.SCK = 0; } return result; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void Pin_Init(void) { PORT_EEPROM.CS = 1; PORT_EEPROM.SCK = 0; PORT_EEPROM.SI = 0; PORT_EEPROM.SO = 0; DDR_EEPROM.CS = 1; DDR_EEPROM.SCK = 1; DDR_EEPROM.SI = 1; DDR_EEPROM.SO = 0; PORT_Switch.Switch = 0; DDR_Switch.Switch = 1; PORT_Led.Led = 1; DDR_Led.Led = 1; PORT_Out_Key.Out_Key = 0; DDR_Out_Key.Out_Key = 0; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// byte SPI_Write_Data(int address, byte* buffer, byte n) { byte ii, result; PORT_EEPROM.CS = 0; SPI_Send_Byte(EEPROM_WRITE); SPI_Send_Byte(address>>8); SPI_Send_Byte(address); for(ii = 0; ii < n; ++ii) { SPI_Send_Byte(buffer[ii]); } PORT_EEPROM.SI = 0; PORT_EEPROM.CS = 1; return result; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// byte SPI_Read_Data(int address, byte* buffer, byte n) { byte ii, result; PORT_EEPROM.CS = 0; SPI_Send_Byte(EEPROM_READ); SPI_Send_Byte(address>>8); SPI_Send_Byte(address); for(ii = 0; ii < n; ii++) { buffer[ii] = SPI_Send_Byte(0); } PORT_EEPROM.SI = 0; PORT_EEPROM.CS = 1; return result; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void SPI_Send_CMD1(byte cmd) { PORT_EEPROM.CS = 0; SPI_Send_Byte(cmd); PORT_EEPROM.SI = 0; PORT_EEPROM.CS = 1; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// byte SPI_Read_SR(void) { byte temp; PORT_EEPROM.CS = 0; temp = SPI_Send_Byte(EEPROM_RDSR); temp = SPI_Send_Byte(0); PORT_EEPROM.SI = 0; PORT_EEPROM.CS = 1; return temp; }; //////////////////////////////////////////////////////////////////////////////////////////////////////// interrupt [2] void ext_interrupt0(void) { byte ii; delay_ms(10); if(PIN_Out_Key.Out_Key == 0) { DS1307_Read(&DS1307_1); for(ii = 0; ii < 8; ++ii) ROM_Code[ii] = 0; Save_Record(&DS1307_1, &ROM_Code[0], Output_Record); PORT_Led.Led = 0; PORT_Switch.Switch = 1; delay_ms(T_msec); PORT_Led.Led = 1; PORT_Switch.Switch = 0; } }; //////////////////////////////////////////////////////////////////////////////////////////////////////// void Save_Record(DS1307_Data* arg1, byte* code, byte type) { byte temp, temp1, temp2[2]; int start; while((temp = SPI_Read_SR()) & 0x01) // Очікувати готовності EEPROM ; // Прочитати значення лічильника подій в змінну temp1 temp = SPI_Read_Data(Record_Count_Addr, &temp1, 1); if(temp1 == N_Record) // Якщо досягнуто максимального значення { temp1 = 1; // Почати заново start = Record_Addr; } else // Інакше обчислити адресу наступного запису { start = Record_Addr + Record_Size * (int)temp1; temp1++; // Збільшити кількість записів на 1 } SPI_Send_CMD1(EEPROM_WREN); // Дозволити запис в EEPROM while((temp = SPI_Read_SR()) & 0x01) // Очікувати готовності EEPROM ; // Записати 8 байт ідентифікаційного номеру DS1990A temp = SPI_Write_Data(start, code, 8); while((temp = SPI_Read_SR()) & 0x01) // Очікувати готовності EEPROM ; SPI_Send_CMD1(EEPROM_WREN); // Дозволити запис в EEPROM while((temp = SPI_Read_SR()) & 0x01) // Очікувати готовності EEPROM ; temp2[0] = arg1->Hour; temp2[1] = arg1->Date; temp = SPI_Write_Data(start + 8, temp2, 2); while((temp = SPI_Read_SR()) & 0x01) ; SPI_Send_CMD1(EEPROM_WREN); while((temp = SPI_Read_SR()) & 0x01) ; temp = SPI_Write_Data(start + 15, &type, 1); while((temp = SPI_Read_SR()) & 0x01) ; SPI_Send_CMD1(EEPROM_WREN); while((temp = SPI_Read_SR()) & 0x01) ; temp = SPI_Write_Data(Record_Count_Addr, &temp1, 1); }; Схема симуляції у Proteus 7  Висновок на даній лабораторній роботі я ознайомилася з принципами побудови модулів управління систем контролю доступу , вивчила правила обміну інформацією через інтерфейси 1 – Wire, IC, SPI та ознайомилася з їх програмною реалізацією для AVR – мікроконтролерів на мові С в середовищі Code VISION AVR
Антиботан аватар за замовчуванням

20.09.2012 21:09-

Коментарі

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

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

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

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

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

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

Admin

26.02.2023 12:38

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