
در کنار lcd های کاراکتری ، صفحه کلید ماتریسی یکی از پرکاربردترین لوازمی است که کاربران از آنها در مدارات میکروکنترلری استفاده می کنند و توسط آنها می توانند از دنیای بیرون به میکروکنترلر دیتا ارسال کرده و آن را پردازش کنند.
صفحه کلید ماتریسی متشکل از تعداد زیادی کلید است ، که بصورت ماتریسی روی هم قرار گرفته اند و ماتریسی بودن کلید ها به ما این امکان را می دهد تا علاوه بر بهرمندی از تعداد زیادی کلید ، تعداد کمی از پایه های میکروکنترلرها را اشغال کنیم .
صفحه کلید ماتریسی در ابعاد و اندازه های مختلفی در بازار وجود دارند. که از پرکاربردترین آنها می توان صفحه کلید ماتریسی ۴*۴ یا شانزده کلید و صفحه کلید ماتریسی ۴*۳ یا دوازده کلید را نام برد .
در پایان آموزش برنامه نوشته شده برای اسکن صفحه کلید ماتریسی ۴*۴ را به یک کتابخانه تبدیل می کنیم تا کاربران براحتی بتوانند تنها با بکاربردن چند دستور ساده عمل کلید خوانی را انجام دهند .

موضوعاتی که در این مقاله به آنها پرداخته خواهد شد :
آموزش اسکن صفحه کلید ماتریسی 4*4 با avr
برای اسکن صفحه کلید ماتریسی 4*4 از الگوریتمی بسیار ساده استفاده شده است . به این صورت که صفحه کلید ماتریسی 4X4 به یک جدول جمع اعداد تشبیه شده است .
اعدادی در سطرها و ستون های صفحه کلید ماتریسی 4×4 قرار داده شده است . که از حاصل جمع آنها موقعیت کلید فشرده شده بدست می آید .
در این روش مقدار کلید فشرده شده طی دو مرحله بدست می آید که در ادامه به آن خواهیم پرداخت . شکل زیر نحوه اتصال یک صفحه کلید ماتریسی 4X4 به یکی از پورتهای میکرو کنترلر avr را نشان می دهد .

مرحله اول اسکن صفحه کلید ماتریسی 4X4
در مرحله اول اسکن صفحه کلید ماتریسی 4X4 پایه هایی را که به ستون های صفحه کلید ماتریسی 4×4 وصل کرده ایم به عنوان پایه های خروجی و پایه هایی را که به سطر های صفحه کلید ماتریسی 4*4 وصل کرده ایم به عنوان پایه های ورودی تعریف می کنیم .
سپس مقدار صفر منطقی را روی پایه های خروجی قرار می دهیم و در نهایت شروع به اسکن پایه هایی که به عنوان ورودی تعریف شده اند می کنیم . اگر مقدار پایه ای صفر باشد به منزله این است که کلیدی در آن سطر فشرده شده و مقدار متناظر با آن سطر را از جدول جمعی که تشکیل داده بودیم در یک متغییر ذخیره می کنیم .

unsigned char row; DDRx =0XF0; // 4 OUT 4 IN PORTx=0X0F; // key columns all low and active pull ups on rows enabled if(PINx.3==0) row=0; if(PINx.2==0) row=4; if(PINx.1==0) row=8; if(PINx.0==0) row=12;
مرحله دوم اسکن صفحه کلید ماتریسی 4X4
در مرحله دوم برعکس مرحله اول عمل می کنیم پایه هایی را که به ستون های صفحه کلید ماتریسی ۴*۴ وصل کرده ایم به عنوان پایه های ورودی تعریف می کنیم و پایه هایی را که به سطرهای صفحه کلید ماتریسی ۴*۴ وصل کرده ایم به عنوان پایه های خروجی تعریف می کنیم .
سپس مقدار صفر منطقی را روی پایه های خروجی قرار می دهیم و در نهایت شروع به اسکن پایه هایی که به عنوان ورودی تعریف شده اند می کنیم و اگر مقدار پایه ای صفر باشد به منزله این است که کلیدی در آن ستون فشرده شده و مقدار متناظر با آن ستون را از جدول جمعی که تشکیل داده بودیم در یک متغییر دیگر ذخیره می کنیم .

