به نام خدا
طراحی keypad فقط با یک پایه میکرو
مقدمه:
همانطور که میدونید کیپدهای موجود در بازار چه کیپدهای فلت و چه نوع دیگه، یک سری محدودیت هایی برای طراح ایجاد میکنن.مثلا تعداد پایه های میکرو که کیپد باید بهش وصل بشه و یا اینکه تعداد کلیدهای کیپد کم هستن و نیاز بعضی پروژه ها رو برآورده نمی کنن و یا اینکه با افزایش کلیدهای کیپد، پین های میکروی بیشتری اشغال میشن…
در این آموزش سعی داریم یه روشی رو بهتون معرفی کنیم که بتونید یک keypad (کیپد) با هر تعداد کلید طراحی کنید و فقط و فقط یک پایه میکروی شما برای کیپد اشغال بشه.
برای طراحی keypad فقط با یک پایه میکرو از مبدل آنالوگ به دیجیتال یا همون ADC میکرو استفاده می کنیم. در این روش اساس کار و مهمترین بخش نحوه چیدن مقاومت هاست که باید طوری چیده شوند که به ازای هر کلید ولتاژ یکتای مربوط به اون کلید توسط ADC میکرو خونده بشه.
در این آموزش با استفاده از یک کلید رو از کیپدی که خودمون طراحی کردیم، میخونیم و روی LCD کاراکتری 16×2 نمایش میدیم. و از میکرو کنترلر Atmega32 استفاده می کنیم.
در ATmega32 پایه های ADC روی پورت A هستن و ما در این پروژه هم LCD و هم Keypad رو روی پورت A وصل می کنیم.
معمولا برای اتصال LCD، پایه های A0,A1,A2,A4,A5,A6,A7 میکرو اشغال میشه و تنها پایه آزاد همون A3 هستش (ADC3) که کیپد رو به اون وصل می کنیم.
در ابتدا برنامه ای در میکرو کنترلر می نویسیم تا ولتاژ روی پایه ADC3 رو به ازای هر کلید به دیجیتال تبدیل کرده و روی LCD نمایش بده.بعد این مقادیر ذیجیتال رو تو یه جدول شبیه زیر می نویسیم و در برنامه استفاده می کنیم.فرض می کنیم keypad ما یک کیپد 4×3 باشه یعنی 3 ستون و 4 تا ردیف.
مهمترین نکته محاسبه مقاومت های عمودی و افقی هست که باید طوری قرار بگیرن که به ازای فشرده شدن هر کلید مقدار ولتاژ یکتایی رو تولید کنه.برای کیپدهای با تعداد کم کلید طراحی راحته و با افزیش تعداد کلیدها ترتیب چینش مقاومت ها نیاز به محاسبه بیشتری داره. اساس کار محاسبه ولتاژ مربوط به هر کلید یه تقسیم ولتاژ ساده است.
مثلا در کیپد شکل بالا با فشرده شدن کلید 1 مقاومت پول آپ دیده شده در ADC3 برابر 1K می باشد.
مقاومت های پول آپ به ازای هر کلید به شکل زیر خواهد بود:
11 | 0 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | شماره کلید |
225K | 105K | 6K | 295K | 175K | 76K | 245K | 125K | 26K | 220K | 100K | 1K | مقاومت معادل |
مقاومت پول آپ معادل دیده شده به ازای هر کلید برابر است با مجموع با مقاومت ستون و عمود مربوط به آن کلید.
پس از طراحی کیپد باید به ازای هر کلید که فشرده می شود عدد دیجیتال تولید شده را بخوانیم تو برنامه اعمال کنیم.
مثلا با فشرده شدن کلید شماره 5 عدد دیجیتال خوانده شده بین 445 تا 465 قرار میگیره. به ازی همه کلیدها باید این عدد رو به دست بیاریم.توجه کنید که با افزایش تعداد کلیدها و حتی با تغییر مقاومت ها این رنج ها باید تغییر کنه و بهترین راهش هم با آزمون و خطا (تقریبا 2 بار) به دست میاد.
خوب حالا وقتشه بریم سراغ برنامه نویسی.
نکته : کدهای زیر با Atmel Studio6.2 نوشته شده و با تغییر اندک میشه تبدیلش کرد به کدویژن.
ابتدا اول برنامه رجیسترهای ADC رو تنظیم می کنیم.من این کار رو توی تابع زیر انجام دادم.
1 2 3 4 5 6 7 8 |
void Keypad_Init() { // ADC initialization // ADC Clock frequency: 500.000 kHz // ADC Voltage Reference: AREF pin ADMUX=ADC_VREF_TYPE & 0xFF; ADCSRA=0x81; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
int GetKeyapdInput() // برای خواندن یک کلید از کیپد این تابع صدا زده می شود { int voltage = -1; int keypad = -1; while(voltage < 15) { voltage = Read_ADC(3);// چون کیپد به پایه 3 وصل شده ،پایه 3 رو می خونیم } if(voltage > 1000) { keypad = ONE; } else if(voltage>505 && voltage<520) { keypad = TWO; } else if(voltage>320 && voltage<330) { keypad = THREE; } else if(voltage>805 && voltage<825) { keypad = FOUR; } else if(voltage>445 && voltage<465) { keypad = FIVE; } else if(voltage>290 && voltage<310) { keypad = SIX; } else if(voltage>575 && voltage<595) { keypad = SEVEN; } else if(voltage>370 && voltage<380) { keypad = EIGHT; } else if(voltage>255 && voltage<270) { keypad = NINE; } else if(voltage>960 && voltage<970) { keypad = TEN; } else if(voltage>495 && voltage<505) { keypad = ZERO; } else if(voltage>315 && voltage<324) { keypad = ELEVEN; } _delay_ms(300); return keypad; } |
1 2 3 4 5 6 7 8 9 10 11 12 |
unsigned int Read_ADC(unsigned char adc_input) { ADMUX=adc_input | (ADC_VREF_TYPE & 0xFF); // Delay needed for the stabilization of the ADC input voltage _delay_us(10); // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ( (ADCSRA & 0x10) == 0 ); ADCSRA|=0x10; return ADCW; } |
دانلود پروژه طراحی keypad فقط با یک پایه میکرو
برای سلامتی آقا امام زمان و تعجیل در ظهورشون صلوات.
مهمان
دوست عزیز خوبه ولی تو مدارات شلوغتر با تغییرات اجزای دیگه چون جریان تغییر میکنه در نتیجه مقادیر مقاومت ها تغییر میکنه و در نتیجه کلا همه محاسبات و کلیدها به هم میریزه!!کسی به این مشکل نخورده؟؟؟؟؟؟؟
مهمان
سلام , چطوری با تقسیم ولتاژ مقدار مقاومت رو به دست بیارم اصلا تقسیم ولتاژ چی هست
مهمان
سلام
من میخوام خودم یه کیپد بسازم ولی از اینی که شما نوشتید هیچی نفهمیدم و تا روز شنبه هم باید این کیپد را درست کنم.و از کد هایی که زدبودینم هیچی نفهمیدم چون من فقط بسکام میزنم سی و…. را بلد نیستم.
این کیپد هم برای حذف نشدن یه حلقه صالحین میخوام(فقط برای اینکه شما تو کار فرهنگی بودی گفتم)
حالا خود دانی اگر جواب بدی یه حلقه برات دعا میکنه.
مهمان
عااااااااااااااااااااااالی
پروژه های بیشتری بذارید
اجرتون لبا خدا
مهمان
مهندس . این عددای دیجیتالی که گذاشتی رو خودت تست کردی دیگه؟؟؟
میخام یه پروژه واسه یکی از دوستان ببندم ، خودم حوسله ازمون و خطا ندارم__ینی میتونم به مقاومتات اتمینان کنم
مهمان
دوست عزیز. بستگی به اندازه ولتاژ و جریان ورودی داره. من از 5 ولت 1 آمپر استفاده کردم جواب داد. (خروجی رو از رگولاتور 7805 بگیر ) ایشالا جواب بده
مهمان
سلام
خیلی ممنون بابت مطالب خیلی خوبتون
می خواستم بپرسم چطور میشه کی پد رو با interrupt پیاده سازی کرد ؟
مدیر سایت
سلام
اگه با کیپد های 6-8 پایه بخواین کار کنید به نظرم باید از میکروهایی استفاده کنید که تموم پایه هاشون وقفه هستش و یا حداقل 4 تا وقفه دارن
و اگه این کیپد 1 پایه منظورته از وقفه adc استفاده کن
مهمان
سلام حاج مهدی
خدا خیرت بده بگو این عددای دیجیتال رو چجوری حساب کنم. من دیگه مخم جواب نمیده 😐
مدیر سایت
سلام
عدد دیجیتال دیگه چیه؟ متوجه منظروت نشدم
مهمان
همین مقدارای دیجیتال . مثلا واسه عدد 9 مقدارش بین 255 تا 270 شده رو چجوری جساب کنم ؟ نحوه تقسیم ولتاژ رو هم اگه بگی ممنونت میشم . ما مدار نداشتیم یاد ندارم 😐
مدیر سایت
تو نت بسرچی آموزش تقسیم ولتاژ در حد تیم ملی هستش.
مهمان
منظور همون عددایی هست که بر اساسش تشخیص میده کدوم کلید فشرده شده . مثلا واسه کلید 9 مقدارش بین 255 تا 275 هست . نحوه ی تقسیم ولتاژشم بگین ممنون میشم . کارم گیره . ممنون
مهمان
سلام.برای خواندن اعداد دیجیتال باید بعد از طراحی keypad، اون رو به میکرو وصل کنید و به ازای هر کلید که فشار میدید عدد ADC که خوانده میشه رو توی ال سی دی نمایش بدید. سپس این عددا رو تو مرحله بعد توی برنامتون اعمال کنید. مثلا اگه من کلید 5 رو فشار بدم عددی که دیده میشه 457 است و من هرگاه مقدار ADC رو بین 445 تا 465 میبینم میفهمم که کلید 5 فشرده شده.
این روش با آزمایش و خطا به دست می آد و بستگی به چینش و طراحی مقاومت ها متفاوت است
مهمان
جالب بود ولی نویز زیادی روش میوفته
مهمان
سلام .میشه کمکم کنی بگی مشکل این برنامه چیه که خود به خود عدد میزنه؟
#include
#include
#include
#include
#include
#asm
.equ __lcd_port=0x18
#endasm
//#############################################
int key(void);
float _Main(void);
void Mohandes(void);
void Mohasebe(void);
void Alamat(int,int);
float Emoji(int);
//#############################################
float a = 0 , b = 0 , c = 0 , q , t;
int i ;
char y=0 , lcd[25] , z ;
//#############################################
void main(void){
lcd_init(16);
lcd_clear();
lcd_gotoxy(2,0);
lcd_putsf(“JABER NOBAKHT”);
lcd_gotoxy(3,1);
lcd_putsf(“UNI *PAYAM*”);
delay_ms(1000);
lcd_clear();
lcd_gotoxy(1,0);
lcd_putsf(“SH DANESHJUYI”);
lcd_gotoxy(3,1);
lcd_putsf(“9254011017″);
delay_ms(1000);
lcd_clear();
lcd_gotoxy(1,0);
lcd_putsf(“OSTADE RAHNAMA”);
lcd_gotoxy(1,1);
lcd_putsf(“OSTAD HASHEMI”);
delay_ms(1000);
lcd_clear();
DDRB=0x0F;
DDRA=0x07;
DDRD=0x0F;
lcd_init(16);
while (1){
_Main();
}
}
//#############################################################
float _Main(void){
int Loop = 1 ;
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if( y 9 && y < 16 ){
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
z = y ;
Alamat(y,1);
while(Loop){
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if( y 15 ){
lcd_clear();
a= 0 ; b = 0 ; c = 0;
Alamat(y , 2);
z = y ;
Loop = 1 ;
while(Loop){
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if(y < 10){
a = (a*10) + y ;
itoa(y , lcd);
lcd_puts(lcd);
delay_ms(50);
}else if ( y == 14){
lcd_putchar('=');
Mohandes();
}
Loop = 1 ;
}
}
return 0;
}
//##########################################################
void Mohasebe(void){
if(z == 10)c = a / b ;
if(z == 11)c = a * b ;
if(z == 12)c = a – b ;
if(z == 13)c = a + b ;
ftoa(c , 3 , lcd);
lcd_puts(lcd);
delay_ms(100);
}
//#########################################################
float Emoji(int rr){
q=1;
for(i=0;i<rr;i++)q = q * 2.71728 ;
return q;
}
//#########################################################
void Mohandes(void){
t = (3.1415926535897932384626433832795/180)*a ;
if(z == 16)c = sin(t) ;
if(z == 17)c = cos(t) ;
if(z == 18)c = tan(t) ;
if(z == 19)c = 1/tan(t) ;
if(z == 20)c = sinh(t) ;
if(z == 21)c = cosh(t) ;
if(z == 22)c = log(a) ;
if(z == 23)c = sqrt(a) ;
if(z == 24)c = Emoji(a) ;
ftoa(c , 3 , lcd);
lcd_puts(lcd);
delay_ms(100);
}
//#########################################################
void Alamat(int Moji,int Halat){
if(Halat == 1){
if(Moji == 10)lcd_putchar('/') ;
if(Moji == 11)lcd_putchar('*') ;
if(Moji == 12)lcd_putchar('-') ;
if(Moji == 13)lcd_putchar('+') ;
delay_ms(100);
}
if(Halat == 2){
if(Moji == 16)lcd_putsf("Sin ") ;
if(Moji == 17)lcd_putsf("Cos ") ;
if(Moji == 18)lcd_putsf("Tan ") ;
if(Moji == 19)lcd_putsf("Cot ") ;
if(Moji == 20)lcd_putsf("sinh") ;
if(Moji == 21)lcd_putsf("cosh") ;
if(Moji == 22)lcd_putsf("log ") ;
if(Moji == 23)lcd_putsf("Sqrt ") ;
if(Moji == 24)lcd_putsf("exp ") ;
delay_ms(100);
}
}
//#########################################################
int key(void){
char KEY = 1 ;
while(KEY){
PORTD.0 = 1 ;
PORTD.1 = 0 ;
PORTD.2 = 0 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 7 ; KEY = 0;delay_ms(50);}
if(PIND.5 == 1){return 8 ; KEY = 0;delay_ms(50);}
if(PIND.6 == 1){return 9 ; KEY = 0;delay_ms(50);}
if(PIND.7 == 1){return 10; KEY = 0;delay_ms(50);}
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 1 ;
PORTD.2 = 0 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 4 ; KEY = 0;}
if(PIND.5 == 1){return 5 ; KEY = 0;}
if(PIND.6 == 1){return 6 ; KEY = 0;}
if(PIND.7 == 1){return 11; KEY = 0;}
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 0 ;
PORTD.2 = 1 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 1 ; KEY = 0;}
if(PIND.5 == 1){return 2 ; KEY = 0;}
if(PIND.6 == 1){return 3 ; KEY = 0;}
if(PIND.7 == 1){return 12; KEY = 0;}
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 0 ;
PORTD.2 = 0 ;
PORTD.3 = 1 ;
if(PIND.4 == 1){return 15; KEY = 0;}
if(PIND.5 == 1){return 0 ; KEY = 0;}
if(PIND.6 == 1){return 14; KEY = 0;}
if(PIND.7 == 1){return 13; KEY = 0;}
//=============================================================================
PORTC.0 = 1 ;
PORTC.1 = 0 ;
PORTC.2 = 0 ;
if(PINC.5 == 1){return 16 ; KEY=0;}
if(PINC.6 == 1){return 17; KEY=0;}
if(PINC.7 == 1){return 18 ; KEY=0;}
//=====================================================
PORTC.0 = 0 ;
PORTC.1 = 1 ;
PORTC.2 = 0 ;
if(PINC.5 == 1){return 19 ; KEY=0;}
if(PINC.6 == 1){return 20 ; KEY=0;}
if(PINC.7 == 1){return 21 ; KEY=0;}
//=====================================================
PORTC.0 = 0 ;
PORTC.1 = 0 ;
PORTC.2 = 1 ;
if(PINC.5 == 1){return 22 ; KEY=0;}
if(PINC.6 == 1){return 23 ; KEY=0;}
if(PINC.7 == 1){return 24 ; KEY=0;}
KEY = 1 ;
}
}
//############################################################
مهمان
سلام عزیز ، واقعا عالی بود ممنون اونقدر عالی و حرفه ای که کیف کردم ، حتی از سایتهای مشابه مثل مهندس یار هم بهتره چرا که خط به خط آموزش بی ریا داری ، خدا صد تو دنیا و هزار تو آخرت بهت ببخشه ، ای کاش فکری هم بحال ما بی سوادا میکردی به زبان بیسکام آموزشش رو میذاشتی ، برات یه فایل آپلود کردم وقت کردی اونو برام توضیح خط به خط بده که خانواده ای رو از نگرانی در میاری ، ( پروژه شش تا کلیده که به adc میکرو وصل میشه و با فشار هرکدوم یه علامت ( مثلا a /b/c/d/e/f تو دات ماتریکس 8*8 نمایش داده میشه ، هر کار میکنم یه ورش لنگ میزنه ، نمیتونم درست در بیارم که با فشار هر کلید یه کاراکتر رو نشون بده …. بتونی مرحمت کنی برنامشو با آموزشش بنویسی ما رو روسفید میکنی . قربانت … آریا
نویسنده این مطلب
سلام دوست عزیز.با تشکر از حسن نظر شما
لطفا پروژتون رو برام ایمیل کنید.
Zare dot hamid66 at gmail dot com
مهمان
shoma gofti:

پس از طراحی کیپد باید به ازای هر کلید که فشرده می شود عدد دیجیتال تولید شده را بخوانیم تو برنامه اعمال کنیم.
مثلا با فشرده شدن کلید شماره ۵ عدد دیجیتال خوانده شده بین ۴۴۵ تا ۴۶۵ قرار میگیره. به ازی همه کلیدها باید این عدد رو به دست بیاریم.توجه کنید که با افزایش تعداد کلیدها و حتی با تغییر مقاومت ها این رنج ها باید تغییر کنه و بهترین راهش هم با آزمون و خطا (تقریبا ۲ بار) به دست میاد.
khob iin adad ro chetori bayad bedast biarim????
مدیر سایت
سلام
با تقسیم ولتاژ …..
مهمان
دست شما دوست گرامی درد نکنه .
من خیلی آموزش ها رو در این زمینه دیده بودم اما این واقعا شاهکاره .
همیشه سالم و شاد و موفق باشید.
مهمان
مررررسی
خیلی خوب بود
نویسنده این مطلب
نظر لطفتونه

قابلی نداشت….
مدیر سایت
خدایش دمت گرم….با یه تقصیم ولتاژ ساده چه کارا که نمیشه کرد…..کلید x رو زدی>>>مقاومت یه چیز>>ولتاز هم یه چیز >>> بعد محاسبه ولتاز >>> بعد میفهمیم رو چی کلیک شده….
دمت گرم خدایشش جز قشنگ ترین پروژه ها و آموزش هایی بود که دیدم تا حالا