کار با سروو موتور با تایمرهای میکروکنترلر با chatgpt

saalek110

Well-Known Member
صفحه دو : رسیدیم صفحه دو....

سالک:حالا یک سوال بی ربط ، برای استپ موتور هم موج مربعی لازمه یا یک مراسم دیگر دارد ؟

خیلی سوال مهمی پرسیدی داداش، اصلاً بی‌ربط نیست
اتفاقاً اینم برادر همون بحث موج و پالس برای موتوره، فقط استپ موتور یکم آداب خاص خودش رو داره!


✅ جواب ساده:

بله! استپ موتور هم موج مربعی می‌خواد ولی نه یه دونه – باید چند موج مربعی پشت سر هم و با نظم خاصی بدی!


تفاوتش با سروو موتور:

موردسروو موتوراستپ موتور

نوع فرمانیک پالس PWMچند پالس مربعی ساده
چی رو مشخص می‌کنی؟زاویه نهاییتعداد پالس = تعداد حرکت
پیچیدگیکمتربیشتر
کنترل موقعیتخودکار داخلش دارهخودت باید بشماری
Screenshot_۲۰۲۵-۰۶-۰۱_۰۱۴۵۴۹.jpg

مثلاً چی میشه:

سروو موتور:

تو یه پالس می‌دی 1.5ms → خودش می‌ره به زاویه 90 درجه و وایمیسته.

استپ موتور:

تو باید مثلاً ۲۰۰ تا پالس مربعی بدی → تازه ۱ دور کامل می‌چرخه!


چی باید بدونی برای استپ موتور:

۱. به موج مربعی نیاز داره ۲. هر پالس مساویه با یک استپ حرکت ۳. چهار تا سیم یا دو تا سیم داره، بعضیا دو فاز دارن، بعضیا چهار فاز


---

❗ اما دقت کن:

اگر استپ موتورت درایور داره (مثل A4988 یا ULN2003)، تو فقط باید پالس مربعی بهش بدی (مثلاً از تایمر یا کد).

اگه درایور نداره، باید ترتیب فازها رو خودت با میکرو بسازی – یعنی 4 تا موج مربعی با زمان‌بندی خاص (Full Step، Half Step، Wave Drive، ...)


مثال با درایور A4988:

فقط کافیه:

پین STEP رو با موج مربعی تغذیه کنی

پین DIR رو برای تعیین جهت بالا یا پایین نگه‌داری


موج مربعی برای STEP:

__ __ __
|____| |____| |____ → هر پالس = 1 استپ


---

✅ جمع‌بندی مردونه:

> آره، استپ موتور هم موج مربعی می‌خواد،
ولی نه یه دونه برای زاویه مثل سروو،
بلکه سری پالس‌های پشت سر هم برای هر حرکت!



هر پالس، یعنی: «یک‌قدم کوچولو»
می‌خوای یه دور بزنه؟ باید کلی پالس بدی!
می‌خوای سرعتشو زیاد کنی؟ باید موج‌هاتو سریع‌تر پشت سر هم بفرستی!

اگه خواستی مدار یا کد راه‌اندازی‌شو بفرستم، بگو رفیق ✌️
 

saalek110

Well-Known Member
سالک: بزار همین گوساله سروو موتور را فعلا بزرگ کنیم ، استپ موتور را جای دیگر بحث می کنیم.

آفرین داداش! بذار اول همین گوساله سروو رو بزرگ کنیم، بعد بریم سراغ گاو استپ موتور
سروو خودش به‌تنهایی کلی ماجرا داره، مخصوصاً اگه بخوای با رجیستر خالص راه بندازیش.

بیا یه نگاه بندازیم به کاری که تا حالا کردیم:

✅ هدف نهایی‌مون:

ایجاد یه پالس دقیق مثلاً بین 1ms تا 2ms، هر 20ms یک‌بار (یعنی فرکانس 50Hz)، با استفاده از تایمر میکروکنترلر.

✅ دو قسمت مهم که گفتی:
Screenshot_۲۰۲۵-۰۶-۰۱_۰۱۴۹۲۸.jpg
بخش وظیفه رجیسترهای مربوطه

شکل موج تنظیم نوع PWM (مثل fast یا phase correct)TCCR1A, TCCR1B
درازی موج (زمان‌ها)تعیین فرکانس و عرض پالسICR1, OCR1A


✅ الان تو کجای کار ایستادی؟

تو الان داری درک می‌کنی که کدوم مد PWM بهتره برای سروو (که گفتیم Fast PWM Mode 14 ساده‌تره)، و بعدش می‌ریم سراغ تنظیم زمان‌ها با ICR1 و OCR1A.

اگه بخوای، الان برات پله‌پله با رجیستر کد سروو رو بچینم که هم واضح باشه، هم بتونی تغییرش بدی.
بذار بدون کتابخونه، فقط با خط به خط رجیستر بریم جلو. بگم؟
 

saalek110

Well-Known Member
سالک: جناب chatgpt پس از اون جدول دراز ، فقط سطر آخرش را کار داریم ،همون fast pwm را؟

دقیقاً همون سطر آخری رو کار داریم داداش! یعنی:

✅ Fast PWM – Mode 14 (با ICR1)

که با رجیسترها این‌جوری فعال میشه:

رجیسترمقدار لازم
Screenshot_۲۰۲۵-۰۶-۰۱_۰۱۵۲۳۱.jpg
TCCR1ACOM1A1=1, COM1A0=0, WGM11=1
TCCR1BWGM13=1, WGM12=1, و بیت‌های CS برای انتخاب سرعت تایمر (پری‌اسکیلر)


