با ما همراه باشید

ATMEGA32

ماشین رأی گیری مبتنی بر RFID

منتشر شده

در

ما می دانیم در دفاتر، مراکز خرید و در بسیاری از نقاط دیگر، تنها افرادی اجازه ورود دارند که کارت خاصی همراه داشته باشند. این سیستم ها از سیستم ارتباطی RFID استفاده می کنند. RFID در مراکز خرید برای جلوگیری از سرقت استفاده می شود، زیرا محصولات با تراشه RFID برچسب گذاری می شوند و هنگامی که یک فرد با تراشه RFID از ساختمان خارج می شود، به طور خودکار هشدار داده می شود. برچسب RFID به اندازه دانه ای از شن و ماسه طراحی شده است. سیستم های تأیید هویت RFID به راحتی و کم هزینه طراحی می شوند. برخی از مدارس و کالج ها امروزه از سیستم های حضور و غیاب مبتنی بر RFID استفاده می کنند.

در این پروژه ما قصد داریم یک دستگاه رأی گیری را طراحی کنیم که فقط تعداد آرا احراز هویت را ثبت می کند. این کار با استفاده از برچسب RFID (شناسایی فرکانس رادیویی) انجام می شود. در اینجا ما قصد داریم یک برنامه برای ATMEGA بنویسیم که به دارنده کارت RFID مجاز اجازه رای دادن بدهد.

قطعات مورد نیاز

سخت افزار:

ATMEGA32

منبع تغذیه ۵ ولت

AVR-ISP PROGRAMMER

JHD_162ALCD (16x2LCD)

خازن ۱۰۰ میکرو فاراد (متصل شده در سراسر منبع تغذیه)

کلید (پنج عدد)

مقاومت ۱۰KΩ (پنج عدد)

خازن ۱۰۰nF (پنج عدد)

LED (دو عدد)

EM-18 (ماژول خواننده RFID).

نرم افزار: Atmel studio 6.1، progisp یا magic flash.

 

مدار و توضیح آن

در مدار پورت A از ATMEGA32 به پورت داده از LCD متصل است. در اینجا باید یادآور شویم که اگر کسی بخواهد از پورت C به عنوان یک پورت ارتباطی معمول استفاده کند، اتصال JTAG در پورت C را به ATMEGA با تغییر بایت های فیوز غیرفعال کنید. به طور کلی اگر نور سیاه وجود داشت در ۱۶×۲ LCD 16 پایه وجود دارد ، اگر نور پشت وجود ندارد ۱۴ پین وجود دارد. می توانید پایه های نور پشت را به برق وصل یا قطع کنید. در حال حاضر در ۱۴ پایه ۸ پایه داده (۷-۱۴ یا D0-D7)، ۲ پایه منبع تغذیه (۱&2 یا  VSS&VDD or gnd&+5v) ، پایه ۳ برای کنترل کنتراست (VEE- کنترل چگونگی ضرب کردن کاراکترها )، ۳ پایه کنترل (RS & RW & E) هستند.

در مدار، می توانید ببینید که من فقط دو پایه کنترل را گذاشته ام، این انعطاف پذیری درک بهتر را می دهد، بیت کنتراست و READ / WRITE اغلب استفاده نمی شود، بنابراین آنها را می توانند به زمین متصل کنید. این باعث می شود که LCD در بالاترین کنتراست و حالت خواندن قرار گیرد. ما فقط نیاز به کنترل پنل های ENABLE و RS برای ارسال کارکترها و داده ها بر این اساس داریم.

اتصالاتی که برای LCD انجام می شود، در زیر آمده است:

پایه ۱ یا VSS به زمین

پایه ۲ یا VDD یا VCC به منبع ۵V

پایه ۳ یا VEE به زمین (حداکثر کنتراست می دهد و برای یک مبتدی بهتر است)

پایه ۴ یا RS (تخصیص ثبات) به PD6 از UC

پایه ۵ یا RW (خواندن / نوشتن) به زمین (LCD در حالت خواندن ارتباطات برای کاربر آسان می کند)

پایه ۶ یا E (فعال کردن) به PD5 از uC

پایه ۷ یا D0 به PA0 از uC

پایه ۸ یا D1 به PA1 از UC

پایه ۹ یا D2 به PA2 از UC

پایه ۱۰ یا D3 به PA3 از UC

پایه ۱۱ یا D4 به PA4 از UC

پایه ۱۲ یا D5 به PA5 از UC

پایه ۱۳ یا D6 به PA6 از UC

پایه۱۴ یا D7 به PA7 از UC

در مدار، می توانید ببینید که ما از ارتباط ۸ بیتی استفاده کرده ایم (D0-D7). با این وجود این اجباری نیست و می توانیم از ارتباط ۴ بیتی (D4-D7) هم استفاده کنیم اما برنامه، ارتباط ۴ بیت پیچیده می شود، بنابراین ارتباط ۸ بیتی را ترجیح می دهیم.

بنابراین از مشاهده گذرای جدول بالا، میابید که ما ۱۰ پایه LCD را به کنترلر متصل می کنیم که در آن ۸ پایه، پایه داده و ۲ پایه برای کنترل است.

قبل از اینکه جلوتر برویم، ما باید درباره ارتباط سریال صحبت کنیم. ماژول RFID این اطلاعات را به کنترل کننده با استفاده از ارتباط سریال ارسال می کند. این حالت ارتباطی نوع دیگری نیز دارد، اما برای ارتباط آسان ما RS232 را انتخاب می کنیم. پایه RS232 ماژول، به پایه RXD، ATMEGA متصل است.

