اطلاعیه

Collapse
No announcement yet.

مشکل با مد sleep ؟

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

    مشکل با مد sleep ؟

    یه مشکل با مد sleep تو برنامه دارم . نمیدونم چرا وقتی از مدهای sleep استفاده میکنم همه چیز درسته و میکرو به هر مدی که انتخاب کنم میره ولی به محض اینکه تایمر Watchdog رو هم روشن کنم دائم میکرو ریست میشه
    اینم بگم موقعی که Watchdog روشن باشه و مد sleep غیر فعال این مشکل بوجود نمیاد پس مشکل از مدت زمان ریست تایمر Watchdog نیست مشکل از جایی دیگست :cry:
    کسی میتونه کمکم کنه؟ :redface:
    ذكات علم ياد دادنه ....

    #2
    پاسخ : مشکل با مد sleep ؟

    والا بستگی داره که برنامه چطوری نوشته شده ، کلی ترین راه که من انجام میدم و جواب میده اینه که اگه تایمر خالی یا دم دستی داری ، تو روتین تایمرت بازمانی کمتر از ، زمانی که برای Watchdog timer تعیین کردی ، رجیستر Watchdog رو referesh کنی

    دیدگاه


      #3
      پاسخ : مشکل با مد sleep ؟

      اگر مشکلت کم کردن توان مصرفیه بهتره از یک روتین برای delay دادن استفاده کنی که زمان delay توی یک تایمر یک میلی ثانیه کم میشه و خود روتین در حالت sleep سیر میکنه تا زمانش تموم بشه و بعدش برمیگرده..

      دیدگاه


        #4
        پاسخ : مشکل با مد sleep ؟

        والا بستگی داره که برنامه چطوری نوشته شده ، کلی ترین راه که من انجام میدم و جواب میده اینه که اگه تایمر خالی یا دم دستی داری ، تو روتین تایمرت بازمانی کمتر از ، زمانی که برای Watchdog timer تعیین کردی ، رجیستر Watchdog رو referesh کنی
        اینگار این روشی که استفاده میکردین جواب داد مشکل حل شد ممنون البته تو مد idel که هست خوبه یعنی وقفه خارجی که میرسه میاد بیرون ولی تو مد Powedown که ست انگاری وقفه خارجی اثری نداره و برنامه به روتین وقفه نمیره اصلا انگار میکرو مرده....
        ذكات علم ياد دادنه ....

        دیدگاه


          #5
          پاسخ : مشکل با مد sleep ؟

          اگر مشکلت کم کردن توان مصرفیه بهتره از یک روتین برای delay دادن استفاده کنی که زمان delay توی یک تایمر یک میلی ثانیه کم میشه و خود روتین در حالت sleep سیر میکنه تا زمانش تموم بشه و بعدش برمیگرده..
          درست متوجه نشودم میشه توضیح بدین؟
          ذكات علم ياد دادنه ....

          دیدگاه


            #6
            پاسخ : مشکل با مد sleep ؟

            ببین عزیزم.
            فرض بر اینه که میکرو وقتی در حالت عادی داره کار میکنه همیشه بایستی کاری برای انجام دادن داشته باشه. منظورم اینه که مثلا ما معمولا برای اینکه delay بدیم یک حلقه با تعداد معادل زمان مورد نیاز برای delay اجرا میکنیم. اما توجه نداریم که در این حالت توان مصرفی میکرو در حداکثر کاری خودشه. بجای این مسئله میشه میکرو رو در حالت idle قرار داد. ولی برای اینکه تابعی که این درخواست تاخیر رو کرده به میزان مورد نیاز زمانی تاخیر پیدا کنه راه بهتری هم هست. فرض کنیم یک تایمر 1 میلی ثانیه داریم که در آن یک متغیر عمومی را (به شرطی که صفر نباشد) کم میکنیم تا به صفر برسد. در تابع delay ابتدا این متغیر را با میزان تاخیر مورد نیاز مقدار دهی میکنیم. سپس تا موقعی که ایم متغیر صفر شود خود را در حالت sleep قرار میدهیم.
            چگونگی کار:
            در تابع delay ما همواره در حالت sleep هستیم تا موقعی که متغیر فوق در روتین تایمر 1 میلی ثانیه صفر شود. در این حین اگگر هر وقفه ای صادر شود (ایضا همین وقفهء 1 میلی ثانیه) روتین delay از حالت sleep درآمده و متغیر را یکبار دیگر چک میکند بنا براین میکرو در این فاصله زمانی فقط برای دو مسئله کار میکند. اول سرویس دادن به وقفه ها و دوم برای چک کردن مقدار متغیر عمومی کذایی.

            فقط

            حواست به نوع sleep باشه چون در تمامی حالات وقفه تایمر باعث درآمدن سیستم از حالت sleep نمیشود.
            راحتترین کار استفاده از حالت صفر است.


            کد:
            volatile unsigned int timeout;
            
            SIGNAL(SIG_OVERFLOW0)
            {
            	....
            	if(timeout)
            		timeout--;
            	....
            }
            
            
            void delay(unsigned int time)
            {
            	timeout = time;
            	while( timeout )
            	{
            		MCUCR |= 0x80;
            		asm("sleep");
            		MCUCR &=~0x80;
            	}
            }
            نکته:
            متغیر عمومی حتما بایستی volatile معرفی شود تا کامپایلر در هنگام دسترسی به مقدار آن از مقدار ذخیره شده قبلی در رجیستر ها استفاده نکند.

            دیدگاه


              #7
              پاسخ : مشکل با مد sleep ؟

              سلام رضا جان...
              اول از همه ممنون از اینکه وقت گذاشتی و توضیح دادی

              یه چنتا سوال داشتم :
              1) شما تو این مثالی که زدین فرمودین که:
              بنا براین میکرو در این فاصله زمانی فقط برای دو مسئله کار میکند. اول سرویس دادن به وقفه ها و دوم برای چک کردن مقدار متغیر عمومی کذایی.

              حال فرض کنید تو برنامه ایی که هست غیر از وقفه ها مثلا یه چنتا پورت رو چک کنه مثلا پورت ADC حالا اگه میکرو بره به یکی از مدهای sleep چطور باید اینکارو انجام داد چون تو مثالایم که دیدم معمولا مدهای Sleep رو درون یه حلقه While قرار میدن میشه توضیح بدین...

              2) این قسمتو هم متوجه نشدم الان با این دستورات میکرو تو چه مدیه؟

              کد:
               while( timeout )
                {
               اینجا چه اتفاقی میوفته ....... MCUCR |= 0x80;
                 asm("sleep");
              و اینجا چطور؟..........MCUCR &=~0x80;
                }
              3) چرا اصلا از این تابع delay استفاده کردین چرا مثلا تو قسمت While برنامه نرفت به مد sleep ؟

              4) این استفاده از حالت 0 یعنی چی؟ حواست به نوع sleep باشه چون در تمامی حالات وقفه تایمر باعث درآمدن سیستم از حالت sleep نمیشود.
              راحتترین کار استفاده از حالت صفر است.


              متغیر عمومی حتما بایستی volatile معرفی شود تا کامپایلر در هنگام دسترسی به مقدار آن از مقدار ذخیره شده قبلی در رجیستر ها استفاده نکند.
              منظورتون اینکه برنامه بتونه از اون حلقه While بیاد بیرون درسته؟
              ذكات علم ياد دادنه ....

              دیدگاه


                #8
                پاسخ : مشکل با مد sleep ؟

                اگر از power down استفاده می کنی باید اینو در نظر بگیری که خود watchdog توان مصرف میکنه

                دیدگاه


                  #9
                  پاسخ : مشکل با مد sleep ؟

                  اگر از power down استفاده می کنی باید اینو در نظر بگیری که خود watchdog توان مصرف میکنه
                  نه از مد idle
                  ذكات علم ياد دادنه ....

                  دیدگاه


                    #10
                    پاسخ : مشکل با مد sleep ؟

                    نوشته اصلی توسط majid.4206
                    اینگار این روشی که استفاده میکردین جواب داد مشکل حل شد ممنون البته تو مد idel که هست خوبه یعنی وقفه خارجی که میرسه میاد بیرون ولی تو مد Powedown که ست انگاری وقفه خارجی اثری نداره و برنامه به روتین وقفه نمیره اصلا انگار میکرو مرده....
                    گفتم که این روش کلی ترین روش هست و جواب میده.این مشکلی هم که هست فکر نکنم مربوط به استفاده از این روش باشه.بقول معروف ، تا کد رو نبینی نمیشه اظهار نظر کرد :mrgreen: :redface:

                    دیدگاه


                      #11
                      پاسخ : مشکل با مد sleep ؟

                      چند تا مسئله:

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

                      دوم اینکه وقتی انجام عملی زودتر از یک زمانی امکانپذیر نیست یا عقلانی نیست پس چک کردن با سرعتی بالاتر از این زمان فقط اتلاف قدرت میکرو است. مثلا اگر قرار باشه وضعیت یک سیگنال توسط یک برنامه چک بشه که این سیگنال با سرعتی معادل 100 هرتز عوض میشه ولی قراره در یک تلگرام هر 50 میلی ثانیه به pc ارسال بشه پس اینکه این سیگنالها هر میلی ثانیه یکبار اسکن بشه عملی است بیخود. یعنی کافیه همون 50 میلی ثانیه به 50 میلی ثانیه کار انجام بشه.

                      پس از انجام این تیپ تحلیل ها زمانی که کاری برای انجام دادن در سیکل اصلی برنامه رو ندارین به حالت sleep برین با استفاده از delay. ولی خوب اگر احتیاج با انجام کاری زمانگیر هست که باید کار انجام بشه. حتی اگر مصرف میکرو حداکثر باشه.

                      ---

                      میکرو در چند حالت میتونه sleep بشه که راحتترینش حالت صفر است که با هر وقفه داخلی و خارجی از sleep بیرون میاد ولی در حالتی مثلا powerdown فقط ریست و وقفه با منشاء خارجی میکرو رو از حالت sleep درمیاره. که خوب برای کاربرد عمومی بدرد نمیخوره. میشه گفت در حالت صفر میکرو چشاش هم میره و در powerdown توی حالت بیهوشیه. هر دوتاش نوعی خوابه اما این کجا و اون کجا!

                      دیدگاه


                        #12
                        پاسخ : مشکل با مد sleep ؟


                        sleep_enable();
                        while (1)
                        {
                        // Place your code here

                        if(bitpass)
                        {
                        Active_Relay();
                        }
                        if(voice)
                        {
                        massage_1();
                        voice=0
                        }

                        idle();
                        };


                        خیلی ممنون از پاسختون

                        قسمت while برنامه اینه 1 دونه وقفه خارجی و دوتا تایمر تو برنامه هست و یه 7تا تابع که تو خودشون فراخونی میشن چون شلوغ میشد نزاشتم :redface: ولی همنطور که فرمودین یه تایمر هم برای ریست کردن Watchdog استفاده کردم حالا یه سوالی به ذهنم رسید وقتی تایمر ی که برای ریست کردن Watchdog استفاده میشه سریز میکنه ایا میکرو از مد مثلا idle بیرون میاد یا نه؟

                        میکرو در چند حالت میتونه sleep بشه که راحتترینش حالت صفر است که با هر وقفه داخلی و خارجی از sleep بیرون میاد
                        منظورتون همون مد idle ؟

                        درضمن اون سوالام هم بی پاسخ موندا :redface:
                        ذكات علم ياد دادنه ....

                        دیدگاه


                          #13
                          پاسخ : مشکل با مد sleep ؟

                          راسیتش من یخده ram ام کم حجمه!

                          جواب سئوالا رو اول بدم چون دفعه بعدی احتمالا میزنی پای چشام!

                          1- فرض بر اینه که ما میخواییم <<<"مواقعی که کاری نداریم میکرو توان مصرفی بالایی مصرف نکنه">>> اما این به این معنی نیست که وقتی کاری برای انجام دادن داریم باز هم بریم در حالت sleep. تازه در اینگونه موارد باز هم طراحی برنامه فرق میکنه مثلا میخواییم دما رو اندازه بگیریم. فرض میکنیم این دما با استفاده از یک adc خونده میشه. اولا میتونیم این کار رو بصورت پس زمینه در تایمر زمانبندی سیستم انجام بدیم. ایضا حتما حواسمون رو جمع میکنیم که دما فاکتوریه که به این زودی ها دستخوش تغییر نمیشه پس نمونه برداری آنالوگ رو میشه مثلا هر 1 ثانیه یک بار انجام داد.
                          حالا این عمل رو میشه به صورت دستی با کد در تایمر انجام داد یا سیکلش رو استارت کرد تا اخذ نتیجه و پردازش >>اولیه<<< در وقفه adc انجام بشه.


                          2- اولا برای مقاصد امنیتی طبق سفارش خود دیتاشیت اتمل بهتره که هر وقت میخواییم در حالت sleep برویم اول استفاده از این حالت را فعال کنیم (MCUCR |= 0x80) بریم به حالت sleep و پس از دراومدن امکان استفاده از این حالت رو غیر فعال کنیم.
                          بنا بر این میشه اطمینان پیدا کرد که اگه جایی سهوا دستور sleep رو استفاده کردیم سیستم به حالت sleep نمیره.
                          ایضا":


                          code phase

                          while( timeout ) a
                          {
                          MCUCR |= 0x80; b
                          asm("sleep" c
                          MCUCR &=~0x80; d
                          } e



                          در فاز >a< سیستم در حالت sleep نیست و داره چک میکنه آیا احتیاجی هست که در حلقه بمونه یا نه یا به عبارتی دیگه زمان delay تموم شده یا نه. فراموش نکنیم که سپری شدن این زمان با استفاده از این متغیر در تایمر مربوطه به این while اطلاع داده میشه.
                          در فاز <b> فهمیدیم که زمان هنوز تموم نشده پس چون کاری غیر از صبر نداریم بایستی امکان استفاده از حالت sleep رو فعال کنیم.
                          در فاز <c> به حالت sleep میریم (و عملا صبر میکنیم تا سیستم به هر دلیلی خودش از sleep بیرون بیاد.
                          در فاز <d> طبق توضیح بند قبلی امکان استفاده از این حالت رو غیر فعال میکنیم.
                          در فاز <e> به بعد انگار که اصلا به sleep نرفته ایم سیستم در حال کار عادی اش است.

                          نکته مهم اینه که این روال یک زمان تقریبی رو صبر میکنه نه یک زمان دقیق. اگر زمان صبرتون بایستی خیلی دقیق باشه بسته به میزان دقت یا دقت ثابت زمانی تایمر اصلی سیستم رو زیاد کنین یا اصلا از کد استفاده کنین.
                          یعنی از این تابع میشه برای جایگزینی عبارت زیر استفاده کرد:
                          >>حدود a میلی ثانیه وقت میتونی تلف کنی<<
                          اما اگر منظور این باشه که بگیم:
                          >>دقیقا a میلی ثانیه صبر کن>> این واژه "دقیقا" به خیلی از عوامل بستگی پیدا میکنه و بهتره که با یک حلقه انجام بشه.

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

                          راجع به مورد آخری باید گفت:
                          کامپایلر گلاب بروتون خره. نمیفهمه که این متغیر در جای دیگه ای ممکنه تغییر کنه. بنا بر این به خیال خودش برای من میخواد کار کنه و عوض اینکه سیکل زیر رو اجرا کنه:

                          1- اخذ مقدار از متغیر در رجیستر های داخلی (که ممکنه توسط تایمر عوض شده باشه).
                          2- مقایسه با صفر.
                          3- اگر صفر نیست برو به وضعیت 1.

                          منطق زیر رو اجرا میکنه

                          1- اخذ مقدار از متغیر در رجیستر های داخلی.
                          2- مقایسه با مقدار صفر.
                          3- اگر صفر نیست برو به وضعیت 2.

                          تا به خیال خودش چون این کار تنها کار سیستم هست دوباره کد بند اول رو مدام اجرا نکنه.
                          به همین خاطر با پیشوند volatile میگیم: اوهوی!! هر دفعه میخوای مقدار این متغیر رو چک کنی مقدارشو مستقیما از حافظه بخون و از مقدار ذخیره شده قبلی در رجیسترهایت استفاده نکن.

                          اگر باز هم مشکلی هست یک مثال میشه طرح کنی تا یه پیشنهاد توپپپپپپ برات دربیارم. قبلش هم خودت اون مسئله رو بدون sleep حل کنی و نتایج رو کنار هم قرار بدی. (البته به C نه basic)!

                          دیگه انگشتام درد گرفت.

                          دیدگاه


                            #14
                            پاسخ : مشکل با مد sleep ؟

                            سلام
                            من می خوام در مد sleep، به ازای تغییر هر یک از ورودی های PortC ،میکرو AVR atmega16A از حالت sleep در بیاد بیرون.
                            آیا این شدنی هست؟!
                            در واقع داستان اینه که ...
                            من 8 تا ورودی در portC دارم که میکرو باید به ازای تغییر هر کدام، کار خاصی رو انجام بده. نمی خوام توی یک Loop بینهایت، همش portC را بخونم و ببینم که کدوم بیت تغییر کرده. بلکه می خوام وقتی تغییری ندارم، میکرو در حالت sleep باشه و با تغییر در هر یک از بیتهای ورودی portC، میکرو بیدار شه و کار مربوطه رو انجام بده.
                            کسی راه حلی داره ؟؟
                            پیشاپیش ممنون

                            دیدگاه


                              #15
                              پاسخ : مشکل با مد sleep ؟

                              در برخی از شماره های AVR یک وقفه خارجی از نوع Pin change وجود دارد که تغییرات روی یک سری از پین ها منجر به یک وقفه مشترک می شود. مثلا در ATTINY2313 تغییرات در کلیه پین های PORTB می تواند باعث ایجاد این نوع وقفه و خروج از وضعیت Sleep شود. اما در ATMEGA16 وقفه Pin change به شکلی که توضیح داده شد وجود ندارد و فقط وقفه های خارجی از نوع عادی وجود دارند.
                              اوژن: به معنای افکننده و شکست دهنده است
                              دانایی، توانایی است-Knowledge is POWER
                              برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                              وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                              قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                              اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                              ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                              دیدگاه

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