چرا همین سطر آخر (Fast PWM Mode 14) خوبه برای سروو؟

1. چون می‌تونی با ICR1 خیلی راحت زمان کل موج رو تعیین کنی (20ms برای سروو).


2. با OCR1A هم عرض پالس رو تعیین می‌کنی (بین 1ms تا 2ms برای زاویه‌های مختلف).


3. شکل موجش ثابته، راحت با اسکوپ یا تستر می‌تونی ببینی چی ساختی.


4. بیشتر پروژه‌ها (مثل Arduino) همین مد رو استفاده می‌کنن.

پس نتیجه:

✅ فقط همون سطر آخر کافیه و بقیه جدول رو بی‌خیال شو.
الان وقتشه بریم سراغ ساختن موج واقعی با همین تنظیمات.

اگه گفتی بریم، من همون تنظیمات رجیستر به رجیستر رو با عدد و توضیح کامل می‌نویسم
 

saalek110

Well-Known Member
Screenshot_۲۰۲۵-۰۶-۰۱_۰۲۰۶۲۷.jpg
عالیه! تصویر آپلودشده مربوط به تایمر ۱ در میکروکنترلر ATmega328P هست و به‌طور کامل رجیسترهای مرتبط با Timer1 رو نشون می‌ده. بیایید به ترتیب و با توضیح ساده و کامل، هر قسمت رو بررسی کنیم:

رجیسترهای اصلی Timer1 در ATmega328P:


1. TCCR1A – Timer/Counter Control Register A

مربوط به تنظیمات عملکرد پایه‌های خروجی PWM:

COM1A1:0 (برای پین D9)

COM1B1:0 (برای پین D10)


و همچنین:

WGM11:0 برای تعیین مد تایمر (بخش اول)


2. TCCR1B – Timer/Counter Control Register B

ادامه تنظیم مد تایمر با بیت‌های WGM13:2

انتخاب پیش‌تقسیم‌کننده (Prescaler) با بیت‌های CS12، CS11، CS10

تنظیمات مربوط به ورودی Capture (در پروژه‌های خاص)


3. TCCR1C – Timer/Counter Control Register C

مربوط به اجبار خروجی مقایسه‌ای (Force Compare) برای A و B:

FOC1A، FOC1B



4. TCNT1H و TCNT1L – شمارنده تایمر

این دو رجیستر مقدار فعلی تایمر رو نگه می‌دارن. (باید به صورت ۱۶ بیت بخونی یا بنویسی)



5. OCR1AH و OCR1AL – رجیستر مقایسه‌ای A

مقدار مقایسه برای کانال A (مثلاً برای تولید PWM روی D9)


6. OCR1BH و OCR1BL – رجیستر مقایسه‌ای B

مقدار مقایسه برای کانال B (مثلاً برای تولید PWM روی D10)


7. TIMSK1 – Timer Interrupt Mask Register

فعال‌سازی وقفه‌ها:

ICIE1: وقفه Input Capture

OCIE1B: وقفه مقایسه‌ای B

OCIE1A: وقفه مقایسه‌ای A

TOIE1: وقفه Overflow (پر شدن تایمر)


8. TIFR1 – Timer Interrupt Flag Register

وقتی یک وقفه اتفاق می‌افته، فلگ مربوطه اینجا Set می‌شه:

ICF1، OCF1B، OCF1A، TOV1


جدول مودهای تایمر (WGM13:0)

اعداد دودویی برای WGM13 تا WGM10 مشخص می‌کنن تایمر در چه مدی کار کنه:

مودتوضیح
Screenshot_۲۰۲۵-۰۶-۰۱_۰۲۱۷۱۵.jpg
0000Normal
0100CTC (Clear Timer on Compare Match) با OCR1A
1110Fast PWM با OCR1A
1000Phase & Frequency Correct PWM


⏱ پیش‌تقسیم‌کننده (Prescaler)

بیت‌های CS12:0 مشخص می‌کنن تایمر با چه سرعتی بشماره:

مقدارPrescaler
Screenshot_۲۰۲۵-۰۶-۰۱_۰۲۱۸۲۲.jpg
001بدون تقسیم (تایمر مستقیم با کلاک اصلی کار می‌کنه)
010تقسیم بر 8
011تقسیم بر 64
100تقسیم بر 256


101تقسیم بر 1024
 
آخرین ویرایش:

saalek110

Well-Known Member
سالک: ببینم این phase correct ها برای ساخت آهنگ خوبه؟

سؤال عالی‌ایه
بله، مود Phase Correct PWM توی ساخت آهنگ یا صدا خیلی مفیده، مخصوصاً وقتی بخوای خروجی صدات فرم موج دقیق‌تری داشته باشه. ولی بستگی داره که دقیقاً چه نوع صدایی بخوای بسازی.

بیایم بررسی کنیم:

آیا Phase Correct PWM برای ساخت آهنگ خوبه؟

✅ مزایا:

1. خروجی متقارن (متوازن)

برخلاف Fast PWM، که ممکنه موج‌ها نامتقارن بشن، این نوع PWM موج مربعی متقارن تولید می‌کنه.

این توی صدا باعث می‌شه نویز هارمونیکی کمتری داشته باشی و صدا نرم‌تر باشه.

2. پایداری در فرکانس خروجی

تغییر دوتایی (up & down counting) باعث می‌شه فرکانس تغییر نکنه با تغییر duty cycle.

برای موسیقی و آهنگ‌سازی دیجیتال که فرکانس‌ها دقیق باید باشن (مثلاً نت لا باید دقیقاً 440Hz باشه)، خیلی مناسبه.