داده های فرستاده شده توسط ماژول RFID به شرح زیر است:

در حال حاضر برای تعامل داشتن ماژول RFID، ویژگی های زیر لازم است:

  1. پین RXD (خصیصه دریافت داده) کنترل کننده باید فعال باشد.
  2. از آنجایی که ارتباط سریال است، مستلزم هستیم که بدانیم هر زمان که اطلاعات ثانوی دریافت می شود ، می توانیم برنامه را متوقف کنیم تا بایت کامل دریافت شود. این کار با فعال کردن یک داده وقفه کامل را دریافت می کند.
  3. RFID داده به کنترلر در حالت ۸ بیتی ارسال می کند. بنابراین دو بار به یک کنترل کننده فرستاده می شود. این در بلوک شکل ۳ نشان داده شده است
  4. از شکل ۳، هیچ بیت برابر نیست، یک بیت متوقف به داده توسط ماژول ارسال می شود.

ویژگی های فوق در رکوردها کنترل می شوند؛ ما به طور مختصر در مورد آنها صحبت خواهیم کرد

قرمز  (RXEN): این بیت نشانگر خصیصه دریافت داده است، این بیت برای داده ها از  طریق ماژول باید توسط کنترلر دریافت شود، همچنین پین RXD کنترل کننده را فعال می کند.

قهوه ای  (RXCIE): این بیت باید برای دریافت وقفه پس از دریافت اطلاعات موفقیت آمیز تنظیم شود. با فعال کردن این بیت ما می دانیم، بعد از دریافت دیتای ۸ بیتی صحیح بوده است.

صورتی  (URSEL): قبل از فعال کردن بیت های دیگر در UCSRC، این بیت باید پس از تنظیم بیت های مورد نیاز در UCSRC تنظیم شود؛ URSEL باید غیرفعال یا صفر باشد.

زرد  (UCSZ0، UCSZ1، UCSZ2): این سه بیت برای انتخاب تعداد بیت های داده ای که ما دریافت و یا ارسال می کنیم، یک بار مورد استفاده قرار می گیرد.

از آنجا که داده های فرستاده شده توسط ماژول RFID  از نوع داده ۸ بیتی (شکل ۳) است، ما باید UCSZ0، UCSZ1 را به یک و UCSZ2 به صفر تنظیم کنید.

نارنجی  (UMSEL): این بیت براساس اینکه آیا سیستم به طور غیرمستقیم (هر دو از ساعت های مختلف استفاده می کنند) یا همزمان (هر دو از ساعت یکسان استفاده می کنند) ارتباط برقرار می کند

از آنجا که ماژول و کنترلر از ساعت های مختلف استفاده می کنند، این بیت باید به صورت صفر تنظیم شود یا به تنهایی باقی بماند چون همه آنها به طور پیش فرض صفر هستند.

سبز  (UPM1، UPM0): این دو بیت بر اساس بیتی که ما در ارتباطات استفاده می کنیم تنظیم می شود.

از آنجائیکه ماژول RFID اطلاعاتی را یکی یکی (شکل۳) می فرستد، ما هر دو UPM1، UPM0 را به صفر تنظیم می کنیم و یا می توانیم به تنهایی باقی بذاریم زیرا تمام بیت ها در هر رجیستری به طور پیش فرض صفر هستند.

آبی  (USBS): این بیت برای انتخاب تعداد بیت های توقف که در طول ارتباطات استفاده می شود.

از آنجا که ماژول RFID داده را با یک بیت توقف ارسال می کند (شکل ۳)، ما باید فقط به بیت یکتای USBS اجازه بدهیم.

نرخ باند (پالس بر ثانیه) در کنترلر با انتخاب UBRRH مناسب است،

مقدار UBRRH توسط نرخ باند متقاطع ارجاع و فرکانس کریستال CPU انتخاب شده است.

بنابراین مقدار UBRR ارجاع متقابل “۶” دیده می شود، بنابراین نرخ باند تنظیم می شود.

در اینجا پنج دکمه وجود دارد ، چهارتای آنها برای افزایش آراء کاندیداها و پنجم برای بازنشانی ( ریست کردن) آرای  نامزدها به صفر است. خازن های موجود در اینجا برای خنثی کردن اثر لرزش دکمه ها است. اگر آنها برداشته شوند، ممکن است کنترل کننده برای هر بار فشار دکمه بیش از یک بار فشار داده شده محاسبه کند.

مقاومت هایی که به پایه ها متصل می شوند برای محدود کردن جریان هستند، هنگامی که دکمه ای فشار داده می شود، پایه به زمین وصل می گردد. هر بار یک دکمه فشار داده می شود، پایه مربوطه کنترلر به زمین وصل می شود و به این ترتیب کنترل کننده به رسمیت می شناسد که دکمه خاصی فشار داده شده و اقدامات مربوطه انجام می گیرد، ممکن است افزایش آرا نامزد و یا تنظیم مجدد آرا باشد، بستگی به دکمه ای که فشاردادیم دارد.

هنگامی که دکمه رای  یک شخص خاصی فشرده می شود، کنترلر آن را بر می دارد و در حافظه داخلی خود تعداد آرا را ذخیره کرده یکی به تعدادش می افزاید و سپس آن را در صفحه نمایش ۱۶×۲ LCD  نمایش می گذارد.

