راه اندازی keypad بوسیله میکروکنترلر AVR
![](https://nirasystem.com/blog/wp-content/uploads/2021/08/1-1.png)
در چه پروژه هایی از keypad استفاده می کنیم؟
فرض کنید عملکرد سیستم طوری هست که نیاز به هندل کردن یک menu داریم
برای راه اندازی ماژول gsm نیاز به وارد کردن شماره تلفن داریم
میخوایم برنامه ماشین حسابی را بنویسیم و …
برای انجام همه ی اینکارها نیاز به keypad داریم تا با استفاده از دکمه ها روند سیستم مورد نظر راه اندازی کنیم.
از دیگر مزایای keypad این هست که به جای اشغال کردن ۱۶ تا پین میکرو برای وصل کردن ۱۶ دکمه از ۸ پین استفاده میکنیم (صرفه جویی در استفاده از پین ها)
نحوه ی عملکرد keypad چگونه است ؟
گفته شد که به جای استفاده از ۱۶ پین قرار هست از ۸ پین استفاده کنیم؛ اما چطور این کار انجام میدیم ؟
اگر با ماتریس ها آشنا باشید ساختار کیپد ها هم مثل همون ماتریس ها هستند. یک keypad 4 * 4 (4 سطر و ۴ ستون) ما ۱۶ تا دکمه خواهیم داشت که سطر و ستون ها به هم متصل هستند. با فشردن یک کلید ارتباطی بین سطر و ستون ایجاد خواهد شد !
در شکل زیر یک keypad ۴*۴ را میتوانید میبینید:
این شکل به طور واضح رابطه بین سطر و ستون های کیپد را به شما نشان میدهد! ۴ پین برای سطر و ۴ پین برای ستون مصرف میشود.
چگونه از keypad استفاده کنیم؟
کافیه که ما همه ی پایه های ستون یک منطقی کنیم و در سطر صفر رو shift دهیم (یک سطر صفر باشد در حالی که بقیه یک منطقی هستن و به همین شکل شیفت داده شود).
و با فشردن یک کلید اتفاق زیر خواهد افتاد:
سطر به ستون متناظر وصل و ستون موردنظر هم صفر خواهد شد. با تشخیص صفر شدن ستون میتوانیم فشردن کلید را تشخیص دهیم.
برای تهیه برد آموزشی میکروکنترلر AVR اینجا کلیک کنید.
نوشتن کد :
قبلا از اینکه وارد نوشتن برنامه بشیم نحوه شیفت دادن صفر میخوام اینجا بهتون بگم. سادست کافیه که ما ۱ رو شیفت بدیم بعد not کنیمش!
PORTD = ~(1 << row);
ابتدا کتابخانه های مورد نیاز برای این پروژه را تعریف میکنیم.
کتابخانه mega16 چون از میکرو mega16 استفاده کردیم.
کتابخونه alcd برای دسترسی به توابع ال سی دی کاراکتری .
کتابخونه delay برای استفاده از تاخیر در برنامه .
#include <mega16.h>
#include <alcd.h>
#include <delay.h>
#include <string.h>
#include <stdint.h>
ستون های keypad از PORTD4 تا PORTD7 در نظر میگیریم و برای خوانایی بهتر برنامه بهشون اسامی بهتری میدیم.
#define C0 PIND.4
#define C1 PIND.5
#define C2 PIND.6
#define C3 PIND.7
قدم بعدی تعریف تابع و آرایه ی کیپد و متغیر هایی هست که در ادامه برنامه احتیاج دارم
void keypad(void);
char layout[16]= {‘C’,’2′,’3′,’/’,’1′,’5′,’6′,’*’,’4′,’8′,’9′,’+’,’7′,’0′,’=’,’-‘};
** این آرایه طبق کلید های کیپدی که داخل شکل خودم بالا هست نوشته شده، شما میتونید تغییرش بدید.
از اونجایی که پایه های سطر قرار صفر رو شیفت بدند پس نیازه که خروجی بشن و بعد هم تابع init ال سی دی کاراکتری رو تعریف کردم.
void main(void)
{
DDRD = 0x0F;//پایه های سطر خروجی شدند
#asm(“sei”)
lcd_init(16);
اگه چیزی از راه اندازی و توابع ال سی دی کاراکتری نمیدونید لینک زیر رو یک نگاهی بندازید اول !
قبل از اینکه وارد while(1) بشیم باید بریم ببینیم داخل keypad چه خبره !
(برای اینکه بهتر شیفت دادن رو متوجه بشید ، پیشنهاد میکنم این تیکرو به تنهایی با تاخیر بیشتر اجرا کنید تا عملکرد رو ببینید)
راه اندازی ال سی دی کاراکتری با میکروکنترلر AVR
متغیر ۸ بیتی بدون علامت row رو تعریف میکنیم که به معنای سطره و به متغیر دیگه ای به اسم keyPadColumn هم احتیاج داریم .
برای اینکه صفر هارو شیفت بدیم از for استفاده کردیم و از همون تکنیکی که بالا گفتم صفر هارو شیفت میدیم . هر بار که داخل for میگرده ۴ تا if رو چک میکنه تا ببینه که آیا کلیدی فشرده شده یا نه ! هر کلیدی که فشرده بشه ، ستون متناظرش صفر میشه(ستون هم که همون پین های D4 تا D7 میکرو بود)
void keypad(void)
{
uint8_t row = 0;
int keyPadColumn = -1;
for(row = 0; row < 4; row++)
{
;PORTD = ~(1 << row)
if (C0 == 0) {keyPadColumn = 0;}
if (C1 == 0) {keyPadColumn = 1;}
if (C2 == 0) {keyPadColumn = 2;}
if (C3 == 0) {keyPadColumn = 3;}
if چک میکنه که حتما کلیدی فشرده شده باشه و مقدار keyPadColumn مخالف مقدار اولیش باشه! حالا keyPadColumn یک مقداری رو با فشردن کلید میگیره و اون مقدار در فرمول keyPadPosition جای گذاری میشه و موقعیت کلید زده مشخص میشه و از داخل آرایه کاراکتر مورد نظر رو برمیداره و روی lcd با تابع lcdputchar نمایش میده !(اگر نمیدونید این تابع کارش چیه حتما مطالب لینک بالا رو بخونید!)
** دقت کنید که نیازه در آخر حتما keyPadColumn دوباره مقدار اولیه ی خودشو بگیره تا دوباره منتظر زدن کلید بشیم و اون رو روی ال سی دی نمایش بدیم.
if(keyPadColumn != -1)
{
keyPadPosition = row * 4 + keyPadColumn;//calculate Position
;lcd_putchar(layout[keyPadPosition])
;keyPadColumn = -1
}
;delay_ms(30)
}
}
** در آخر هم باید این تابع رو توی while(1) تعریف کنیم تا بی نهایت بار تکرار بشه .
دوره ویدیوئی برنامه نویسی Embedded c مقدماتی
در قسمت فایل های ضمیمه فایل برنامه گذاشته شده میتونید دانلودش کنید.
موفق باشید .