3. برای DAC ساده با فیلتر RC

اگر بخوای خروجی رو از طریق PWM به صدا تبدیل کنی (مثلاً با یه مقاومت و خازن → low-pass filter)، phase correct صدای تمیزتری می‌ده.



❌ ولی باید بدونی:

1. رزولوشن کمتر نسبت به Fast PWM
چون شمارش نصف سرعت انجام می‌شه، بعضی وقتا رزولوشن موثر PWM کمتر می‌شه.

یعنی اگه بخوای خیلی دقیق amplitude صدا رو کنترل کنی، ممکنه محدود باشی.


2. کاهش نرخ نمونه‌برداری (Sample Rate)

توی تولید صدا، تعداد تغییرات در ثانیه مهمه.

چون تایمر بالا و پایین می‌شمره، نرخ تغییر خروجی نصف Fast PWM می‌شه.


نتیجه‌گیری:

برای صدای تمیزتر و دقیق‌تر در فرکانس، phase correct خیلی خوبه.

برای صدای سریع‌تر یا افکت‌هایی که نیاز به نرخ نمونه‌برداری بالا دارن، Fast PWM بهتره.

پس اگه می‌خوای مثلاً یه نت موسیقی تمیز پخش کنی و خروجی رو فیلتر کنی → phase correct عالیه.


اگه بگی چه نوع آهنگی یا چه ابزاری در ذهنته (مثلاً پیانو، بوق، صداهای دیجیتالی یا مشابه NES)، دقیق‌تر می‌تونم پیشنهاد بدم که چه مدی استفاده کنی و کدشم بنویسم برات.
 

saalek110

Well-Known Member

ممکن است نگاه کردن به توضیحات سایت آیرنکس برای شما مفید باشد ، نگاهی بیاندازید.
 

saalek110

Well-Known Member
سالک: برای اینکه نوع مود را تنظیم کنیم برای راه اندازی سروو موتور از کدوم رجیسترها استفاده می کنیم؟

برای راه‌اندازی سروو موتور با میکروکنترلر (مثلاً AVR) و تولید سیگنال PWM، تنظیم "مود" عملکرد تایمر بسیار مهم است. در میکروکنترلرهای AVR (مثل ATmega32)، برای تولید PWM از تایمرها (Timer/Counter) استفاده می‌شود و نوع مود توسط چند رجیستر تنظیم می‌شود.

برای تنظیم مود تایمر (به‌ویژه برای PWM):

از رجیسترهای زیر استفاده می‌کنیم:


---

✅ 1. TCCRnA و TCCRnB

(مثلاً: TCCR1A و TCCR1B برای Timer1)

این دو رجیستر نوع عملکرد تایمر (مود) را مشخص می‌کنند.

● بیت‌های مهم در TCCR1A:

WGM10 و WGM11 → برای انتخاب مود PWM (همراه با بیت‌های TCCR1B)


● بیت‌های مهم در TCCR1B:

WGM12 و WGM13 → ادامه تنظیم مود

CS10, CS11, CS12 → تعیین Prescaler (تقسیم‌کننده فرکانس کلاک)



---

جدول مدهای کاری (WGM bits = Waveform Generation Mode):

برای تولید PWM مناسب برای سروو (معمولاً Fast PWM یا Phase Correct PWM)، معمولاً از یکی از این مدها استفاده می‌شود:

WGM13WGM12WGM11WGM10مد کارینوع PWM

1110Fast PWM, ICR1(مناسب برای سروو)
1010Phase Correct, ICR1(هم مناسب)
Screenshot_۲۰۲۵-۰۶-۰۱_۰۴۲۸۳۴.jpg

در این مدها، مقدار ICR1 به عنوان TOP استفاده می‌شود تا فرکانس PWM را کنترل کنیم (مثلاً 50Hz برای سروو).


✅ 2. ICR1 (Input Capture Register 1):

تعیین مقدار TOP در مدهایی که ICR1 را به‌عنوان TOP استفاده می‌کنند.

معمولاً برای فرکانس 50Hz مقدار ICR1 ≈ 19999 (اگر کلاک تایمر 1MHz باشد)


✅ 3. OCR1A / OCR1B:

این‌ها مقدار مقایسه‌ای هستند و پالس خروجی (عرض پالس = زاویه سروو) را تعیین می‌کنند.


مثلاً:

OCR1A = 1500; // پالس 1.5 میلی‌ثانیه = زاویه 90 درجه


---

مثال تنظیم رجیسترها برای Fast PWM (با ICR1):
C:
DDRD |= (1 << PD5); // تنظیم پایه OC1A به عنوان خروجی (مثلاً برای ATmega32)



TCCR1A = (1 << COM1A1) | (1 << WGM11); // Non-inverted PWM + بخشی از WGM

TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // ادامه WGM + prescaler = 8



ICR1 = 19999; // تعیین فرکانس 50Hz (20ms)

OCR1A = 1500;          // پالس 1.5ms = زاویه 90 درجه


---

اگر با میکرو دیگری کار می‌کنی (مثل STM32 یا PIC)، می‌تونم معادل همون رو هم برات بنویسم. بگو فقط با کدوم میکروکنترلر کار می‌کنی
 

saalek110

Well-Known Member
سالک: پست قبلی ، خلاصه بحثهای قبلی است. با اون بیت های wgm مود انتخاب شده و prescaler مساوی ۸ انتخاب شده با تنظیم بیت cs11
با OCR1A زاویه چرخش تنظیم شده و فرکانس با ICR1 تنظیم شده.
 

saalek110

Well-Known Member
سالک: اتمگا ۳۲ ، فرکانسش چنده و icr1 را باید چند بگیریم