بهتر است مراحل گام به گام کد C کارکرد دستگاه رأی گیری در زیر قرار داده شده است، نگاهی بی اندازید:

 

توضیح کد

#include <avr/io.h>

 // هدر برای فعال کردن کنترل جریان داده ها بر پایه های میکروکنترلر

#define F_CPU 1000000

     // تعریف کردن فرکانس کریستال متصل شده به میکروکنترلر

#include <util/delay.h>

 // هدر برای فعال کردن تابع تاخیر در برنامه

#define    E   ۵

 // enable کردن پایه ۵ از پورتD، که پایه اتصال به LCD فعال است

#define RS  ۶

 // register selection پایه ۶ از پورتD، آنجایی که به پایه LCD RS متصل است

void send_a_command(unsigned char command);

void send_a_character(unsigned char character);

void send_a_string(char *string_of_characters);

int main(void)

{

DDRA = 0xFF;

// قرار دادن پورت a  به عنوان پایه های خروجی

DDRD = 0b11111110;

_delay_ms(50);

//دادن تاخیر ۵۰ms

DDRB = 0b11110000;

// گرفتن بعضی از پایه های پورت B به عنوان ورودی.

UCSRB |=(1<<RXEN)|(1<<RXCIE);

// داده های برای دریافت وقفه کامل فعال می شوند، داده ها از پایه ها دریافت می شوند

UCSRC |=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);

// تغییر بیت های دیگر باید اول  URSEL تنظیم شود، تنظیماتی برای ارتباط ۸ بیتی

UCSRC &=~(1<<UMSEL);

 // استفاده از ارتباطات ناهمزمان

UBRRH &=~(1<<URSEL);

UBRRL=6;

// تنظیم سرعت باد (پالس بر ثانیه)

int16_t  VOTEA = 0;

// آرای اولین شخص  در حافظه ذخیره می کند

char A [4];

// آرای اولین شخص  روی LCD نشان می دهد

int16_t VOTEB = 0; ;

// آرای دومین شخص در حافظه ذخیره می شود

char B [4];

// آرای دومین شخص روی LCD نمایش می دهد

int16_t VOTEC = 0; ;

// آرای سومین شخص در حافظه ذخیره می کند

char C [4];

// آرای سومین شخص روی LCD نمایش داده می شود

int16_t VOTED = 0; ;

// آرای چهارمین شخص در حافظه ذخیره می کند

char D [4];

/ / آرای چهارمین شخص روی LCD نمایش داده می شود

// موارد زیر حاوی شناسه برچسب‌ها هستند ، این ها باید برای برچسب‌های مختلف تغییر داده شوند، و بایدبرای پروژه به روز شوند.

// پس از حذف برنامه در کنترلر، باید کارتهایی را که باید مجاز باشند و شناسه برچسب ها دریافت کنند، با قرار دادن برچسب در کنار ماژول RFID و شناسه روی صفحه نشان داده می شود. پس از دریافت شناسه، برنامه باید با جایگزینی شماره های شناسه زیر با شماره های شناسه جدید به روز شود.

char ADMIT [5][4]={{(0x97),(0xa1),(0x90),(0x92)},{(0x97),(0xa1),(0x90),(0x93)},{(0x97),(0xa1),(0x90),(0x94)},{(0x97),(0xa1),(0x90),(0x95)},{(0x97),(0xa1),(0x90),(0x96)}};

در حال حاضر در بالا ما تنها به پنج کارت اجازه دادیم ، البته این تعداد را می توان به هر مقداری تغییر داد،

به عنوان مثال ، در نظر بگیرید که برنامه پیش‌فرض در میکروکنترلر خالی شود ، کارتهایی که مجاز هستند یکی پس از دیگری به ماژول نزدیک کنید، تا شناسه های به عنوان مثال  xxxxxxxx (907a4F87) دریافت کند،

اگر ۷ برچسب داریم، پس از آن ۷ شناسه هشت بیتی خواهیم داشت.

// در حال حاضر برای هفت کارتی که به دست می‌آید

//char ADMIT[7][4]={{(0x90),(0x7a),(0x4F),(0x87)},[},{},{},{},{},{}}

// حال، زمانی که تمام شناسه ها نوشته شده اند به عنوان شناسه برچسب های مجاز در نظر گرفته می شوند

Int16_t COUNTA = 0;

//  تخصیص حافظه برای ذخیره شناسه و ارسال آن توسط ماژول

char SHOWA [4];

//  تخصیص حافظه برای ذخیره شناسه و ارسال آن توسط ماژول

int i=0;

int vote =0;

int k =0;

send_a_command(0x01);

// پاک کردن صفحه نمایش ۰x01 = 00000001

_delay_ms(50);

send_a_command(0x38);

// برای تعریف LCD ما از خط فرمان ۸ بیتی استفاده می کنیم/ حالت داده

_delay_ms(50);

send_a_command(0b00001111);

// صفحه LCD روشن می شود و مکان نما چشمک می زند

char MEM[4];

// تخصیص حافظه برای ذخیره شناسه کامل برچسب ها

send_a_string (“RFID NUMBER”);

// ارسال رشته

send_a_command(0x80 + 0x40 + 0);

// حرکت مکان نما به خط دوم

while(1)

