اطلاعیه

Collapse
No announcement yet.

تایمر-CCS

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

    تایمر-CCS

    سلام به دوستان و اساتید گرامی
    دوتا سوال داشتم در مورد تایمر.
    با pic18f452-CCS-crystal=16mhz - no PLL

    1- آیا راهی ( به جز استفاده از متغیر های عمومی ) برای انتقال متغیر به تابع اینتراپت هست ؟
    مثلا:
    کد:
    #int_timer2
    void timer2_ISR(float variable1 , unsigned int8 variable2)
    2-اگر بخواهیم تایمر یه عدد غیر رند مثلا 62470 رو بشماره باید چیکار کرد؟
    با حساب کتاب من باید تایمر رو اینجوری تنظیم کرد:
    کد:
    setup_timer2(16,255,16);
    و بعد 3.8 برابر صبر کرد!
    خوب این میشه 3 بار اینتراپت به علاوه ی 208 بار شمارش اضافی.
    این شمارش اضافی رو شما بودید چه طور در میاوردید؟

    مشکل اینه که با تغییر دادن مقدار تایمر تنظیمات تایمر یعنی -period-postscaler-prescaler از بین میره .

    متشکر
    -----------------------------
    ویرایش جدید:
    البته برای سوال دوم خودم چند تا راهکار به ذهنم میرسه که هیچکدوم چنگی به دل نمیزنه:
    1- استفاده از setup_timer دو بار در وقفه یک بار برای تنظیم حالت شمارش 0.8 یک بار هم برای برگرداندن از اون حالت
    2- استفاده از تاخیر delay که واقعا بده
    3- گرفتن مقدار الان تایمر و یک جمع و تفریق برای در آوردن 0.8 و صبر کردن تا رسیدن به مقدار جدید ( یه چیزی مثل همون مورد دوم )
    که بازم میگم همه روش های ابتدایی و بدی هستن
    دوستان عزیزم تصمیم گرفتم تا یه مدت کمتر به تالار سر بزنم . اگر دیر جواب دادم ببخشید.

    #2
    پاسخ : تایمر-CCS

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

    دیدگاه


      #3
      پاسخ : تایمر-CCS

      نوشته اصلی توسط ramez
      سلام دوست عزیز .من از هرطرف میخونم چیزی دست گیرم نمیشه میشه یکم بیشتر توضیح بدی.اگه دقیقا بگی چیکارمی خوای بکنب بهتر میشه کمک کرد
      خدا خیرت بده.( بلاخره یه نفر اومد)
      اول خدمتت عرض کنم که من می خوام کار رو بهینه کنم ( وگرنه با همون روش هایی که گفتم الان دارم کار می کنم)
      دوم خدمتتون عرض کنم که من این سوال رو بعد از اینکه یه هفته تو این سایت موند و کسی جواب نداد رفتم از بچه های سایت ccsinfo پرسیدم اونا جواب دادن ( البته اونا هم گفتن که نمیشه- همین رو استفاده کن)
      سوم:
      و اما مشکل:
      1- شما چطور متغیر هاتون رو به تابع وقفه (ISR) منتقل می کنید ؟
      من از متغیر های عمومی استفاده کردم ، شما راه بهتری بلدید؟
      2- فرض کنید عددی رو بصورت منظم می خواهید بشمارید
      مثلا 58 میلی ثانیه.
      در این صورت تایمرتون رو چطور تنظیم می کنید؟
      ( توجه کنید که حداکثر مقداری که با تنظیم مقادیر postscaler-prescaler-period بدست میاد 16384 میکروثانیه است)
      دوستان عزیزم تصمیم گرفتم تا یه مدت کمتر به تالار سر بزنم . اگر دیر جواب دادم ببخشید.

      دیدگاه


        #4
        پاسخ : تایمر-CCS

        سلام.
        1-منم از روش متغیرهای عمومی استفاده میکنم(بالاخره متغیر عمومی واسه همین روزاست دیگه :smile

        2-طبق تنظیماتی ک برای تایم2 انجام دادی نمیشه58میلی ثانیه درست کرد ولی با یکم تغییر میشه
        کد:
        pic18f452-CCS-crystal=16mhz - no PLL
        setup_timer2(T2_DIV_BY_16,249,1);
        ×هر 4us تایمر یک واحد افزایش بیدا میکنه.
        ×هر 1ms تایمر overflow میشه.(وقتی تایمر به 250 رسید اورفلو میشه)
        ×هر 1ms وقفه تایمر 2 اتفاق می افته.

        حالا اگه شما تو ISR وقفه تایمر 2, تعداد دفعات وقفه رو بشمری هر 58 تا وقفه میشه 58 میلی ثانیه

        دیدگاه


          #5
          پاسخ : تایمر-CCS

          نوشته اصلی توسط ramez
          سلام.
          1-منم از روش متغیرهای عمومی استفاده میکنم(بالاخره متغیر عمومی واسه همین روزاست دیگه :smile

          2-طبق تنظیماتی ک برای تایم2 انجام دادی نمیشه58میلی ثانیه درست کرد ولی با یکم تغییر میشه
          کد:
          pic18f452-CCS-crystal=16mhz - no PLL
          setup_timer2(T2_DIV_BY_16,249,1);
          ×هر 4us تایمر یک واحد افزایش بیدا میکنه.
          ×هر 1ms تایمر overflow میشه.(وقتی تایمر به 250 رسید اورفلو میشه)
          ×هر 1ms وقفه تایمر 2 اتفاق می افته.

          حالا اگه شما تو ISR وقفه تایمر 2, تعداد دفعات وقفه رو بشمری هر 58 تا وقفه میشه 58 میلی ثانیه
          خیلی متشکر
          روشی که شما استفاده کردید روش ضربی بود(یعنی حاصلضرب چند تا وقفه).
          من با این روش دو تا مشکل دارم:
          بازه ی تغییرات زمانی که من از تایمر می خوام زیاده. همون طور که گفتم من از این برنامه دارم برای ساخت برنامه PWM نرم افزاری استفاده می کنم و انتظار دارم که این برنامه بتونه در تمام فرکانس هایی که کاربر می خواد و میکرو قادر به انجام اون هست کار کنه.(الان یه نمونه اولیه + یک اصلاح از این برنامه رو در زیرـانجمن "پروژه های تکمیل شده" گذاشتم-البته با همون روش ناقص خودم".
          برنامه اینجوری هست که بعد از گرفتن فرکانس و زمان وظیفه دلخواه موج رو برای کار بر ایجاد می کنه.(این فرکانس می تونه از 0.1 هرتز تا 10 کیلو هرتز باشه(برای میکرویی با سیکل کاری 0.25 میکروثانیه)
          داشتم اینو می گفتم که این روش دو تا مشکل برای من به وجود میاره:
          1- الگوریتمی که برای پیدا کردن پارامتر ها بوسیله ی این روش استفاده می شه دقیق نیست.( البته الگوریتمی که من درست کردم ، اگه میشه شما الگوریتم خودتون رو بفرمایید ، شاید اون دقیق باشه)
          2- بهینه ترین حالت برای این نرم افزار و در کل هر نرم افزاری استفاده کمتر از برنامه وقفه است . یعنی اینکه میکرو وقت خودش رو کمتر صرف گذراندن در وقفه این برنامه بکنه و بتونه به کارهای دیگه هم برسه. و این مستلزم اینه که تا اونجا که میشه تعداد وقفه ها کم ولی زمان هر وقفه طولانی تر بشه.(مثلا برای ایجاد پالس های 1 ثانیه ای بهتر اینه که فقط 65 بار وقفه اعلام بشه )

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

          دیدگاه


            #6
            پاسخ : تایمر-CCS

            قطعا درگیری کمتر با وقفه ها بهینه تره.از طرفی چون شما می خوای pwm بصورت نرم افزاری راه اندازی کنی خود بخود با برنامه کاربر تداخل داره یعنی شما باید درصدی از نرم افزارتو به این کار اختصاص بدی .
            بر اساس تجربه شخصی خودم:pwm نرم افزاری از نظر تایمینگ و خوب در اوردن شکل موج،دشواری های زیادی داره مخصوصا برای شما که تو این رنج فرکانسی کار میکنی.برای مثال دستور ساده (output_high(pin اول میاد pinرو بصورت خروجی در میاره بعد اونو یک میکنه واین ینی دستور بیشتر از یک سیکل طول میکشه.ولی درکل برای کارهایی که فرکانس انچنان مهم نیست مناسبه.
            اجمالا راهی که بنظرم میرسه اینه که اسمبلی بنویسی ومستقیم با خود رجیسترها کار کنی

            دیدگاه


              #7
              پاسخ : تایمر-CCS

              نوشته اصلی توسط ramez
              قطعا درگیری کمتر با وقفه ها بهینه تره.از طرفی چون شما می خوای pwm بصورت نرم افزاری راه اندازی کنی خود بخود با برنامه کاربر تداخل داره یعنی شما باید درصدی از نرم افزارتو به این کار اختصاص بدی .
              بر اساس تجربه شخصی خودم:pwm نرم افزاری از نظر تایمینگ و خوب در اوردن شکل موج،دشواری های زیادی داره مخصوصا برای شما که تو این رنج فرکانسی کار میکنی.برای مثال دستور ساده (output_high(pin اول میاد pinرو بصورت خروجی در میاره بعد اونو یک میکنه واین ینی دستور بیشتر از یک سیکل طول میکشه.ولی درکل برای کارهایی که فرکانس انچنان مهم نیست مناسبه.
              اجمالا راهی که بنظرم میرسه اینه که اسمبلی بنویسی ومستقیم با خود رجیسترها کار کنی
              متشکر ، الگوریتمی که استفاده می کنید چطور هست ؟
              برای پیدا کردن مشخصات تایمر و تعداد وقفه؟
              مثلا الان تو محاسباتی که کرده بودید 58 میلی ثانیه رو دقیق بدست آورده بودید . آیا میشه الگوریتیمی(ضربی) برای مشخص کردن دقیق زمان داشت؟
              ( من فکر می کردم نمی شه و حتما باید از الگوریتمی مبتنی بر جمع و ضرب همزمان استفاده کرد ، ولی دومین ارسال شما رو که دیدم یاد یه روش جدید افتادم که شاید بتونه هم دقیق باشه و هم از روش ضربی استفاده کنه)
              متشکر
              دوستان عزیزم تصمیم گرفتم تا یه مدت کمتر به تالار سر بزنم . اگر دیر جواب دادم ببخشید.

              دیدگاه


                #8
                پاسخ : تایمر-CCS

                فر می کنیم می خواهیم دو موج pwm با فرکانس 20KHZ روی بایه های b0, b1 درست کنیم ک در این صورت دوره تناوب میشه 50us.سبس تایمر رو طوری تنظیم می کنیم که هر 50us یک وقفه ایجاد کنه اینجوری
                کریستال 16MHz
                کد:
                setup_timer_2(T2_DIV_BY_4,49,1);   //50.0 us overflow, 50.0 us interrupt
                تو روتین وقفه اینجوری مینویسیم
                کد:
                #int_TIMER2
                void TIMER2_isr(void) //every 50us
                {
                  output_high(pin_b0);
                  output_high(pin_b1);
                
                }
                با این حرکت میکرو هر 50us میره بایه های مورد نظر رو یک میکنه تا اینجا فرکانس 20khz رو درست کردیم حالا باید دیوتی سایکل رو درست کنیم
                کد:
                void main()
                {
                  int8 du_1=25,du_2=10;
                  setup_timer_2(T2_DIV_BY_4,49,1);   //50.0 us overflow, 50.0 us interrupt
                
                  enable_interrupts(INT_TIMER2);
                  enable_interrupts(GLOBAL);
                
                  while(TRUE)
                  {
                   
                   if(get_timer2()>du_1)
                     output_low(pin_b0);
                   if(get_timer2()>du_2)
                     output_low(pin_b1);
                    
                  }
                
                }
                متغیر du_1 برای دیوتی سایکل بین bo وdu_2 هم برای بین b1 هست.

                دیدگاه


                  #9
                  پاسخ : تایمر-CCS

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

                  دیدگاه

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