این پروژه توسط میکروکنترلر ATMEGA32 و کامپایلر کدویژن طراحی شده. ابتدا با انتخاب * یا # یکی از منو ها انتخاب می شود . برای وارد کردن پسوورد دکمه # فشرده شود و برای تغییر پسوورد دکمه * زده شود.
اگر # انتخاب شود سیستم منتظر دریافت کد می شود اگرعددی اشتباه وارد کردید با زدن دکمه * پاک می شود در صورتی که تمام ارقام کد را وارد کرده برای تائید کد, دکمه # زده شود اگر درست بود خروجی متصل به رله به مدت 500 میلی ثانیه فعال می شود و درب را باز می کند.
اگر کد اشتباه بود برای 2 مرتبه دیگر می توان کد وارد کرد و بعد از آن سیستم دیگر کد دریافت نمی کند. و تنها با فشردن دکمه متصل به پورت B0 به حالت پیش فرض با کد: 1234 بر می گردد.
اما در صورتی که تغییر پسوورد انتخاب شود پسوورد قبلی را وارد می کنید در صورتی که درست بود پسوورد جدید را نیز وارد کرده و با زدن دکمه # آن را تائید میکنید تا ثبت شود.از این پس با این پسوورد وارد می شوید و پسوورد قبلی مورد قبول نمی باشد.
لینک دانلود فایل های این پروژه در انتهای این مطلب آمده است.
توضیحات کد
با دستور اسمبلی زیر lcd کاراکتری به پین میکروکنترلر (پورت A)کانفیگ خواهد شد.
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
رمز ورود نباید بعد از قطع برق از بین برود، بنابراین متغیر pass
( که رمز ورود را در خود ذخیره می کند) را در ایپیرام ذخیره می کنیم برای این کار از کلمه کلیدی eeprom
قبل از تعریف متغیر استفاده می کنیم (در کدویژن) مانند زیر:
متغیر j تعداد دفعاتی که رمز اشتباه وارد می شود.(بعد از سه بار اشتباه قفل شود و دیگر عددی دریافت نکند)
نکته: میکروکنترلر mega32 دارای حافظه ایپیرام داخلی است.
eeprom int pass ,j;
آرایه key[10]
برای ذخیره اعداد (0-9)، * و # می باشد زمانی که دکمه ها فشرده می شود.
unsigned char key[10];
توابع شامل:
unsigned char keypad();
void change_pass();
int enter_pass();
از تابع keypad برای دریافت کاراکتر از کلید ماتریسی استفاده می شود اگر کلیدی فشرده شود کاراکتر متناظر آن را برمی گرداند (0-9 * و #). بنابراین هر زمانی که در برنامه نیاز بود تا کاراکتری از کلید دریافت کنیم این تابع را فراخوانی می کنیم.
از تابع change_pass برای تغییر رمز قبلی استفاده می شود.
و تابع enter_pass برای دریافت رمز ورود استفاده می شود.
الگوریتم برنامه:
در حلقه اصلی برنامه تابع keypad را صدا می زنیم تا مدام در حال اسکن صفحه کلید ماتریسی باشد.
while (1)
{
lcd_puts(" # ENTER PASS");
lcd_gotoxy(0,1);
lcd_puts(" * CHANGE PASS");
lcd_putchar(j);
Temp=keypad();
delay_ms(200);
- اگر
#
فشرده شود رمز دریافت شود.
- و اگر
*
فشرده شود رمز قبلی تغییر داده شود.
حالا اگر # بود و تعداد اشتباه از حد مجاز عبور نکرده بود؟
آنوقت با تابع enter_pass رمز را دریافت کنید و با pass
رمز اصلی ورود مقایسه کند اگر برابر بودند در باز شود (پین خروجی متصل به رله به مدت 500 میلی ثانیه یک شود) و در lcd کاراکتری OPEN نمایش داده می شود.
if(Temp=='#' && j>0)
{
if(enter_pass()== pass)
{
lcd_clear();
lcd_puts("OPEN");
OUTPUT_PORT =128;
delay_ms(500);
lcd_clear();
OUTPUT_PORT =0;
j=3;
}
else
ولی اگر اشتباه بود متغییر j به روز شود زیرا رمز اشتباه وارد شده. ودر lcd کاراکتری نمایش داده می شود.
نکته: اینجا مقدار اولیه j برابر با سه است بنابراین هربار اشتباه وارد شد یکی از مقدار آن کم می کنیم اگر به صفر رسید یعنی از حد مجاز عبور کرده است.
else
{
lcd_clear();
lcd_puts("CLOSE");
delay_ms(500);
lcd_clear();
j--;
}
اگر * بود و تعداد اشتباه از حد مجاز عبور نکرده بود؟
آنوقت با تابع change_pass عملیات تغییر رمز را انجام می دهیم. ابتدا رمز قبلی را باید وارد کرده (در lcd کاراکتری ENTER OLD PASS نمایش داده می شود) در صورتی که درست بود از شما می خواهد که رمز جدید را وارد کنید (در lcd کاراکتری ENTER NEW PASS نمایش داده می شود) در صورت موفقیت آمیز بودن OK در lcd نمایش داده می شود و رمز جدید در متغییر pass
ذخیره می شود.
else if(Temp=='*' && j>0)
change_pass();
و تابع change_pass
void change_pass()
{
lcd_clear();
lcd_puts("ENTER OLD PASS");
delay_ms(500);
while(j!=0)
{
if(enter_pass()==pass)
{
lcd_clear();
lcd_puts("ENTER NEW PASS");
delay_ms(500);
pass = enter_pass();
lcd_clear();
lcd_puts("OK");
delay_ms(500);
return;
}
else j--;
}
}
و در نهایت در حلقه اصلی تعداد رمز ورود اشتباه بررسی میشود. اگر j
به صفر رسیده بود (از 3 به صفر رسیده بود از حد مجاز عبور کرده بود) در lcd کاراکتری SORRY نمایش داده میشود و وارد یک حلقه می شود که تنها با فشردن دکمه ریست از آن خارج می شود. و مقدار متغیرهای pass
و j
به حالت اول بر می گردد و در lcd کاراکتری RESET نمایش داده می شود.
if(j<=0)
{
lcd_clear();
lcd_puts("SORRY");
while(1)
{
if(RESET_PIN==0)
{
lcd_clear();
lcd_puts("RESET");
pass=1234;
j=3;
delay_ms(1000);
lcd_clear();
break;
}
}
}
}
تابع keypad:
این تابع کلید ماتریسی 3در4 را اسکن میکند به این صورت که هر کلیدی که فشرده شود دو پین میکرو کنترلر تغییر می کنند آن را در متغییر scanCode
ذخیره می کند و با دستور switch کاراکتر متناظر آن را بر می گرداند.
نکته: در صورتی که دکمه ای فشرده نشود کاراکتر پیش فرض _
را بر می گرداند.
char keypad()
{
unsigned char scanCode=0xf0 ,butNum;
while(scanCode==0xf0)
{
KEYPAD_DDR = 0x0f;
KEYPAD_PORT = 0xf0;
delay_us(5);
scanCode= KEYPAD_PIN;
}
KEYPAD_DDR = 0xf0;
KEYPAD_PORT = 0x0f;
delay_us(5);
scanCode |= KEYPAD_PIN;
switch (scanCode)
{
case 0xee: butNum='1'; break;
case 0xed: butNum='2'; break;
case 0xeb: butNum='3'; break;
case 0xe7: butNum=0; break;
case 0xde: butNum='4'; break;
case 0xdd: butNum='5'; break;
case 0xdb: butNum='6'; break;
case 0xd7: butNum=0; break;
case 0xbe: butNum='7'; break;
case 0xbd: butNum='8'; break;
case 0xbb: butNum='9'; break;
case 0xb7: butNum=0; break;
case 0x7e: butNum='*'; break;
case 0x7d: butNum='0'; break;
case 0x7b: butNum='#'; break;
case 0x77: butNum=0; break;
default: butNum='_';
};
return butNum;
}