{

while(!(UCSRA&(1<<RXC)));

// صبر کنید تا داده های هشت بیتی دریافت شود

{

}

COUNTA=UDR;

// UDR اطلاعات هشت بیتی دریافت شده را ذخیره می کند و به یک عدد صحیح وارد می شود.

MEM[0]=COUNTA;

// نخست دو کارکتر در حافظه بروزرسانی می شود

itoa(COUNTA,SHOWA,16);

//  دستوری برای قرار دادن شماره متغیر در ال سی دی (شماره متغیر ، کدام کارکتر برای جایگزینی، کدام مبنای متغیر است (سپس در اینجا که شمارش تعداد در مبنای ۱۰ است))

send_a_string(SHOWA);

// تعریف صفحه نمایش برای نمایش کارکترها (جایگزین کردن مقدار متغیر) شخص دوم پس از موقعیت مکان نما در LCD

while(!(UCSRA&(1<<RXC)));

// صبر کنید تا اطلاعات هشت بیتی دریافت شود

{

}

COUNTA=UDR;

itoa(COUNTA,SHOWA,16);

send_a_string(SHOWA);

MEM[1]=COUNTA;

// کارکتر سوم و چهارم در حافظه به روز می شود

while(!(UCSRA&(1<<RXC)));

// صبر کنید تا داده های هشت بیتی دریافت شود

{

}

COUNTA=UDR;

itoa(COUNTA,SHOWA,16);

send_a_string(SHOWA);

MEM[2]=COUNTA;

//  کارکترهای پنجم و ششم در حافظه به روز می شوند

while(!(UCSRA&(1<<RXC)));

// صبر کنید تا اطلاعات هشت بیتی چهارم دریافت شود

{

}

COUNTA=UDR;

itoa(COUNTA,SHOWA,16);

send_a_string(SHOWA);

MEM[3]=COUNTA;

// کارکترهای هفتم و هشتم در حافظه به روز می شوند

send_a_string(”        “);

send_a_command(0x80 + 0x40 + 0);

UCSRB &=~(1<<RXEN);

// داده های دریافتی را غیرفعال کنید تا شناسه برچسب برای اجازه داشتن بررسی شود

for (i=0;i<5;i++)

{

if ((MEM[0]==ADMIT[i][0])&(MEM[1]==ADMIT[i][1])&(MEM[2]==ADMIT[i][2])&(MEM[3]==ADMIT[i][3]))

{

 // بررسی مجوز خرید با دو کارکتر در یک زمان با کارکترهای حافظه مقایسه کنید

PORTB|=(1<<PINB4);

// اگر مجاز باشد، LED روشن شود

vote=1;

// اگر مجاز بود رای (VOTE) تعیین کن

}

}

if (vote==0)

// اجازه داده نمی شود اگر رأی تعیین نشده باشد

{

UCSRB |=(1<<RXEN);

 //  شروع به دریافت داده از ماژول می کند

}

while (vote==1)

// این حلقه را تا زمان رای دادن، اگر مجاز باشد، انجام دهید

{

send_a_command(0x80 + 0);

// به موقعیت صفر در خط ۱ بروید

send_a_string (“VOTE NOW       “);

//  نمایش رشته ها

if (bit_is_clear(PINB,0))

//  وقتی یک دکمه فشار داده شد

{

VOTEA++;

 // افزایش یک رأی شخص اول در حافظه

vote=0;

// اجازه دادن به حلقه بعد از رأی گیری

}

if (bit_is_clear(PINB,1 ))

// هنگامی که دکمه ۲ فشار داده می شود

{

VOTEB++;

// افزایش یک رأی شخص دوم در حافظه

vote=0;

}

if (bit_is_clear(PINB,2))

// هنگامی که دکمه ۳ فشار داده می شود

{

VOTEC++;

// افزایش یک رأی شخص سوم در حافظه

vote=0;

}

if (bit_is_clear(PINB,3))

 // هنگامی که دکمه ۴ فشار داده می شود

{

VOTED++;

 //  افزایش یک رأی شخص چهارم در حافظه

vote=0;

}

if (vote==0)

// پس از رأی دریافت شده پاک شود

{

send_a_command(0x80 + 0);

// به موقعیت صفر از خط ۱ حرکت کنید

send_a_string (“THANK U FOR VOTE”);

// نمایش رشته

for (k=0;k<10;k++)

{

_delay_ms(220);

}

PORTB&=~(1<<PINB4);

//  LED آرا خاموش می شود

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(VOTED,D,10);

send_a_string(D);

send_a_command(0x80 + 0x40 + 16);

for (k=0;k<25;k++)

{

_delay_ms(220);

}

UCSRB |=(1<<RXEN);

// فعال کردن پایه دریافت داده بعد از رای

send_a_command(0x01);

send_a_command(0x80 + 0);

//  حرکت به موقعیت صفر

send_a_string (“RFID NUMBER”);

// فرستادن یک رشته

send_a_command(0x80 + 0x40 + 0);

}

}

void send_a_command(unsigned char command)

{

PORTA = command;

PORTD &= ~ (1<<RS);

// قرار دادن ۰ در RS برای ارسال به LCD ، ما فرمان ارسال کردیم

PORTD |= 1<<E;

//  تعریف  lcd برای دریافت فرمان / داده در پورت

_delay_ms(50);

PORTD &= ~1<<E;

// تعریف LCD، ما ارسال داده ها را تکمیل کردیم

PORTA= 0;

}

void send_a_character(unsigned char character)

{

PORTA= character;

PORTD |= 1<<RS;

// تعریف LCD، ما داده ها ی که دستورات نیست ارسال می کنیم

PORTD |= 1<<E;

// تعریف LCD برای دریافت دستور / داده ها

_delay_ms(50);

PORTD &= ~1<<E;

// تعریف LCD، ما ارسال داده / فرمان را تکمیل کردیم

PORTA = 0;

}

void send_a_string(char *string_of_characters)

{

while(*string_of_characters > 0)

{

send_a_character(*string_of_characters++);

}

}

 

 

کد پروژه به صورت کامل

/*

RFID Based Electronic Voting Machine

 */ 

#include <avr/io.h>

#define F_CPU 1000000

#include <util/delay.h>

#include <stdlib.h>

#define enable            ۵

#define registerselection 6

void send_a_command(unsigned char command);

void send_a_character(unsigned char character);

void send_a_string(char *string_of_characters);

int main(void)

{

    DDRA = 0xFF;

    DDRB = 0b11110000;

    

    DDRD = 0b11111110;

    _delay_ms(50);

    

    UCSRB |=(1<<RXEN)|(1<<RXCIE);

    UCSRC |=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);

    UCSRC &=~(1<<UMSEL);

    UBRRH &=~(1<<URSEL);

    UBRRL=6;

    

    char ADMIT [5][4]={{(0x97),(0xa1),(0x90),(0x92)},{(0x97),(0xa1),(0x90),(0x93)},{(0x97),(0xa1),(0x90),(0x94)},{(0x97),(0xa1),(0x90),(0x95)},{(0x97),(0xa1),(0x90),(0x96)}};

    int16_t COUNTA = 0;

    char SHOWA [4];

    int i=0;

    int vote =0;

    int k =0;

    

    int16_t VOTEA = 0;

    char A [4];

    int16_t VOTEB = 0;

    char B [4];

    int16_t VOTEC = 0;

    char C [4];

    int16_t VOTED = 0;

    char D [4];

    send_a_command(0x01); //Clear Screen 0x01 = 00000001

    _delay_ms(50);

    send_a_command(0x38);

    _delay_ms(50);

    send_a_command(0b00001111);

    _delay_ms(50);

    char MEM[4];

    send_a_string (“RFID NUMBER”);

    send_a_command(0x80 + 0x40 + 0);

    while(1)

    {

        while(!(UCSRA&(1<<RXC)));

        {

            

        }

        COUNTA=UDR;

        MEM[0]=COUNTA;

        itoa(COUNTA,SHOWA,16);

        send_a_string(SHOWA);

        

        while(!(UCSRA&(1<<RXC)));

        {

            

        }

        COUNTA=UDR;

        itoa(COUNTA,SHOWA,16);

        send_a_string(SHOWA);

        MEM[1]=COUNTA;

        

        while(!(UCSRA&(1<<RXC)));

        {

            

        }

        COUNTA=UDR;

        itoa(COUNTA,SHOWA,16);

        send_a_string(SHOWA);

        MEM[2]=COUNTA;

        while(!(UCSRA&(1<<RXC)));

        {

            

        }

        COUNTA=UDR;

        itoa(COUNTA,SHOWA,16);

        send_a_string(SHOWA);

        MEM[3]=COUNTA;

        

        send_a_string(”        “);

        

        send_a_command(0x80 + 0x40 + 0);

        

        UCSRB &=~(1<<RXEN);

        for (i=0;i<5;i++)

        {

            

            if ((MEM[0]==ADMIT[i][0])&(MEM[1]==ADMIT[i][1])&(MEM[2]==ADMIT[i][2])&(MEM[3]==ADMIT[i][3]))

            {

                PORTB|=(1<<PINB4);

                vote=1;

            }

        }

        if (vote==0)

        {

            UCSRB |=(1<<RXEN);

        }

        while (vote==1)

        {

            send_a_command(0x80 + 0);

            send_a_string (“VOTE NOW       “);

            if (bit_is_clear(PINB,0))

            {

                VOTEA++;

                vote=0;

            }

            if (bit_is_clear(PINB,1))

            {

                VOTEB++;

                vote=0;

            }

            if (bit_is_clear(PINB,2))

            {

                VOTEC++;

                vote=0;

            }

            if (bit_is_clear(PINB,3))

            {

                VOTED++;

                vote=0;

            }

            

            if (vote==0)

            {

                send_a_command(0x80 + 0);

                send_a_string (“THANK U FOR VOTE”);

                for (k=0;k<10;k++)

                {

                    _delay_ms(220);

                }

                PORTB&=~(1<<PINB4);

                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(VOTED,D,10);

                send_a_string(D);

                send_a_command(0x80 + 0x40 + 16);

                for (k=0;k<25;k++)

                {

                    _delay_ms(220);

                }

                    UCSRB |=(1<<RXEN);

                send_a_command(0x01);

                send_a_command(0x80 + 0);

                send_a_string (“RFID NUMBER”);

                send_a_command(0x80 + 0x40 + 0);

            }

        }

    }

}

