אנו יודעים במשרדים, בקניונים ובמקומות רבים אחרים שרק מי שיש לו כרטיס הרשאה רשאי להיכנס לחדר. מערכות אלו משתמשות במערכת תקשורת RFID. RFID משמש בקניונים כדי לעצור גניבה כאשר המוצרים מתויגים עם שבב RFID וכשאדם עוזב את הבניין עם שבב ה- RFID אזעקה מופעלת באופן אוטומטי. תג ה- RFID מתוכנן כחלק מחול. מערכות האימות של RFID קלות לתכנון וזולות בעלותן. כמה בתי ספר ומכללות משתמשים כיום במערכות נוכחות מבוססות RFID.
בפרויקט זה אנו מתכננים מכונת הצבעה אשר סופרת רק קולות מאומתים. זה נעשה באמצעות תגי RFID (זיהוי תדרים רדיו). כאן אנו נכתוב תוכנית עבור ATMEGA המאפשרת רק לבעלי תגי RFID מורשים להצביע. (בדוק גם את פרויקט מכונת ההצבעה הפשוטה הזו)
רכיבים נדרשים
חומרה: ATMEGA32, ספק כוח (5v), AVR-ISP PROGRAMMER, JHD_162ALCD (16x2LCD), קבל 100uF (מחובר על פני ספק כוח), כפתור (חמש חלקים), נגד 10KΩ (חמש חלקים), קבל 100nF (חמש חלקים), LED (שני חלקים), EM-18 (מודול קורא RFID).
תוכנה: Atmel studio 6.1, פרוגיספ או קסם פלאש.
תרשים מעגל והסבר
במעגל PORTA של ATMEGA32 מחובר ליציאת נתונים של LCD. כאן צריך לזכור להשבית את תקשורת JTAG ב- PORTC ל- ATMEGA על ידי שינוי בתים הנתיכים, אם רוצים להשתמש ב- PORTC כיציאת תקשורת רגילה. ב- LCD 16x2 יש 16 פינים בסך הכל אם יש אור שחור, אם אין תאורה אחורית יהיו 14 פינים. אפשר להפעיל או להשאיר את סיכות התאורה האחורית. כעת ב -14 הפינים ישנם 8 פינים נתונים (7-14 או D0-D7), 2 פינים לאספקת חשמל (1 & 2 או VSS & VDD או GND & + 5V), סיכה שלישית 3 לבקרת ניגודיות (VEE- שולט עד כמה הדמויות צריכות להיות עבות מוצג), 3 סיכות בקרה (RS & RW & E)
במעגל, תוכלו לראות שלקחתי רק שני סיכות בקרה, זה נותן את הגמישות של הבנה טובה יותר, סיביות הניגודיות ו- READ / WRITE לא משמשים לעתים קרובות, כך שניתן לקצר אותם לקרקע. זה מכניס את LCD למצב הניגודיות והקריאה הגבוה ביותר. אנחנו רק צריכים לשלוט בסיכות ENABLE ו- RS כדי לשלוח תווים ונתונים בהתאם.
החיבורים שבוצעו עבור LCD מובאים להלן:
PIN1 או VSS לקרקע
PIN2 או VDD או VCC ל- + 5v כוח
PIN3 או VEE לקרקע (נותן ניגודיות מרבית הטובה ביותר למתחילים)
PIN4 או RS (בחירת רישום) ל- PD6 של uC
PIN5 או RW (קריאה / כתיבה) לקרקע (מכניס את LCD למצב קריאה מקל על התקשורת עבור המשתמש)
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 פינים של LCD לבקר, בהם 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 הם מסוג נתונים 8bit (איור 3), עלינו להגדיר UCSZ0, UCSZ1 לאחד ו- UCSZ2 לאפס.
ORANGE (UMSEL): סיבית זו נקבעת על סמך אם המערכת מתקשרת באופן אסינכרוני (שניהם משתמשים בשעון אחר) או באופן סינכרוני (שניהם משתמשים באותו שעון),
מכיוון שהמודול והבקר משתמשים בשעון שונה, יש להגדיר ביט זה לאפס או להשאיר אותו לבד מכיוון שכולם מוגדרים לאפס כברירת מחדל.
ירוק (UPM1, UPM0): שני סיביות אלה מותאמות על סמך זוגיות הסיביות בה אנו משתמשים בתקשורת.
מכיוון שמודול ה- RFID שולח נתונים ללא זוגיות (איור 3), הגדרנו את שניהם UPM1, UPM0 לאפס או שהם יכולים להישאר לבד מכיוון שכל הסיביות בכל האגפים מוגדרות כבר לאפס כברירת מחדל.
כחול (USBS): סיבית זו משמשת לבחירת מספר סיביות העצירה בהן אנו משתמשים במהלך התקשורת.
מכיוון שמודול ה- RFID שולח נתונים עם ביט עצירה אחד (איור 3), עלינו פשוט להשאיר את ביט ה- USBS לבד.
כעת סוף סוף עלינו להגדיר את קצב השידור, מאיור 3 ברור שמודול ה- RFID שולח נתונים לבקר בקצב שידור של 9600bps (ביט לשנייה).
קצב השידור נקבע בבקר על ידי בחירת ה- UBRRH המתאים,
ערך UBRRH נבחר על ידי קצב שידור מצולב ותדר גביש המעבד,
אז על ידי הפניה צולבת ערך UBRR נתפס כ- '6', ולכן קצב השידור מוגדר.
ישנם כאן חמישה כפתורים, ארבעה להגדלת קולות המועמדים והחמישי הוא לאיפוס קולות המועמדים לאפס. הקבלים המצויים כאן נועדים לביטול האפקט המקפיץ של כפתורים. אם הם מוסרים הבקר עשוי לספור יותר מאחד בכל לחיצה על הכפתור.
הנגדים המחוברים לסיכות נועדו להגבלת הזרם, כאשר לוחצים על הכפתור כדי למשוך את הסיכה לקרקע. בכל פעם שלוחצים על כפתור, הסיכה המתאימה של הבקר מושכת לקרקע וכך הבקר מזהה שלוחצים על כפתור מסוים ופעולה המתאימה לביצוע, זה עשוי להגדיל את קולות המועמד או לאפס קולות בהתאם ללחצן.
כאשר לוחצים על הכפתור המייצג אדם המתאים, הבקר בוחר אותו ומגדיל את מספר האדם המתאים בזיכרון לאחר התוספת הוא מראה את ציון האנשים המתאימים בתצוגת LCD 16x2.
העבודה של מכונת ההצבעה מוסברת בצורה הטובה ביותר שלב אחר שלב של קוד C המופיע להלן:
הסבר קוד
#include // כותרת כדי לאפשר בקרת זרימת נתונים על סיכות
#define F_CPU 1000000 // מציין תדר גביש לבקר
#לִכלוֹל
#define E 5 // מתן השם "לאפשר" כדי 5 th סיכה של PORTD, שכן הוא קשור LCD לאפשר סיכה
RS #define 6 // מתן השם "registerselection" כדי 6 th סיכה של PORTD, מאז מחוברת סיכה RS LCD
בטל send_a_command (פקודת char לא חתומה);
בטל send_a_character (דמות char לא חתומה);
בטל send_a_string (char * string_of_characters);
int main (בטל)
{
DDRA = 0xFF; // הצבת פורטה כסיכות פלט
DDRD = 0b11111110;
_ Delay_ms (50); // מתן עיכוב של 50ms
DDRB = 0b11110000; // לוקח כמה סיכות portB כקלט.
UCSRB - = (1 <
// הפעלת נתוני הפעלת הפסקה מלאה, הפעלת סיכת קבלת נתונים
UCSRC - = (1 <
// שינוי ביטים אחרים על ידי הגדרת URSEL ראשונה, הגדרת תקשורת 8 ביט
UCSRC & = ~ (1 <
UBRRH & = ~ (1 <
UBRRL = 6; // הגדרת קצב שידור
int16_t VOTEA = 0; // קולות person1 המאחסנים זיכרון
תו A; // קולות אדם 1 המציגים אופי על גבי LCD
int16_t VOTEB = 0;; // person2 קולות המאחסנים זיכרון
תו B; // קולות person2 המציגים אופי על גבי LCD
int16_t VOTEC = 0;; // person3 קולות המאחסנים זיכרון
char C; // person3 קולות המציגים אופי על LCD
int16_t הצביע = 0;; // person4 קולות המאחסנים זיכרון
char D; / / person4 קולות המציגים אופי על גבי LCD
// הבא מכיל מזהה של תגים, יש לשנות אותם לתגים שונים, יש לעדכן אותם כדי שהפרויקט יעבוד
// לאחר השלכת התוכנית לבקר יש לקחת את הכרטיסים שיש לאשר ולקבל את מזהה התגים, אלה מתקבלים על ידי הצבת התג ליד מודול 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 _עיכוב_מס (50); send_a_command (0x38); // אומר ל- lcd שאנחנו משתמשים במצב פקודה / נתונים 8bit _עיכוב_מס (50); send_a_command (0b00001111); // מסך LCD מופעל וקורס מהבהב char MEM; // הקצאת זיכרון לאחסון מזהה שלם של התג send_a_string ("מספר RFID"); // מחרוזת שליחה send_a_command (0x80 + 0x40 + 0); // העברת הקורס לשורה השנייה בעוד (1) { בעוד (! (UCSRA & (1 <
{ } COUNTA = UDR; // UDR מאחסן את נתוני שמונת הסיביות שהתקבלו ונלקח למספר שלם. MEM = COUNTA; // שתי התווים הראשונים מתעדכנים בזיכרון itoa (COUNTA, SHOWA, 16); // פקודה להכנסת מספר משתנה ב- LCD (מספר משתנה, באיזה תו להחליף, איזה בסיס משתנה (עשר כאן כפי שאנו סופרים מספר בבסיס 10)) send_a_string (SHOWA); // אומר לתצוגה להציג תו (מוחלף במספר משתנה) של אדם שני לאחר מיקום הקורס על גבי LCD בעוד (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // התווים השלישי והרביעי מתעדכנים בזיכרון בעוד (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // התווים החמישית והשישית מתעדכנים בזיכרון בעוד (! (UCSRA & (1 <
{ } COUNTA = UDR; itoa (COUNTA, SHOWA, 16); send_a_string (SHOWA); MEM = COUNTA; // שביעיות ושמונה תווים מתעדכנים בזיכרון send_a_string (""); send_a_command (0x80 + 0x40 + 0); UCSRB & = ~ (1 <
עבור (i = 0; i <5; i ++) { אם ((MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT) & (MEM == ADMIT)) {// בדיקת אישור קנייה המשווה בין שתי תווים בכל פעם לתווים בזיכרון PORTB - = (1 <
הצבעה = 1; // אם מורשה קבע VOTE } } אם (הצבעה == 0) // ההרשאה נכשלה אם ההצבעה לא הוגדרה { UCSRB - = (1 <
} בעוד (הצבעה == 1) // עשו את הלולאה הזו עד להצביע, אם היא מורשית { send_a_command (0x80 + 0); // עבור למיקום אפס בשורה 1 send_a_string ("הצביע עכשיו"); // מציג מחרוזת אם (bit_is_clear (PINB, 0)) // כאשר לוחצים על כפתור אחד { VOTEA ++; // הגדל את זיכרון ההצבעה של גוף ראשון אחד להצביע = 0; // לתת תוך כדי לולאה לאחר ההצבעה } אם (bit_is_clear (PINB, 1)) // כאשר לוחצים על כפתור 2 { VOTEB ++; // להגדיל את הזיכרון ההצבעה של 2 nd אדם על ידי אחד הצבעה = 0; } אם (bit_is_clear (PINB, 2)) // כאשר לוחצים על כפתור 3 { VOTEC ++; // הגדל את זיכרון ההצבעה של אדם שלישי אחד הצבעה = 0; } אם (bit_is_clear (PINB, 3)) // כאשר לוחצים על כפתור 4 { הצבעת ++; // להגדיל את זיכרון ההצבעה של 4 th אדם על ידי אחד הצבעה = 0; } אם (הצבעה == 0) // אושר לאחר קבלת ההצבעה { send_a_command (0x80 + 0); // לעבור למיקום אפס של קו 1 send_a_string ("תודה על הצבעה"); // מחרוזת תצוגה עבור (k = 0; k <10; k ++) { _עיכוב_מס (220); } PORTB & = ~ (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // הצגת קולות של כל ארבעת האנשים send_a_string ("A ="); send_a_command (0x80 + 2); itoa (VOTEA, A, 10); send_a_string (A); send_a_command (0x80 + 8); send_a_string ("B ="); send_a_command (0x80 + 10); itoa (VOTEB, B, 10); send_a_string (B); send_a_command (0x80 + 0x40 + 0); send_a_string ("C ="); send_a_command (0x80 + 0x40 + 2); itoa (VOTEC, C, 10); send_a_string (C); send_a_command (0x80 + 0x40 + 8); send_a_string ("D ="); send_a_command (0x80 + 0x40 + 10); itoa (הצביעו, ד, 10); send_a_string (D); send_a_command (0x80 + 0x40 + 16); עבור (k = 0; k <25; k ++) { _עיכוב_מס (220); } UCSRB - = (1 <
send_a_command (0x01); send_a_command (0x80 + 0); // עובר למצב אפס send_a_string ("מספר RFID"); // שלח מחרוזת send_a_command (0x80 + 0x40 + 0); } } בטל send_a_command (פקודת char לא חתומה) { PORTA = פקודה; PORTD & = ~ (1 <
פורט - = 1 <
_עיכוב_מס (50); PORTD & = ~ 1 <
פורטה = 0; } בטל send_a_character (תו לא חתום) { PORTA = דמות; פורט - = 1 <
פורט - = 1 <
_עיכוב_מס (50); PORTD & = ~ 1 <
פורטה = 0; } בטל send_a_string (char * string_of_characters) { בעוד (* string_of_characters> 0) { send_a_character (* string_of_characters ++); } } |