unsigned char column; DDRx =0X0F; // 4 IN 4 OUT / change port configuration PORTx=0XF0; // enable pull ups on columns and write 0s to rows if(PINx.7==0) column =0; if(PINx.6==0) column =1; if(PINx.5==0) column =2; if(PINx.4==0) column =3;
بعد از مراحل اسکن صفحه کلید ماتریسی 4X4 ، برای مشخص کردن موقعیت کلید فشرده شده ، کافیست تا اعدادی را که از دو مرحله قبل در متغییرهای row , column ذخیره کردیم با یکدیگر جمع کنیم . در پایان نیز با تعریف یک آرایه شانزده رقمی و قرار دادن مقادیر asci اعداد در آن می توان کاراکتر متناظر با صفحه کلید را از درون این آرایه جهت نمایش روی lcd کاراکتری استخراج کرد .
flash char kbd_table[16]={‘۱’,’۲′,’۳′,’A ‘۴’,’۵’,’۶’,’B’, ‘۷’,’۸’,’۹’,’C’, ‘*’,’۰’,’#’,’D’}; char key; key=kbd_table [ row + column ];
برای درک بهتر مسئله به ذکر یک مثال می پردازیم :
فرض می کنیم کلید شماره ۹ از روی صفحه کلید ماتریسی ۴*۴ را فشرده ایم طبق مرحله اول اسکن صفحه کلید ، P.1 از پایه های پورت ما برابر با مقدار صفر می شود و با توجه به دستور if(PINx.1==0) row=8 مقدار ۸ در متغییر row جا می گیرد .
در مرحله دوم اسکن صفحه کلید ، P.6 از پایه های پورت ما برابر با مقدار صفر می شود و با توجه به دستور if(PINx.6==0) column =1 مقدار ۱ در متغییر column جا می گیرد و در نهایت با جمع دو متغییر row+column عدد ۹ بدست می آید که همان مقدار کلید فشرده شده است .
معرفی توابع کتابخانه اسکن صفحه کلید ماتریسی ۴*۴ با نرم افزار codevision

تابع kbd_init
الگوی این تابع به شکل زیر می باشد :
void kbd_init(void);
این تابع جهت initializes یا مقدار دهی اولیه پورت می باشد .
تابع debounce
الگوی این تابع به شکل زیر می باشد :
void debounce(unsigned char Debouncing_time);
این تابع دارای یک پارامتر با نام Debouncing_time است که مقدار آن از ۰ تا ۲۰۰ بر حسب میلی ثانیه می باشد و یک تاخیر از ۰ تا ۲۰۰ میلی ثانیه بعد از فشرده شدن هر کلید بوجود می آورد تا لرزشی که در هنگام فشرده شدن کلید پدید می آید از بین برود و این لرزش به منزله فشرده شدن کلید طلقی نگردد .
اگر مقداری بیشتر از ۲۰۰ به آرگومان این تابع بدهیم حداکثر تاخیر یعنی همان ۲۰۰ میلی ثانیه منظور می گردد ، مناسب ترین مقدار برای جلوگیری از لرزش کلیدمقدار ۱۰۰ میلی ثانیه می باشد . مقدار Debouncing_time بصورت پیش فرض ۱۰۰ قرار داده شده .

تابع waitkey
الگوی این تابع به شکل زیر می باشد :
void waitkey(void);
این تابع منتظر فشرده شدن کلید می ماند .
تابع waitnokey
الگوی این تابع به شکل زیر می باشد :
void waitnokey(void);
این تابع منتظر می ماند تا کلید فشرده شده رها شود یا به عبارتی فشرده نشدن کلیدها را چک می کند .
تابع readkey
الگوی این تابع به شکل زیر می باشد :
char readkey(void);
این تابع صفحه کلید را اسکن می کند و اگر کلیدی فشرده شده باشد مقدار آن را می خواند .
تابع getkey
الگوی این تابع به شکل زیر می باشد :
char getkey(void);
این تابع اصلی ترین تابع می باشد که ما برای اسکن صفحه کلید ماتریسی ۴*۴ از آن استفاده می کنیم ، این تابع ترکیبی از توابعی است که قبلا ذکر شد .
این تابع منتظر فشرده شدن کلید می ماند و پس از فشرده شدن کلید عمل debounce گیری را انجام می دهد سپس صفحه کلید را اسکن کرده و مقدار کلید فشرده شده را می خواند و درنهایت منتظر می ماند تا کلید فشرده شده رها شود .
تابع getnum
الگوی این تابع به شکل زیر می باشد :
char getnum(void);
عملکرد این تابع شبیه عملکرد تابع getkey می باشد با این تفاوت که فقط مقادیر کاراکتر های ۰ تا ۹ را برمی گرداند .
اگر مقادیر خوانده شده از صفحه کلید ، متناظر با کلید فشرده شده توسط شما نبود . فایل کتابخانه ای keypad.lib را توسط محیط کدویژن باز نموده و با جابجایی کاراکترها در جدول kbd_lib این مشکل را برطرف نمایید .

اسکن صفحه کلید ماتریسی ۴*۴ و نمایش بر روی lcd 2*16
ابتدا از پوشه library که پیوست این مقاله می باشد فایل هدر keypad.h را در پوشه inc و فایل کتابخانه ای keypad.lib را در پوشه lib در مسیری که نرم افزار کدویژن را نصب کرده اید کوپی کنید .
سپس نرم افزار کدویژن را اجرا کرده و توسط کدویزارد از زبانه Chip آی سی مورد نظر و از قسمت Alphanumeric LCD پیکربندی LCD را انجام داده و در ادامه با ذخیره فایل تولید شده توسط codewizard بستری را برای برنامه نویسی خود فراهم کنید.
سپس با استفاده از دستور پیش پردازنده <include <keypad.h# فایل هدر keypad را به برنامه خود اضافه کنید . حال نوبت به معرفی پورتی که قرار است کیپد ۴*۴ را به آن متصل کنیم می رسد .
برای سادگی و قابل فهم بودن پیکربندی keypad روی پورت مورد نظر ، از الگوی پیکربندی lcd کاراکتری که در ورژن های قدیمیتر کدویژن و به زبان اسمبلی استفاده می شد بکار گرفته شده است ، برای انجام پیکربندی ابتدا باید آدرس پورتهای خروجی میکروکنترلر AVR را بدانیم.

الگوی پیکربندی lcd کاراکتری به شکل زیر می باشد :
#asm .equ __lcd_port=0x18 ;portb #endasm #include <lcd.h>;
الگوی پیکربندی ۴*۴ keypad به شکل زیر می باشد :
#asm .equ __kbd_port=0x1b ;porta #endasm #include <keypad.h>;
نمایش کلید فشرده شده بر روی lcd کاراکتری

/**************************************************** Project : 4 x 4 Keypad - polling Version : 1 Date : 4/5/2013 Author : hossein ghiasvand Company : http://www.micronik.ir E-mail :hossein.ghiasvand@gmail.com Chip type : ATmega16 Program type : Application AVR Core Clock frequency: 8.000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 ****************************************************/ #include <mega16.h> #include <delay.h> #include <alcd.h> #asm .equ __kbd_port=0x1b ;PORTA #endasm #include <keypad.h> void main(void) { lcd_init(16); kbd_init(); while (1) { unsigned char keypressed; lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Enter Key:"); lcd_gotoxy(0,1); _lcd_write_data(0x0f); //Cursor blanked while(1) { keypressed=getkey(); lcd_putchar(keypressed); if(keypressed=='C') break; //'C'-----> clear screen } } }
در مثال ذکر شده اسکن صفحه کلید ماتریسی ۴*۴ به روش polling یا سرکشی صورت می پذیرد ، یعنی میکروکنترلر باید دائما به پورتی که کیپد به آن متصل شده سرکشی کند تا فشرده شدن کلیدی را متوجه شود .
این عمل باعث اشغال شدن cpu می شود و از کارایی میکروکنترلر avr کاسته می شود ، برای رفع این مشکل از روشی به نام wake up در اسکن صفحه کلید ۴*۴ استفاده می کنیم .
در این روش با استفاده از چهار عدد دیود 1N4148 سطرهای کیپد ( P.0 تا P.3) را به یکی از وقفه های خارجی میکروکنترلر متصل می کنیم و با فعال سازی وقفه خارجی ، هنگامی که کلیدی فشرده شود زیر برنامه وقفه خارجی اتفاق می افتد و با نوشتن دستورات مربوط به کلید خوانی در زیر برنامه وقفه ، مقدار کلید فشرده شده را بدون نیاز به سرکشی دائم و اشغال شدن cpu میکروکنترلر بدست می آورد .

مثال :
ابتدا با استفاده از چهار عدد دیود 1N4148 پینهای صفر تا سه از پورتی که کیپد به آن متصل شده را مطابق شکل به پایه INT0 میکروکنترلر وصل کنید . سپس PIND.2 که ورودی وقفه خارجی صفر است را به عنوان ورودی و مقاومت poll up آن را فعال نموده و وقفه خارجی صفر را در مد low level قرار دهید . در این مثال lcd روی PORTB پیکربندی شده .
/**************************************************** Project : 4 x 4 Keypad - Wake-up on Keypress Version : 2 Date : 4/5/2013 Author : hossein ghiasvand Company : http://www.micronik.ir E-mail :hossein.ghiasvand@gmail.com Comments: • ۱۶ Key Pushbutton Pad in 4 x 4 Matrix Chip type : ATmega16 Program type : Application AVR Core Clock frequency: 8.000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 ****************************************************/ #include <mega16.h> #include <delay.h> #include <alcd.h> #include <keypad.h> #asm .equ __kbd_port=0x1b ;PORTA #endasm _Bool wakeup=0; char k; void main(void) { DDRD=0X00; PORTD=0Xff; MCUCR=0x30; GIMSK=0x40; lcd_init(16); lcd_clear(); kbd_init(); #asm("sei") while (1) { if(wakeup){ k=getkey(); wakeup=0; lcd_putchar(k); if( k=='C') lcd_clear(); //'C'-----> clear }; // Place your code here } } interrupt [EXT_INT0] void ext_int0_isr(void) { wakeup=1; }
قابلیت های کتابخانه صفحه کلید 4*4 و 4*3 برای STM32
اسکن صفحه کلید به روش polling
اسکن صفحه کلید به روش external inrerrupt
اسکن صفحه کلید به روش timer
اتصال پایه های صفحه کلید به پایه های دلخواه از میکروکنترلر
پیکربندی پایه ها در محیط نرم افزار stm32cubemx ، بدون نیاز تغییر در کتابخانه
قابل استفاده در keil و stm32cubeide
نوشته شده توسط توابع HAL
به همراه کتابخانه LCD کاراکتری ، مثال و راهنمای استفاده
پروژه قفل رمزدار دیجیتال توسط STM32
قابلیت نمایش رمز تایپ شده تا 8 رقم بر روی LCD کاراکتری
قابلیت پاک کردن رمز و کاراکترهای تایپ شده بر روی LCD
قفل شدن اتوماتیک ، در صورت عدم تایپ بعد از 15 ثانیه
قابلیت تغییر رمز عبور و ذخیره در حافظه EEPROM Emulation میکروکنترلر STM32
قابلیت بازنشانی رمز عبور به رمز پیشفرض با نگهداشتن کلید مخفی به مدت 6 ثانیه
به همراه کتابخانه کیپد و LCD کاراکتری برای STM32