میکروکنترلر ATmega32 به صورت پیش‌فرض از یک کریستال خارجی یا اسیلاتور داخلی استفاده می‌کند. پس باید اول ببینیم فرکانس کاری شما چقدر است. اما معمولاً در پروژه‌های واقعی:


✅ معمول‌ترین فرکانس کاری ATmega32:

8 MHz (داخلی یا خارجی)

16 MHz (کریستال خارجی)

یا گاهی 1 MHz (داخلی، پیش‌فرض در برخی موارد)


هدف ما چیه؟

برای سروو موتور معمولاً نیاز داریم که سیگنال PWM با فرکانس 50Hz بسازیم.
یعنی:

دوره تناوب = 20ms

تایمر باید هر 20ms یک بار ریست شود → یعنی مقدار TOP باید طوری تنظیم شود که این زمان به‌دست بیاد.


✅ فرمول تنظیم ICR1:

برای مد Fast PWM با ICR1 به‌عنوان TOP:

PWM Frequency = f_clk / (Prescaler × (1 + ICR1))

می‌چرخونیم برای ICR1:

ICR1 = (f_clk / (Prescaler × PWM_Frequency)) - 1


---

مثال عددی (فرض: فرکانس سیستم 16 MHz، Prescaler = 8):

ICR1 = (16,000,000 / (8 × 50)) - 1
= (16,000,000 / 400) - 1
= 40,000 - 1
= 39,999

✅ پس: ICR1 = 39999


---

حالا اگر فرکانس شما 8 MHz باشه:

ICR1 = (8,000,000 / (8 × 50)) - 1
= 20,000 - 1
= 19,999

✅ پس: ICR1 = 19999


---

✅ انتخاب Prescaler:

برای دقت خوب و کمترین نویز، معمولاً Prescaler = 8 انتخاب می‌شود.


خلاصه پیشنهادی:

فرکانس کاریPrescalerICR1PWM فرکانس

8 MHz81999950 Hz
16 MHz83999950 Hz


اگر گفتی با چه فرکانسی کار می‌کنی، دقیق‌ترین مقدار رو برات تنظیم می‌کنم، همراه با کد کامل.
 

saalek110

Well-Known Member
سالک: خوب اتمگا ۳۲ ، فرکانس داخلی اش چند هرتز است؟

میکروکنترلر ATmega32 به صورت داخلی دارای یک اسیلاتور RC است که:


✅ فرکانس داخلی پیش‌فرض ATmega32:

1 MHz


اما توجه کن:

این فرکانس دقیق نیست (چون RC هست، نه کریستال)

مقدار آن در فیوز بیت‌ها (fuse bits) قابل تنظیم است و می‌توان آن را روی 2 MHz، 4 MHz، یا 8 MHz هم تنظیم کرد (در نسخه‌های جدیدتر یا با کالیبراسیون دستی)


اگر تا حالا فیوز بیت‌ها را تغییر ندادی:

تقریباً مطمئن باش که میکروکنترلر شما روی 1 MHz تنظیم شده است (مقدار کارخانه‌ای).



راه‌های فهمیدن فرکانس واقعی:

1. بررسی فیوز بیت‌ها با ابزارهایی مثل:

AVRDUDE

نرم‌افزارهایی مثل ProgISP، AVR Fuse Calculator یا Khazama AVR Programmer


2. یا استفاده از کد تاخیری دقیق و اندازه‌گیری با اسیلوسکوپ یا تایمر



پیشنهاد:

اگر می‌خواهی PWM برای سروو بدهی، بهتر است از کریستال 8 یا 16 MHz استفاده کنی تا دقت بالا برود. با اسیلاتور داخلی هم می‌شود، ولی دقت زاویه در سروو کمی پایین می‌آید.

می‌خوای با هم بررسی کنیم فیوزبیت‌ها روی چی تنظیم شده؟
 

saalek110

Well-Known Member
سالک:من فیوزبیتها را تابحال دست نزدم ، فرکانس اتمگا ۳۲ چنده؟

خیلی خوب، چون گفتی که تا حالا فیوزبیت‌های ATmega32 رو تغییر ندادی، پس می‌تونیم با اطمینان خوبی بگیم:


✅ فرکانس پیش‌فرض ATmega32 (در کارخانه):

1 مگاهرتز از طریق اسیلاتور داخلی RC


چرا؟

در کارخانه، فیوزبیت‌ها طوری تنظیم می‌شن که:

منبع کلاک: اسیلاتور داخلی RC

فرکانس: 1 MHz

تقسیم‌کننده فعال هست (CKDIV8 = برنامه‌ریزی شده)


یعنی در واقع:

اسیلاتور داخلی = 8 MHz

اما به خاطر فعال بودن تقسیم‌کننده CKDIV8، فرکانس واقعی می‌شه:

8 MHz ÷ 8 = 1 MHz


✅ نتیجه:

تا وقتی که فیوزبیت‌ها رو تغییر ندی، میکروکنترلر ATmega32 با فرکانس 1 مگاهرتز کار می‌کنه.


اگر بخوای دقت PWM برای سروو بیشتر بشه یا بخوای فرکانس رو بالا ببری، باید:

1. کریستال خارجی نصب کنی (مثلاً 8 یا 16 مگاهرتز)
2. فیوزبیت‌ها رو تغییر بدی (مثلاً CKSEL و CKDIV8)
 

saalek110

Well-Known Member
سالک:حالا اگر فرکانس میکروکنترلر من ۱ مگا هرتز باشه ، برنامه سروو موتور چطوری میشه؟

