اطلاعیه

Collapse
No announcement yet.

برنامه نویسی به شیوه ماژولار

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    برنامه نویسی به شیوه ماژولار

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

    ین شیوه قالب کلی برنامه تون رو تعیین میکنه . یعنی شما قبل از اینکه هر بخشی از برنامه تون رو بخواهید بنویسید باید اول قالب و ساختار برنامه نویسی تون رو تعیین کنید که برنامه تون رو چه طوری میخواهید بنویسید ؟
    من خودم تا حالا از شیوه ماژولار استفاده کردم و توصیه می کنم شما هم از همین شیوه استفاده کنید .
    این توضیحات مربوط به زبان برنامه نویسی C هستش :
    وقتی شما تو Codevision تنظیمات آیسی رو انجام میدید در آخر میرسید به مهم ترین بخش برنامه یا همون حلقه اصلی ( While ) . خیلی ها تمام برنامه رو تو همین وایل مینویسند . گاهی اوقات این وایل به حدود 200 یا 300 خط میرسه و دیباگ کردنش خیلی سخت میشه . امکان خطا هم بسیار بالا میره .برای رفع این مشکل شما میتونید قبل از وایل توابعی رو که میخواهید استفاده کنید به طور دستی تعریف کنید . مثلا میخواهید موتور سمت راست شروع به چرخش به سمت چپ بکنه . به جای اینکه تو وایل به درایور دستور بدین میتونید یه تابع به طور دستی خودتون بنویسید که با دادن جهت و سرعت به عنوان دو تا متغیر به تابع خود تابع موتور رو کنترل کنه . توی وایل فقط کافیه تابع رو احضار کنید ! مثلا :
    While (1)
    {
    ….
    if (&hellip
    Motor ( 1,75);
    ….
    }
    توی تابع بالا 1 نشونه جهت موتور و 75 درصد سرعت موتوره . دیدین که تو وایل فقط یه خط نوشتین و توضیحات تابع رو قبل از وایل نوشتین .
    تو این روش شاید وایل اصلی شما حدود 20 یا 30 خط بشه . مثلا اگه شما خواستید روبات یه جا وایسه و یه چشمک هم با LED بزنه دیگه لازم نیست تمام برنامه رو تو وایل بنویسید بلکه میتونسد قبل از وایل یه تابع به نام ()Cheshmak تعریف کنید . مراحل برنامه رو توش بنویسید . حالا تو وایل فقط با احضار کردن اون تابع میتونید چشمک بزنید .
    یه نمونه ساده خط یاب با استفاده از این شیوه :
    ( لازم به ذکره OCR1A,B همون تایمره که برای تنظیم سرعت استفاده میشه و PWM میده .)
    In1-4 هم به in های درایور 0 و 1 میده . )


    void strate(void)
    {
    OCR1A=80;
    OCR1B=80;
    in1=1;
    in2=0;
    in3=1;
    in4=0;

    }
    void right1(void)
    {
    OCR1A=100;
    OCR1B=50;
    in1=1;
    in2=0;
    in3=1;
    in4=0;
    }

    void right2(void)
    {
    OCR1A=110;
    OCR1B=0;
    in1=1;
    in2=0;
    in3=1;
    in4=0;
    }

    void right3(void)
    {
    OCR1A=130;
    OCR1B=0;
    in1=1;
    in2=0;
    in3=0;
    in4=1;
    }

    void right4(void)
    {
    OCR1A=120;
    OCR1B=50;
    in1=1;
    in2=0;
    in3=0;
    in4=1;
    }

    void right5(void)
    {
    OCR1A=120;
    OCR1B=100;
    in1=1;
    in2=0;
    in3=0;
    in4=1;
    }

    void left1(void)
    {
    OCR1A=50;
    OCR1B=100;
    in1=1;
    in2=0;
    in3=1;
    in4=0;
    }

    void left2(void)
    {
    OCR1A=0;
    OCR1B=110;
    in1=1;
    in2=0;
    in3=1;
    in4=0;
    }

    void left3(void)
    {
    OCR1A=0;
    OCR1B=130;
    in1=0;
    in2=1;
    in3=1;
    in4=0;
    }

    void left4(void)
    {
    OCR1A=50;
    OCR1B=120;
    in1=0;
    in2=1;
    in3=1;
    in4=0;
    }

    void left5(void)
    {
    OCR1A=100;
    OCR1B=120;
    in1=0;
    in2=1;
    in3=1;
    in4=0;
    }
    …..

    void main(void)
    {

    …....
    …....


    while (1)
    {

    if (sen1<min)
    left5();


    if (sen11<min )
    right5();


    if (sen2<min )
    left4();


    if (sen10<min )
    right4();


    if (sen3<min )
    left3();


    if (sen9<min )
    right3();


    if (sen4<min )
    left2();


    if (sen8<min )
    right2();


    if (sen5<min )
    left1();


    if (sen7<min )
    right1();



    if (sen6<min )

    strate();

    };

    }

    به رویاهات فکر کن!!

    #2
    پاسخ : برنامه نویسی به شیوه ماژولار

    با سلام
    ببخشید ولی به نظرم این چیزی که شما فرمودید مطلب جدیدی نیست ، به نظر من اگر روی multitasking و RTOS کار کنیم بهتره (البته نه اینکه مطلب جدیدی باشند ها خیر بلکه یادگیری این شکل از برنامه نویسی که شاید بشه گفت یکجور برنامه نویسی ماژولار باشه البته نه به مفهوم استفاده از توابع کتابخونه ای) ، فکر میکنم کلا منظور از ماژولار نوشتن یعنی اینکه برنامه رو طوری نوشت که در زمان های آینده برای توسعه و یا انجام کارهای مشابه نیار به صرف زمان کمتری باشه حالا میتونه استفاده از تابع که داخل فایل مین تعریف میشند یا توابع کتابخونه ای که در فایل های کتابخانه ای نوشته و به برنامه اصلی الصاق میشند باشه.

    دیدگاه


      #3
      پاسخ : برنامه نویسی به شیوه ماژولار

      نوشته اصلی توسط mojtaba_led
      با سلام
      ببخشید ولی به نظرم این چیزی که شما فرمودید مطلب جدیدی نیست ، به نظر من اگر روی multitasking و RTOS کار کنیم بهتره.
      سلام دوست عزیز
      همونطوری که شاید حدس زده باشین من تازه کارم و چون این مطلب به نظرم جالب اومد ، پستش کردم.
      درمورد multitasking و RTOS اگه میتونین اطلاعات بیشتری بذارین اینجا و اینکه فرقش با ماژولار و توابع فرغی چی هشتش.. مرسی :smile:

      به رویاهات فکر کن!!

      دیدگاه


        #4
        پاسخ : برنامه نویسی به شیوه ماژولار

        خوب اگه به لحن بنده هم دقت کرده باشید متوجه میشید که من چیزی زیادی در این باره نمیدونم تازه با این ها آشنا شدم در مورد فرقشون همونطور که گفتم اول باید بگیم اصلا ماژولار یعنی چی ؟ اولین چیزی که به ذهن من میرسه هر وقت این کلمه ماژول و مازولار رو میشنوم یاد ماژولای plc میفتم که در مقابل کامپکت قرار میگره یعنی یه مجموعه فشرده، حالا این جا با توجه به اون نعریفی که شما گفتین میشه گفت ماژول یعنی چند خط برنامه مثل یک تابع که بشه بدون هیچ گونه تغییری در اون در هر برنامه با کاربری مشابه ازش استفاده کرد که نمونه بارز میشه همین توابع کتابخونه ای که با اینکلود کردنشون در ابتدای برنامه میشه از اون ها استفاده کرد ، از این بابت بود که گفتم چیز جدیدی نیست و باید باهاش آشنا بود اما در مورد multitasking , RTOS من چیز زیادی نمیدونم ولی فقط همین رو میتونم بگم که یک دید هر چند شاید اشتباه بهش بدست بیارید کلا تا اونجا که من فهمیدم تو این این دوشیوه برنامه نویسی کل برنامه به چند تا TASK تقسیم میشه و با اختصاص کل زمان اجرا به هر تسک به یک اندازه مشخص در یک چرخه بی نهایت فرایند اصلی مورد نظر انجام میشه منظور از هر تسک یک فایل برنامه هست که قسمتی از فرایند کنترلی ما در اون نوشته شده مثلا من الان خودم چند وقتی که میخوام به همین روش یک برنامه کنترل دور برای موتور از نوع PID کنترلر بنویسم که ست پوینتش بوسیله PC از طریق پورت USB تعیین میشه و اونور با یه انکودر سرعت و بخونه هم برای کنترل دور هم برای نمایش دور موتور روی یه سون سگمنت که حالا من یه سورس که فکر میکنم به روش MULTITASKING توسط اتمل برای ارتباط با پورت USB نوشته شده دارم که میخوام خودم دو تا تسک دیگه برای کارایی که گفتم بهش اضافه کنم اما هنوز نمیدونم چجوری !

        دیدگاه


          #5
          پاسخ : برنامه نویسی به شیوه ماژولار

          روش یک برنامه کنترل دور برای موتور از نوع PID کنترلر بنویسم که ست پوینتش بوسیله PC از طریق پورت USB تعیین میشه و اونور با یه انکودر سرعت و بخونه هم برای کنترل دور هم برای نمایش دور موتور روی یه سون سگمنت که حالا من یه سورس که فکر میکنم به روش MULTITASKING توسط اتمل برای ارتباط با پورت USB نوشته شده دارم که میخوام خودم دو تا تسک دیگه برای کارایی که گفتم بهش اضافه کنم اما هنوز نمیدونم چجوری !
          با سلام آقا مجتبی کار جالبیه به نظر من تو سایت مطرح کن تاهم مشکل شما حل بشه و هم ما یه چیزی یاد بگیریم

          دیدگاه


            #6
            پاسخ : برنامه نویسی به شیوه ماژولار

            با سلام،

            این مطالب جالبی که توی پست اول مطرح شده، فقط یه بخش کوچک و اساسی در برنامه نویسی اصولی، چه در میکرو و یا هر محیط دیگه ای محسوب میشه. و یک جز کوچک در برنامه نویسی ماژولار میکرو هستش ( البته تاکید میکنم اینا نظرات منه و ممکنه با نظرات شما مغایر باشه! )

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

            به این خطوط توجه کنید که PB2 رو خروجی تعریف میکنه و مثلا یه LED سبز رو که بهش متصله خاموش و روشن میکنه :
            DDRB |= (1<<2);
            PORTB |= (1<<2);
            PORTB &= ~(1<<2);

            و این خطوط هم همون کار رو انجام میده :
            //----------- Green LED (output)
            #define GLED_PRT PORTB
            #define GLED_DDR DDRB
            #define GLED_BIT 2

            //---------------------
            #define GLED_INI() {GLED_DDR |= (1<<GLED_BIT); GLED_PRT &= ~(1<<GLED_BIT);} //Set output & OFF
            #define GLED(x) (x ? (GLED_PRT |= (1<<GLED_BIT)) : (GLED_PRT &= ~(1<<GLED_BIT)))

            و در یک قدم جلوتر این هم همونه ( با تعریف یه ماکرو دیگه ) :
            //----------- Green LED (output)
            #define GLED_PRT PORTB
            #define GLED_DDR DDRB
            #define GLED_BIT 2

            //---------------------
            #define GLED_INI() {sbi(GLED_DDR, GLED_BIT); cbi(GLED_PRT, GLED_BIT);} //Set output & OFF
            #define GLED(x) (x ? (sbi(GLED_PRT, GLED_BIT)) : (cbi(GLED_PRT, GLED_BIT)))

            خوب حالا به نظر شما کدوم نوع از نمونه برنامه نویسی ارائه شده در آینده راحت تر توسعه داده میشه و کد نهایی برنامه در کدوم روش زیبا تر و جمع و جور تر میشه؟ کدومش رو راحت تر میشه Trace یا بررسی کرد؟

            البته این یک نمونه ساده و پیش پا افتاده است، حالا اگر فراتر بریم و از سایر رجیسترهای میکرو برای کاربردهای متنوعی مثل PWM, Timer و غیره استفاده کنیم، با توجه به تفاوت های سخت افزاری بین انواع میکروها ( حتی یک خانواده واحد) ، این موضوع ملموس تر و پیچیده تر خواهد شد.......

            به نظرم نکته مهم ماژولار نویسی، همینه... :biggrin:

            ( برای مشاهده بهتر کدها، اونا رو توی ادیتور خودتون کپی کنید تا از این بهم ریختگی در بیان!!! )

            و نکته بعدی اینکه برنامه نویسی MultiTasking کاملا ضروری و غیر قابل اجتنابه و با موضوع ماژولار نویسی خیلی مربوط نیست و استفاده از OS هم به نظرم برنامه نویسی خیلی ماژولاره! و همیشه قابل استفاده نیست ( بدلیل حجم و سرعت ) و باید بگم که خود من استفاده از OS رو خیلی مناسب کار حرفه ای نمیبینم ...
            مادامی که از شخصی یاد میشود، او و افکارش زنده اند ....

            Sh_Nourbakhsh@Yahoo.com

            http://s2.picofile.com/file/7170362468/_Wall_e_.jp

            دیدگاه


              #7
              پاسخ : برنامه نویسی به شیوه ماژولار

              و نکته بعدی اینکه برنامه نویسی MultiTasking کاملا ضروری و غیر قابل اجتنابه و با موضوع ماژولار نویسی خیلی مربوط نیست و استفاده از OS هم به نظرم برنامه نویسی خیلی ماژولاره! و همیشه قابل استفاده نیست ( بدلیل حجم و سرعت ) و باید بگم که خود من استفاده از OS رو خیلی مناسب کار حرفه ای نمیبینم ...
              ممنون
              اگه میشه در مورد برنامه نویسی MultiTasking یه خورده توضیح بدین مثلا اصول نوشتن یه همچین برنامه نویسی چیه چارت کلی همچین برنامه نویسی ای به چه صورت هست ؟ و اگر بشه من اون سورسی که گفتم لینکشو بزارم تا اگه وقت داشتین یه نگاهی بهش بندازید ببینید اصلا MultiTasking هست یا نه ؟

              البته با اجازه دوست عزیز eric_s88 ، ببخشید که دارم سوالم رو توی تایپیک شما مطرح میکنم .

              دیدگاه


                #8
                پاسخ : برنامه نویسی به شیوه ماژولار

                نوشته اصلی توسط mojtaba_led

                البته با اجازه دوست عزیز eric_s88 ، ببخشید که دارم سوالم رو توی تایپیک شما مطرح میکنم .
                خواهش میکنم من خوشحالم میشمٍ و میخوام از پست هایی که مطرح میشه نهایت استفاده رو بکنم
                به رویاهات فکر کن!!

                دیدگاه


                  #9
                  پاسخ : برنامه نویسی به شیوه ماژولار

                  با سلام،

                  ساده ترین برنامه MultiTask بر اساس سیستم عامل DOS نوشته میشه! به این صورت که شما یه تایمر رو بصورت لود شدن خودکار فعال و ست میکنی ( مثلا هر 10 میلی ثانیه ) و از سر ریزش بعنوان تیک سیستم استفاده میکنی. حالا برای هر Task که داری یه اسم، یه فلگ و یه کانتر مجزا تعریف میکنی. بر اساس کانتری که برای هر Task تعریف کردی، در همون تعداد تیک، به این واقعه رسیدگی میکنی. مثلا دو تا LED داری که یکیش هر 30 میلی ثانیه خاموش و روشن میشه و دیگری هر 70 میلی ثانیه، پس شما در هر 3 تیک به وضعیت یکی رسیدگی میکنی و در هر 7 تیک به وضعیت اون دیگری، یعنی در این سیستم فرضی، شما با رزولوشن 10میلی ثانیه ای به وقایع رسیدگی خواهید کرد. البته این یه مثال ساده است، مواقعی پیش میاد که شما در غیر از این شیوه کارتون پیش نخواهد رفت. مثلا میخواید یه تاخیر 2 ثانیه ای رو داشته باشید و در عین حال به کلی کار دیگه بپردازید و.....
                  این در اصل MultiTask نیست، بلکه رسیدگی به وقایع در هر 10 میلی ثانیه است که بهش میگن مولتی تسک..... :mrgreen:

                  این رو به احتمال زیاد دیدید، ( ببخشید اگه تکراریه ) توی این یه توضیح مختصری در این مورد داده :
                  ttp://www.avrfreaks.net/modules/FreaksArticles/files/14/Multitasking%20on%20an%20AVR.pdf
                  مادامی که از شخصی یاد میشود، او و افکارش زنده اند ....

                  Sh_Nourbakhsh@Yahoo.com

                  http://s2.picofile.com/file/7170362468/_Wall_e_.jp

                  دیدگاه


                    #10
                    پاسخ : برنامه نویسی به شیوه ماژولار

                    ممنون نه اینو ندیده بودم
                    اگه میشه به این سورس اتمل یک نگاهی بندازید ببینید چیه ؟
                    http://www.atmel.com/dyn/resources/p...-cdc-1_0_3.zip

                    دیدگاه


                      #11
                      پاسخ : برنامه نویسی به شیوه ماژولار

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

                      کد:
                      //
                      //	Co-operative multitasking framework tutorial code
                      //	(c)Russell Bull 2010. Free for any use.
                      //	Code built for a Mega168 @ 16MHz
                      //
                      //	flash two outputs (PORTB.4,PORTB.5) at different speeds - blinky#2.
                      //
                      
                      #include 
                      #include 
                      #include 
                      
                      void init_devices(void);
                      void timer0_init(void);
                      void reset_task(char tsk);
                      void set_task(char tsk);
                      void task_dispatch(void);
                      void task0(void);
                      void task1(void);
                      void task2(void);
                      void task3(void);
                      void task4(void);
                      void task5(void);
                      void task6(void);
                      void task7(void);
                      
                      #define NUM_TASKS 8
                      char task_bits = 0; /* lsb is hi priority task */
                      volatile char tick_flag = 0;  /* if non-zero, a tick has elapsed */
                      unsigned int task_timers[NUM_TASKS]={0,0,0,0,0,0,0,0};         /* init the timers to 0 on startup */
                      static const PROGMEM char bit_mask[]={1,2,4,8,16,32,64,128};      /* value -> bit mask xlate table */
                      
                      int main(void) 
                      { 
                      
                       init_devices();
                      //
                      //	start at least one task here
                      //
                      set_task(7);	//task7 runs
                      set_task(6);	//task6 runs
                      
                      //   main loop 
                      
                       while(1)
                        {
                        if (tick_flag)
                         {
                         tick_flag = 0;
                      	 task_dispatch();       // well.... 
                      	 }
                      	}
                       return 0;
                      } 
                      //
                      //	a task gets dispatched on every tick_flag tick (10ms)
                      //
                      void task_dispatch(void)
                      {
                       /* scan the task bits for an active task and execute it */
                      
                       char task;
                      	
                      
                      /* take care of the task timers. if the value ==0 skip it
                      	else decrement it. If it decrements to zero, activate the task associated with it */
                      
                       task=0;
                       while (task < NUM_TASKS )
                        {
                        if (task_timers[task])
                      	  {
                       	  task_timers[task]--;      /* dec the timer */
                      	  if (task_timers[task] == 0 )
                      	  		{
                      	  	set_task(task); /* if ==0 activate the task bit */
                      			}
                      	  }
                        task++;
                        }
                      
                       task = 0; /* start at the most significant task */
                       while (task <= NUM_TASKS )
                        {
                      	 if ((task_bits & pgm_read_byte(&bit_mask[task])))
                      	 		{
                      	 		break; /* if activate task found..*/
                      			}
                         task++;     /* else try the next one */
                        }
                       switch(task)      /* if task bit is active..execute the task */
                        {
                        case 0:
                         task0();
                         break;
                        case 1:
                         task1();
                         break;
                        case 2:
                         task2();
                         break;
                        case 3:
                         task3();
                         break;
                        case 4:
                         task4();
                         break;
                        case 5:
                         task5();
                         break;
                        case 6:
                         task6();
                         break;
                        case 7:
                         task7();
                         break;
                        default:
                         break;         /* no task was active!! */
                        }            
                      }
                      
                      // enable a task for execution
                      void set_task(char tsk)
                      {
                       task_bits |= pgm_read_byte(&bit_mask[tsk]);    /* sets a task bit */
                      }
                      // disable a task from executing
                      void reset_task(char tsk)
                      {
                       task_bits &= (~pgm_read_byte(&bit_mask[tsk])); /* resets a task bit */
                      }
                      
                      void task0(void)
                      {
                       reset_task(0);
                      }
                      void task1(void)
                      {
                       reset_task(1);
                      }
                      void task2(void)
                      {
                       reset_task(2);
                      }
                      void task3(void)
                      {
                       reset_task(3);
                      }
                      void task4(void)
                      {
                       reset_task(4);
                      }
                      void task5(void)
                      {
                       reset_task(5);
                      }
                      //
                      //	flash PORTB.4 at 2hz
                      //
                      void task6(void)
                      {
                      PORTB ^= (1<<4);
                      task_timers[6] = 25;		//every 250ms
                      reset_task(6);
                      }
                      //
                      //	flash PORTB.5 at 1hz
                      //
                      void task7(void)
                      {
                      PORTB ^= (1<<5);
                      task_timers[7] = 50;		//every 500ms 
                      reset_task(7);
                      }
                      //call this routine to initialize all peripherals
                      void init_devices(void)
                      {
                       //stop errant interrupts until set up
                       cli(); //disable all interrupts
                      
                      
                       DDRB = 0x30;	//port 4 & 5 as outputs
                      
                       timer0_init();
                       
                       MCUCR = 0x00;
                       EICRA = 0x00; //extended ext ints
                       EIMSK = 0x00;
                       
                       TIMSK0 = 0x02; //timer 0 interrupt sources
                       
                       PRR = 0x00; //power controller
                       sei(); //re-enable interrupts
                       //all peripherals are now initialized
                      }
                      //TIMER0 initialize - prescale:1024
                      // WGM: CTC
                      // desired value: 10mSec
                      // actual value: 10.048mSec (-0.5%)
                      void timer0_init(void)
                      {
                       TCCR0B = 0x00; //stop
                       TCNT0 = 0x00; //set count
                       TCCR0A = 0x02;	//CTC mode
                       OCR0A = 0x9C; 
                       TCCR0B = 0x05; //start timer
                      }
                      
                      ISR(TIMER0_COMPA_vect)
                      {
                       //TIMER0 has overflowed
                       	tick_flag = 1;
                      }
                      //-----------------------------------------------------------------------


                      لطفا نظرتون را برای ادامه ی بحث بفرمایید.
                      Reveng will surely come... Your hard time are ahead
                      // - - - - - - - - - -
                      برگه های کتاب به منزله بالهایی هستند که روح ما را به عالم نور و روشنایی پرواز میآ*دهند. فرانسوا ولتر
                      // - - - - - - - - - -
                      اگر برای هرچیزی به غیر از علاقه ی شدیدتان به الکترونیک تلاش کنید ، خیلی دور نخواهید رفت / خیلی هم خوب نخواهید شد.
                      // - - - - - - - - - -

                      دیدگاه

                      لطفا صبر کنید...
                      X