اطلاعات خویش را به دیگران بیاموزید تا دیگران راه رفته شما را دوباره نروند بلکه ادامه دهند!
سلام
اول روش کار با تایمر :
ما میخوایم یه برنامه بنویسیم که باهاش بشه یه موج مربعی با فرکانس 50 هرتز ساخت ( بقیه کار رو مرحله به مرحله اضافه میکنیم )
خب موجمون فرکانسش 50 هرتز هست ، بنابراین زمان تنابش میشه 20 میلی ثانیه ، یعنی اگه ما یه پایه رو 10 میلی ثانیه 1 کنیم و 10 میلی ثانیه صفر واین کار رو مدام انجام بدیم ، یه شکل موج با فرکانس 50 هرتز ساختیم :
ما باید تایمر رو یه جوری پیکربندی کنیم که تا 10 میلی ثانیه بشمره و بعد از سرریز شدن به زیر روال وقفه بره و و ضعیت یه پایه رو برعکس کنه :
زمانی که تایمر میشمره از فرمول زیر بدست میاید :
فرکانس کریستال /(بیت تایمر * مقدار پرسکلیر )=زمان
از انجا که با تایمر 8 بیتی 0 و 2 بهتر میتوان زمان های کم را ساخت (دقیق تر ) ما از این دوتا استفاده میکنیم :
16 /( * (دو به توان 8 یا 256)* 64 )=1میلی ثانیه
خب با یه ضرب وتقسیم میشه فهمید که ما با استفاده از کریستال 16 مگاهرتز و پریسکلیر 64 و تایمر 16 بیتی میتونیم زمان 0.001024 ثانیه رو بدست بیاریم :
خب بر نامه رو مینویسیم :
شرح برنامه بالا :کد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output dim a as word Config Timer0 = Timer , Prescale = 64 Enable Interrupts Enable Ovf0 On Ovf0 Q Do Locate 1 , 1 Lcd "t:" Loop End Q: if a>9 then Toggle Portb.0 a=0 endif Return
$regfile = "M8DEF.dat" : $crystal = 16000000
در این خط میکرو و فرکانس کاری اون مشخص شده ، میکررو مورد استفاده مگا 8 و مقدار کریستال 8 مگا هرتز است .
Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0
در این دوخط lcd راه اندازی شده است ، lcd به پایه های پورت d متصل است .
Config Lcd = 16 * 2 : Cursor Off : Cls
در این خط نوع lcd مشخص شده ، همچنین مکان نما خاموش شده و lcd پاک میشود.
Config Pinb.0 = Output
در این خط پورت b.0 به عنوان خروجی تعریف شده ، چون ما میخواییم از این پورت ولتاژ بگیریم.
Config Timer0 = Timer , Prescale = 64
در این خط تایمر 0 راه اندازی شده
Enable Interrupts
Enable Ovf0
On Ovf0 Q
در این سه خط ، ابتدا وقفه سراسری را اندازی شده است ، شما در هنگام استفاده از هر نوع وقفه ابتدا باید این وقفه را راه اندازی کنید ، در خط بعدی وقفه تایمر ودر خط سوم ، مکانی که تایمر پس از سرریز شدن به انجا پرش میکند معین شده است
Do
Locate 1 , 1
Lcd "t:"
Loop
End
در این قسمت یک حلقه do-loop موجود است که در ان عبارت t روی lcd نمایش داده میشود و فعلا به برنامه ما ربطی ندارد .
Q:
if a>9 then
Toggle Portb.0
a=0
endif
Return
این قسمت از برنامه مکانی است که cpu بعد از سرریز شدن تایمر به ان پرش میکند ، در اینجا 1واحد به مقدار a اضافه میشود ، هنگامی که a برابر 10 شد ، وضعیت پورت b.0 برعکس میشود (اگر صفر است یک و اگر 1 است صفر میشود ) و cpu با دستور return به حلقه ی اصلی باز میگردد.
سوالاتی که ممکنه پیش بیاد ..
چرا از وقفه استفاده میشه ؟
شما توی حلقه ی do-loop تا دلت میخئاد از دستور wait استفاده کن ، اما تایمر با استفاده از وقفه کار خودش رو انجام میده ، به محض اینکه تایمر تا 256 شمرد cpu حلقه ی اصلی رو رها میکنه و به زیر روال وقفه میره ، کار های که در اونجا وجود داره رو انجام میده و دوباره به مکانی که اومده بود برمیگرده .
با استفاده از مقدار پریسکلیر و فرکانس و... شما مشخص میکنی که تایمر شمرده از 0 تا 255 رو چقدر طول بده ، توی مثال بالا این زمان 10 میلی ثانیه طول میکشه ، اگه که موارد رو تغییر بدی ممکنه این زمان کمتر یا بیشتر بشه .
همون طور که میدونی میکرو در حالت عادی با فرکانس 1 مگاهرتز کار میکنه ، شما برای اینکه نتیجه بگیرید ، باید میکرورو روی کریستال خارجی 16 مگ پروگرام کنید ، در صورتی که این کار رو انجام بدین با جدا کردن کریستال از میکرو ، میکرو خاموش میشه .
خب به برنامه راه اندازی adc ودیگر موارد رو هم اضافه میکنیم :
خب توی برنامه بالا فقط adc راه اندازی شده و مقدار اندازه رفته شده از کانال 0 کانال صفر روی lcd نمایش داده میشهکد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim T As Word, a as word CONFIG ADC = single, PRESCALER = AUTO Config Timer0 = Timer , Prescale = 64 Start Adc Enable Interrupts Enable Ovf0 On Ovf0 Q Do T = Getadc(0) Locate 1 , 1 Lcd "t:" ; T Loop End Q: if a>9 then Toggle Portb.0 a=0 endif Return
حالا ماباید این مقدار دیجتال رو یه جوری به تایمر ربط بدیم ، خب یه روش رو که توی کویر الکترونیک گفتم ، اینم یه روش دیگه :
ما از دوتا تایمر استفاده میکنیم :
توی برنامه بالا توسط دوتا تایمر زمان 1 میلی ثانیه ساخته شده ، تایمر صفر روشن میشه ، تا یک میلی ثانیه میشماره و به زیر روال وقفه میره در اونجا به a یه واد اضافه میکنه و.... هنگامی که وقدار a شد 10 یعنی 10 میلی ثانیه گذشته ، بنابرای طبق شرط پایه b.0 یک میشه و تایمر 0 خاموش میشه و تایمر 2 روشن میشه ، تایمر تا 1 میلی ثانیه میشمره و به زیر روال وقفه میره و کی واحد به b اضافه میکنه ، برای صفر شدن پایه باید مقدار b بیشتر از مقدار t بشه ، t همون مقدار گرفته شده از adc است که به 100 تقسیم شده ، ..............کد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim T As Word , A As Word , B As Word CONFIG ADC = single, PRESCALER = AUTO Config Timer0 = Timer , Prescale = 64 Config Timer2 = Timer , Prescale = 64 Start Adc Start Timer0 Enable Interrupts Enable Ovf0 Enable Ovf2 On Ovf0 Q On Ovf2 W Do T = Getadc(0) Locate 1 , 1 Lcd "t:" ; T ; " " T = T / 100 Loop End Q: Incr A If A > 9 Then Set Portb.0 Stop Timer0 Start Timer2 A = 0 End If Return W: Incr B If B > T Then Reset Portb.0 Stop Timer2 Start Timer0 B = 0 End If return
با این حساب طول پالس منفی همیشه ثابت هست و فقط طول پالس مثبت تغییر میکنه
برنامه بریز رو میکرو ببین کار میکنه یا نه ، بعد شما بپرس تا من جواب بدم
سیگنال برعکس ایجاد شد یعنی حدود 70 میلی ثانیه طول موج مثبت و 10 میلی ثانیه طول موج صفر شد و رو هم رفته فرکانس هم شد 12.5 هرتز !!
و با ADC هم تغییر به وجود نمیامد
سلام
برنامه در پروتوس مشکلی نداره ، میتونی فایل شبیه سازی شده رو از زیر دانلود کنی .
ممکنه عیب از موارد زیر باشه
برای ولتاژ avcc از برحسب vcc استفاده کنید (که بالای برچسب گراند هست)
توی مدار مقدار پالس به صورت غیر خطی زیاد میشه که به خاطر مقاومت غیر خطی هست ، در صورتی که از مقاومت خطی 20 کیلو استفاده کنید همه چیز درست میشه
چند سوال :
میتونی رو سایت چیزی بزاری (فضای برای اپلود در نظر گرفته شده )؟
دیشب من جواب پیامت رو فرستادم ، بدستت رسید ؟
جواب سوالها:
بله من الان نرم افزار PCB WIZARD رو تو بخش نرم افزارها گزاشتم و جواب سوالمم رسید دیشب
و اما درباره برنامه : ممکنه مقاومت خطی و غیر خطی رو تو پروتئوس توضیح بدی؟؟؟
و فایل پروتئوس شما رو هم دانلود کردم ولی با تغییر پتانسیومتر فرکانس تغییر میکنه که ما نمیخواهیم فرکانس متغیر باشه بلکه میخواهیم طول پالس مثبت 1 تا 2 میلی ثانیه تغییر کنه که در این صورت طول پاسل صفر 18 تا 19 میلی ثانیه متغیر میشه تا رو فرکانس 50 هرتز ثابت باشه ، حالا اگر طول پالس صفر متغیر نبود مشکلی نیست ولی طول پالس مثبت اهمیت داره!
من ی نمونه از برنامه رو که با دستور WAIT نوشتم میزارم اینجا من میخوام خروجی سیگنال اینجوری باشه (با تغییر پتانسیومتر):
من دقیقا این خروجی سیگنال رو میخوام ، این برنامه خودم این کارو میکنه ولی مشکلش اینه که با دستور wait هست و اگر بخوام اینو داخل یک برنامه بزرگتر قرار بدم به دلیل زیاد شدن دستورات دیگر برنامه ، طول موجها کم و زیاد میشن و فرکانس تغییر میکنه ، برا همین میخوام از تایمر استفاده بشه که اگر برنامه 100 خط دیگه هم ادامه داشت این فرکانس و طول موجها حفظ بشه!
سلام
نمیدونم قبلا چی فکر میکردی ، ولی من الان فهمیدم شما چی میگی ( جریان جنگل هست و قصه )
خب این برنامه :
(تست کن اگه خودش بود بگو تا توضیحش رو بزارم )
مدار هم همون مدار قبلی هستکد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim A As Word , B As Word , C As Word , D As Word , F As Word Config Adc = Single , Prescaler = Auto Config Timer0 = Timer , Prescale = 8 Config Timer2 = Timer , Prescale = 8 Start Adc Start Timer0 Enable Interrupts Enable Ovf0 Enable Ovf2 On Ovf0 Q On Ovf2 W Do A = Getadc(0) A = A / 127 D = 15 - A Locate 1 , 1 Lcd A ; " " Loop End Q: Incr B If B > F Then Set Portb.0 B = 0 F = 140 + A Stop Timer0 start TIMER2 End If Return W: Incr C If C > D Then Reset Portb.0 C = 0 Stop Timer2 Start Timer0 End If Return
در کل ما دونوع مقاومت متغیر داریم ، یه نمونه ، موقعی که میچرخونیش مقاومت بین سرکناری وسر وسط با یه نصبت زیاد میشه ، مثلا 1 اهم 2 اهم .....و اما درباره برنامه : ممکنه مقاومت خطی و غیر خطی رو تو پروتئوس توضیح بدی؟؟؟
یه نمونه هم وجود داره که خطی نیست ، مثلا مقاومت در وسط 1 کیلو هست و یه خروده اونوتر 100 کیلو
توی پروتوس فقط نمونه دوم وجود داره
خوب فرکانس 50 هرتز درست شده و طول موج مثبت با حدود1.1 میلی ثانیه تا 2 میلی ثانیه کنترل میشه ولی یک نکته ای تو مداریکه من با wait ساخته بودم خیلی دقیق با حرکت پتانسیومتر طول پالس تغییر میکرد و سروو آرام آرام میچرخید ولی اینجا از 90 یهو میپره به 75 ، انگار تمام زاویه سروو تقسیم بر 8 منطقه شده باشه فکر کنم دلیلش این باشه که شما ADC رو تقسیم بر 127 کردین و تو D ریختین با این کار حرکت سروو رو به 8 منطقه یا استپ محدود کردین کاش طوری بود که حداقل 50 منطقه داشت!
و نکته دیگه هم اینکه از 1.1 میلی ثانیه شروع میشه که سبب میشه سروو حداقل به زاویه -85 برسه و به -90 اصلا نمیرسه !
اگه طول پالس مثبت از 0.9 تا 2.1 باشه خیلی عالیه! یعنی 0.1 برای اطمینان کار باشه!
سلام
اینم ربرنامه اصلاح شده .
کم بودن رنج هم به دلیل هست که خودت گفتی ، اگه خواستی بگو تا برات تغییرش بدم ، تا فردا شب برنامه pwm رو هم میزارم .
راستی با ماژول gps چه کار کردی ؟
کد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim A As Word , B As Word , C As Word , D As Word , F As Word Config Adc = Single , Prescaler = Auto Config Timer0 = Timer , Prescale = 8 Config Timer2 = Timer , Prescale = 8 Start Adc Start Timer0 Enable Interrupts Enable Ovf0 Enable Ovf2 On Ovf0 Q On Ovf2 W Do A = Getadc(0) A = A / 127 D = 16 - A Locate 1 , 1 Lcd A ; " " Loop End Q: Incr B If B > F Then Set Portb.0 B = 0 F = 139 + A Stop Timer0 start TIMER2 End If Return W: Incr C If C > D Then Reset Portb.0 C = 0 Stop Timer2 Start Timer0 End If Return
خوب یک سمت سیگنال درست شد ولی به جای بزرگ شدن محدوده ، سیگنال شیفت پیدا کرد یعنی شده از 1.2 تا 2.2 میلی ثانیه که این سبب میشه سروو از طرف منفی تا 62- بیشتر نره و تا 90- فاصله زیادی داره و در طرف مقابل پتانسیومتر که به 1/3 آخرش هنوز نرسیده سروو به 90+ میرسه یعنی همون شیفت !
اگه بشه 0.9 تا 2.1 میلی ثانیه خوبه!
در آخر هم یک توضیح کامل درباره چگونگی کار با تایمرها و محاسباتشون بفرمایید
متشکرم
ماژول gps هم ی مشکلات کوچیکی برای راه اندازیش دارم که دارم حلش میکنم مثلا باید کل کامپیوتر رو ببرم فضای آزاد و.....
سلام
خب این محدوده درست شد :
کد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim A As Word , B As Word , C As Word , D As Word , F As Word Config Adc = Single , Prescaler = Auto Config Timer0 = Timer , Prescale = 8 Config Timer2 = Timer , Prescale = 8 Start Adc Start Timer0 Enable Interrupts Enable Ovf0 Enable Ovf2 On Ovf0 Q On Ovf2 W Do A = Getadc(0) A = A / 102 D = 16 - A Locate 1 , 1 Lcd A ; " " Loop End Q: Incr B If B > F Then Set Portb.0 B = 0 F = 140 + A Stop Timer0 start TIMER2 End If Return W: Incr C If C > D Then Reset Portb.0 C = 0 Stop Timer2 Start Timer0 End If Return
خب همونطور که قبلا گفته شد زمانی که توسط تایمر بدست میاد از فرمول زیر هست :
فرکانس کریستال /(بیت تایمر * مقدار پرسییکال )=زمان
الان توی برنامه بالا مقدار Prescale برابر 8 و فرکانس کریستال برابر 16 مگ و تایمر هم 8 بیتی هست که بیت تایمر میشه 2به توان 8 یعنی 256
اگه این اعداد رو توی فرمول بالا بزاری میبینیکه مقدار زمان بدست اومده برابر با
0.000128 ثانیه میشه ، یعنی هنگامی که تامیر از 0تا 255 (از یک تا 256 ) میشمره 0.000128 ثانیه طول میکشه ، از اونجا که وقفه سرریزی تایمر رو فعال کردیم (با دستور Enable Ovf1 ) هنگامی که تایمر سرریز میشه ، cpu برنامه های در دست اجرا رو رها میکنه و زیر روال وقفه (مکانی که توسط On Ovf0 w مشخص شده ) میره توی برنامه ما به c یه واحد اضافه میکنه و چون شرط برقرار نیست برمیگرده ، دوباره میشمره ، به c اضافه مکنه و انقدر اینکار رو انجام میده که مقدار c از dبیشتر بشه (فرض کن پتانسیومتر در اول قرار داره و مقدار d برابر با 16 هست (a صفر هست) با این حساب برای برقرار شدن شرط ، مقدار c 17 بشه ، یعنی ما 17 حلقه تکرار شده داریم ، که اگه 17 رو در زمان اولیه ضرب کنی مقدار تاخیر بدست مییاد (0.002176) در صورتی که پتانسیومتر اخر باشه ، مقدار a 10 هست و مقدار c باید 7 بشه ، کمترین زمان هم میشه 0.000896 .
کار با تایمر ها فقط بازی با اعداد هست .
خوب الان بازه شد 1 تا 2.2 میلی ثانیه
خودم دستکاریش میکنم ببینم چی میشه کافیه 0.1 شیفت پیدا کنه به سمت 1 میلی ثانیه همه چی درست میشه!
خوب برای اون تقسیم بر 102 چکار کنیم که بازه رو محدود کرده ؟! ی تغییراتی در اون ضرب و تقسیم اولیه باید انجام بدیم!
سلام
خب من برنامه رو تغییر دادم و محدوده تغییرات رو به 68 استب رسوندم :
البته با تغییر دادن اعداد هنوز هم میشه ، محدوده رو بیشتر کرد . اگه سوالی نیست بریم سراغ روش pwmکد:$regfile = "M8DEF.dat" : $crystal = 16000000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Config Pinb.0 = Output Dim A As Word , B As Word , C As Word , D As Word , F As Word Config Adc = Single , Prescaler = Auto Config Timer0 = Timer , Prescale = 1 Config Timer2 = Timer , Prescale = 1 Start Adc Start Timer0 Enable Interrupts Enable Ovf0 Enable Ovf2 On Ovf0 Q On Ovf2 W Do A = Getadc(0) A = A / 15 D = 127 - A Locate 1 , 1 Lcd A ; " " Loop End Q: Incr B If B > F Then Set Portb.0 B = 0 F = 1123 + A Stop Timer0 start TIMER2 End If Return W: Incr C If C > D Then Reset Portb.0 C = 0 Stop Timer2 Start Timer0 End If Return
نه ممنون عالیه
خوب بریم سراغ PWM
سلام
توی برنامه بالا ما با استفاده از pwm تایمر 1 یه دونه پالس 50 هرتز ساختیم ،کد:$regfile = "M8DEF.dat" $crystal = 6528000 Config Lcdpin = Pin , Db4 = Pind.2 , Db5 = Pind.3 , Db6 = Pind.4 , Db7 = Pind.5 , E = Pind.1 , Rs = Pind.0 Config Lcd = 16 * 2 : Cursor Off : Cls Dim A As Word , B As Byte Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 256 Config Adc = Single , Prescaler = Auto Start Adc Config Portb = Output Do A = Getadc(0) A = A / 63 B = 227 + A Pwm1a = B Locate 1 , 1 Lcd A Loop End
خب فرکانس پالس از رابطه ی زیر بدست مییاد :
پرسیکال * 512 )/ فکانس کریستال = فرکانس pwm
با pwm نشد ، فرکانس 50 هرتز خالص رو با کریستال استاندارد ساخت ، بنابراین شما باید از نوسان ساز rc خارجی استفاده کنی وفرکانس نوسان ساز باید 6.528MHz باشه تا فرکانس pwm دقیق باشه .
بعد از راه اندازی pwm نوبت به مقدار دهی اون هست ، هنگامی که شما از دستور Pwm1a = B استفاده میکنید ، دارید مقدار سطح صفر نصبت به سطح یک یا دیتوی سایکل رو مشخص میکنید ، در اینجا ما به یه پالس با زمان تناوب 20 میلی ثانیه نیاز داریم که 18 میلی ثانیه ش صفر باشه و 2 میلی ثانیه 1 در واقع نصب یک به صفر اون 2 به 18 یا 11.1 درصد باشه ، (خب دیتوی سایکل ما شد 11.1 درصد.
توی برنامه بالا pwm هشت بیتی هست ، یعنی 256 تا قسمت (پله ) داره ،
با یه دونه ضرب تقسیم میشه فهمید که باید 227 تا پله صفر باشه (18 میلی ثانیه ) و 29 تا پله 1 (2میلی ثانیه ) ، برای تغییر دادن نصبت صفر به یک کافی این اعداد رو کم یا زیاد کرد .
در این روش فرکانس کاملا ثابت هست ، اگه شما سطح صفر رو کم کنید ، سطح یک زیاد میشه و اگه سطح 1 رو کم کنید ، سطح صفر اضافه میشه .
فقط یادت باشه کریستال باید مقدار گفته شده باشه
امید وارم متوجه منظورم شده باشید ، اگه سوالی بود ، من در خدمتم
ممکنه ابتدا یک آموزش از PWM ، کاربرد و استفاده و مزایا و طریقه راه انداختن آن بزارید؟ و بعد با این مثال موضوع کامل بشه؟
سلام
تو سایت اقای 1nafar یه مقاله در مورد موتورها نوشته حمید بادامی نجات گذاشتن که در مورد pwm اطلاعات خوبی داره
بهتره اول اونو بخونیند بعد اگه با بیسکام کار می کنین بگین تا دستوراتش هم گفته بشه و یه رفرنس خوب با هم تو این مورد بسازیم
موفق باشین
اون مقاله رو کامل خوندم اتفاقا خیلی کامله مشکل فقط استفاده نکردن از زبان شیرین بیسکامه که این باید اینجا حل بشه
خوب ما اینجا راه های مختلف رو داریم امتحان میکنیم و در نهایت باید بهترین و حرفه ای ترین رو بکار ببریم و الان رسیدیم به بحث PWM
سلام
اول ببینیم pwm چی هست ؟
pwm یا Pulse Width Modulator یا مدولاسیون پهنای پالس نوعی از مدولاسیون (ایجاد ولتاژ ) هست که در اون فرکانس موج ثابت و نصبت صفر به یک یا Duty cycle یا چرخه ی کار متغیر هست .
در زیر من نحوه راه اندازی تایمر 1 در مد pwm رو توضیح میدم :
تایمر 1 با دستورات زیر در مد pwm پیکر بندی میشه :
Pwm = 8|9|10: pwm با این دستور بیت pwm یا میزان پله ی ان مشخص میشود ، در ادامه در این مورد بیشتر توضیح داده میشودکد:Config Timer1 = Pwm,Pwm = 8|9|10 , Compare A Pwm=Clear Up |Clear Down ,Compare B Pwm =Clear Up |Clear Down , Prescale=1|8|64|256|1024
Compare A Pwm=Clear Up |Clear Down : : با انتخاب گزینه Clear Up، موج pwm1a یا خروجی پایه oc1a از سطح یک کم میشود و در صورت انتخاب Clear Down ، موج pwm1a از سطح صفر کم میشود .( در این مورد در ادامه بیشتر توضیح داده میشود )
Compare b Pwm=Clear Up |Clear Down : : با انتخاب گزینه Clear Up، موجpwm1b یا خروجی oc1b از سطح یک کم میشود و در صورت انتخاب Clear Down ، موج pwm1b از سطح صفر کم میشود .( در این مورد در ادامه بیشتر توضیح داده میشود )
Prescale : این گزینه و مقدار کریستال , بیت pwm در تعیین فرکانس pwm نقش دارند . برای تولید PWM با فرکانس های متفاوت از این گزینه ها استفاده می شود.
فرکانس pwm از روابط زیر محاسبه میشود :
در صورتی که بیت pwm 8 باشد :
(پرسکال* 510 )/ فرکانس کریستال = فرکانس pwm
در صورتی که بیت pwm 9 باشد :
(پرسکال* 1022 )/ فرکانس کریستال = فرکانس pwm
در صورتی که بیت pwm 10 باشد :
(پرسکال* 2046 )/ فرکانس کریستال = فرکانس pwm
Duty cycle یا چرخه ی کار چیست ؟
فرض کنید شما از pwm ده بیتی استفاده کرده اید ، در این صورت pwm شما میتواند 1023 پله داشته باشد
با چند تا مثال ادامه میدیم :
یک موج مربعی با زمان تناوب 20 میلی ثانیه وDuty cycle نود درصد تولید کنید؟
جواب :
اولین مرحله ساخت یه دونه موج pwm با فرکانس 50 هرتز هست، ما میتونیم از بین فرکانس ها و بیت ها موجود یه دونه رو به دلخواه انتخاب کنیم ، من کریستال 6528000 هرتز و pwm هشت بیتی و مقدار Prescale = 256 انتخاب کرده بودم :
در برنامه بالا ، ابتدا پایه oc1a در سطح صفر میباشد . هنگامی که مقدار شمره شده توسط تایمر به رقم 10 رسید ، وضعیت پایه معکوس میشود ، از انجا که pwm هشت بیتی است ، موج 256 ( دو بتوان 8 ) پله دارد . تایمر تا 255 میشمرد (از صفر تا 255 برابر 256 پله است ) و صفر میشود ، با صفر شدن تایمر دو با ره وضعیت پایه oc1a معکوس میشود ، دو باره تایمر تا 10 میشمارد ، دو باره وضعیت پایه معکوس میشود و این روند مدام تکرار میشود .کد:$regfile = "M8DEF.dat" $crystal = 6528000 Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 256 Do Pwm1a = 10 Loop End
با این حساب ، از 255 پله ، تعداد 10 عدد در صطح صفر و تعداد 245 عدد در سطح یک می باشد .در صورتی که 255 را صد درصد بگیریم ، میتواین بگوییم که 96.07 درصد موج را سطح یک ان تشکیل میدهد (255/(100*245))و در واقع ضریب مدولاسیون یا چرخه ی کار یا Duty cycle برابر با 96.07 درصد است .
با تغییر دادن رقم 10 به 25 میتوان به ضریب مدولاسیون 90% دست پیدا کرد .
مثال 2 :
توسط تایمر یک ، موجی با فرکانس 2 کیلو هرتز و با مشخات زیر ایجاد کنید .
60 میکرو ثانیه از این موج را سطح صفر و الباقی را سطح یک در برگیرد :
جواب :
همانند مثال قبل ابتدا مقدار کریستال و بیت تایمر وپرسیکال را محاسبه میکنیم .
( من معمولا مقدار پرسیکال و بیت تامیر را ثابت در نظر میگیرم و مقدار فرکانس را برای ان محاسبه میکنم )
من از pwm ده بیتی و پرسیکال 1 استفاده میکنم و مقدار فرکانس کریستال را بدست میاورم :
Prescale * بیت pwm * فرکانس pwm = مقدار کریستال
4092000=1 * 2046 * 2000
در صورتی که از کریستال 4092000 هرتز استفاده کنیم ، مقدار فرکانس pwm برابر با 2 کیلو هرتز خواهد شد .
نوشتن برنامه :راه اندازی تایمر در مد pwm :کد:$regfile = "M8DEF.dat" $crystal = 6528000
میتوانستیم pwm را در حالت زیر نیز راه اندازی کنیم ، در این حالت پایه oc1b خروجی بود ( همچنین میشد از Clear down به جای Clear up استفاده کرد )کد:Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Up , Prescale = 1
$regfile = "M8DEF.dat"
$crystal = 4092000
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear down , Prescale = 1
Do
Pwm1a = 10
Loop
End
شما حتما باید یک مقدار در ریجستر مقایسه ای pwm ( در هنگام استفاده از oc1a بPwm1a = 10 و در موقع استفاده از oc1b ب Pwm1b = 10 )قرار دهید تا موج pwm ایجاد شود .
تا کنون موجی با فرکانس 2 کیلو ساختیم ، در زیر میخواهیم شرط را اجرا کنیم:
مقدار زمان تناوب کل ، 500 میکرو ثانیه است ، موج باید 60 میکرو ثانیه در سطح صفر و 440 میکرو ثانیه در سطح یک باشد ، در این صورت Duty cycle برابر با 88 در صد است ، چون pwm ده بیتی است ، یعنی 1024 پله دارد (دو بتوان 10 ) از این 1024 پله باید 88% در سطح یک منطقی باشد و الباقی در سطح صفر ، با یک حساب ساده میشود فهمید که 901 پله در سطح یک هستند ، بنابراین ماباید به جای 10 عدد 901 را بگذاریم .
در این مثال اگر به جای Clear Down از Clear up استفاده میکردیم ، باید به جای 901 رقم 901-1023 یا 121 را قرار میدادیم .
حالا شما موارد زیر رو طراحی کنید جواب رو تا چند روز دیگه میزارم)
1- موجی با فرکانس 65 هرتز و Duty cycl چهل ویک درصد
2- موجی با فرکانس 96 هرتز و Duty cycl نود و شش درصد
حتما مثال های بالا رو شبیه سازی کنید و نتیجه رو ببینید . (مقدار کریستال فراموش نشود)
با توجه به روشهای بالا ، روشیکه بتوانیم این برنامه و کنترل موج رو تو برنامش داشته باشیم و کارهای غیره دیگری هم تو برناممون داشته باشیم و " تداخل یا تغییری تو این فرکانس و دیوتی سایکل پیش نیاد" چه روشیه؟
روش PWM که فکر نکنم مناسب باشه چون از یک فرکانس خاص باید استفاده بشه مگر فرکانس کاری به فرکانس PWM نزدیک باشه! درسته؟
(البته یک نکته بگم برای کنترل سروو اگر فرکانس کلی از 40 تا 60 تغییر داشته باشه مشکلی نیست فقط اون 1 تا 2 میلی ثانیه سطح یک بودن نباید در این تغییرات ، تغییری کنه!!!) مثلا در بالا میشه از 6 مگ استفاده کرد با بودن شرط گفته شده)
فکر کنم اگر فرکانس کار میکرو را بالا ببریم و تاخیر در بقیه برنامه (کارهای دیگر) نزاشته باشم زیاد رو این قسمت برنامه و دیوتی سایکل و فرکانس پالسمون اثری نداشته باشه؟؟!!
سلام
روش تایمر از همه مناسب تر هستبا توجه به روشهای بالا ، روشیکه بتوانیم این برنامه و کنترل موج رو تو برنامش داشته باشیم و کارهای غیره دیگری هم تو برناممون داشته باشیم و " تداخل یا تغییری تو این فرکانس و دیوتی سایکل پیش نیاد" چه روشیه؟
در صورتی که به پالس با فرکانس دقیق نیاز باشه درستهروش PWM که فکر نکنم مناسب باشه چون از یک فرکانس خاص باید استفاده بشه مگر فرکانس کاری به فرکانس PWM نزدیک باشه! درسته؟
بستگی به کاری داره که میکرو میخواد انجام بده ، مثلا ممکنه شما در کنار راه اندازی سروو به یه ساعت یا دما سنج هم نیاز داشته باشی ، در این مورد فرکانس کاری خیلی تفاوتی نمیکنهفکر کنم اگر فرکانس کار میکرو را بالا ببریم و تاخیر در بقیه برنامه (کارهای دیگر) نزاشته باشم زیاد رو این قسمت برنامه و دیوتی سایکل و فرکانس پالسمون اثری نداشته باشه؟؟!!