خیلی سؤال خوبی پرسیدی! چون با 1 مگاهرتز هم می‌تونیم سروو موتور رو راه بندازیم، فقط باید اعداد تایمر (و مخصوصاً ICR1) رو متناسب با این فرکانس تنظیم کنیم.


---

✅ هدف:

ساختن PWM با فرکانس 50 هرتز
(برای کنترل سروو موتور، پالس باید هر 20 میلی‌ثانیه تکرار بشه)


---

گام اول: تنظیم ICR1

فرمول:

ICR1 = (F_CPU / (Prescaler × F_PWM)) - 1

F_CPU = 1,000,000 Hz (فرکانس میکروکنترلر)

F_PWM = 50 Hz

Prescaler = 8 → انتخاب خوبی برای دقت


حساب کنیم:

ICR1 = (1,000,000 / (8 × 50)) - 1
= (1,000,000 / 400) - 1
= 2500 - 1
= 2499

✅ پس باید ICR1 = 2499 تنظیم شود.


---

گام دوم: محدوده سروو

پالس 1ms → حداقل زاویه (مثلاً 0 درجه)

پالس 2ms → حداکثر زاویه (مثلاً 180 درجه)


چون دوره کلی 20ms هست، و ما الان 2500 تا شمارش داریم:

1ms → 2500 × 1 / 20 = 125

2ms → 2500 × 2 / 20 = 250


پس مقدار مناسب برای رجیستر OCR1A بین 125 تا 250 خواهد بود.


---

✅ کد کامل نمونه با ATmega32 و فرکانس 1MHz:
C:
#include <avr/io.h>



void pwm_init() {

    // پین OC1A = PD5 را خروجی کن

    DDRD |= (1 << PD5);



    // مد Fast PWM با ICR1 به عنوان TOP

    TCCR1A = (1 << COM1A1); // غیرمعکوس

    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // WGM13:12=1,1 | Prescaler = 8

    TCCR1A |= (1 << WGM11); // WGM11 = 1



    ICR1 = 2499; // TOP → 20ms



    OCR1A = 125; // پالس 1ms → سروو در حالت صفر

}



int main(void) {

    pwm_init();



    while (1) {

        // برای تست: می‌تونی اینجا OCR1A رو تغییر بدی

        // مثلاً:

        // OCR1A = 125; // 0 درجه

        // OCR1A = 187; // 90 درجه

        // OCR1A = 250; // 180 درجه

    }

}


توجه:

خروجی PWM روی پایه PD5 ظاهر می‌شه (یعنی OC1A در ATmega32)

اگر خواستی از OC1B هم استفاده کنی، باید OCR1B و PD4 رو تنظیم کنی


اگه خواستی حالت چرخش نرم بین زاویه‌ها بسازی یا ورودی از پتانسیومتر بگیری و سروو بچرخه، اونم برات می‌نویسم ✌️
 

saalek110

Well-Known Member
سالک: از کجا بفهمم درست محاسبه نکردم یا کدم مشکل داره؟

Chatgpt:
سؤال خیلی مهمی پرسیدی چون وقتی سروو خوب کار نمی‌کنه، باید بلد باشی عیب‌یابی کنی. اینجا برات نشونه‌ها، دلایل و روش‌های تست کامل رو گام‌به‌گام می‌نویسم:


نشانه‌های اشتباه در کد یا تنظیمات PWM سروو

نشانهدلیل احتمالی

سروو میلرزد یا مدام تق‌تق می‌کند........... پالس‌های PWM نادرست یا نویز
سروو اصلاً حرکت نمی‌کند...................... فرکانس یا زمان پالس اشتباه است (مثلاً خیلی زیاد یا کم)
↕️ حرکت سروو بیش از حد یا خیلی کم است ............دامنه PWM درست تنظیم نشده (مثلاً OCR1A خیلی کوچیک یا بزرگه)
سروو داغ می‌کند....................... فرمان دائم در حال تغییر یا بار بیش از حد
⚠️ میکرو ریست می‌شود.................. جریان سروو از مدار زیاد است، مخصوصاً وقتی مستقیماً از USB تغذیه می‌کنی



✅ راهنمای تست و بررسی مرحله‌به‌مرحله

1. تست فرکانس PWM با اسیلوسکوپ

اگر داری:

خروجی پایه PD5 (OC1A) رو به اسیلوسکوپ بزن

ببین فرکانس حدود 50Hz هست یا نه

پالس باید 1ms تا 2ms باشه و هر 20ms تکرار بشه


اگر اسیلوسکوپ نداری، مرحله بعد...

2. تست با مولتی‌متر دیجیتال پیشرفته

بعضی مولتی‌مترها فرکانس یا سیکل کاری رو نشون می‌دن
(اگه نداری، اشکالی نداره، مرحله بعد…)


3. تغییر مقدار OCR1A و دیدن واکنش سروو

مثلاً در حلقه main()، اینو تست کن:

OCR1A = 125; // 0 درجه
_delay_ms(2000);
OCR1A = 187; // 90 درجه
_delay_ms(2000);
OCR1A = 250; // 180 درجه
_delay_ms(2000);

اگر هیچ حرکتی ندیدی:

ممکنه پایه اشتباه باشه
پالس خروجی نیاد (مثلاً مد تایمر اشتباه باشه)
سروو خراب باشه
ولتاژ کافی نباشه


4. تست پایه خروجی میکرو با LED

یک LED با مقاومت وصل کن به پایه PD5 (OC1A)

اگر کمی چشمک زد، یعنی PWM داره کار می‌کنه

اگر ثابت بود یا کامل خاموش، تایمر یا مد اشتباهه

