راه اندازی صفحه کلید

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

سخت افزار مورد استفاده:  در این جا از 12 عدد پوش باتن که به صورت ماتریس 3×4 در برد آموزشی avr شرکت نامینیک مبتنی بر ATMEGA32 است استفاده شده. این کلید ها مستقیما به پایه های میکرو وصل شده و pullup نشده است. 4 عدد ستون صفحه کلید به پین های 0 تا 3 پورت c میکرو و 3 سطر صفحه کلید به پین های 4 تا 6 همین پورت متصل است.

کتابخانه های مورد استفاده: در این جا مهم راه اندازی پورت ها است پس کتابخانه تعریف خود میکرو لازم است. به علاوه کتابخانه lcd کاراکتری، کتابخانه توابع ورودی خروجی و کتابخانه تاخیر ها در خطوط 9 الی 12 برنامه دیده می شود. (راه اندازی ال سی دی کاراکتری به صورت جداگانه در سایت نامینیک برسی شده است.)

شرح کد برنامه:

صفحه کلید دارای 4 سطر و 3 ستون است. هر کلید در تقاطع یک سطر با یک ستون قرار گرفته است. به محض فشرده شدن یک کلید ارتباط کل آن سطر با کل آن ستون برقرار می شود. اگر دو کلید مختلف که روی یک سطر قرار دارند همزمان فشرده شوند، فقط همان سطر به دو ستونی که کلید ها بر آن ها قرار دارند متصل می شود. پس معمولا بهتر است در هر لحظه فقط یک کلید فشرده شود. در اینجا جمع سطر ها و ستون ها 7 تاست. در روش اول می توان بسته به شرایط مثلا ابتدا همه ستون ها را خروجی تعریف کرده و سطر ها را ورودی. به همه خروجی ها مقدار 1 می دهیم. بعد در برنامه ستون ها (خروجی ها) را یکی یکی به ترتیب صفر کرده . تمام سطر ها را می خوانیم. چون سطر ها مقاومت پول آپ دارند آن سطری که صفر شده را خوانده و به همراه همان ستون که باعث صفر شدن بوده در خروجی نمایش می دهیم. البته می توان از یک آرایه دوبعدی برای بازسازی سمبولیک هر دکمه نیز استفاده کرد. که یک بعد آن را به شماره سطر و بعد دیگر را به شماره ستون صفحه کلید نسبت داد.

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

خوشبختانه سرعت پاسخ دهی میکرو خیلی سریعتر از انسان است. به محض فشرده شدن کلید، قبل از اینکه دست از روی کلید برداشته شود، میکرو کلید صحیح را یافته است. بعضی اوقات هم این سرعت دردسر ساز می شود که موضوع بحث ما نیست.

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

لازم به ذکر است که این ها طرح کلی کار است و قطعا برنامه دارای جزئییات دقیقتری است. مثلا این که می گوییم سطر را بازیابی می کنیم، نگفتیم چگونه! که جزئییات آن به روش برنامه نویس بر می گردد. ما در این مقاله سعی کردیم روشی ساده به کار بریم.

به برنامه برمی گردیم.

در خطوط 59 تا 64 در یک حلقه for بدنه اسکن پورت ماست. تابع col_condition درون این حلقه که در خطوط 17 تا 43 تعریف شده به ازای ستونی خاص شماره سطر مربوطه را بر می گرداند و در نهایت در خطوط 66 تا 76 نتایج نمایش داده می شود.

/*****************************************************
Chip type               : ATmega32
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/
 
#include <mega32.h>
#include <delay.h>
#include <stdio.h>  //for call sprintf.
#include <alcd.h>   //for lcd functions and definitions.
 
 
unsigned int row,column;
 
void col_condition(int count)
{
  if((PINC & 0x70)==0x60)
  {
    column=count+1;
    row=1;
  }
  if((PINC & 0x70)==0x50)
  {
    column=count+1;
    row=2;
  }
  if((PINC & 0x70)==0x30)
  {
    column=count+1;
    row=3;
  }
}//end of col_condition.
 
void main(void)
{
 
int i=0;
char lcd_result[10];
unsigned char port_st[4]={0x0E,0x0D,0x0B,0x07};
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=out Func2=Out Func1=Out Func0=Out
// State7=T State6=P State5=P State4=P State3=1 State2=1 State1=1 State0=1
PORTC=0x7F;
DDRC=0x0F;     //pins(0,1,2) defined as output with 1 value and pins(3,4,5,6) defined in with pull up.
 
lcd_init(16);   //initiate lcd.
 
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Press Any Key:");
 
while (1)
      {
       row=0;
       column=0;
       
       for(i=0;i<4;i++)      //3 is column in 4*3 matrix key.(3 is less)
       {
         PORTC=((PORTC & 0xF0)| port_st[i]);        
         col_condition(i);
         delay_ms(20);
       }//end of for.
       
       if(row!=0)
       {
          lcd_clear();
          lcd_gotoxy(0,0);
          lcd_putsf("Last COL & ROW:");
          
          lcd_gotoxy(0,1);
          sprintf(lcd_result,"%1d AND %1d",column,row);
          lcd_puts(lcd_result);
          delay_ms(50);
       }
       
      }//while(1)
}

دانلود سورس کد

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

با کلیک بر روی عکس زیر فیلم راه اندازی این پروژه را مشاهده کیند.

 

Tags: , ,