pwm یک خروجی دیجیتال.
اساس کارش به طور خلاصه اینطور که تایمر شروع به شمردن میکنه از 0 تا 255 . مثلا OCR1A=127 قرار دادیم. تا زمانی که تایمر به 127 نرسید خروجی PWM برابر 1 منطقی(5V)، و از 127 تا 255 خروجی PWM برابر 0 منطقی(0V).
تایمر هم با هر پالس داخلی میکرو افزوده میشه. یعنی اگر OCR1A رو عددی بزرگتری قرار بدیم نسبت زمان 1 بودن PWM به 0 بودنش بیشتر میشه. حالا وقتی از اون فیلتر استفاده کنید. خروجی تبدیل میشه به یک ولتاژ آنالوگ از 0 تا 5V. عدد 0 یعنی 0V و عدد 255 یعنی 5 ولت. یا 127 یعنی 2.5 ولت. حالا کافی با ADC مقدار ولتاژ رو بخونید و عدد 8Bit مورد نظر رو به pwm هاتون بفرستید. برای این که نیاز به ضرب و تقسیم اضافی نباشه. باید ADC رو با ولتاژ REF5V در نظر بگیرید.
البته راه اندازه گیری دقیق تر برای کپی PWM اینه که از فیلتر و ADC استفاده نشه. و از طریق اینتراپت و تایمر زمان صفر و یک بودن رو اندازه بگیرید. البته شاید دشوار تر باشه.
واقعا ممنون خدا خیرتون بده کارم راه افتاد
(۲۷-آذر-۱۳۹۰, ۱۴:۴۹:۲۵)فروم باز نوشته است: [ -> ]1- ولتاژ 0 درصد و 100 درصد رو بين دوتا ولتاژ مثلا a و b بزاري یعنی چی؟
2- با این کد که ولتاژ رفرنسو aref گرفتید ولتاژ خروجی pwm اندازه ی ولتاژ ورودی pwm خواهد بود؟
من دقیقا میخوام pwm های خروجی کپی pwm های ورودی باشند از آی سی های دیگه هم استفاده نکردم چون میخوام اگر که خواستم و یه موقعی احتیاج شد روی pwm ها کنترل داشته باشم بتونم این کار رو انجام بدم.
سلام
ببخشيد اين پست صفحه قبليتونو دير ديدم .
منظورم از A تا b اين بود كه اگر شما ولتاژ آنالوگ وروديتون بين 0.14 تا 0.24 ولته (به جاي 0 تا 5 ) ميتونيد از اون فرمول كه عرض كردم تو برنامه استفاده كنيد . يعني:
در مورد سوال دومي هم آقا مرتضي توضيح دادند .
در مورد سوال سومي ، شما نميخواين هيچ اختلاف فازي بين pwm ورودي و خروجي باشه . اين قدر دقت به چه كار شما مياد ؟
در آخر باز هم عذر خواهي ميكنم اگر دير جوابتونو دادم . هرچند دوستان لطف كردند و جواب شما رو زودتر دادن.
التماس دعا
ممنون از جواب های کاملتون
من با بسکام کار کردم و هرچی تلاش کردم نتونستم تو بسکام این رو پیاده سازی کنم. pwm رو تونستم ولی adc رو نه. همین مثال رو میشه تو بسکام برام بزنید یا اگه نمیشه همین کد رو با mega64 بخوام تغییر بدم باید چی کار کنم؟ با همون کد ویژن ویزارد یا هر چیزی که صلاح میدونید.
با تشکر.
سلام
اين برنامه mega64 :
کد:
#include <mega64.h>
#include <delay.h>
#define ADC_VREF_TYPE 0x20
// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}
// Declare your global variables here
void main(void)
{
unsigned int PWM;
PORTB=0x00;
DDRB=0xF0;
ASSR=0x00;
TCCR0=0x6A;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0xA1;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
TCCR2=0x6A;
TCNT2=0x00;
OCR2=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x86;
while (1)
{
PWM=read_adc(0);
OCR1A=PWM;
OCR1B=PWM;
OCR2=0.9*PWM;
OCR0=0.9*PWM;
}
}
شبيه سازيش رو هم توي پيوست گذاشتم .
درضمن يه پيشنهاد دارم اگر با adc نميتونين كار كنين ميتونين با اين روش كار كنين:
اگر وروديتون (كه Pwm هست ) پيك ولتاژش 5 ولته ، يعني منطق صفر و يكش ، همون صفر و 5 ولته ، ميتونين ورودي رو به دوتا اينتراپت ميكرو وصل كنين . يكيش توي بالارفتن كلاك فعال بشه و يكي ديگه ( دومي) توي پايين اومدن كلاك . وقتي اينتراپت اولي (بالارونده ) فعال شد يه تايمر رو توي تابع اينتراپت فعال ميكنيم تا شروع كنه به شمردن .يعني مقدار رجيستر tctnt اون تايمرو صفر ميزاريم البته قبلش مقدارشو توي يه متغيير ميريزيم. وقتي اينتراپت دومي فعال شد مقدار رجيستر tcnt تايمري كه فعال كرديم رو توي يه متغيير ديگه ميريزيم. حالا ما دو تا متغيير داريم و با تقيم اين دوتا متغيير ميتونيم درصد pwm رو تعيين كنيم . حالا كافيه كه اين عددرو (حاصل تقسيم) در ماكسيمم pwm (كه توي حالت شمارش تا 255 ،ميشه 255 (و اگر مدهاي ديگه انتخاب كنين اين عدد تغيير ميكنه)) ضرب كنين و حاصل كار شبيه به همون برنامه بالا ميشه ولي با اين تفاوت كه ديگه نيازي به Adc ندارين . بنابراين توي بسكام هم ميتونين خودتون برنامشو بنويسين.
تشکر از توضیحات واقعا کاملتون کارم عجله ایه این روش رو هم که گفتید حتما تست میکنم و دوباره مزاحمتون میشم.
با تشکر فراوان از تمام بجه هایی که در این زمینه من رو کمک کردند.
سلام من دوباره اومدم
من تو اوسیلوسکوپ خروجی pwm مدارم رو دیدم همونی که میخوام از روش کپی کنم تو اوسیلوسکوپ vp رو به من 3.2 ولت داد
حالا من باید ولتاژ رفرنس رو به 3.2 ولت وصل کنم؟ یا کارای دیگه لازمه؟
با تشکر.
سلام
اگر هدفتون از pwm فقط كم و زياد شدن ولتاژ dc هست . لازم نيست به چيزي دست بزنين . ولي اگر ميخواين همون pwm رو توي خروجي داشته باشين بايد متغييري كه مقدار adc رو توش ريختين رو در يه ضريب ضربش كنين حالا چون adc رو توي حالت 8 بيت گرفتيم ميشه pwm رو در اين عدد ضرب كرد:
در ضمن ولتاژ رفرنسو نميتونين كمتر از 4.5 ولت بزارين .
با این فرمول ولتاژ پیک خروجی همون 3.2 ولت خواهد بود؟ یا pwm یه جوری تغییر میکنه که با این ولتاژ مساوی میشه؟
با تشکر.
سلام
همونطور كه توي پست قبلي عرض كردم با اين فرمول شما ميتونين نسبت pwm رو توي خروجي ثابت نگه دارين . يعني اگر عرض پالس مثلا 12 درصد از پريود موج هست ، توي خروجي هم عرض پالس 12 درصد پريود هست . با اين تفاوت كه خروجي شما داراي پيك 5 ولته . پس مقدار dc خروجي توي عرض پالسهاي برابر بيشتر از ورودي ميشه .
حالا اگر ميخواين مقدار dc توي خروجي همون مقدار وروديتون باشه ، لازم نيست كه برنامه رو تغيير بدين . چون pwm رو برابر با adc قرار داديم ، پس وتاژ dc خروجي هم برابر با ورودي ميشه . البته توي اين حالت خاص ( Adc رو تو مد 8 بيتي قرار داديم و مد pwm رو هم روي شمارش حداكثر 255 (0xFF) گذاشتيم كه يعني همون 8 بيتي )
یه مساله ای هست من از mega64L استفاده کردم. این آی سی تو رنج ولتاژ 3.3 ولت هم کار میکنه اگه ولتاژ آی سی رو 3.3 ولت بدیم چه طور؟ پیک ولتاژ خروجی 3.3 بهمون میده؟ من دقیقا میخوام زمانی که خروجی تو حالت 1 قرار داره پیکش 3.3 باشه.
با تشکر.