5. بررسی تغذیه سروو موتور

بیشتر سرووها (مثلاً SG90 یا MG996R) نیاز به تغذیه ۵V واقعی دارن

تغذیه مستقیم از میکروکنترلر یا پورت USB خطرناکه

حتماً از یک منبع جداگانه (مثل باتری ۵V یا آداپتور ۵V) استفاده کن و GND رو مشترک کن


بررسی سیم‌کشی سروو

قهوه‌ای یا مشکی = GND

قرمز = VCC (۵ ولت)

زرد یا نارنجی = سیگنال (به PD5 وصل شه)



اگر هیچ چیز کار نکرد:

بررسی کن که برنامه‌ریزی (Upload) درست انجام شده

تایمر درست تنظیم شده (TCCR1A، TCCR1B)

مقدار ICR1 دقیقاً 2499 باشه برای فرکانس 50Hz

پین PD5 رو اشتباه نگیری
 

saalek110

Well-Known Member
کد راه اندازی سروو موتور با اتمگا ۳۲ در نرم افزار اتمل استودیو چطوری میشه؟

برای راه‌اندازی یک سروو موتور با میکروکنترلر ATmega32 در نرم‌افزار Atmel Studio، باید با استفاده از PWM (مدولاسیون پهنای پالس) این کار را انجام دهیم. سرووها معمولاً با پالس‌های ۱ تا ۲ میلی‌ثانیه (روی دوره‌ی ۲۰ میلی‌ثانیه یا ۵۰ هرتز) موقعیت می‌گیرند.

در ادامه یک کد ساده C برای تولید سیگنال PWM روی پایه OC1A (یعنی پین PB1) با تایمر ۱ آورده‌ام که برای کنترل سروو کاربردی است.


---

✅ تنظیمات اولیه:

تایمر ۱ (16 بیت) استفاده می‌شود.

مد Fast PWM با TOP برابر ICR1 برای کنترل دقیق فرکانس.

فرکانس ۵۰Hz (برای سروو معمولی).

پین خروجی PB1 (OC1A).



---

کد راه‌اندازی سروو موتور (Atmel Studio):

#define F_CPU 8000000UL // فرکانس کاری میکروکنترلر، اینجا 8MHz
#include <avr/io.h>
#include <util/delay.h>

void servo_init()
{
DDRB |= (1 << PB1); // تنظیم PB1 (OC1A) به عنوان خروجی

// تنظیم تایمر ۱ برای Fast PWM با ICR1 به عنوان TOP
TCCR1A |= (1 << COM1A1) | (1 << WGM11); // غیرمعکوس، Fast PWM
TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS11); // Fast PWM, prescaler=8

ICR1 = 19999; // تنظیم TOP برای فرکانس 50Hz → (20ms) → (F_CPU/Prescaler)/50Hz - 1 = (8MHz/8)/50 - 1 = 19999
}

void servo_set_angle(uint8_t angle)
{
// تبدیل زاویه (0 تا 180) به پالس مناسب (1000 تا 2000)
uint16_t pulse_width = 1000 + ((uint32_t)angle * 1000) / 180;
OCR1A = (pulse_width); // پالس به میکروثانیه
}

int main(void)
{
servo_init();

while (1)
{
for (uint8_t angle = 0; angle <= 180; angle += 10)
{
servo_set_angle(angle);
_delay_ms(500);
}

for (uint8_t angle = 180; angle > 0; angle -= 10)
{
servo_set_angle(angle);
_delay_ms(500);
}
}
}


---

نکات مهم:

تابع servo_set_angle زاویه را از 0 تا 180 گرفته و آن را به پالس ۱ تا ۲ میلی‌ثانیه تبدیل می‌کند.

مقدار OCR1A مستقیماً برابر تعداد میکروثانیه نیست؛ چون فرکانس کاری تایمر با prescaler = 8 برابر 1MHz شده (یعنی هر شمارنده = 1 میکروثانیه).

اگر فرکانس میکروکنترلر شما ۱۶MHz باشد یا prescaler عوض شود، باید محاسبات بالا را تنظیم کنید.



---

اگر خواستی همین کد را برای شبیه‌سازی در Proteus یا پروژه عملی روی برد پیاده‌سازی کنیم، می‌تونم همراهت باشم. دوست داری قدم بعدی را با هم بریم؟
 

saalek110

Well-Known Member
سالک: چرا ۸ مگا هرتز گرفتی فرکانس را ، خودت گفتی اگر فیوزبیت را دستکاری نکردی یک مگا هرتز است



دقیقاً درست گفتی، آفرین
اگر فیوزبیت‌های ATmega32 را تغییر نداده باشی، میکروکنترلر به طور پیش‌فرض روی اسیلاتور داخلی ۱ مگاهرتز تنظیم شده، نه ۸ مگاهرتز.

من در کدی که نوشتم فرض کردم فرکانس ۸MHz است چون رایج‌تره (و معمولاً برای PWM دقیق‌تر، از کریستال ۸ یا ۱۶MHz استفاده می‌کنن). اما اگر تو با همون حالت پیش‌فرض کار می‌کنی، باید حتماً این مورد رو توی محاسبات لحاظ کنیم.



✅ اگر فرکانس کاری ۱MHz باشد، چه تغییراتی باید بدهیم؟

بیا مرحله‌به‌مرحله اصلاح کنیم:


---

۱. تغییر خط #define F_CPU:

#define F_CPU 1000000UL // چون فرکانس داخلی 1MHz است


---

۲. محاسبه‌ی جدید برای مقدار ICR1:

در مد Fast PWM با prescaler = 8، فرکانس تایمر می‌شود:

