صفحه کلید یا Keypad

ارتباط با صفحه کلید در تمام پروژه های میکروکنترولری مشترک است . در پست قبلی یک روش ساده ارتباطی که از یک پورت استفاده میکرد توضیح داده شد .این روش در مواردی که تعداد کلید ها کم باشد و پین های I/O خالی و استفاده نشده داشته باشیم مناسب است .اما کیبورد کامپیوتر را در نظر بگیرید که از حدود بیش از 105تا دکمه تشکیل شده در صورتی که بخواهیم یک کیبورد با میکروکنترولر بسازیم نمی توان از این روش استفاده کرد چون حداکثر 23تا دکمه به Mega8 میتوان وصل کرد در ضمن خروجی را هم باید در نظر گرفت که باز هم کمتر میشود .در نتیجه این روش اصلا برای این مسئله خاص مناسب نیست چون تعداد زیادی از پین های میکرو را اشغال میکند و بهینه نیست .

راه حل استفاده از یک ماتریس است .در علم کامپیوتر ماتریسها از اهمیت ویژه ای برخوردار هستند نه تنها در نرم افزار ( بردار ها , ماتریس دوران ,ماتریس انتقال ,جداول و . . . ) بلکه در سخت افزار ( مانند این مثال ) هم از آنها استفاده میشود پس هرچقدر در مورد ماتریس مطلب بخوانید ضرر نخواهید کرد .با استفاده از یک شبکه از کلید ها که به صورت سطری و ستونی به یکدیگر وصل شده اند میتوان تعداد بیشتری کلید را به میکرو وصل کرد سپس با Scan کردن این ماتریس موقعیت کلید فشرده شده را در شبکه پیدا کرد , بعد با استفاده از یک جدول Scan Code مربوطه را استخراج میکنیم .( از ماتریس برای Decode کردن ماتریس استفاده میکنیم خیلی جالبه نه !)


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


بعد از تهیه صفحه کلید نوبت به برنامه نویسی میرسد . چندین راه برای خواندن صفحه کلید وجود دارد .

یک راه استفاده از Switch است . در این روش مقدار پورت در یک متغییر ذخیره میشود و با switch کردن آن, scancode بدست می آید.

راه دوم استفاده از دو آرایه است .در آرایه اول مقادیری که با فشرده شدن یک کلید در پورت ظاهر میشود و در آرایه دوم scancode ی که در آرایه اول ذخیره شده قرار میگیرند . برای دیکد کردن , در یک حلقه مقداری که از پورت خوانده شده با اعداد آرایه اول مقایسه می شود در صورت برابر بودن مقادیر , اندیس ذخیره میشود و با استفاده از آن scancode از آرایه دوم بدست می آید .

راه سوم ( که از نمونه کد های خودم هستش وبهینه بودن ازش می باره و البته در این مورد خوب جواب میده ) بدین صورت است که شماره سطر وستون کلید را تبدیل به یک عدد کنیم که آن عدد اندیس scancode در یک آرایه باشد .فرمول تبدیل هم همان فرمول ذخیره سازی یک آرایه دو بعدی در حافظه است که در درس ساختمان داده خواندیم .

راههای دیگری هم وجود دارد مثلاً میتوان با استفاده از ADCیا (Analog-to-Digital Converter) و فقط با یک پایه I/O جای کلید را پیدا کرد . اگر کسی علاقه مند بود میتواند از این سایت بیشتر در این مورد تحقیق کند .

من برنامه هایی که نوشتم را به صورت تابع در آوردم تا اگر خواستید استفاده کنید ,یکی از برنامه های زیر را در بالای تابع main کپی کنید یا به صورت یک هدر در آورید و به برنامه اضافه کنید. اگر خواستید پورت صفحه کلید را هم عوض کنید کافیست نام پورت و رجیستر جهت را که در جلوی عبارت پیش پردازنده define آمده را تغییر دهید.لازم به ذکر است که توابع زیر تا زمانی که کلیدی فشارداده نشود منتظر میمانند و در صورتی استفاده میشوند که پردازنده کار دیگری برای انجام دادن نداشته باشد وفقط بخواهد مقادیری را دریافت کند .این مورد کم پیش می آید که پردازنده بی کار باشد ,برای رفع این مشکل باید از Interrupt استفاده کنیم .(در این مورد بحث نمی کنیم ولی اگر سوالی داشتید بپرسید.)

 

#define KEYPAD_DDR  DDRB
#define KEYPAD_PORT PORTB

char Get_Key()
{
    char btn,i,j;
    do
    {
        KEYPAD_DDR=0xF0;
        KEYPAD_PORT=0x0F;
        delay_us(500);
        btn=PINB;

        KEYPAD_DDR=0x0F;
        KEYPAD_PORT=0xF0;
        delay_us(500);
        btn|=PINB;
    }
    while (btn==0xFF);
    i=j=~btn;
    if((i=(i&0x0F)>>1)==4)i--;
    if((j=(j&0xF0)>>5)==4)j--;
    return i*4+j;
}

 

#define KEYPAD_DDR  DDRB
#define KEYPAD_PORT PORTB
flash unsigned char tbl[16]=
{
    0x11, 0x21, 0x41, 0x81,
    0x12, 0x22, 0x42, 0x82,
    0x14, 0x24, 0x44, 0x84,
    0x18, 0x28, 0x48, 0x88
};
char Get_Key()
{
    char btn=0;
    char i;
    do
    {
        KEYPAD_DDR=0xF0;
        KEYPAD_PORT=0x0F;
        delay_us(500);
        btn=PINB;

        KEYPAD_DDR=0x0F;
        KEYPAD_PORT=0xF0;
        delay_us(500);
        btn|=PINB;
    }
    while (btn==0xFF);
    btn=~btn;
    for(i=0;i<16;++i)
         if(tbl[i]==btn)
                return i;
}

و برای استفاده کردن در main هم فقط کافیه یک خط کد مثلاً به صورت زیر بنویسید .


PORTD=Get_Key();

دیگه کم کم داریم حرفه ای میشیم ها ! پست بعدی در مورد LCD خواهد بود.

پایان!

Advertisements

دربارهٔ DeltaCode

Somewhere near the sky Far away from people Far away from noise Somewhere near yourself

Posted on ژانویه 29, 2011, in AVR and tagged , . Bookmark the permalink. 7 دیدگاه.

  1. وحید یک نکته، (قبلش بابت مطلب خوب تشکر ی کنم) این که اول مطلب گفتی تو پست قبلی ، اما بهش لینک ندادی.

  2. راستی ساختمان داده …شیری یا روباه ؟

  3. تو چی فکر میکنی ؟

  4. شیر که هستی اما این که چند درصد شیر باشی نمی دونم!

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

  6. اینها که گفتی چه ربطی به AVR داشت اگر سوالی راجع به keypad داری بپرس.

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

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: