اطلاعیه

Collapse
No announcement yet.

کمک در مورد سروو موتور

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

    #61
    پاسخ : کمک در مورد سروو موتور

    ده روش برای استفاده از تایمرهای میکرو وجود داره.
    من خیلی در استفاده از تایمر خست به خرج می دم. یعنی فقط از یک تایمر برای همه زمان بندی ها استفاده می کنم.
    مثلا اگه کمترین زمان مورد نیازم 10 میکروثانیه باشه یکی از تایمرها رو طوری تنظیم می کنم که هر 10 میکروثانیه اینتراپت بده.
    در روتین اینتراپت یک FLAG رو یک می کنم. در برنامه اصلی حلقه اصلی برنامه هروقت این FLAG یک شد میام و کارهای لازم رو انجام میدم. مثلا اگه زمان 1 میلی ثانیه لازم داشته باشم صدتا 10 میکروثانیه برام 1 میلی ثانیه می سازه.
    هر تایمینگی که دلت بخواد با این روش می تونی بسازی. یعنی بی شمار تایمر دقیق خواهی داشت فقط با استفاده از یک تایمر میکرو.
    این روش توی PLCآ‌های استاندارد هم استفاده میشه.
    در این برنامه هم می تونی از همین روش برای کنترل سرووها و باقی زمانهای لازم برا یخوندن فرکانس، کنترل LCD و... استفاده کنی.
    در ضمن الان یه اینتراپت تایمرت برای کنترل سرووها فعاله. اگه زمان این تایمر ثابته می تونی از همین تایمر بعنوان time base استفاده کنی و خوندن فرکانس رو داخل همین روتین اینتراپت انجام بدی.
    مثلا اگه روتین تایمر سروو هر 1 میلی ثانیه اجرا میشه باید یه متغیر رو توش یکی یکی اضافه کنی تا به 800 برسه. وقتی به 800 رسید کانتر فرکانس رو می خونی و دوباره همه متغیر و کانتر رو صفر می کنی.

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

    دیدگاه


      #62
      پاسخ : کمک در مورد سروو موتور

      نوشته اصلی توسط ahmadmn
      ده روش برای استفاده از تایمرهای میکرو وجود داره.
      من خیلی در استفاده از تایمر خست به خرج می دم. یعنی فقط از یک تایمر برای همه زمان بندی ها استفاده می کنم.
      مثلا اگه کمترین زمان مورد نیازم 10 میکروثانیه باشه یکی از تایمرها رو طوری تنظیم می کنم که هر 10 میکروثانیه اینتراپت بده.
      در روتین اینتراپت یک FLAG رو یک می کنم. در برنامه اصلی حلقه اصلی برنامه هروقت این FLAG یک شد میام و کارهای لازم رو انجام میدم. مثلا اگه زمان 1 میلی ثانیه لازم داشته باشم صدتا 10 میکروثانیه برام 1 میلی ثانیه می سازه.
      هر تایمینگی که دلت بخواد با این روش می تونی بسازی. یعنی بی شمار تایمر دقیق خواهی داشت فقط با استفاده از یک تایمر میکرو.
      این روش توی PLC‌های استاندارد هم استفاده میشه.
      در این برنامه هم می تونی از همین روش برای کنترل سرووها و باقی زمانهای لازم برا یخوندن فرکانس، کنترل LCD و... استفاده کنی.
      در ضمن الان یه اینتراپت تایمرت برای کنترل سرووها فعاله. اگه زمان این تایمر ثابته می تونی از همین تایمر بعنوان time base استفاده کنی و خوندن فرکانس رو داخل همین روتین اینتراپت انجام بدی.
      مثلا اگه روتین تایمر سروو هر 1 میلی ثانیه اجرا میشه باید یه متغیر رو توش یکی یکی اضافه کنی تا به 800 برسه. وقتی به 800 رسید کانتر فرکانس رو می خونی و دوباره همه متغیر و کانتر رو صفر می کنی.

      با همه این روش ها الان اگه تایمر اضافه داری می تونی ازش به همون سبکی که در بالا گفتی استفاده کنی. یعنی مقدار ماکزیمم تایمر رو از زمان مورد نیاز تفریق کنی و بریزی توی تایمر. هر وقت هم که سرریز شد فرکانس رو بخونی.
      ممنونم آقا از توضیحات کاملتون.
      جناب مهندس دلیل اینکه من این روش رو عرض کردم این بود که راه حل دیگه ای به ذهنم نمیرسید :redface:
      و اصلا با روش جالبی که شما فرمودید برا ساخت 800 میلی ثانیه آشنائی ندارم و با این سواد نم دارم باید روش کار کنم، همه ی سعیم رو هم از وقتی پست شما رو دیدم دارم میکنم بلکه بتونم کد مربوط به روش شما رو بنویسم، اما متاسفانه فعلا که نشد.

      البته برام مهم نظر شماست که از کدوم روش استفاده کنم،چون تجربه ی شما خیلی دقیقتر از بنده میتونه تصمیم بگیره و پر واضح هم هست که روش شما منطقی تر و حرفه ای تر خواهد بود اما اگه کار من خیلی سوتی نیست!!و فهمیدن و به کار بستن روش شما برای من خیلی زمان بر میشه از سبکی که بنده عرض کردم (البته اگه تایمر هام اجازه بدند) استفاده کنم،
      در غیر این صورت بنده تابع اوامر شمام.
      از تایمرها و وقفه هایی که واسه کنترل سروو تو برنامم استفاده شده:
      یکی وقفه ی واحد ccp در مد compare همراه با ریست تایمر 1 در زمان برابری مقایسه هست.
      و وقتی وقفه روی داد توی روتین وقفه از سر ریز تایمر صفر برا ساخت زمان 1 تا 2 میلی ثانیه برا چرخش سرووها استفاده شده.
      در نتیجه با این حساب تایمر صفرم در گیر هست.
      ولی نمیدونم حالا که از ریست تایمر 1 در زمان برابری مقایسه استفاده شده، آیا میتونم از سر ریز اون استفاده کنم برا خوندن فرکانس؟!

      زندگی برگ بودن در مسیر باد نیست
      امتحان ریشه هاست
      ریشه هم هرگز اسیر باد نیست
      زندگی چون پیچک است
      انتهایش میرسد پیش خدا!

      دیدگاه


        #63
        پاسخ : کمک در مورد سروو موتور

        دمت دایی
        از تایمری که برای سروو استفاده شده نمیشه به روش خودت برای کار دیگه استفاده کرد.
        راستش من از روتین سروویی که گذاشتی زیاد سر در نیاوردم. هم به زبان بیسیکه، هم اینکه AVRآ‌نیست که من بهش عادت دارم.
        سرووها یه زمان رفرش دارند که معمولا 20 میلی ثانیه است. این 20 میلی ثانیه رو من در برنامه شما پیدا نکردم.
        در همین روتین اینتراپت 20 میلی ثانیه می تونی یه متغیر رو بهش اضافه کنی تا به 40 برسه. هر وقت به چهل رسید مقدار کانتر فرکانس رو می خونی و هم متغیر و هم کانتر فرکانس رو صفر می کنی. تا دفعه بعد که متغیر به 40 برسه و...
        در واقع شما با یه time base با زمان 20 میلی ثانیه و یه متغیر تونستید تایمر 800 میلی ثانیه بسازید.
        در آخر توصیه می کنم برنامه کنترل سرووها رو هم خودت بنویسی تا PAUSE داخل اون هم حذف بشه.
        کسی که این برنامه رو نوشته قصد نداشته از میکرو برای مقصود دیگه ای استفاده کنه. اما شما که می خوای از میکرو کلی کار بکشی نباید از دستور PAUSE در هیچ جای برنامه استفاده کنی.
        نوشتن برنامه کنترل سرووها چندان هم سخت نیست. کافیه یه تایمر 1 رو برای 20 میلی ثانیه تنظیم کنی تا اینتراپت بده. داخل روتین اینتراپت، خروجی سرووی اول رو 1 می کنی و تایمر 2 رو فعال می کنی تا در زمان پالس مورد نیاز برای این سروو اینتراپت بده. وقتی اینتراپت تایمر دوم اومد خروجی سرووی اول صفر میشه و خروجی سرووی دوم 1 میشه و تایمر 2 رو برای پهنای پالس سرووی دوم تنظیم می کنی تا اینتراپت بده و ...
        با توجه به اینکه هر سروو به حداکثر 2 میلی ثانیه نیاز داره با این روش می تونی تا 10 سروو رو کنترل کنی. بدون اینکه میکروی شما هیچوقت جایی گیر کرده باشه.




        با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

        دیدگاه


          #64
          پاسخ : کمک در مورد سروو موتور

          نوشته اصلی توسط ahmadmn
          دمت دایی
          از تایمری که برای سروو استفاده شده نمیشه به روش خودت برای کار دیگه استفاده کرد.
          راستش من از روتین سروویی که گذاشتی زیاد سر در نیاوردم. هم به زبان بیسیکه، هم اینکه AVRنیست که من بهش عادت دارم.
          سرووها یه زمان رفرش دارند که معمولا 20 میلی ثانیه است. این 20 میلی ثانیه رو من در برنامه شما پیدا نکردم.
          در همین روتین اینتراپت 20 میلی ثانیه می تونی یه متغیر رو بهش اضافه کنی تا به 40 برسه. هر وقت به چهل رسید مقدار کانتر فرکانس رو می خونی و هم متغیر و هم کانتر فرکانس رو صفر می کنی. تا دفعه بعد که متغیر به 40 برسه و...
          در واقع شما با یه time base با زمان 20 میلی ثانیه و یه متغیر تونستید تایمر 800 میلی ثانیه بسازید.
          در آخر توصیه می کنم برنامه کنترل سرووها رو هم خودت بنویسی تا PAUSE داخل اون هم حذف بشه.
          کسی که این برنامه رو نوشته قصد نداشته از میکرو برای مقصود دیگه ای استفاده کنه. اما شما که می خوای از میکرو کلی کار بکشی نباید از دستور PAUSE در هیچ جای برنامه استفاده کنی.
          نوشتن برنامه کنترل سرووها چندان هم سخت نیست. کافیه یه تایمر 1 رو برای 20 میلی ثانیه تنظیم کنی تا اینتراپت بده. داخل روتین اینتراپت، خروجی سرووی اول رو 1 می کنی و تایمر 2 رو فعال می کنی تا در زمان پالس مورد نیاز برای این سروو اینتراپت بده. وقتی اینتراپت تایمر دوم اومد خروجی سرووی اول صفر میشه و خروجی سرووی دوم 1 میشه و تایمر 2 رو برای پهنای پالس سرووی دوم تنظیم می کنی تا اینتراپت بده و ...
          با توجه به اینکه هر سروو به حداکثر 2 میلی ثانیه نیاز داره با این روش می تونی تا 10 سروو رو کنترل کنی. بدون اینکه میکروی شما هیچوقت جایی گیر کرده باشه.
          سلام مهندس.
          بسیار ممنونم جناب کوهستانی از توجه و توضیحات کاملتون.
          اول از همه از تاخیر تو پاسخ پستتون معذرت میخوام، سر دیکد کردن خروجی سنسور گاز به مشکل خوردم، سرم گرم اون شد، واقعا عذر میخوام.

          قبل از هر چیز به رسم ادب و امانتداری تشکر میکنم از جناب perfect بابت زحمتشون برای نوشتن برنامه ی 7 سروو، و فرمایش شما رو کاملا قبول دارم، ایشون برنامه رو برای میکرو با این فرض نوشتن که میکرو فقط سرووها رو بچرخونه و خبر از این که قرار هست ما کارهای بیشتری همزمان از میکرو بکشیم، نداشتن.

          جناب مهندس perfect قبلا لطف کرده بودند و در توضیح زمان 20 میلی ثانیه برای کنترل سروو این توضیحات رو فرموده بودند که بنده هم بدون کم و کاست نقلش میکنم:
          چون برای کنترل سروو موتور یک دوره تناوب 20ms نیاز است که این دوره تناوب توسط ماژول CCP1 ایجاد میشه. باتوجه به اینکه از کریستال 8Mhz استفاده شده کلاک داخی برابر 2mhz میشه و برای تولید 20 میلی ثانیه تایمر 1 رو با همون کلاک 2Mhz راه اندازی کردیم. رجیستر های مقایسه واحد Compare (یعنی دو رجیستر CCPR1H و CCPR1L) مقدار تایمر رو با عدد 40000 مقایسه میکنند و در صورت برابری برنامه وارد وقفه میشه. همچنین برای کنترل سروو مدت یک بودن پالس در این دوره 20ms فقط بین 1 الی 2 میلی ثانیه میتونه باشه .بنابراین ما این تایم رو داخل سرویس وقفه ایجاد میکنیم به این ترتیب که اون رو به دو بخش تقسیم کردیم. بخش اول که یک زمان ثابت حدود 1 میلی ثانیه است که توسط دستور PAUSEUS 990 تولید شده و زمان بین 1ms تا 2ms توسط تایمر صفر به صورت تقریبی تولید میشه. علت اینکه بخش ثابت رو دقیق 1 میلی ثانیه انتخاب نکردیم تاخیر هایی هست که اجرای دستورات بعدی برای راه اندازی تایمر و غیره ایجاد میکنند.

          توضیحات خوب و کاملتون راجع به نحوه ی تنظیم تایمرها برای خوندن فرکانس و کنترل سروو راهنمای خیلی خوبی برای شروع نوشتن کد مربوطش بودن، همین الان شروع به نوشتن برنامش میکنم، (البته اگر این سنسور گاز و A/D بگذارند، چون علاوه بر مشکلی که با خود سنسور دارم باید برنامه ی A/D مربوط به دیکد خروجیش رو طبق فرمایشات شما عوض کنم چون توی این برنامه هم از دستور PAUSE استفاده کردم :sad

          امیدوارم بتونم از پس برنامه ی حرکتی سروو با شرطهایی که دارم بر بیام...

          باز هم ممنونم جناب مهندس کوهستانی از لطفتون.


          اضافه شده در تاریخ :
          باز هم سلام خدمت همه ی دوستان و اساتید محترم.
          دوستان گرامی امیدوارم حوصلتون از سوالات پیاپی بنده سر نره و مثل همیشه کمک حال بنده ی کم سواد باشید.
          بنده، میخوام با کمک تایمرهای میکرو روشی برای طی کردن زمان مورد نیاز یا همان تاخیر در برنامه ایجاد کنم، (هدف جایگزین کردن روشی برای استفاده از دستور pause هست).
          و بعد از اون برنامه ی خوندن فرکانسی رو که هر 800 میلی ثانیه پدیت میشه بنویسم در اصل هدف بر این هست که طبق فرموده ی جناب کوهستانی به جای دستور pause 800 از تایمرهای میکرو برای ایجاد تاخیر استفاده کنم.
          تا جائی که سواد نم دار بنده قد میده با استفاده از دستورات زیر و با کمک وقفه ی سر ریز تایمر صفر میکرو میشه این زمان رو به این ترتیب ایجاد کرد:
          برای ایجاد تاخیر 800 میلی ثانیه اگر ثبات تایمر صفر رو با مقدار 125 پر بشه و prescaler رو هم 64 در نظر بگیریم در این صورت با 100 بار سرریز کردن این تایمر دقیقا زمان 800 میلی ثانیه طی خواهد شد.
          A var byte
          On interrupt goto lable
          Option_reg = % 10100101 ' انتخاب prescaler 1:64
          Timr 0 = 125
          A = 0
          Intcon = %10100000
          Main:
          if A = 100 then
          اینجا باید فرکانس رو بخونم اما نمیدونم چجوری؟!
          A= 0
          Endif
          Goto main

          DISABLE
          Lable:
          A = A + 1
          Tmr 0 = 125
          Intcon . 2 = 0
          RESUME
          ENABLE
          END
          واسه خوندن فرکانس هم یه چیزایی میدونم ولی نمیدونم چی کارش کنم تا با کمک این کدها بتونم به جای دستور تاخیر از کدهای فوق استفاده کنم!!
          برای طولانی نشدن مطالب در پست بعدی برنامه های مربوط به فرکانس رو میارم.
          بسیار بسیار سپاسگذارم از دوستانی که حوصله به خرج میدن و مثل همیشه کمک حال بنده و سایر دوستان هستند.



          اضافه شده در تاریخ :
          این 2 برنامه مربوط به خوندن فرکانس هستند:
          این یکی که با کمک وقفه ی خارجی نوشته شده:

          define osc 8
          @ DEVICE PIC16F877A ,WDT_OFF ,PWRT_ON ,PROTECT_OFF ,LVP_ON ,HS_OSC ,BOD_OFF
          f_temp var word
          f var word

          trisb.0 = 1
          intcon = %10010000
          on interrupt goto lable
          main:
          f_temp = 0
          pause 800
          f = f_temp

          goto main
          disable
          lable:
          f_temp = f_temp + 1
          intcon.1 = 0
          resume
          enable
          end

          منتها فکر میکنم همینجوریشم، (جدای از اینکه دستور تاخیر رو در خودش داره)، این برنامه یه ایرادی داشته باشه!!!
          آخه وقتی بهش lcd میزنم و به ورودیش فرکانس میدم تا بخونه، فقط اعداد 0 و 1 رو نشون میده!!!!
          حالا نمیدونم چرا؟!
          و برنامه ی دیگه ای که با کمک تایمر صفر نوشته شده به این صورت هست:

          @ DEVICE pic16f877a,WDT_OFF ,PWRT_ON ,PROTECT_OFF ,LVP_ON

          define debuge_mode 1
          DEFINE DEBUG_BAUD 9600
          define lcd_dreg portd
          define lcd_dbit 4
          define lcd_rsreg portd
          define lcd_rsbit 2
          define lcd_ereg portd
          define lcd_ebit 3
          define lcd_bits 4

          temp var byte
          trisc = %00000001
          portc = %00000000
          option_reg = %10101000
          main:
          tmr0 = 0
          pause 800
          temp = tmr0
          lcdout $fe, 1
          lcdout #temp
          lcdout $fe, $14
          lcdout "hz"
          goto main
          end
          حالا موندم حیرون و سرگردون که چه کار کنم تا بتونم این کدها رو با هم ادغام کنم تا در نهایت بتونم یک فرکانس متری داشته باشم که توش دستور pause نداشته باشه.....

          میدونم سوالاتم خیلی زیادن اما متاسفانه بنده در حین انجام پروژم به این موارد بر خورد کردم و هر چقدر هم سعی کردم نتونستم از پسشون بر بیام، :sad: برای همین مزاحم وقت دوستان شدم تا در صورت امکان بنده رو راهنمائی بفرمائید.
          قبلا از لطف و همکاری همه ی شما نهایت تشکر رو دارم.
          زندگی برگ بودن در مسیر باد نیست
          امتحان ریشه هاست
          ریشه هم هرگز اسیر باد نیست
          زندگی چون پیچک است
          انتهایش میرسد پیش خدا!

          دیدگاه


            #65
            پاسخ : کمک در مورد سروو موتور

            نوشته اصلی توسط pama
            باز هم سلام خدمت همه ی دوستان و اساتید محترم.
            دوستان گرامی امیدوارم حوصلتون از سوالات پیاپی بنده سر نره و مثل همیشه کمک حال بنده ی کم سواد باشید.
            بنده، میخوام با کمک تایمرهای میکرو روشی برای طی کردن زمان مورد نیاز یا همان تاخیر در برنامه ایجاد کنم، (هدف جایگزین کردن روشی برای استفاده از دستور pause هست).
            و بعد از اون برنامه ی خوندن فرکانسی رو که هر 800 میلی ثانیه پدیت میشه بنویسم در اصل هدف بر این هست که طبق فرموده ی جناب کوهستانی به جای دستور pause 800 از تایمرهای میکرو برای ایجاد تاخیر استفاده کنم.
            تا جائی که سواد نم دار بنده قد میده با استفاده از دستورات زیر و با کمک وقفه ی سر ریز تایمر صفر میکرو میشه این زمان رو به این ترتیب ایجاد کرد:
            برای ایجاد تاخیر 800 میلی ثانیه اگر ثبات تایمر صفر رو با مقدار 125 پر بشه و prescaler رو هم 64 در نظر بگیریم در این صورت با 100 بار سرریز کردن این تایمر دقیقا زمان 800 میلی ثانیه طی خواهد شد.
            A var byte
            On interrupt goto lable
            Option_reg = % 10100101 ' انتخاب prescaler 1:64
            Timr 0 = 125
            A = 0
            Intcon = %10100000
            Main:
            if A = 100 then
            اینجا باید فرکانس رو بخونم اما نمیدونم چجوری؟!
            A= 0
            Endif
            Goto main

            DISABLE
            Lable:
            A = A + 1
            Tmr 0 = 125
            Intcon . 2 = 0
            RESUME
            ENABLE
            END
            واسه خوندن فرکانس هم یه چیزایی میدونم ولی نمیدونم چی کارش کنم تا با کمک این کدها بتونم به جای دستور تاخیر از کدهای فوق استفاده کنم!!
            برای طولانی نشدن مطالب در پست بعدی برنامه های مربوط به فرکانس رو میارم.
            بسیار بسیار سپاسگذارم از دوستانی که حوصله به خرج میدن و مثل همیشه کمک حال بنده و سایر دوستان هستند.
            سلام دایی جان
            خسته نباشی
            برای خوندن فرکانس با روش های معمولی، به دو تیکه از سخت افزار میکرو نیاز داریم. یکی کانتر که پالسها رو بشماره. و یکی تایمر که در زمان معینی کانتر رو صفر کنه.
            برای ساختن تایمر بهترین راه اینه که از تایمرهای دیگه استفاده بشه. یعنی نیازی نیست برای هر کار یه تایمر داشته باشیم. چون شما برای کنترل سرووها یه تایمر رو در مد اینتراپت قرار دادی از همون می تونی بعنوان مبنای زمان استفاده کنی.
            کافیه در روتین اینتراپت تایمر سرووها یه متغیر رو یکی یکی اضافه کنی. و در برنامه اصلی ببینی این متغیر به مقدار خاصی رسید یا نه. اگه رسید باید کانتر شمارنده فر کانس رو بخونی و داخل یه متغیر به اسم frq بریزی. بعد باید کانتر و اون متغیر زمان سنجی رو صفر کنی و روز از نو روزی از نو.
            فعلا نمی تونی به LCD هم اعتماد کنی چون داخل کتابخونه LCD هم از دستور pause استفاده شده!
            با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

            دیدگاه


              #66
              پاسخ : کمک در مورد سروو موتور

              نوشته اصلی توسط ahmadmn
              سلام دایی جان
              خسته نباشی
              برای خوندن فرکانس با روش های معمولی، به دو تیکه از سخت افزار میکرو نیاز داریم. یکی کانتر که پالسها رو بشماره. و یکی تایمر که در زمان معینی کانتر رو صفر کنه.
              برای ساختن تایمر بهترین راه اینه که از تایمرهای دیگه استفاده بشه. یعنی نیازی نیست برای هر کار یه تایمر داشته باشیم. چون شما برای کنترل سرووها یه تایمر رو در مد اینتراپت قرار دادی از همون می تونی بعنوان مبنای زمان استفاده کنی.
              کافیه در روتین اینتراپت تایمر سرووها یه متغیر رو یکی یکی اضافه کنی. و در برنامه اصلی ببینی این متغیر به مقدار خاصی رسید یا نه. اگه رسید باید کانتر شمارنده فر کانس رو بخونی و داخل یه متغیر به اسم frq بریزی. بعد باید کانتر و اون متغیر زمان سنجی رو صفر کنی و روز از نو روزی از نو.
              فعلا نمی تونی به LCD هم اعتماد کنی چون داخل کتابخونه LCD هم از دستور pause استفاده شده!
              با سلام و عرض ادب و احترام فراوان خدمت شما جناب مهندس کوهستانی.
              بسیار متشکرم از پاسختون که با توجه به اینکه میدونم مشغله های فراوانی دارید اما باز هم بنده رو مورد لطف خودتون قرار میدید.
              اگر بنده درست متوجه منظور شما شده باشم باید برای خوندن فرکانس طبق روتین زیر عمل کنم:
              فرضا اگر تایمر صفر در مد کانتر تعریف بشه برای اینکه پالسهای ورودی رو بشمره ما باید با این روال برنامه رو بنویسیم:
              Frq var byte
              A var byte
              Option _ reg = %10101000 ' که با این تعریف تایمر صفر رو در مد کانتر تعریف کردیم'
              Main:
              Tmr0 = 0
              حالا طبق فرموده ی شما باید در اینجا به جای تاخیر 800 میلی ثانیه با دستور pause ، با شرطی چک کنم که آیا متغیری که در روتین اینتراپت تایمر سرووها یکی یکی بهش اضافه کرده بودم به مقداری رسیده که 800 میلی ثانیه رو برامون بسازه یا خیر که اگر جواب مثبت بود مقدار کانتر رو توی متغیر frq بریزیم.
              یا به عبارتی:
              If A = …. Then
              Tmr0 = frq
              A = 0
              Goto main

              تا اینجا رو درست عرض کردم جناب مهندس یا باز هم اشتباه کردم؟
              فقط نکته ی اصلی که باقی میمونه ایجاد تایم بیسی هست که شما میفرمائید و باید در اون متغیر A رو اضافه کنیم تا 800 میلی ثانیه رو برامون بسازه، یا با متغیرهای دیگه سایر زمان های مورد نیاز دیگه ی برنامه رو بسازیم، که تا بحال تلاش بنده برای ساختن اون بی فایده بوده.
              اما هر طور که شده یه جوری راش میندازم. :agree:




              زندگی برگ بودن در مسیر باد نیست
              امتحان ریشه هاست
              ریشه هم هرگز اسیر باد نیست
              زندگی چون پیچک است
              انتهایش میرسد پیش خدا!

              دیدگاه


                #67
                پاسخ : کمک در مورد سروو موتور

                دقیقا درست متوجه شدی دایی جان
                البته یه endif قبل از A=0 باید باشه(اگه بیسیک یادم مونده باشه)
                در ضمن متغیر A باید نوع global باشه. یعنی در همه جای برنامه قابل دسترس باشه. متغیرهای local فقط در همون روتین خاص که تعریف شدن با معنی هستند، اما متغیرهای global در تمام روتین ها.
                اون روتین اینتراپت تایمر که سرووها رو کنترل می کنه، هر ۲۰ میلی ثانیه اینتراپت میده. متغیر A باید اونجا یکی یکی اضافه بشه.
                در روتین اصلی وقتی که به ۴۰ رسید یعنی ۸۰۰ میلی ثانیه گذشته.
                با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

                دیدگاه


                  #68
                  پاسخ : کمک در مورد سروو موتور

                  نوشته اصلی توسط ahmadmn
                  دقیقا درست متوجه شدی دایی جان
                  البته یه endif قبل از A=0 باید باشه(اگه بیسیک یادم مونده باشه)
                  و باز هم بسیار سپاسگذار جناب مهندس.
                  بله درست میفرمائید باید endif هم باشه، بنده فراموش کردم.

                  نوشته اصلی توسط ahmadmn
                  در ضمن متغیر A باید نوع global باشه. یعنی در همه جای برنامه قابل دسترس باشه. متغیرهای local فقط در همون روتین خاص که تعریف شدن با معنی هستند، اما متغیرهای global در تمام روتین ها.
                  ok، یعنی حتما باید در ابتدای برنامه تعریف بشه نه در روتینی که در حال خوندن فرکانس هستیم، درست عرض میکنم؟!

                  نوشته اصلی توسط ahmadmn
                  اون روتین اینتراپت تایمر که سرووها رو کنترل می کنه، هر ۲۰ میلی ثانیه اینتراپت میده. متغیر A باید اونجا یکی یکی اضافه بشه.
                  در روتین اصلی وقتی که به ۴۰ رسید یعنی ۸۰۰ میلی ثانیه گذشته.
                  بله جناب کوهستانی متوجه شدم که باید برای ساخت 800 میلی ثانیه این کار رو انجام بدیم، مثلا اگر در جای دیگه از برنامه به زمان 100 میلی ثانیه احتیاج داشتیم در این روتین 20 میلی ثانیه، باید یک متغیر رو یکی یکی اضافه کنیم در محل مورد نیاز هر گاه این متغیر به 5 رسید، یعنی زمان مورد نیاز طی شده،
                  منتها نمیتونم بفهمم که این روتین 20 میلی ثانیه که باید به عنوان تایم بیس برای زمانهای مورد نیاز برناممون مورد استفاده قرار بگیره، دقیقا کجای برنامه ی کنترل سرووهاست!
                  البته میدونم خیلی خنده داره که برنامه ای که خودم دارم رو نمیتونم بفهمم که 20 میلی ثانیه کجاش هست!!
                  جناب perfect فرمودند این 20 میلی ثانیه رو واحد ccp1 داره میسازه که متن زیر عین فرمایش ایشون هست منتها بنده چندین بار این متن رو خوندم اما باز هم دستگیرم نشد این زمان کجاست :sad:

                  " چون برای کنترل سروو موتور یک دوره تناوب 20ms نیاز است که این دوره تناوب توسط ماژول CCP1 ایجاد میشه. باتوجه به اینکه از کریستال 8Mhz استفاده کردیم کلاک داخی برابر 2mhz میشه و برای تولید 20 میلی ثانیه تایمر 1 رو با همون کلاک 2Mhz راه اندازی کردیم. رجیستر های مقایسه واحد Compare (یعنی دو رجیستر CCPR1H و CCPR1L) مقدار تایمر رو با عدد 40000 مقایسه میکنند و در صورت برابری برنامه وارد وقفه میشه. همچنین برای کنترل سروو مدت یک بودن پالس در این دوره 20ms فقط بین 1 الی 2 میلی ثانیه میتونه باشه .بنابراین ما این تایم رو داخل سرویس وقفه ایجاد میکنیم"
                  زندگی برگ بودن در مسیر باد نیست
                  امتحان ریشه هاست
                  ریشه هم هرگز اسیر باد نیست
                  زندگی چون پیچک است
                  انتهایش میرسد پیش خدا!

                  دیدگاه


                    #69
                    پاسخ : کمک در مورد سروو موتور

                    دمت دایی جان
                    تصحیح می کنم:
                    یه endif بعد از A=0 باید باشه.
                    دقیقا دایی جان. متغیرهای global در ابتدای برنامه، یعنی خارج از روتین ها تعریف میشه تا در همه روتین ها شناخته شده باشه(در پاسکال و C اینطوره)
                    ای ول دایی جان. بهترین و ساده ترین نوع زمان سنجی همینه. کافیه A=A+1 رو در اول روتین اینتراپت تایمر ccp1 بزاری.
                    اگه زمان دیگه ای لازم داری B=B+1 رو بعد از همین A=A+1 بزار و ...
                    با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

                    دیدگاه


                      #70
                      پاسخ : کمک در مورد سروو موتور

                      نوشته اصلی توسط ahmadmn
                      دمت دایی جان
                      تصحیح می کنم:
                      یه endif بعد از A=0 باید باشه.
                      دقیقا دایی جان. متغیرهای global در ابتدای برنامه، یعنی خارج از روتین ها تعریف میشه تا در همه روتین ها شناخته شده باشه(در پاسکال و C اینطوره)
                      ای ول دایی جان. بهترین و ساده ترین نوع زمان سنجی همینه. کافیه A=A+1 رو در اول روتین اینتراپت تایمر ccp1 بزاری.
                      اگه زمان دیگه ای لازم داری B=B+1 رو بعد از همین A=A+1 بزار و ...
                      سلام جناب مهندس.
                      و باز هم بسیار سپاسگذارم از توجه و حوصلتون.
                      ok دایی احمد، پس بنده میرم برنامه ی جدید رو تنظیم کنم و بیام.
                      امیدوارم به قول فرمایش شما این" تیر خلاص" به هدف بخوره :agree:

                      اضافه شده در تاریخ :
                      با سلام دوباره.
                      جناب مهندس برنامه رو با شرط فرکانس اونطور که شما فرمودید و طبق برنامه ی جناب مهندس perfect به صورت زیر اصلاح کردم، که قسمتهای رنگی مربوط به خوندن فرکانس و شرط کردن اون برای حرکت سرووهاست، آیا همون روالی هست که مد نظر شما بود؟

                      چند تا سوال دارم برای اینکه ببینم کاری که انجام شده درست هست یا خیر.
                      اولی اینکه آیا عبارت tmr0 = 0 محل اومدنش درست هست یا اینکه باید بعد از a = 0 باشه؟
                      و محل اومدن دستور تنظیم تایمر صفر به عنوان کانتر (option_reg) آیا درست هست یا باید قبل از خط main بیاد؟!


                      DEFINE OSC 8
                      @ DEVICE pic16f877a,WDT_OFF ,PWRT_ON ,PROTECT_OFF ,LVP_ON ,HS_OSC ,BOD_OFF
                      servo1 var byte
                      servo2 var byte
                      servo3 var byte
                      servo4 var byte
                      servo5 var byte
                      servo6 var byte
                      servo7 var byte

                      f var byte
                      a var byte

                      ON INTERRUPT GOTO _interrupt
                      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



                      TRISD=$00
                      PORTD=$00

                      TRISb = %00000001 ' برای تعریف پین b.0 به عنوان ورودی فرکانس
                      PORTb.0 = 1


                      TMR1L=0
                      TMR1H=0

                      CCP1CON=$0b

                      CCPR1H=$9c ;high byte of (40000)
                      CCPR1L=$40 ;low byte of (40000)

                      PIR1.2=0
                      PIE1.2=1

                      T1CON=$01 ;turn on timer1

                      option_reg = %10101000

                      INTCON.6=1 ;PEIE=1
                      INTCON.7=1 ;GIE=1 , enable global interrupt



                      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                      main:
                      tmr0 = 0
                      if a = 40 then
                      tmr0 = f
                      a = 0
                      endif

                      if f >= 20 and f <= 25 then
                      servo1 = 0
                      endif

                      if f >= 35 and f <= 40 then
                      servo2 = 25
                      endif

                      if f >= 55 and f <= 60 then
                      servo3 = 75
                      endif

                      if f >= 75 and f <= 80 then
                      servo4 = 125
                      endif

                      if f >= 95 and f <= 100 then
                      servo5 = 175
                      endif

                      if f >= 110 and f <= 115 then
                      servo6 = 200
                      endif

                      if f >= 125 and f <= 130 then
                      servo7 = 250
                      endif

                      goto main

                      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                      _interrupt:
                      ; interrupt service

                      DISABLE INTERRUPT ;disable interrapt

                      if PIR1.2=1 then ; if CCP1IF then

                      a = a + 1

                      PORTD = $01
                      PAUSEUS 990
                      INTCON.2=0
                      TMR0 = 255-servo1
                      OPTION_REG = OPTION_REG & $c0
                      OPTION_REG = OPTION_REG | $02
                      while INTCON.2=0
                      wend
                      PORTD=$00
                      ;;;;;;;;;;;;;;;;;;;;;;;;;;
                      .
                      .
                      .
                      به همین ترتیب تا سرووی هفتم(6 روتین دستور کنترل دیگه مثل روتین بالا) و در آخر هم:
                      ;;;;;;;;;;;;;;;;;;;;;;;;;;
                      PIR1.2=0 ; clear CCP1IF
                      endif

                      RESUME ;return from interrapt
                      ENABLE INTERRUPT


                      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                      End
                      در آخر هم بسیار ممنون خواهم شد نظرتون رو راجع به برنامه ی اخیر، محل if ها و هر چی که صلاح میدونید و محل ایرادهاشو بفرمائید.
                      جناب مهندس کوهستانی خیلی میترسم از اینکه باز هم تست کنم و جواب نده :sad:
                      زندگی برگ بودن در مسیر باد نیست
                      امتحان ریشه هاست
                      ریشه هم هرگز اسیر باد نیست
                      زندگی چون پیچک است
                      انتهایش میرسد پیش خدا!

                      دیدگاه


                        #71
                        پاسخ : کمک در مورد سروو موتور

                        ای ول دایی جان
                        ایدیت می کنم:
                        if a = 40 then
                        f = tmr0
                        tmr0 = 0
                        a = 0
                        endif

                        تنظیمات باید قبل حلقه اصلی برنامه انجام بشه. متغیر های لازم هم باید اونجا مقدار اولیه بگیرن تا وقتی وارد حلقه اصلی برنامه میشن باعث تغییر نابجا نشن. مثلا f=0 رو باید قبل main بنویسی. اگه همه متغیرها باید صفر بشن می تونی از یه دستور خاصی که توی بیسیک هست و من نمی دونم استفاده کنی.
                        با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

                        دیدگاه


                          #72
                          پاسخ : کمک در مورد سروو موتور

                          نوشته اصلی توسط ahmadmn
                          ای ول دایی جان
                          ایدیت می کنم:
                          if a = 40 then
                          f = tmr0
                          tmr0 = 0
                          a = 0
                          endif

                          تنظیمات باید قبل حلقه اصلی برنامه انجام بشه. متغیر های لازم هم باید اونجا مقدار اولیه بگیرن تا وقتی وارد حلقه اصلی برنامه میشن باعث تغییر نابجا نشن. مثلا f=0 رو باید قبل main بنویسی. اگه همه متغیرها باید صفر بشن می تونی از یه دستور خاصی که توی بیسیک هست و من نمی دونم استفاده کنی.
                          سلام جناب مهندس کوهستانی.
                          و بسیار سپاسگذارم از اینکه هنوزم حوصله ی بنده رو دارید.
                          ok،ممنونم از توضیحاتتون.
                          منتها مهندس ما f رو هیچ جا صفر نمیکنیم فکر میکنم منظورتون متغیر a هست، درست عرض میکنم؟

                          علاوه بر این هم ظاهرا بنده یک سوتی خیلی بزرگ دادم!
                          اونم اینکه از تایمر صفر به عنوان کانتر برای فرکانس متراستفاده کردم در صورتی که جناب مهندس perfect قبلا از این تایمر برای کنترل سرووها استفاده کرده بودند.
                          برای همین اگر تایمر 1 رو به عنوان کانتر به صورت زیر در نظر بگیرم درست هست؟

                          f var word
                          temp var byte
                          t1con = %00000010
                          temp = 0
                          'و به قول فرمایش شما a = 0 هم باید اینجا بیاد، درست عرض میکنم؟!
                          main :
                          tmr1h = 0
                          tmr1l = 0
                          pir1.0 = 0
                          t1con.0 = 1
                          if a = 40 then
                          t1con.0 = 0
                          f.byte1 = tmr1h
                          f.byte0 = tmr1l
                          endif

                          حالا اینجا ifها بیان و ادامه ی ماجرا...
                          برنامه ی جدید رو تنظیم میکنم و در پست بعدی میارم...
                          زندگی برگ بودن در مسیر باد نیست
                          امتحان ریشه هاست
                          ریشه هم هرگز اسیر باد نیست
                          زندگی چون پیچک است
                          انتهایش میرسد پیش خدا!

                          دیدگاه


                            #73
                            پاسخ : کمک در مورد سروو موتور

                            از تایمر1 قبلاً در ماژول CCP1 جهت تولید وقفه در هر 20ms استفاده شده. با توجه به اینکه تنها تایمر آزاد فعلی تایمر2 است و این تایمر قابلیت کار به عنوان کانتر را ندارد به نظر میرسه تغییرات اساسی و فوری باید در برنامه ایجاد کنید. برای این کار دو انتخاب دارید:
                            1- از تایمر1 همچنان جهت تولید وقفه در هر 20ms استفاده کنید و در روتین وقفه مربوطه هم به جای تایمر 0 از تایمر 2 استفاده کنید و از تایمر 0 به عنوان کانتر و جهت شمارش فرکانس استفاده کنید. ولی باید توجه داشت با توجه به 8بیتی بودن این تایمر در حالت عادی فقط قادر به اندازه گیری تا فرکانس 255Hz خواهید بود مگر اینکه منتظر پرچم OVF آن باشید یا از وقفه استفاده کنید که در این صورت کار کنترل سرووها در روتین وقفه رو سخت تر میکنه .
                            2- راه دوم و بهتر اینه که از تایمر2 جهت ایجاد وقفه در هر 20ms استفاده کنید و از تایمر 1 هم در مد کانتر جهت شمارش فرکانس استفاده بشه که باتوجه به 16 بیتی بودنش تا فرکانس 65535hz قابل اندازه گیری خواهد بود. و تایمر0 هم برای همون منظور قبلی در روتین وقفه 20ms استفاده بشه.

                            دیدگاه


                              #74
                              پاسخ : کمک در مورد سروو موتور

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

                              نوشته اصلی توسط Perfect
                              از تایمر1 قبلاً در ماژول CCP1 جهت تولید وقفه در هر 20ms استفاده شده. با توجه به اینکه تنها تایمر آزاد فعلی تایمر2 است و این تایمر قابلیت کار به عنوان کانتر را ندارد به نظر میرسه تغییرات اساسی و فوری باید در برنامه ایجاد کنید. برای این کار دو انتخاب دارید:
                              بله، کاملا درست میفرمائید نباید مادامی که از تایمر 0 و 1 در کنترل سرووها استفاده میشه از اون برای فرکانس متری هم استفاده کنم و این اشتباه بنده بود.
                              نوشته اصلی توسط Perfect
                              1- از تایمر1 همچنان جهت تولید وقفه در هر 20ms استفاده کنید و در روتین وقفه مربوطه هم به جای تایمر 0 از تایمر 2 استفاده کنید و از تایمر 0 به عنوان کانتر و جهت شمارش فرکانس استفاده کنید. ولی باید توجه داشت با توجه به 8بیتی بودن این تایمر در حالت عادی فقط قادر به اندازه گیری تا فرکانس 255Hz خواهید بود مگر اینکه منتظر پرچم OVF آن باشید یا از وقفه استفاده کنید که در این صورت کار کنترل سرووها در روتین وقفه رو سخت تر میکنه .

                              2- راه دوم و بهتر اینه که از تایمر2 جهت ایجاد وقفه در هر 20ms استفاده کنید و از تایمر 1 هم در مد کانتر جهت شمارش فرکانس استفاده بشه که باتوجه به 16 بیتی بودنش تا فرکانس 65535hz قابل اندازه گیری خواهد بود. و تایمر0 هم برای همون منظور قبلی در روتین وقفه 20ms استفاده بشه.
                              بسیار متشکرم از توضیحات دقیقتون.
                              بله جناب مهندس بنده هم برای ایجاد تغییرات با روش دوم موافقترم .
                              از لحاظ فرکانس هم باید عرض کنم که فرکانس ما تا 135 هرتز بیشتر نیست منتها مدام در حال تغییر هست در واقع در مدت زمان فرضا 4 یا 5 ساعتی که دستگاه مورد نظر ما در حال کار کردن هست این فرکانس در این بازه 0 تا 130 هرتز که عرض کردم تغییر میکنه و نوسان خواهد داشت، و ما باید طبق فرکانسی که در هر زمان میخونیم برای حرکت سرووها تصمیم بگیریم یا بگیم در هر فرکانس خاصی یه سری از سرووها در زاویه ی خاص خودشون باشند که میشه همون شرطهامون.
                              این مساله که مشکلی ایجاد نمیکنه و تایمر 16 بیتیه 1 برای این کار مناسبه جناب مهندس درسته؟!

                              ولی راجع به نحوه ی استفاده از تایمر2 جهت ایجاد وقفه در هر 20 میلی ثانیه یه سری ابهامات برام وجود داره:
                              یکی اینکه اینی که شما میفرمائید اگر تایمر 2 بیاد برای کنترل سروو، اونوقت 20 میلی ثانیمون خیلی دقیق نمیشه،میخوام بدونم این زمان خیلی به هم میریزه یا اینکه خیر طوری نیست که روی عملکرد سرووها تاثیر بسزایی بگذاره؟

                              از طرفی اگر این 20 میلی ثانیه به هم بریزه تایم 800 میلی ثانیه هم خراب میشه!!

                              و حالا اگر به هم ریختن این زمان خیلی محسوس نباشه برای این که تایمر 2 برای کنترل سرووها و تایمر 1 برای شمردن فرکانس استفاده بشه در این صورت باید در تنظیمات اول برنامه این تغییرات داده بشه، درست عرض میکنم؟!
                              به جای TMR1L=0 و TMR1H=0 از TMR2=0 استفاده بشه.
                              و به جای T1CON=$01 از T2CON.2=1 استفاده بشه.
                              ولی نمیدونم رجیستر CCP1CON باید به چه نحوی تنظیم بشه؟ و آیا CCPR1H , CCPR1L همونطور مثل قبل باید مقدار دهی بشن؟

                              مطمئنم جناب perfect که شما و جناب کوهستانی با توجه به مشغله های فراوانی که دارید با حوصله پاسخ گوی سوالات پیاپی بنده هستید از این بابت ازتون بسیار بسیار متشکرم .
                              زندگی برگ بودن در مسیر باد نیست
                              امتحان ریشه هاست
                              ریشه هم هرگز اسیر باد نیست
                              زندگی چون پیچک است
                              انتهایش میرسد پیش خدا!

                              دیدگاه


                                #75
                                پاسخ : کمک در مورد سروو موتور


                                سلام. بعد از کمی بررسی متوجه شدم تایمر 2 هم میتونه به طور دقیق همون سیگنال وقفه در هر 20ms رو تولید کنه و از این نظر مشکلی نیست.
                                دستورات مورد نیاز برای تولید وقفه توسط تایمر2 در هر 20ms :
                                کد:
                                PIR1.1=0 ; TMR2IF=0
                                TMR2=0
                                PR2=249
                                PIE1.1=1 ; Enable timer2 interrupt
                                T2CON=$4F
                                بیتهای فعال کننده سراسری وقفه یعنی GIE و PEIE قبلاً در برنامه set شدن. در روتین وقفه بجای چک کردن بیت پرچم وقف ماژول CCP1 ( یعنی PIR1.2 ) باید بیت پرچم تایمر2 (یعنی TMR2IF ) رو چک کنید. ضمناً دستورات مربوط به پیکره بندی این ماژول رو هم از برنامه حذف کنید. اگر وقت پیدا کردم برنامه رو تغییر میدم و در اختیارتون میزارم. تا اون موقع ببینید خودتون میتونید حلش کنید؟


                                اضافه شده در تاریخ :
                                در برنامه زیر تایمر 1 در مد شمارنده پیکره بندی شده که پالس ورودی باید به پین RC0 اعمال بشه و تایمر 2 هم در هر 20ms یک وقفه ایجاد میکنه. البته برنامه تست نشده. خودتون زحمت تست رو بکشید:

                                کد:
                                '****************************************************************
                                '* Name  : UNTITLED.BAS                   *
                                '* Author : [select VIEW...EDITOR OPTIONS]          *
                                '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
                                '*     : All Rights Reserved                *
                                '* Date  : 10/7/2011                     *
                                '* Version : 1.0                        *
                                '* Notes  :                          *
                                '*     :                          *
                                '****************************************************************
                                
                                 DEFINE OSC 8
                                 
                                servo1 var byte 
                                servo2 var byte 
                                servo3 var byte 
                                servo4 var byte 
                                servo5 var byte 
                                servo6 var byte 
                                servo7 var byte
                                a var byte
                                F_in var word
                                
                                ON INTERRUPT GOTO _interrupt
                                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                
                                
                                 
                                   TRISD=$00
                                   PORTD=$00
                                
                                ;;;;;;;;;       
                                 TMR1L=0
                                 TMR1H=0
                                 T1CON=$03 ;turn on timer1 in counter mode
                                ;;;;;;;;;
                                 PIR1.1=0 ; TMR2IF=0
                                 TMR2=0
                                 PR2=249
                                 PIE1.1=1 ; Enable timer2 interrupt
                                 T2CON=$4F
                                ;;;;;;;;;
                                
                                  INTCON.6=1  ;PEIE=1
                                  INTCON.7=1  ;GIE=1 , enable global interrupt
                                  
                                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
                                    
                                
                                
                                again:
                                      ; main loop
                                  
                                ;;;;;;;;;
                                
                                if a = 40 then
                                
                                F_in=TMR1H
                                F_in=F_in << 8
                                F_in=F_in | TMR1L
                                
                                 a=0
                                 TMR1L=0
                                 TMR1H=0
                                endif
                                
                                ;;;;;;;;;
                                   
                                 servo1=0
                                 servo2=25
                                 servo3=50
                                 servo4=125
                                 servo5=175
                                 servo6=200
                                 servo7=251 
                                    
                                
                                goto again
                                
                                
                                
                                
                                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                
                                
                                _interrupt:            ; interrupt service
                                
                                     DISABLE INTERRUPT    ;disable interrapts
                                
                                    if PIR1.1=1 then     ; if TMR2IF=1 then
                                    
                                       a = a + 1
                                   
                                     OPTION_REG = OPTION_REG & $c0 
                                     OPTION_REG = OPTION_REG | $02 
                                
                                     PORTD = $01
                                     PAUSEUS 990 
                                     INTCON.2=0
                                     TMR0 = 255-servo1
                                     while INTCON.2=0
                                     wend   
                                     PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;
                                      PORTD=$02;
                                      PAUSEUS 990 
                                      INTCON.2=0
                                      TMR0 = 255-servo2 
                                      while INTCON.2=0
                                      wend
                                       PORTD=$00    
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;; 
                                      PORTD=$04;
                                      PAUSEUS 990 
                                      INTCON.2=0
                                      TMR0 = 255-servo3
                                      while INTCON.2=0
                                      wend
                                       PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;  
                                      PORTD=$08;
                                      PAUSEUS 990  
                                      INTCON.2=0
                                      TMR0 = 255-servo4 
                                      while INTCON.2=0
                                      wend
                                       PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;  
                                      PORTD=$10
                                      PAUSEUS 990  
                                      INTCON.2=0
                                      TMR0 = 255-servo5
                                      while INTCON.2=0
                                      wend
                                       PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;; 
                                      PORTD=$20
                                      PAUSEUS 990  
                                      INTCON.2=0
                                      TMR0 = 255-servo6 
                                      while INTCON.2=0
                                      wend
                                       PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;  
                                      PORTD=$40
                                      PAUSEUS 990  
                                      INTCON.2=0
                                      TMR0 = 255-servo7
                                      while INTCON.2=0
                                      wend
                                      PORTD=$00
                                     ;;;;;;;;;;;;;;;;;;;;;;;;;; 
                                      PIR1.1=0  ; clear TMR2IF
                                      endif 
                                      
                                      RESUME     ;return from interrapt 
                                      ENABLE INTERRUPT 
                                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                
                                end
                                ضمناً در این برنامه فرکانس در متغیر F_in که یک متغیر 16 بیتی هست قرار میگیره.

                                دیدگاه

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