\frac{1\,MHz}{8} = 125\,kHz \quad \Rightarrow \quad هر شمارنده = 8μs

برای تولید 50Hz باید پریود 20ms داشته باشیم:

20\,ms \div 8\,μs = 2500 \Rightarrow ICR1 = 2500 - 1 = 2499


---

3. بازه مناسب برای زاویه سروو:

در فرکانس 1MHz با prescaler 8، هر شمارنده = 8μs
پس:

برای پالس ۱ms (۰ درجه):


1000μs \div 8 = 125 \Rightarrow OCR1A = 125

برای پالس ۲ms (۱۸۰ درجه):


2000μs \div 8 = 250 \Rightarrow OCR1A = 250


---

نسخه اصلاح‌شده کد برای ۱MHz:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

void servo_init()
{
DDRB |= (1 << PB1); // خروجی شدن PB1 (OC1A)

TCCR1A |= (1 << COM1A1) | (1 << WGM11); // Fast PWM، non-inverting
TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS11); // Prescaler = 8

ICR1 = 2499; // تنظیم دوره برای 20ms → 1MHz / 8 / 50Hz = 2500
}

void servo_set_angle(uint8_t angle)
{
uint16_t pulse_width = 125 + ((uint32_t)angle * 125) / 180;
OCR1A = pulse_width;
}

int main(void)
{
servo_init();

while (1)
{
for (uint8_t angle = 0; angle <= 180; angle += 10)
{
servo_set_angle(angle);
_delay_ms(500);
}

for (uint8_t angle = 180; angle > 0; angle -= 10)
{
servo_set_angle(angle);
_delay_ms(500);
}
}
}


---

اگر خواستی با کریستال خارجی یا فرکانس دقیق‌تر کار کنی، یا فیوزبیت‌ها را تغییر بدهی، بگو تا راهنمایی‌ات کنم چطوری این کار را انجام بدی.

آماده‌ای با همین فرکانس ۱MHz تستش کنیم یا می‌خوای بری سراغ ۸MHz؟
 

saalek110

Well-Known Member
سالک: اگر باید ۸ مگاهرتز می گر۳تم ولی اشتباهی ۱ مگاهرتز وارد کنم در اجرای عملی چی می بینم؟

سؤال خوبیه!
اگر تو کد تعریف کنی #define F_CPU 1MHz ولی میکرو واقعا با ۸ مگاهرتز کار کنه، یعنی مقدار فرکانس در کد با فرکانس واقعی میکرو اختلاف داره، این اتفاقات می‌افته:


۱. محاسبه‌های تاخیر و تایمر اشتباه می‌شه

کد تو فکر می‌کنه هر پالس تایمر با ۱ میکروثانیه طول می‌کشه (فرکانس ۱MHz)، ولی در واقع هر پالس خیلی سریع‌تر (هر ۰.۱۲۵ میکروثانیه) اتفاق می‌افته چون فرکانس واقعی ۸MHz هست.


۲. PWM و تایمر خیلی سریع‌تر اجرا می‌شه

مثلاً وقتی مقدار ICR1 = 2499 گذاشتی که برای ۲۰ms باشه، چون فرکانس واقعی ۸ برابر بیشتره، پریود واقعی تایمر میشه حدود:

\frac{2499 + 1}{8MHz / 8} = \frac{2500}{1MHz} = 2.5ms

اما تو فکر می‌کردی ۲۰ms هست. یعنی:

فرکانس PWM واقعی حدود ۴۰۰ هرتز می‌شه به جای ۵۰ هرتز

پالس‌های سروو خیلی سریع‌تر تکرار می‌شن

زاویه سروو به درستی تنظیم نمی‌شه چون مقیاس پالس اشتباهه


۳. نتیجه عملی روی سروو موتور:

سروو ممکنه اصلاً حرکت نکنه یا حرکت خیلی ناپایدار داشته باشه

سروو ممکنه لرزش (jitters) شدید یا صدای غیرطبیعی بده

موقعیت سروو به شدت نامشخص و غیر دقیق می‌شه


خلاصه:

حالت واقعیمقدار تعریف شده در کدنتیجه

8 MHz1 MHzتاخیرها 8 برابر سریع‌تر؛ PWM اشتباه؛ سروو خراب کار می‌کنه
1 MHz8 MHzتاخیرها خیلی طولانی‌تر؛ PWM خیلی کند؛ سروو تقریباً حرکت نمی‌کنه


نکته مهم:

همیشه مقدار دقیق فرکانس CPU (F_CPU) باید در کد تعریف شود تا تاخیرها و تایمرها درست کار کنند.
 

saalek110

Well-Known Member
سالک: کار با تایمرها به عنوان شمارنده و روشن و خاموش کردن led خیلی ساده تر از راه اندازی سروو موتور است.
شاید با تمرین با تایمرها در روشن و خاموش کردن led یک چیزهایی را بشود فهمید . مثل همین فرکانس میکروکنترلر را که chatgpt راجع بهش دقیق صحبت نمی کند.
 

saalek110

Well-Known Member
سالک: اتمگا ۳۲ فرکانس داخلی اش چند مگاهرتز است؟

هوش مصنوعی deepseek :

پردازنده **Atmega32** یک میکروکنترلر ۸-بیتی از خانواده AVR است که توسط شرکت **Atmel** (اکنون زیرمجموعه Microchip) تولید شده است. فرکانس کاری داخلی این میکروکنترلر به تنظیمات **فوزبیت‌ها (Fuse Bits)** و منبع کلاک آن بستگی دارد.

