نمایش/عدم نمایش سایدبار
رفتن به بالای صفحه
أَللّهُمَّ ارْزُقْنی شَفاعَةَ الْحُسَیْنِ یَومَ الْوُرُودِ
حمید زارع

طراحی keypad فقط با یک پایه میکرو

82

به نام خدا

طراحی keypad فقط با یک پایه میکرو

Keypad_1

مقدمه:

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

در این آموزش سعی داریم یه روشی رو بهتون معرفی کنیم که بتونید یک 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 تا ردیف.

 کیپد معمولی

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

نحوه چینش مقاومت ها در کیپد 3x4

مثلا در کیپد شکل بالا با فشرده شدن کلید 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 رو تنظیم می کنیم.من این کار رو توی تابع زیر انجام دادم.

تابع زیر هم هر وقت خواستیم یه کلید از keypad بخونیم صدا زده میشه. در این تابع تا زمانی که کلیدی فشرده نشه توی حلقه while می مونه و بعد از فشرده شدن کلید مقدار ADC رو میخونه و سپس عدد کلید مورد نظر رو بر می گردونه.
تابع زیر هم برای خوندن مقدار ADC یا همون مبدل آنالوگ به دیجیتال روی پایه ADC میکرو استفاده می شه.این تابع شماره پایه ADC رو به عنوان آرگومان ورودی میگیره.
و  در پایان شماتیک مدار با نرم افزار پروتئوس و کدهای برنامه با Ateml Studio6.2 رو برای دانلود قرار دادم.

دانلود پروژه طراحی keypad فقط با یک پایه میکرو

برای سلامتی آقا امام زمان و تعجیل در ظهورشون صلوات.

درباره : 
تعداد مطالب : 3 تا
دانشجوی دکتری هوش مصنوعی و رباتیکز دانشگاه شیراز علاقه مندی ها:برنامه نویسی،AVR،شبکه های عصبی، نجوم،رویت هلال،عکاسی،Game Design، 3D Modeling،Image Processing
بقیه جلسات :
این مطلب هیچ طبقه بندی یی ندارد!
ارسال دیدگاه
24
نظرات این مطلب بسته شده است.
  1. امیر

    مهمان

    امیر

    دوست عزیز خوبه ولی تو مدارات شلوغتر با تغییرات اجزای دیگه چون جریان تغییر میکنه در نتیجه مقادیر مقاومت ها تغییر میکنه و در نتیجه کلا همه محاسبات و کلیدها به هم میریزه!!کسی به این مشکل نخورده؟؟؟؟؟؟؟

  2. محمدمهدی

    مهمان

    محمدمهدی

    سلام , چطوری با تقسیم ولتاژ مقدار مقاومت رو به دست بیارم اصلا تقسیم ولتاژ چی هست

  3. غریب طوس

    مهمان

    غریب طوس

    سلام
    من میخوام خودم یه کیپد بسازم ولی از اینی که شما نوشتید هیچی نفهمیدم و تا روز شنبه هم باید این کیپد را درست کنم.و از کد هایی که زدبودینم هیچی نفهمیدم چون من فقط بسکام میزنم سی و…. را بلد نیستم.
    این کیپد هم برای حذف نشدن یه حلقه صالحین میخوام(فقط برای اینکه شما تو کار فرهنگی بودی گفتم)
    حالا خود دانی اگر جواب بدی یه حلقه برات دعا میکنه.

  4. علی

    مهمان

    علی

    عااااااااااااااااااااااالی
    پروژه های بیشتری بذارید
    اجرتون لبا خدا

  5. ممدم

    مهمان

    ممدم

    مهندس . این عددای دیجیتالی که گذاشتی رو خودت تست کردی دیگه؟؟؟
    میخام یه پروژه واسه یکی از دوستان ببندم ، خودم حوسله ازمون و خطا ندارم__ینی میتونم به مقاومتات اتمینان کنمsmile

    مشاهده پاسخ ها (1)
    • حمید

      مهمان

      حمید

      دوست عزیز. بستگی به اندازه ولتاژ و جریان ورودی داره. من از 5 ولت 1 آمپر استفاده کردم جواب داد. (خروجی رو از رگولاتور 7805 بگیر ) ایشالا جواب بده smile

  6. مهسا

    مهمان

    مهسا

    سلام
    خیلی ممنون بابت مطالب خیلی خوبتون
    می خواستم بپرسم چطور میشه کی پد رو با interrupt پیاده سازی کرد ؟

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      مدیر سایت

      مهدی دمرچیلو

      سلام
      اگه با کیپد های 6-8 پایه بخواین کار کنید به نظرم باید از میکروهایی استفاده کنید که تموم پایه هاشون وقفه هستش و یا حداقل 4 تا وقفه دارن
      و اگه این کیپد 1 پایه منظورته از وقفه adc استفاده کن

  7. حمید

    مهمان

    حمید

    سلام حاج مهدی
    خدا خیرت بده بگو این عددای دیجیتال رو چجوری حساب کنم. من دیگه مخم جواب نمیده 😐

    مشاهده پاسخ ها (5)
    • مهدی دمرچیلو

      مدیر سایت

      مهدی دمرچیلو

      سلام
      عدد دیجیتال دیگه چیه؟ متوجه منظروت نشدم

      • حمید

        مهمان

        حمید

        همین مقدارای دیجیتال . مثلا واسه عدد 9 مقدارش بین 255 تا 270 شده رو چجوری جساب کنم ؟ نحوه تقسیم ولتاژ رو هم اگه بگی ممنونت میشم . ما مدار نداشتیم یاد ندارم 😐

        • مهدی دمرچیلو

          مدیر سایت

          مهدی دمرچیلو

          تو نت بسرچی آموزش تقسیم ولتاژ در حد تیم ملی هستش.

      • حمید

        مهمان

        حمید

        منظور همون عددایی هست که بر اساسش تشخیص میده کدوم کلید فشرده شده . مثلا واسه کلید 9 مقدارش بین 255 تا 275 هست . نحوه ی تقسیم ولتاژشم بگین ممنون میشم . کارم گیره . ممنون

    • حمید

      مهمان

      حمید

      سلام.برای خواندن اعداد دیجیتال باید بعد از طراحی keypad، اون رو به میکرو وصل کنید و به ازای هر کلید که فشار میدید عدد ADC که خوانده میشه رو توی ال سی دی نمایش بدید. سپس این عددا رو تو مرحله بعد توی برنامتون اعمال کنید. مثلا اگه من کلید 5 رو فشار بدم عددی که دیده میشه 457 است و من هرگاه مقدار ADC رو بین 445 تا 465 میبینم میفهمم که کلید 5 فشرده شده.
      این روش با آزمایش و خطا به دست می آد و بستگی به چینش و طراحی مقاومت ها متفاوت است

  8. mojtaba

    مهمان

    mojtaba

    جالب بود ولی نویز زیادی روش میوفته

  9. امیر

    مهمان

    امیر

    سلام .میشه کمکم کنی بگی مشکل این برنامه چیه که خود به خود عدد میزنه؟
    #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 ;
    }
    }
    //############################################################

  10. آریا

    مهمان

    آریا

    سلام عزیز ، واقعا عالی بود ممنون اونقدر عالی و حرفه ای که کیف کردم ، حتی از سایتهای مشابه مثل مهندس یار هم بهتره چرا که خط به خط آموزش بی ریا داری ، خدا صد تو دنیا و هزار تو آخرت بهت ببخشه ، ای کاش فکری هم بحال ما بی سوادا میکردی به زبان بیسکام آموزشش رو میذاشتی ، برات یه فایل آپلود کردم وقت کردی اونو برام توضیح خط به خط بده که خانواده ای رو از نگرانی در میاری ، ( پروژه شش تا کلیده که به adc میکرو وصل میشه و با فشار هرکدوم یه علامت ( مثلا a /b/c/d/e/f تو دات ماتریکس 8*8 نمایش داده میشه ، هر کار میکنم یه ورش لنگ میزنه ، نمیتونم درست در بیارم که با فشار هر کلید یه کاراکتر رو نشون بده …. بتونی مرحمت کنی برنامشو با آموزشش بنویسی ما رو روسفید میکنی . قربانت … آریا

    مشاهده پاسخ ها (1)
    • حمید زارع

      نویسنده این مطلب

      حمید زارع

      سلام دوست عزیز.با تشکر از حسن نظر شما
      لطفا پروژتون رو برام ایمیل کنید.
      Zare dot hamid66 at gmail dot com

  11. hosein

    مهمان

    hosein

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

    مشاهده پاسخ ها (1)
    • مهدی دمرچیلو

      مدیر سایت

      مهدی دمرچیلو

      سلام
      با تقسیم ولتاژ ….. blum

  12. بهزاد

    مهمان

    بهزاد

    دست شما دوست گرامی درد نکنه .
    من خیلی آموزش ها رو در این زمینه دیده بودم اما این واقعا شاهکاره .
    همیشه سالم و شاد و موفق باشید.

  13. میلاد

    مهمان

    میلاد

    مررررسی
    خیلی خوب بود smile

  14. حمید زارع

    نویسنده این مطلب

    حمید زارع

    نظر لطفتونه boast
    قابلی نداشت…. give_rose

  15. مهدی دمرچیلو

    مدیر سایت

    مهدی دمرچیلو

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