void send_a_command(unsigned char command)

{

    PORTA = command;

    PORTD &= ~ (1<<registerselection);

    PORTD |= 1<<enable;

    _delay_ms(20);

    PORTD &= ~1<<enable;

    PORTA = 0;

}

void send_a_character(unsigned char character)

{

    PORTA = character;

    PORTD |= 1<<registerselection;

    PORTD |= 1<<enable;

    _delay_ms(20);

    PORTD &= ~1<<enable;

    PORTA = 0;

}

void send_a_string(char *string_of_characters)

{

    while(*string_of_characters > 0)

    {

        send_a_character(*string_of_characters++);

    }

}

برای دانلود فایل های این پروژه اینجا کلیک کنید.

ادامه مطلب
1 دیدگاه

1 دیدگاه

یک پاسخ بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

ATMEGA32

ارتباط صفحه کلید ۴در۴ با میکروکنترلر ATmega32

منتشر شده

در

توسط

ارتباط صفحه کلید ۴ در ۴ با میکروکنترلر AVR  (ATmega32)

در این آموزش، ما یک صفحه کلید ۴ در ۴ (۱۶ کلیدی) به میکروکنترلر ATMEGA32A متصل می کنیم. ما می دانیم که صفحه کلید یکی از مهم ترین ابزار ورودی مورد استفاده در پروژه های الکترونیک است. صفحه کلید یکی از ساده ترین راه ها برای دادن دستورات یا دستورالعمل ها به یک سیستم الکترونیکی است.

قطعات مورد نیاز

سخت افزار:

ATMEGA32

منبع تغذیه (۵V)

پروگرامر AVR-ISP

JHD_162ALCD  (۲*۱۶) LCD

خازن ۱۰۰uF

خازن ۱۰۰nF

مقاومت ۱۰ کبلو اهم ۸ عدد

نرم افزار:

Atmel studio 6.1 یا  Atmel studio 6.2

progisp  یا  flash magic

 

شمایل مدار و توضیح کار

در این مدار پورت B  از ATMEGA32 به عنوان پورت داده به  LCD متصل است. در اینجا باید یادآور شوم که با تغییر بایت های فیوز  اتصال JTAG را در پورت C از ATMEGA غیرفعال می کنیم، اگر کسی بخواهد از پورت C  به عنوان یک پورت ارتباطی معمول استفاده کند . در ۲ LCD در ۱۶ که ۱۶پایه دارد بیشترین پایه داراست بخاطر این هست که می شود نور پشت زمینه (نور بک گراند) هم داشت ، اگر نور پشت زمینه وجود نداشت ۱۴ پایه هستند. می توانید پایه های نور پشت را به برق وصل یا خاموش کنید. در حال حاضر در ۱۴ پایه ۸ پایه داده (۷-۱۴ ) یا )۰-D7))، ۲ پایه برای منبع تغذیه (۱ و ۲ یا VSS و VDD یا gnd + 5v)، پین ۳ برای کنترل کنتراست (VEE- کنترل چگونگی ضرب کردن کاراکترها ) و ۳ پین کنترل (RS & RW & E)هستند.

در این مدار، شما می توانید ببینید که من فقط دو پایه برای کنترل گرفتم، این انعطاف پذیری، بیت کنتراست و READ / WRITE هست که اغلب استفاده نمی شود، بنابراین آنها می توانند به زمین متصل شوند. این باعث می شود که ال سی دی در بالاترین کنتراست و حالت خواندن قرار گیرد. ما فقط نیاز به پایه های ENABLE و RS برای کنترل داریم تا بتواند کارکترها و داده ها بر این اساس ارسال کند.

اتصالاتی که برای LCD انجام می شود، در زیر آمده است:

پایه ۱ یا VSS به زمین

پایه ۲ یا VDD یا VCC به منبع تغذیه ۵V

پایه ۳ یا VEE به زمین (حداکثر کنتراست می دهد برای یک مبتدی بهتر است که پایه ۳ به زمین وصل کند)

پایه ۴  یا  RSبه پورتD6  از میکروکنترلر

پایه ۵  یا RW (خواندن / نوشتن) به زمین (ال سی دی در حالت خواندن قرار می دهد و ارتباطات را برای کاربر آسان می کند)

