Ми знаємо в офісах, торгових центрах та в багатьох інших місцях, де в кімнату допускається лише особа, що має авторизаційну картку. Ці системи використовують систему зв'язку RFID. RFID використовується в торгових центрах, щоб зупинити крадіжку, оскільки продукти позначаються мікросхемою RFID, а коли людина виходить із будівлі з мікросхемою RFID, автоматично спрацьовує сигнал тривоги. Тег RFID розроблений настільки маленький, як частина піску. Системи аутентифікації RFID легко спроектувати і дешеві за вартістю. Сьогодні деякі школи та коледжі використовують системи відвідування на основі RFID.
У цьому проекті ми плануємо розробити машину для голосування, яка підраховує лише підтверджені голоси. Це робиться за допомогою тегів RFID (ідентифікація радіочастот). Тут ми збираємося написати програму для ATMEGA, щоб дозволити голосувати лише уповноваженим власникам тегів RFID. (Також перевірте цей простий проект машини для голосування)
Потрібні компоненти
Апаратне забезпечення: ATMEGA32, блок живлення (5 в), AVR-ISP PROGRAMMER, JHD_162ALCD (16x2LCD), конденсатор 100 мкФ (підключений через блок живлення), кнопка (п’ять штук), резистор 10 кОм (п’ять штук), конденсатор 100 нФ (п’ять штук), світлодіод (дві штуки), EM-18 (модуль зчитування RFID).
Програмне забезпечення: Atmel studio 6.1, progisp або flash magic.
Принципова схема та пояснення
У ланцюзі PORTA ATMEGA32 підключений до порту даних РК-дисплея. Тут слід пам’ятати про те, щоб вимкнути зв'язок JTAG у PORTC на ATMEGA, змінивши байти запобіжників, якщо потрібно використовувати PORTC як звичайний порт зв'язку. У РК-дисплеї 16x2 є 16 висновків, якщо є чорне світло, якщо немає підсвічування, буде 14 висновків. Можна підключити або залишити шпильки підсвічування. Тепер у 14 висновках є 8 висновків даних (7-14 або D0-D7), 2 висновки джерела живлення (1 & 2 або VSS & VDD або gnd & + 5v), 3- й висновок для контролю контрасту (VEE-контролює, наскільки товстими повинні бути символи показано), 3 керуючі штифти (RS & RW & E)
У схемі ви можете помітити, що я взяв лише два керуючі штифти, це дає гнучкість для кращого розуміння, біт контрасту та READ / WRITE не часто використовуються, тому їх можна замикати на землю. Це дає РК-дисплею найвищий контраст і режим читання. Нам просто потрібно контролювати ENABLE та RS-шпильки, щоб відповідно надсилати символи та дані.
Підключення, які виконуються для РК-дисплея, наведені нижче:
PIN1 або VSS на землю
PIN2 або VDD або VCC до + 5 В потужності
PIN3 або VEE на землю (забезпечує максимальний контраст найкращий для початківця)
PIN4 або RS (реєстрація вибору) до PD6 uC
PIN5 або RW (читання / запис) на землю (переведення РК в режим читання полегшує зв'язок для користувача)
PIN6 або E (увімкнути) для PD5 uC
PIN7 або D0 до PA0 uC
PIN8 або D1 до PA1 uC
PIN9 або D2 до PA2 uC
PIN10 або D3 до PA3 uC
PIN11 або D4 до PA4 uC
PIN12 або D5 до PA5 uC
PIN13 або D6 до PA6 з UC
PIN14 або D7 до PA7 uC
У схемі ви можете бачити, що ми використовували 8-бітний зв'язок (D0-D7). Однак це не є обов'язковим, і ми можемо використовувати 4-бітний зв'язок (D4-D7), але з 4-бітовою програмою зв'язку стає трохи складнішою, тому я віддав перевагу 8-бітовому зв'язку.
Отже, з простого спостереження за наведеною таблицею ми підключаємо 10 висновків РК-дисплея до контролера, в якому 8 висновків - це висновки для даних і 2 висновки для управління.
Перш ніж рухатися вперед, нам слід зрозуміти послідовний зв’язок. Тут модуль RFID послідовно надсилає дані на контролер. Він має інший режим зв'язку, але для зручності спілкування ми обираємо RS232. Контакт модуля RS232 підключений до контакту RXD ATMEGA.
Дані, що надсилаються модулем RFID, виглядають так:
Тепер для інтерфейсу модуля RFID потрібні такі функції:
1. Штифт RXD (функція отримання даних) контролера повинен бути ввімкнений.
2. Оскільки зв’язок є послідовним, нам потрібно знати, коли отримуються дані до побачення, щоб ми могли зупинити програму до отримання повного байта. Це робиться, дозволяючи даним отримувати повне переривання.
3. RFID передає дані контролеру в 8-бітному режимі. Отже, два символи будуть надіслані контролеру одночасно. Це показано в блоці на малюнку3
4. З малюнка 3 в даних, що передаються модулем, немає бітів парності, один стоп-біт.
Вищевказані функції встановлені в регістрах контролерів; ми їх коротко обговоримо,
ЧЕРВОНИЙ (RXEN): Цей біт представляє функцію прийому даних, цей біт повинен бути встановлений для того, щоб дані з модуля приймалися контролером, він також дозволяє RXD-штифт контролера.
BROWN (RXCIE): Цей біт повинен бути встановлений для отримання переривання після успішного прийому даних. Увімкнувши цей біт, ми дізнаємось одразу після отримання 8-бітових даних.
PINK (URSEL): цей біт повинен бути встановлений перед увімкненням інших бітів в UCSRC, після встановлення інших необхідних бітів в UCSRC; URSEL потрібно відключити або встановити на нуль.
ЖОВТИЙ (UCSZ0, UCSZ1, UCSZ2): Ці три біти використовуються для вибору кількості бітів даних, які ми отримуємо або надсилаємо за один прийом.
Оскільки дані, що надсилаються модулем RFID, мають 8-бітний тип даних (ФІГ.3), ми повинні встановити UCSZ0, UCSZ1 на одиницю, а UCSZ2 на нуль.
ОРАНЖЕВИЙ (UMSEL): цей біт встановлюється на основі того, чи система взаємодіє асинхронно (обидва використовують різні годинники) або синхронно (обидва використовують однакові годинники),
Оскільки модуль і контролер використовують різні тактові частоти, цей біт потрібно встановити на нуль або залишити в спокої, оскільки всі вони встановлюються на нуль за замовчуванням.
ЗЕЛЕНИЙ (UPM1, UPM0): Ці два біти регулюються залежно від паритету бітів, який ми використовуємо в спілкуванні.
Оскільки модуль RFID надсилає дані без паритету (РИСУНОК 3), ми встановили як UPM1, UPM0 на нуль, так і їх можна залишити в спокої, оскільки всі біти в будь-яких регістрах за замовчуванням встановлені на нуль.
СИНІЙ (USBS): Цей біт використовується для вибору кількості стопових бітів, які ми використовуємо під час зв’язку.
Оскільки модуль RFID надсилає дані з одним стоповим бітом (малюнок 3), нам просто потрібно залишити біт USBS у спокої.
Нарешті, нам потрібно встановити швидкість передачі даних, з малюнка 3 стає зрозуміло, що модуль RFID передає дані контролеру зі швидкістю передачі даних 9600 біт / с.
Швидкість передачі даних встановлюється в контролері, вибираючи відповідний UBRRH,
Значення UBRRH вибирається шляхом швидкості передачі в боді та частоти кристалів процесора,
Отже, за перехресним посиланням значення UBRR розглядається як '6', і тому швидкість передачі даних встановлюється.
Тут є п’ять кнопок, чотири - для збільшення голосів кандидатів, а п’ята - для скидання голосів кандидатів до нуля. Конденсатори, присутні тут, призначені для анулювання ефекту підстрибування кнопок. Якщо їх видалити, контролер може рахувати більше одного при кожному натисканні кнопки.
Резистори, підключені для штифтів, призначені для обмеження струму, коли натискається кнопка, щоб опустити штифт на землю. Кожного разу, коли натискається кнопка, відповідний штифт контролера опускається на землю, і, таким чином, контролер розпізнає, що натискається певна кнопка і здійснюються відповідні дії, це може бути збільшення голосів кандидатів або скидання голосів залежно від натиснутої кнопки.
Коли натискається кнопка, що представляє відповідну особу, контролер вибирає її та збільшує номер відповідної особи всередині своєї пам'яті після збільшення, на якій відображається оцінка відповідних осіб на РК-дисплеї 16x2.
Робота машини для голосування найкраще пояснюється поетапно кодом С, наведеним нижче:
Пояснення коду
#include // заголовок, щоб увімкнути управління потоком даних над штифтами
#define F_CPU 1000000 // повідомляється прикріплена частота кристала контролера
#включати
#define E 5 // даючи назву “enable” 5- му виводу PORTD, оскільки він підключений до вимикача включення РК
#define RS 6 // даючи назву “registerselection” 6- му контакту PORTD, оскільки підключений до LCD RS-контакту
void send_a_command (команда без знака char);
void send_a_character (символ без підпису);
void send_a_string (char * string_of_characters);
int main (void)
{
DDRA = 0xFF; // розміщення порта як вихідних штифтів
DDRD = 0b11111110;
_delay_ms (50); // передача затримки 50 мс
DDRB = 0b11110000; // Беремо кілька контактів portB як вхідні.
UCSRB - = (1 <
// ввімкнення даних отримує повне переривання, увімкнення отримання даних pin
UCSRC - = (1 <
// зміна інших бітів шляхом першого встановлення URSEL, налаштування для 8-бітового зв'язку
UCSRC & = ~ (1 <
UBRRH & = ~ (1 <
UBRRL = 6; // встановлення швидкості передачі
int16_t VOTEA = 0; // голоси person1 зберігають пам'ять
char A; // людина1 голос, що відображає символ на РК-дисплеї
int16_t VOTEB = 0;; // людина2 голоси, що зберігають пам’ять
char B; // людина2 голоси, що відображають символ на РК-дисплеї
int16_t VOTEC = 0;; // людина3 голоси, що зберігають пам’ять
char C; // людина3 голоси, що відображають символ на РК-дисплеї
int16_t ГОЛОСУВАЛИ = 0;; // людина4 голоси, що зберігають пам'ять
char D; / / person4 голоси, що відображають символ на РК-дисплеї
// Далі міститься ідентифікатор тегів, які потрібно змінити для різних тегів. Вони повинні бути оновлені, щоб проект працював
// Після скидання програми в контролер потрібно взяти картки, які повинні бути авторизованими, і отримати ідентифікатор тегів, які отримуються, розміщуючи тег біля модуля RFID, і ідентифікатор відображатиметься на екрані. Отримавши ідентифікатори, програму потрібно оновити, замінивши наведені нижче ідентифікаційні номери на нові ідентифікаційні номери.
char ADMIT = {{(0x97), (0xa1), (0x90), (0x92)}, {(0x97), (0xa1), (0x90), (0x93)}, {(0x97), (0xa1), (0x90), (0x94)}, {(0x97), (0xa1), (0x90), (0x95)}, {(0x97), (0xa1), (0x90), (0x96)}}; |
Тепер вище ми дозволяємо лише п’ять карток, які можна змінити на будь-яку кількість, Наприклад, розглянемо, що програма за замовчуванням скидається в контролер, дістаньте карти, які слід авторизувати, розміщуйте одну за одною біля модуля, ви отримаєте ідентифікатор кожної з них як xxxxxxxx (907a4F87)
Якщо у нас є 7 тегів, то ми матимемо 7 восьмирозрядних ідентифікаторів.
// зараз для семи карток це як // char ADMIT = {{(0x90), (0x7a), (0x4F), (0x87)},; // виділення пам'яті для відображення ідентифікатора, відправленого модулем int i = 0; int голос = 0; int k = 0; send_a_command (0x01); // Очистити екран 0x01 = 00000001 _delay_ms (50); send_a_command (0x38); // повідомляючи lcd, що ми використовуємо 8-бітний режим команд / даних _delay_ms (50); send_a_command (0b00001111); // РК-ЕКРАН УВІМКНЕНО, а курсор блимає char MEM; // виділення пам'яті для зберігання повного ідентифікатора тегу send_a_string ("НОМЕР RFID"); // рядок надсилання send_a_command (0x80 + 0x40 + 0); // переміщення курсора до другого рядка поки (1) { while (! (UCSRA & (1 <
{ } COUNTA = UDR; // UDR зберігає отримані вісім розрядних даних і приймається у ціле число. MEM = COUNTA; // перші два символи оновлюються до пам'яті ітоа (КОНТА, ШОУ, 16); // команда для введення змінної числа в РК (номер змінної, який символ замінити, яка основа є змінною (тут десять, оскільки ми підраховуємо число в base10)) send_a_string (SHOWA); // вказівка дисплею показати символ (замінений номером змінної) другої особи після розміщення курсора на РК-дисплеї while (! (UCSRA & (1 <
{ } БІЛИНА = UDR; ітоа (КОНТА, ШОУ, 16); send_a_string (SHOWA); МЕМ = КОНТАКТ; // третій і четвертий символи оновлюються до пам'яті while (! (UCSRA & (1 <
{ } БІЛИНА = UDR; ітоа (КОНТА, ШОУ, 16); send_a_string (SHOWA); MEM = COUNTA; // п'ятий та шостий символи оновлюються до пам'яті while (! (UCSRA & (1 <
{ } БІЛИНА = UDR; ітоа (КОНТА, ШОУ, 16); send_a_string (SHOWA); MEM = COUNTA; // сьомий і вісім символів оновлюються до пам'яті send_a_string (""); send_a_command (0x80 + 0x40 + 0); UCSRB & = ~ (1 <
для (i = 0; i <5; i ++) { якщо ((MEM == ДОПУСТИТИ) & (MEM == АДМІТУВАТИ) & (MEM == АДМІТУВАТИ) & (MEM == АДМІТУВАТИ)) {// перевірка авторизації купуємо, порівнюючи два символи одночасно з символами в пам'яті PORTB - = (1 <
vote = 1; // якщо дозволено встановити VOTE } } if (vote == 0) // авторизація не вдалася, якщо голосування не встановлено { UCSRB - = (1 <
} while (vote == 1) // виконуємо цей цикл, доки не проголосуємо, якщо це дозволено { send_a_command (0x80 + 0); // перехід до нульового положення на рядку1 send_a_string ("ГОЛОСУЙТЕ ЗАРАЗ"); // відображення рядка if (bit_is_clear (PINB, 0)) // при натисканні однієї кнопки { VOTEA ++; // збільшення пам’яті голосів від першої особи на одиницю vote = 0; // відпускання циклу while після голосування } if (bit_is_clear (PINB, 1)) // при натисканні кнопки 2 { VOTEB ++; // збільшуємо пам’ять голосів 2- ї особи на одну голосувати = 0; } if (bit_is_clear (PINB, 2)) // при натисканні кнопки 3 { VOTEC ++; // збільшуємо пам’ять голосів третьої людини на одного голосувати = 0; } if (bit_is_clear (PINB, 3)) // при натисканні кнопки 4 { VOTED ++; // збільшуємо пам’ять голосів 4- ї особи на одного голосувати = 0; } if (vote == 0) // очищається після отримання голосу { send_a_command (0x80 + 0); // переміщення в нульове положення рядка1 send_a_string ("ДЯКУЄМО ЗА ГОЛОС"); // відображення рядка для (k = 0; k <10; k ++) { _delay_ms (220); } PORTB & = ~ (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // відображення голосів усіх чотирьох осіб send_a_string ("A ="); send_a_command (0x80 + 2); ітоа (VOTEA, A, 10); send_a_string (A); send_a_command (0x80 + 8); send_a_string ("B ="); send_a_command (0x80 + 10); ітоа (VOTEB, B, 10); send_a_string (B); send_a_command (0x80 + 0x40 + 0); send_a_string ("C ="); send_a_command (0x80 + 0x40 + 2); ітоа (VOTEC, C, 10); send_a_string (C); send_a_command (0x80 + 0x40 + 8); send_a_string ("D ="); send_a_command (0x80 + 0x40 + 10); itoa (ГОЛОСУВАЛИ, D, 10); send_a_string (D); send_a_command (0x80 + 0x40 + 16); для (k = 0; k <25; k ++) { _delay_ms (220); } UCSRB - = (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // переміщення в нульове положення send_a_string ("НОМЕР RFID"); // надсилаємо рядок send_a_command (0x80 + 0x40 + 0); } } void send_a_command (команда без знака char) { PORTA = команда; PORTD & = ~ (1 <
PORTD - = 1 <
_delay_ms (50); PORTD & = ~ 1 <
ПОРТА = 0; } void send_a_character (символ без знака без підпису) { PORTA = символ; PORTD - = 1 <
PORTD - = 1 <
_delay_ms (50); PORTD & = ~ 1 <
ПОРТА = 0; } void send_a_string (char * string_of_characters) { while (* string_of_characters> 0) { send_a_character (* рядок_знаків ++); } } |