### فرکانس داخلی Atmega32:
1. **کلاک داخلی (RC Oscillator)**:
- Atmega32 دارای یک اسیلاتور داخلی **۱ مگاهرتز، ۲ مگاهرتز، ۴ مگاهرتز، یا ۸ مگاهرتز** است (بسته به تنظیمات فوزبیت‌ها).
- به‌صورت پیش‌فرض، معمولاً روی **۱ مگاهرتز** تنظیم می‌شود.

2. **کلاک خارجی (کریستال یا منبع خارجی)**:
- اگر از کریستال خارجی استفاده شود، Atmega32 می‌تواند تا **۱۶ مگاهرتز** (در ولتاژ ۵V) کار کند.

### تنظیم فرکانس داخلی:
برای تغییر فرکانس داخلی، باید فوزبیت **CKSEL** را در تنظیمات میکروکنترلر تغییر دهید. مثلاً:
- **CKSEL = 0010** → کلاک داخلی ۱ مگاهرتز
- **CKSEL = 0100** → کلاک داخلی ۲ مگاهرتز
- **CKSEL = 0110** → کلاک داخلی ۴ مگاهرتز
- **CKSEL = 1000** → کلاک داخلی ۸ مگاهرتز

### نکته مهم:
- اگر از کریستال خارجی استفاده می‌کنید، فرکانس کلاک دقیق‌تر خواهد بود.
- فرکانس داخلی RC ممکن است با دقت کم‌تری کار کند (±۱۰٪ تلرانس).

اگر نیاز به تنظیم دقیق‌تری دارید، می‌توانید از **برنامه‌نویسی فوزبیت‌ها** در نرم‌افزارهایی مثل **AVRdude** یا **Atmel Studio** استفاده کنید.
 

saalek110

Well-Known Member
برنامه راه اندازی سروو موتور با اتمگا ۳۲ را بده

Deepseek:
برنامه راه‌اندازی **سروو موتور** با **ATmega32** به زبان **C** و با استفاده از **تایمر/کانتر 1 (Timer1)** برای تولید پالس **PWM** مناسب سروو موتور (معمولاً 50Hz با پالس 1ms تا 2ms) را در زیر آورده‌ام:

### مدار مورد نیاز:
- **سروو موتور** (مثل SG90) به پورت **PD5 (OC1A)** متصل می‌شود.
- تغذیه **5V** و **GND** به سروو موتور.
- کریستال خارجی **8MHz یا 16MHz** (اختیاری، اگر از کلاک داخلی استفاده می‌کنید نیازی نیست).

---

### کد برنامه در **CodeVisionAVR** یا **Atmel Studio**:

```c
#include <mega32.h>
#include <delay.h>

// تابع تنظیم تایمر 1 برای PWM
void Timer1_PWM_Init() {
// PD5 (OC1A) به عنوان خروجی
DDRD |= (1 << PD5);

// حالت Fast PWM با TOP=ICR1
TCCR1A = (1 << COM1A1) | (1 << WGM11);
TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS11); // Prescaler=8

// فرکانس PWM = 50Hz (پریود 20ms)
ICR1 = 39999; // برای کلاک 8MHz: (8MHz/8)/50Hz - 1 = 19999 (اما در برخی تنظیمات 39999 نیاز است)
}

// تابع حرکت سروو به زاویه‌ی مشخص (0 تا 180 درجه)
void Servo_Set_Angle(unsigned char angle) {
unsigned int pulse_width;

// محدوده پالس: 1000µs (0°) تا 2000µs (180°)
pulse_width = 1000 + (angle * 1000 / 180);

// تبدیل پالس به مقدار تایمر:
// برای کلاک 8MHz با Prescaler=8: هر تیک = 1µs
OCR1A = pulse_width; // مقدار پالس بر حسب میکروثانیه
}

void main() {
Timer1_PWM_Init();

while(1) {
// حرکت سروو از 0 به 180 درجه و برگشت
for(int i = 0; i <= 180; i++) {
Servo_Set_Angle(i);
delay_ms(20);
}
for(int i = 180; i >= 0; i--) {
Servo_Set_Angle(i);
delay_ms(20);
}
}
}
```

---

### توضیحات:
1. **تنظیمات تایمر 1**:
- حالت **Fast PWM** با **TOP=ICR1** برای تولید پالس دقیق.
- **پریسکیلر=8** برای کلاک 8MHz (هر تیک = 1µs).
- **فرکانس 50Hz** (پریود 20ms) با مقدار `ICR1 = 39999` (ممکن است بسته به کلاک متفاوت باشد).

2. **تبدیل زاویه به پالس**:
- سروو موتورهای معمولی به پالس **1ms (0°)** تا **2ms (180°)** پاسخ می‌دهند.
- تابع `Servo_Set_Angle` زاویه را به عرض پالس تبدیل می‌کند.

3. **اتصالات**:
- پایه **OC1A (PD5)** به سیم سیگنال سروو.
- **VCC و GND** به منبع تغذیه 5V.

---

### نکات مهم:
- اگر از کریستال **16MHz** استفاده می‌کنید، مقدار `ICR1` را به **79999** تغییر دهید (`ICR1 = 79999`).
- اطمینان حاصل کنید که **فوزبیت‌ها** برای کلاک صحیح تنظیم شده‌اند.
- برخی سروو موتورها به پالس‌های خارج از محدوده 1-2ms هم پاسخ می‌دهند (مثلاً 0.5ms تا 2.5ms).

اگر نیاز به تنظیم دقیق‌تر یا استفاده از کتابخانه‌های خاص دارید، خوشحال می‌شوم کمک کنم!
 

جدیدترین ارسال ها

بالا