پایه ۶ یا E ((Enable به پورت D5 از میکروکنترلر

پایه ۷ یا D0  به  پورت B0  از میکروکنترلر

پایه ۸ یا D1  به  پورت B1  از میکروکنترلر

پایه ۹ یا D2  به  پورت B2  از میکروکنترلر

پایه ۱۰ یا D3  به  پورت B3  از میکروکنترلر

پایه ۱۱ یا D4  به  پورت B4  از میکروکنترلر

پایه ۱۲ یا D5  به  پورت B5  از میکروکنترلر

پایه ۱۳ یا D6  به  پورت B6  از میکروکنترلر

پایه ۱۴ یا D7  به  پورت B7  از میکروکنترلر

 

در مدار شما می توانید ببینید که ما از ارتباط ۸ بیتی (D0-D7) استفاده کرده ایم، اما این اجباری نیست، ما می توانیم ارتباط ۴ بیتی (D4-D7) نیز استفاده کنیم، اما برنامه با ارتباط ۴ بیتی پیچیده می شود. بنابراین با مشاهده گذرا جدول بالا، ما ۱۰ پایه ال سی دی را به کنترلر متصل می کنیم که در آن ۸ پایه، پایه داده و ۲ پایه برای کنترل است.

حالا در مورد صفحه کلید صحبت می کنیم، صفحه کلید چیزی جز کلید های چندگانه نیست. دکمه ها در یک فرم چندمنظوره برای کاهش استفاده از پایه های به یک سیستم کنترل (کنترلر) متصل می شوند.

در نظر داشته باشید که ما یک صفحه کلید ۴ در ۴ داریم، در این صفحه کلید ما ۱۶ دکمه داریم، در موارد عادی ۱۶ پایه کنترل کننده برای ۱۶ دکمه نیاز هست اما این مد نظر سیستم کنترل نیست. استفاده از این فرم چندگانه می تواند تعداد پایه های متصل شده به کنترل کننده کاهش یابد.

برای مثال ما فکر میکنیم که ۱۶ دکمه داریم و می خواهیم آن را به یک کنترل کننده وصل کنیم تا یک صفحه کلید ایجاد کنیم، این کلیدها به شکل زیر نشان داده شده است:

این دکمه ها توسط ستون های معمولی به شکل زیر نشان داده شده است:

همانطور که در شکل نشان داده شده، انتهای هر چهار دکمه ادامه می یابد تا آنرا به شکل یک ستون تبدیل کند، و بنابراین برای ۱۶ کلید، ما چهار ستون داریم.

اگر اتصالات ستونها را از بالا چشم پوشی کنیم، و با هم به شکل یک ردیف متصل شده اند، که متشکل از انتهای هر چهار دکمه هست.

همانطور که در شکل نشان داده شده است، برای ۱۶ کلید ما چهار ردیف به صورتی که در شکل داریم نشان داده شده است.

حالا زمانی که آنها هر دو با هم ترکیب شوند ما چیزی شبیه به مدار زیر می بینیم:

در اینجا ما ۱۶ کلید را در یک فرم چندتایی متصل کرده ایم تا پایه های مورد استفاده کنترلر را کاهش دهیم.

در مقایسه با اولین مورد از اتصال ۱۶ کلیدبه کنترلر ما ۱۶ پایه  میکروکنترلر نیاز داریم اما اکنون بعد از چندتایی کردن، ما فقط ۸ پایه از کنترل کننده برای اتصال ۱۶ کلید نیاز داریم.

به طور معمول این چیزی است که در داخل صفحه کلید ارائه شده است:

همانطور که در شکل بالا نشان داده شده است، ۱۶ کلید در صفحه کلید بالا وجود دارد و هر یک از این کلید ها پیکربندی یک دکمه در کی پد را نشان می دهد. و همچنین اتصال ۸ پایه که در شکل بالا وجود دارد نماد اتصال کی پد است.

اکنون برای کار:

صفحه کلید در اینجا دارای چهار ستون و چهار ردیف است، برای اینکه فشار دکمه توسط میکروکنترلر تشخیص داده شود، ما از روش مرجع متقابل استفاده می کنیم. در اینجا ابتدا تمام ستون ها یا تمام ردیف ها را به vcc وصل می کنیم، بنابراین اگر ردیف ها به vcc مشترک وصل شوند، ما ستون ها را به عنوان ورودی ها به کنترل کننده می گیریم.

حالا اگر دکمه  ای را بفشاریم به  صورت شکل زیر نشان داده شده است، می باشد:

پس از آن یک جریان از میان مدار مانند شکل عبور می کند:

بنابراین ما برای C1 ولتاژ داریم وقتی که یک دکمه را به فشاریم. در این لحظه ما قصد داریم که پورت های ورودی و ولتاژ دار تغییر دهیم. می خواهیم ستون ها را ولتاژ دار کنیم و ردیف ها را به عنوان ورودی استفاده کنیم. با این کار جریان به صورت زیر نشان داده می شود:

بنابراین ردیف R1 دارای ولتاژ هست.

در حال حاضر برای مورد اول C1 ولتاژ دارد و برای مورد دوم R1 نیز دارای ولتاژهست، بنابراین با استفاده از موقعیت ماتریسی دکمه ها یعنی شماره یک فشار داده شده است.

اگر دکمه دوم فشار داده شود، ما C1 به عنوان ستون داریم که دارای ولتاژ منطقی یک (+۵ ولت) است، R2 نیز ستون مشترک قرار می گیرد، بنابراین ما C1 و R2 خواهیم داشت، از این رو موقعیت ماتریسی دکمه دوم را داریم.

سوال اینجاست که چگونه ما قرار هست که برنامه ای بنویسیم، ما هشت پایه صفحه کلید را به هشت پایه کنترلر وصل می کنیم.

 

و برای شروع ما چهار پایه کنترل کننده را برای تغذیه دادن به چهار ردیف صفحه کلید وصل می کنیم، در این حال چهار پایه دیگر به عنوان ورودی گرفته می شود. هنگامی که دکمه  ستون مربوطه فشرده می شود پس پین کنترل کننده کشیده می شود، این کار برای شناسایی تغییر ورودی به تغذیه و توان ورودی است، بنابراین ما به عنوان ورودی ردیف در نظر می گیریم.

با این کار، ما دکمه ی مورد نظر کاربر که فشار داده بدست می آوریم. . این آدرس ماتریس به شماره مربوطه اش هدایت می شود و این شماره در LCD نشان داده می شود.

عملکرد ارتباط صفحه کلید با میکروکنترلر AVR  به صورت گام به گام در کد C ، در زیر توضیح داده شده است. همچنین می توانید ارتباط صفحه کلید با میکروکنترلر ۸۰۵۱  بررسی کنید.

 

برنامه

#include <avr/io.h>

//header to enable data flow control over pins

                #define F_CPU 1000000

//telling controller crystal frequency attached

                #include <util/delay.h>

//header to enable delay function in program

                #define    E   ۵

//giving name “enable”  to 5th pin of PORTD, since it Is connected to LCD enable pin

                #define RS  ۶

//giving name “registerselection” to 6th pin of PORTD, since is connected to LCD RS pin

                void send_a_command(unsigned char command);

                void send_a_character(unsigned char character);

               void send_a_string(char *string_of_characters);

                int main(void)

                {

                                DDRB = 0xFF;

                                      //putting portB and portD as output pins

                                DDRD = 0xFF;

                                _delay_ms(50);//giving delay of 50ms

                                int key=0;//allocating integer to reset the LCD once it reaches its display limit

                                int keypressed=0;//integer for storing matrix value

                                send_a_command(0x01); //Clear Screen 0x01 = 00000001

                                _delay_ms(50);

                                send_a_command(0x38);//telling lcd we are using 8bit command /data mode

                                _delay_ms(50);

                                send_a_command(0b00001111);//LCD SCREEN ON and courser blinking

                                send_a_string(“PRESS A KEY”);//displaying a string

                                send_a_command(0x80 + 0x40 +0);// moving courser to second line of LCD

                                                DDRA=0xF0;//taking column pins as input and row pins as output

                                                _delay_ms(1);

                                                PORTA=0x0F;// powering the row ins

                                                _delay_ms(1);

                                while(1)

                {

                       if (PINA!=0b11110000)//in any of column pins goes high execute the loop

                                {

                                                _delay_ms(5);

                                                keypressed = PINA;//taking the column value into integer

                                                DDRA ^=0b11111111;//making rows as inputs and columns as ouput

                                                _delay_ms(1);

                                                PORTA ^= 0b11111111;//powering columns

                                                _delay_ms(1);

                                                keypressed |=PINA;taking row value and OR ing it to column value

                                                if (keypressed==0b00010001)

                                                {

                                                                send_a_string(“1”);//if row1 and column1 is high show “۱”

                                                                                key++;

                                                }

                                                if (keypressed==0b00010010)

                                                {

                                                                send_a_string(“4”);// if row1 and column2 is high show “۴”

                                                                                key++;

                                                }

                                                if (keypressed==0b00010100)

                                                {

                                                                send_a_string(“7”);// if row1 and column3 is high show “۷”

                                                                                key++;

                                                }

                                                if (keypressed==0b00011000)

                                                {

                                                                send_a_string(“*”);//if row1 and column4 is high show “*”

                                                                                key++;

                                                }

                                                if (keypressed==0b00100001)

                                                {

                                                                send_a_string(“2”);// if row2 and column1 is high show “۲”

                                                                key++;

                                                }

                                                if (keypressed==0b00100010)

                                                {

                                                                send_a_string(“5”);// if row2 and column2 is high show “۵”

                                                                key++;

                                                }

                                                if (keypressed==0b00100100)

                                                {

                                                                send_a_string(“8”);// if row2 and column3 is high show “۸”

                                                                key++;

                                                }

                                                if (keypressed==0b00101000)

                                                {

                                                                send_a_string(“0”);// if row2 and column4 is high show “۰”

                                                                key++;

                                                }

                                                if (keypressed==0b01000001)

                                                {

                                                                send_a_string(“3”);

                                                                key++;

                                                }

                                                if (keypressed==0b01000010)

                                                {

                                                                send_a_string(“6”);

                                                                key++;

                                                }

                                                if (keypressed==0b01000100)

                                                {

                                                                send_a_string(“9”);

                                                                key++;

                                                }

                                                if (keypressed==0b01001000)

                                                {

                                                                send_a_string(“#”);

                                                                key++;

                                                }

                                                if (keypressed==0b10000001)

                                                {

                                                                send_a_string(“A”);

                                                                key++;

                                                }

                                                if (keypressed==0b10000010)

                                                {

                                                                send_a_string(“B”);

                                                                key++;

                                                }

                                                if (keypressed==0b10000100)

                                                {

                                                                send_a_string(“C”);

                                                                key++;

                                                }

                                                if (keypressed==0b10001000)

                                                {

                                                                send_a_string(“D”);

                                                                key++;

                                                }

                                                keypressed=0;//after showing integer erasing the row column memory

                                                DDRA ^=0b11111111;//shifting input and power port

                                                _delay_ms(1);

                                                PORTA ^= 0b11111111;//powering row pins of keypad

                                                _delay_ms(220);

                                }

                                if (key==16)//if 16 characters are shown on LCD

                                {

                                                send_a_command(0x01);//clear lcd

                                                send_a_string(“PRESS A KEY”);//display string

                                                send_a_command(0x80 + 0x40 +0);//move courser to second line.

                                                key=0;

                                }

                }

                }

                void send_a_command(unsigned char command)

                {

                                PORTA = command;

                                PORTD &= ~ (1<<RS); //putting 0 in RS to tell lcd we are sending command

                                PORTD |= 1<<E; //telling lcd to receive command /data at the port

                                _delay_ms(50);

                                PORTD &= ~1<<E;//telling lcd we completed sending data

                                PORTA= 0;

                }

                void send_a_character(unsigned char character)

                {

                                PORTA= character;

                                PORTD |= 1<<RS;//telling LCD we are sending data not commands

                                PORTD |= 1<<E;//telling LCD to start receiving command/data

                                _delay_ms(50);

                                PORTD &= ~1<<E;//telling lcd we completed sending data/command

                                PORTA = 0;

                }

                void send_a_string(char *string_of_characters)

{

                while(*string_of_characters > 0)

                {

                                send_a_character(*string_of_characters++);

                }

}

برای دانلود فایل های این پروژه اینجا کلیک کنید.

ادامه مطلب

مطالب برتر

>