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

saalek110

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

خیلی خوشحالم که تایمرها برات مفید بود!
هر وقت خواستی بیشتر درباره تایمرها، وقفه‌ها، یا هر بخش دیگه‌ای از میکروکنترلرها بدونی، من اینجا هستم.
یادگیری سخت ولی شیرینیه، و تو داری عالی پیش می‌ری! ✨

اگر سوال دیگه‌ای داری یا می‌خوای یه پروژه عملی با تایمر بسازیم، فقط بگو!

سالک: اون رجیستر اولی فقط مشروح بود ولی اونم ساده بود

دقیقاً همینطوره!
رجیستر اولی یعنی TCCRn (Timer/Counter Control Register) از نظر مفهومی مهم و پایه‌ایه چون تنظیمات اصلی تایمر رو دستشه، ولی خب گاهی شرحش مفصل و به ظاهر پیچیده می‌شه چون هر بیتش یه کاری انجام می‌ده.

اما وقتی قدم به قدم جلو بری و هر بیت رو جدا جدا بفهمی، مثل یه کلید ساده برای کنترل تایمر می‌مونه.
در نهایت، همون‌طور که گفتی، ساده است ولی چون ریزجزئیاتش زیاد هست، مشروح و طولانی توضیح داده می‌شه.

خلاصه اینکه:
اولش کمی پیچیده به نظر میاد، ولی با تمرین و مرور، ساده و قابل درک می‌شه.

در عکس زیر رجیسترها و نقششان مرور شده:
Screenshot_۲۰۲۵-۰۵-۳۱_۲۰۴۴۵۸.jpg
 
آخرین ویرایش:

saalek110

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

برای راه‌اندازی سررو موتور (Servo Motor) با میکروکنترلرهای معمول مثل AVR (مثلاً ATmega32)، اصلی‌ترین کار استفاده از تایمر با مد PWM است تا بتوانیم زاویه سروو را کنترل کنیم.


کدوم رجیسترها باید تنظیم بشن؟

۱. تایمر/کانتر کنترل رجیستر (TCCRn)

این رجیستر تنظیمات تایمر را مشخص می‌کند:

مد تایمر (PWM، CTC، ...)،

تقسیم فرکانس (Prescaler)،

نوع PWM (Fast PWM یا Phase Correct PWM)



۲. OCRn (Output Compare Register)

مقدار خروجی PWM را مشخص می‌کند، یعنی پهنای پالس را تعیین می‌کند که زاویه سروو به آن وابسته است.


۳. DDRx (Data Direction Register)

پایه‌ای که PWM را روی آن تولید می‌کنیم باید به عنوان خروجی تنظیم شود.



خلاصه مراحل کلیدی:

رجیستروظیفه

TCCRnتنظیم مد PWM و Prescaler تایمر
OCRnتنظیم پهنای پالس PWM (زاویه سروو)
DDRxتنظیم پین خروجی PWM به حالت خروجی


نکته مهم برای سرور موتور استاندارد:

فرکانس PWM حدود 50 هرتز (دوره 20 میلی‌ثانیه) است.

پهنای پالس بین تقریباً 1 تا 2 میلی‌ثانیه برای حرکت زاویه از 0 تا 180 درجه.

بنابراین باید تایمر را طوری تنظیم کنی که بتوانی پهنای پالس دقیق بسازی.


اگر بخواهی، می‌توانم مثال کد ساده برای راه‌اندازی سروو با AVR (مثلاً ATmega32) برات بنویسم که رجیسترها را هم دقیق مشخص کند. فقط بگو.
 

saalek110

Well-Known Member
سالک: لطفا کد را بنویس

البته!
اینجا یک مثال ساده و کامل برای راه‌اندازی سروو موتور با استفاده از ATmega32 و تایمر 1 در حالت Fast PWM با فرکانس 50 هرتز هست.


توضیح کوتاه:

تایمر ۱ چون 16 بیت هست، دقت بهتری برای ساخت پالس دقیق داره.

ما تایمر رو با prescaler مناسب تنظیم می‌کنیم تا فرکانس PWM 50 هرتز بشه (20ms دوره)

مقدار OCR1A پهنای پالس را تعیین می‌کند (بین تقریباً 1 تا 2 میلی‌ثانیه برای زاویه 0 تا 180)



---

کد نمونه (به زبان C و رجیستر محور):
C:
#define F_CPU 8000000UL  // فرکانس کریستال 8 مگاهرتز
#include <avr/io.h>
#include <util/delay.h>

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

    // تنظیم تایمر1 در مد Fast PWM با ICR1 به عنوان TOP
    // WGM13:0 = 14 (Mode 14) -> Fast PWM, TOP = ICR1
    // COM1A1:0 = 2 -> Clear OC1A on compare match, set at BOTTOM (non-inverting PWM)
    TCCR1A = (1 << COM1A1) | (1 << WGM11);
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11) | (1 << CS10); // prescaler = 64

    // مقدار TOP را برای فرکانس 50 هرتز تنظیم کن
    // فرمول: Frequency = F_CPU / (Prescaler * (1 + TOP))
    // TOP = (F_CPU / (Prescaler * Frequency)) - 1
    // TOP = (8,000,000 / (64 * 50)) - 1 = 2499
    ICR1 = 2499;
}

void servo_set_angle(uint8_t angle) {
    // زاویه از 0 تا 180 درجه
    // تبدیل زاویه به مقدار OCR1A (پهنای پالس بین 1ms تا 2ms)
    // OCR1A برای 1ms = 125 (64 prescaler: 8MHz/64*0.001)
    // OCR1A برای 2ms = 250
    // خطی بین 125 تا 250 برای زاویه 0 تا 180

    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 (int angle = 180; angle >= 0; angle -= 10) {
            servo_set_angle(angle);
            _delay_ms(500);
        }
    }
}


Screenshot_۲۰۲۵-۰۵-۳۱_۲۱۰۲۰۵.jpg

سالک: من این کد را تست عملی نکردم ، فقط برای بحث و بررسی تئوری است فعلا.
 
آخرین ویرایش:

saalek110

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

حتماً عزیزم!
حالا به زبان خیلی ساده و خودمانی بگویم این کد چطوری کار می‌کند و هر رجیستر چه کاری انجام می‌دهد:


۱. تنظیم پایه خروجی (DDRB)

با دستور DDRB |= (1 << PB1);
یعنی پایه PB1 (که به آن OC1A می‌گوییم و سیگنال PWM رویش ساخته می‌شود) را تبدیل می‌کنیم به یک پایه خروجی.
مثل این می‌ماند که به میکرو بگو: «اینجا قراره برق بفرستی.»


۲. تنظیم تایمر ۱ (TCCR1A و TCCR1B)

تایمر ۱ را روی مد Fast PWM می‌گذاریم (یعنی تایمر به سرعت پالس PWM تولید می‌کند).

همچنین می‌گوییم: هر وقت تایمر به مقدار خاصی رسید (مقدار ICR1)، دوباره از صفر شروع کن (این مقدار TOP است و دوره PWM را تعیین می‌کند).

تایمر را با تقسیم فرکانس (prescaler) روی ۶۴ تنظیم می‌کنیم تا سرعت شمارش مناسب شود و فرکانس PWM شود حدود ۵۰ هرتز (20 میلی‌ثانیه دوره).


۳. مقدار TOP (ICR1)

رجیستر ICR1 عدد ۲۴۹۹ را نگه می‌دارد که تعیین می‌کند تایمر از ۰ تا ۲۴۹۹ بشمارد و بعد صفر شود.

این تعداد شمارش باعث می‌شود دوره کل پالس PWM حدود 20 میلی‌ثانیه شود که سرووها برای کار کردن به این دوره نیاز دارند.


۴. مقدار پهنای پالس (OCR1A)

رجیستر OCR1A تعیین می‌کند که پالس PWM چقدر طولانی باشد، یعنی چقدر سیگنال روی پایه PB1 در حالت «روشن» (High) بماند.

پهنای پالس بین تقریباً 1 میلی‌ثانیه (زاویه 0 درجه) تا 2 میلی‌ثانیه (زاویه 180 درجه) تغییر می‌کند.

این مقدار توسط تابع servo_set_angle محاسبه و در OCR1A قرار می‌گیرد.


۵. خلاصه عملکرد:

تایمر با سرعت مناسب شروع به شمارش می‌کند.

وقتی تایمر به مقدار OCR1A می‌رسد، پایه خروجی خاموش می‌شود (پالس قطع می‌شود).

وقتی تایمر به مقدار ICR1 می‌رسد، شمارش صفر می‌شود و دوباره پالس شروع می‌شود.

نتیجه: یک سیگنال PWM با فرکانس 50 هرتز و پهنای پالس متغیر که زاویه سروو را کنترل می‌کند.


پس به طور خلاصه:

رجیسترکارکرد به زبان ساده

DDRBتنظیم پایه PB1 به عنوان خروجی سیگنال PWM
TCCR1Aانتخاب مد PWM و فعال کردن خروجی PWM روی پایه
TCCR1Bتنظیم سرعت تایمر و حالت PWM (Fast PWM)
ICR1تعیین مدت کل دوره PWM (20 میلی‌ثانیه)
OCR1Aتعیین مدت زمان روشن بودن پالس PWM (زاویه سروو)
Screenshot_۲۰۲۵-۰۵-۳۱_۲۱۰۵۵۶.jpg
 

saalek110

Well-Known Member
سالک:یک بار دیگه بگو



اجازه بده یه جور دیگه هم توضیح بدم.

میکروکنترلر ما یک تایمر داره که شمارش می‌کنه از صفر تا عددی که ما براش تعیین کردیم (اون عدد تو ICR1) — این تعیین می‌کنه چقدر طول می‌کشه تا یک دوره PWM کامل بشه (مثلاً 20 میلی‌ثانیه).

داخل اون دوره، یک پالس روشن (High) میاد که طولش با عددی که تو OCR1A گذاشتیم مشخص میشه (مثلاً 1 تا 2 میلی‌ثانیه).

اون پالس روشن به سروو میگه چقدر بچرخه.

TCCR1A و TCCR1B به تایمر میگن که چطور این شمارش رو انجام بده و چطوری پالس رو روی پین خروجی تولید کنه.

DDRB هم به پین خروجی میگه که قراره برق بده.
 

saalek110

Well-Known Member

تاپیک بالا را ساختم تا کار با سروو موتور با تایمرهای میکروکنترلر را جدا بررسی کنیم ولی مطالب اون تاپیک می تونه مکمل مطالب این تاپیک باشه ، نگاهی به اون تاپیک هم بیاندازیم تا بیشتر با رجیسترهای میکروکنترلر و باقی بحث های وابسته آشنا بشوید.
 

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

بالا