پرسش و پاسخ در مورد پروژه ساعت

saeeddelshad0020

همکار
سلام.با اجازه اقای اسدی این موضوع رو اضافه کردم تا بنده و دوستانی که در مورد این پروژه سوالاتی دارن بپرسن تا شبهات از بین بره.
ممنون از دوستانی که پاسخ میدن
 

saeeddelshad0020

همکار
تو اولین قدم من تو قسمت دیبانس کردن کلید ها و نحوه دیبانس کردن مشکل داشتم.که دیشب تا ساعت 3 نصف شب!! اقای اسدی زحمت کشیدن توضیحات کاملی دادن که مطلب واسم روشن شد.
برداشتی رو که داشتم اینجا بیان میکنم تا دوستانی که در درک قسمت کلید ها مشکلی داشتن استفاده کنن. ممنونم از اقای اسدی بخاطر همه چیز.


کد:
ISR(TIMER0_COMP_vect){
    static uint16_t ms = 0;

    uint8_t key;
    static uint8_t t_buz,t_key, c_key;

    if(++ms >= 1000) //1 Sec
    {
        ms = 0;

    }

    if(t_buz)
    {
        t_buz--;
        if(t_buz == 50)
        {
            BUZZER_OFF();
        }
    }
    else
    {
        if(BEEP)
        {
            BEEP--;
            BUZZER_ON();
            t_buz = 100;
        }
    }

    key = KEY_PIN & NO_KEY;
    if(key == t_key)
    {
        if(c_key < KEY_DEBOUNCE)
        {
            c_key++;
            if(c_key == KEY_DEBOUNCE && key != NO_KEY)BEEP = 1;
        }
        else
            KEY.Data = key;
    }
    else
    {
        t_key = key;
        c_key = 0;
        KEY.Flag = 0;
    }
}

خب.به فرض این که تایمر رو واسه ایجاد یک زمان کوچیک واسه دیبانس تنظیم کردیم
کد:
    static uint16_t ms = 0;
متغیر ms را معرفی میکنیم واسه اینکه اگه بخوایم با استفاده از وقفه های یک میلی ثانیه ای زمان یک ثانیه ای ایجاد کنیم بکار ببریم.
کد:
    uint8_t key;
    static uint8_t t_buz,t_key, c_key;
این متغیر هارو هم واسه این معرفی میکنیم که بتونیم مقادیر فعلی و قبلی کلید های خونده شده رو توش بریزیم....دقیقا همینجاش منم مشکل داشتم که با ادامه توضیحات اقای اسدی مفهوم شدم
کد:
if(++ms >= 1000) //1 Sec
    {
        ms = 0;

    }
این شرط ما هم برای ایجاد زمان یک ثانیه هس که اختیاریه
کد:
 if(t_buz)
    {
        t_buz--;
        if(t_buz == 50)
        {
            BUZZER_OFF();
        }
    }
    else
    {
        if(BEEP)
        {
            BEEP--;
            BUZZER_ON();
            t_buz = 100;
        }
    }
این قسمت از کد هم اینه که موقع فشردن کلیدی بازر به صدا بیاد و اون تاخیر های داخل کد هم واسه هماهنگ کردن زمانی بین فشرن کلید و به صدا در اومدن بازر هس...(اینجا جا داره احسنت بگیم به مهندس اسدی...تو عمل نتیجه فوق العاده بود)
کد:
key = KEY_PIN & NO_KEY;
تو این خط key_pin همون رجیستر پین ورودی ما هس که کلید ها بهش وصله و تو دیفاین میشه دید.no_key هم همون مقدار 0b00001111 هست. خب وظیفه این خط اینه که تو حالت عادی اگه کلیدی فشرده نشده باشه اینجوری میشه key=0b00000000&0b00001111 یعنی کلیدی نزده شده...و مقدار کلید نزده شده میریزه به متغیر key.خب اگه کلیدی هم زده شده باشه به فرض مثال اینجوری میشه key=0b00000001&0b00001111 و مقدار کلید زده شده میریزه داخل متغیر key
کد:
if(key == t_key)
    {
        if(c_key < KEY_DEBOUNCE)
        {
            c_key++;
            if(c_key == KEY_DEBOUNCE && key != NO_KEY)BEEP = 1;
        }
        else
            KEY.Data = key;
    }
    else
    {
        t_key = key;
        c_key = 0;
        KEY.Flag = 0;
    }
اولین شرط اینو میگه که اگه مقدار فعلی کلید زده با مقدار قبلی برابر باشد__ ادامه
بعدش که یه متغیر c_key تعریف کردیم اگه تا زمانی که مقدارش کمتر از key_debounce (که همون 10 )هست باشه__ادامه (این if همون وقفه 10 بار سر زدن به وقفه تایمر رو ایجاد میکنه)
c_key++ یه واحد به این متغیر اضافه میکنه
کد:
if(c_key == KEY_DEBOUNCE && key != NO_KEY)BEEP = 1;
اگر c_key (مقدار چک کردن وقفه) برابر با (key_debounce (10 باشد و و و key (که همون مقدار فشرده شدن کلید هس) (NO_key ( 0b00001111 نباشه -->beep رو یک کنه.که همون صدای بیپ هس
در غیر این صورت KEY.Data = key;
یه استراکچر تعریف میکنیم در هدر دیفاین بدین صورت که
کد:
typedef struct {
    uint8_t        Data;
    uint8_t        Flag;
} KEY_DATA;
داخل متغیر key_data دو متغیر flag , data هست
متغیر key که مقدار کلید خونده شده هس رو میریزم توی key_data
در اخر هم متغیر هارو صفر کرده و key_flag رو صفر میکنیم.این key_flag زمانی یک میشه که روال دیبانس تو وقفه اجرا بشه



خب حالا main اصلی برنامه
کد:
while (1)
    {

        if(!KEY.Flag)
        {
            switch(KEY.Data)
            {
                case UP:

                break;
                case DOWN:

                break;
                case SET:

                break;
                case ESC:

                break;
            }
        }
        _delay_ms(10);
    }
اول چک میکنیم که اگر فلق یک باشه ادامه (یعنی روال وقفه اجرا شده و الگوریتم دیبانس ما موفقیت آمیز بوده)
از دستور سوییچ کیس استفاده کردیم که مقدار key_data که همون مقدار key هست (key_data=key) (داخل وقفه برابر کردیم)
مقدار key_data هر چی باشه معادل همون توی کیس های پایینی اجرا میشه. که معادل کلید های up_down_ok_esc توی دیفاین معلوم هس

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

پیوست‌ها

  • Graphic_clock.rar
    308.3 کیلوبایت · بازدیدها: 4
  • Like
واکنش‌ها[ی پسندها]: Alma

Alma

مدیر
پرسنل مدیریت
با تشکر از اقای دلشاد
بعد از وارد کردن کد به متن نوشته تون حتما اونو با ابزار های بالای ادیتور چپ چینش کنید تا کد به هم نریزه
من در پست شما تغییرات لازم رو دادم و ویرایشش کردم

موفق باشید
 

saeeddelshad0020

همکار
سلام
مهندس توی این کتابخونه ال سی دی گرافیکی نمیشه سایز نوشتمون رو تغییر بدیم؟؟؟
 

Alma

مدیر
پرسنل مدیریت
خیلی ممنون.
یه توضیحی هم در مورد الگوریتم نوشتن منو ها یا صفحات پی در پی میدین؟

یادمه توی یکی از این جلسات به این مورد پرداشته شده
ولی بازم توضیح میدم
برای منو ها ما یه جدول داریم که موارد مشترک هر منو توش ذخیره میشه
برای مثال ادیکس رشته مینومم و ماکزیمم منو نوع منو واحد منو و ...
برای ایجاد هر کار گروهی باید بگردیم و موارد مشترک رو در بیاریم و اونها رو توی یه جدول قرار بدیم که کار رو راحت کنه
برای منو هم همین کارو میکنم
در کل ممکنه دونوع مونو داشته باشیم
1 - منو هایی که زیر منو دارن
2 - منو هایی که مقدار دهی باید بشن

پس به دوتا تابع کلی نیاز خواهیم داشت
1 - اول تابعی برای نمایش لیست منوها
2 - دوم تابعی برای مقدار دهی منوی انتخاب شده

در ابتدا تابع اول فراخوانی میشه و لست منوها نمایش داده میشه
منوهایی که زیر منو دارن مقداری برای تنظم شدن ندارن پس وقتی انتخاب میشن باید یه لیست از منو های تازه نمایش داده میشه پس دوباره تابع اول فراخوانی میشه
اما برای منوهای که مقدار دارن باید یه تابع دومی هم باشه که بتونیم نسبت به جدول واحد و رشته و شرایط مناسب برای مقدار دهی ایجاد کرد
برای مثال مقدار رو از مینیمم و ماکزیممی که توی جدول داده شده محدود بشه واحدی که برای منوی انتخاب شده در نظر گرفته شده نمایش داده بشه و ....

البته توجه داشته باشید که این بحث وقتی به درد میخوره که تعداد منو ها زیاد باشه و تو در تو باشن
 

saeeddelshad0020

همکار
یادمه توی یکی از این جلسات به این مورد پرداشته شده
ولی بازم توضیح میدم
برای منو ها ما یه جدول داریم که موارد مشترک هر منو توش ذخیره میشه
برای مثال ادیکس رشته مینومم و ماکزیمم منو نوع منو واحد منو و ...
برای ایجاد هر کار گروهی باید بگردیم و موارد مشترک رو در بیاریم و اونها رو توی یه جدول قرار بدیم که کار رو راحت کنه
برای منو هم همین کارو میکنم
در کل ممکنه دونوع مونو داشته باشیم
1 - منو هایی که زیر منو دارن
2 - منو هایی که مقدار دهی باید بشن

پس به دوتا تابع کلی نیاز خواهیم داشت
1 - اول تابعی برای نمایش لیست منوها
2 - دوم تابعی برای مقدار دهی منوی انتخاب شده

در ابتدا تابع اول فراخوانی میشه و لست منوها نمایش داده میشه
منوهایی که زیر منو دارن مقداری برای تنظم شدن ندارن پس وقتی انتخاب میشن باید یه لیست از منو های تازه نمایش داده میشه پس دوباره تابع اول فراخوانی میشه
اما برای منوهای که مقدار دارن باید یه تابع دومی هم باشه که بتونیم نسبت به جدول واحد و رشته و شرایط مناسب برای مقدار دهی ایجاد کرد
برای مثال مقدار رو از مینیمم و ماکزیممی که توی جدول داده شده محدود بشه واحدی که برای منوی انتخاب شده در نظر گرفته شده نمایش داده بشه و ....

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

Alma

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

توضیح که دادم منظور از نکات مشترک یعنی نوع منو - واحد مقدار - مینیمم و ماکزیمم مقدار و اندیکس رشته و ....
تعداد کلیدها و ... که فرقی نمیکنه و اصلا ربطی به منوها نداره کادر صفحه و ... هم که باز همیشه ثابت هست و فرقی نمیکنه

upload_2019-4-2_21-14-20.png

نمونه کد نمیتونم بدم اول خودتون یه تلاشی بکنید یه استارتی بزنید تا راهنمایی کنم

توضیحات بیشتری رو هم اینجا دادم که میتونید مطالعه کنید
 
بالا پایین