class Timer -- التحكم في المؤقتات الداخلية

يمكن استخدام المؤقتات في مجموعة كبيرة ومتنوعة من المهام. في الوقت الحالي، تم تنفيذ أبسط حالة فقط: وهي استدعاء دالة بشكل دوري.

يتكوّن كل مؤقت من عدّاد يعدّ تصاعديًا بمعدل معين. والمعدل الذي يعدّ به هو تردد ساعة الطرفية (بالهرتز) مقسومًا على مقسِّم المؤقت (prescaler). عندما يصل العدّاد إلى دورة المؤقت يقوم بإطلاق حدث، ثم يُعيد العدّاد ضبط نفسه إلى الصفر. وباستخدام طريقة دالة رد النداء، يمكن لحدث المؤقت أن يستدعي دالة Python.

مثال على الاستخدام لتبديل حالة LED بتردد ثابت:

tim = pyb.Timer(4)              # create a timer object using timer 4
tim.init(freq=2)                # trigger at 2Hz
tim.callback(lambda t:pyb.LED(1).toggle())

مثال يستخدم دالة مسماة لدالة رد النداء:

def tick(timer):                # we will receive the timer object when being called
    print(timer.counter())      # show current timer's counter value
tim = pyb.Timer(4, freq=1)      # create a timer object using timer 4 - trigger at 1Hz
tim.callback(tick)              # set the callback to our tick function

أمثلة إضافية:

tim = pyb.Timer(4, freq=100)    # freq in Hz
tim = pyb.Timer(4, prescaler=0, period=99)
tim.counter()                   # get counter (can also set)
tim.prescaler(2)                # set prescaler (can also get)
tim.period(199)                 # set period (can also get)
tim.callback(lambda t: ...)     # set callback for update interrupt (t=tim instance)
tim.callback(None)              # clear callback

ملاحظة: يُستخدم Timer(1) للكاميرا. وبالمثل، يتحكم Timer(5) في مشغّل المؤازرة (servo)، ويُستخدم Timer(6) لعمليات القراءة/الكتابة المؤقتة في ADC/DAC. يُوصى باستخدام المؤقتات الأخرى في برامجك.

ملاحظة: لا يمكن تخصيص الذاكرة أثناء دالة رد النداء (المقاطعة) ولذلك فإن الاستثناءات التي تُطلق داخل دالة رد النداء لا تعطي الكثير من المعلومات. راجع micropython.alloc_emergency_exception_buf() لمعرفة كيفية تجاوز هذا القيد.

المنشئات

class pyb.Timer(id: int, *args, **kwargs)

ينشئ كائن مؤقت جديد بالمعرّف المعطى. إذا أُعطيت وسائط إضافية، فستتم تهيئة المؤقت عبر init(...). تعتمد مجموعة قيم id الصالحة على وحدة المعالجة الدقيقة STM32 الموجودة في OpenMV Cam المستخدمة؛ راجع دليل STM32 المرجعي للاطلاع على المؤقتات العامة الغرض ومؤقتات التحكم المتقدم المتاحة.

الطرائق

init(*, freq: int | float | None = None, prescaler: int | None = None, period: int | None = None, mode: int = Timer.UP, div: int = 1, callback: Callable[[Timer], None] | None = None, deadtime: int = 0, brk: int = Timer.BRK_OFF, hard: bool = True) None

تهيئة المؤقت. يجب أن تكون التهيئة إما بالتردد (بالهرتز) أو بالمقسِّم (prescaler) والدورة معًا:

tim.init(freq=100)                  # set the timer to trigger at 100Hz
tim.init(prescaler=83, period=999)  # set the prescaler and period directly

الوسائط المفتاحية:

  • freq --- يحدد التردد الدوري للمؤقت. يمكنك أيضًا اعتبار هذا التردد الذي يكمل به المؤقت دورة كاملة واحدة.

  • prescaler [0-0xffff] - يحدد القيمة التي يجب تحميلها في سجل المقسِّم (PSC) الخاص بالمؤقت. يُقسَّم مصدر ساعة المؤقت على (prescaler + 1) لاشتقاق ساعة المؤقت. يأتي مصدر الساعة من ناقل APB الأصل للمؤقت وهو يعتمد على وحدة المعالجة الدقيقة. على STM32، عادةً ما تعمل المؤقتات على APB1 بساعة 2 * pclk1 والمؤقتات على APB2 بساعة 2 * pclk2؛ اقرأ ترددات الناقل الحالية باستخدام pyb.freq() وراجع دليل STM32 المرجعي الخاص بوحدة المعالجة الدقيقة في OpenMV Cam.

  • period [0-0xffff] للمؤقتات 1 و3 و4 و6-15. [0-0x3fffffff] للمؤقتين 2 و5. يحدد القيمة التي يجب تحميلها في سجل إعادة التحميل التلقائي (ARR) الخاص بالمؤقت. وهذا يحدد دورة المؤقت (أي متى يكمل العدّاد دورته). سيتجاوز عدّاد المؤقت قيمته القصوى بعد period + 1 من دورات ساعة المؤقت.

  • يمكن أن يكون mode أحد الخيارات التالية:

    • Timer.UP - يضبط المؤقت ليعدّ من 0 إلى ARR (الافتراضي)

    • Timer.DOWN - يضبط المؤقت ليعدّ من ARR تنازليًا إلى 0.

    • Timer.CENTER - يضبط المؤقت ليعدّ من 0 إلى ARR ثم تنازليًا مرة أخرى إلى 0.

  • يمكن أن يكون div إما 1 أو 2 أو 4. يقسّم ساعة المؤقت لتحديد ساعة أخذ العينات المستخدمة من قِبل المرشحات الرقمية.

  • callback - وفقًا لـ Timer.callback()

  • deadtime - يحدد مقدار الوقت "الميت" أو غير النشط بين التحولات على القنوات التكميلية (ستكون كلتا القناتين غير نشطتين خلال هذا الوقت). يمكن أن يكون deadtime عددًا صحيحًا بين 0 و1008، مع القيود التالية: 0-128 بخطوات من 1. 128-256 بخطوات من 2، 256-512 بخطوات من 8، و512-1008 بخطوات من 16. يقيس deadtime نبضات source_freq مقسومة على div من نبضات الساعة. deadtime متاح فقط على المؤقتين 1 و8.

  • brk - يحدد ما إذا كان وضع الكسر (break) يُستخدم لإيقاف خرج PWM عند تأكيد دخل BRK_IN. تحدد قيمة هذا الوسيط ما إذا كان الكسر ممكّنًا وما هي قطبيته، ويمكن أن تكون إحدى القيم Timer.BRK_OFF أو Timer.BRK_LOW أو Timer.BRK_HIGH. لاختيار الدبوس BRK_IN أنشئ كائن Pin بـ mode=Pin.ALT, alt=Pin.AFn_TIMx. تتوفر ميزات دخل GPIO للدبوس في الوضع البديل (alt) - pull= و value() و irq().

  • يمكن أن يكون hard أحد الخيارات التالية:

    • True - سيتم تنفيذ دالة رد النداء في سياق المقاطعة الصلبة (hard interrupt)، مما يقلل التأخير والارتعاش (jitter) لكنه يخضع للقيود الموصوفة في كتابة معالجات المقاطعات بما في ذلك عدم القدرة على التخصيص في الكومة (heap).

    • False - ستتم جدولة دالة رد النداء كمقاطعة ناعمة (soft interrupt)، مما يسمح لها بالتخصيص لكنه قد يُدخل أيضًا تأخيرات وارتعاشًا ناتجين عن جمع المهملات (garbage collection).

    القيمة الافتراضية لهذا الخيار هي True.

يجب أن تحدد إما freq أو كلًا من period وprescaler.

deinit() None

يُلغي تهيئة المؤقت.

يعطّل دالة رد النداء (والمقاطعة irq المرتبطة بها).

يعطّل أي دوال رد نداء للقنوات (والمقاطعة irq المرتبطة بها). يوقف المؤقت، ويعطّل طرفية المؤقت.

callback(fun: Callable[[Timer], None] | None) None

يضبط الدالة التي سيتم استدعاؤها عند إطلاق المؤقت. يُمرَّر إلى fun وسيط واحد، وهو كائن المؤقت. إذا كان fun يساوي None فسيتم تعطيل دالة رد النداء.

channel(channel: int, mode: int | None = None, *args, **kwargs) TimerChannel | None

إذا تم تمرير رقم قناة فقط، فسيتم إرجاع كائن قناة سبق تهيئته (أو None إذا لم تكن هناك قناة سابقة).

وإلا، فسيتم تهيئة كائن TimerChannel وإرجاعه.

يمكن تكوين كل قناة لأداء pwm أو مقارنة الخرج (output compare) أو التقاط الدخل (input capture). تشترك جميع القنوات في المؤقت الأساسي نفسه، مما يعني أنها تشترك في ساعة المؤقت نفسها.

الوسائط المفتاحية:

  • يمكن أن يكون mode أحد الخيارات التالية:

    • Timer.PWM --- يكوّن المؤقت في وضع PWM (نشط عند المستوى المرتفع).

    • Timer.PWM_INVERTED --- يكوّن المؤقت في وضع PWM (نشط عند المستوى المنخفض).

    • Timer.OC_TIMING --- يشير إلى عدم تشغيل أي دبوس.

    • Timer.OC_ACTIVE --- سيتم جعل الدبوس نشطًا عند حدوث تطابق في المقارنة (يُحدَّد النشاط حسب القطبية)

    • Timer.OC_INACTIVE --- سيتم جعل الدبوس غير نشط عند حدوث تطابق في المقارنة.

    • Timer.OC_TOGGLE --- سيتم تبديل حالة الدبوس عند حدوث تطابق في المقارنة.

    • Timer.OC_FORCED_ACTIVE --- يُفرض على الدبوس أن يكون نشطًا (يُتجاهل تطابق المقارنة).

    • Timer.OC_FORCED_INACTIVE --- يُفرض على الدبوس أن يكون غير نشط (يُتجاهل تطابق المقارنة).

    • Timer.IC --- يكوّن المؤقت في وضع التقاط الدخل (Input Capture).

    • Timer.ENC_A --- يكوّن المؤقت في وضع المُرمِّز (Encoder). يتغير العدّاد فقط عندما تتغير CH1.

    • Timer.ENC_B --- يكوّن المؤقت في وضع المُرمِّز (Encoder). يتغير العدّاد فقط عندما تتغير CH2.

    • Timer.ENC_AB --- يكوّن المؤقت في وضع المُرمِّز (Encoder). يتغير العدّاد عندما تتغير CH1 أو CH2.

  • callback - وفقًا لـ TimerChannel.callback()

  • pin بقيمة None (الافتراضية) أو كائن Pin. إذا تم تحديده (ولم يكن None) فسيؤدي ذلك إلى تكوين الدالة البديلة للدبوس المحدد لقناة المؤقت هذه. سيُطلق خطأ إذا كان الدبوس لا يدعم أي دوال بديلة لقناة المؤقت هذه.

الوسائط المفتاحية لأوضاع Timer.PWM:

  • pulse_width - يحدد قيمة عرض النبضة الأولية المراد استخدامها.

  • pulse_width_percent - يحدد النسبة المئوية الأولية لعرض النبضة المراد استخدامها.

الوسائط المفتاحية لأوضاع Timer.OC:

  • compare - يحدد القيمة الأولية لسجل المقارنة.

  • يمكن أن تكون polarity إحدى القيم التالية:

    • Timer.HIGH - الخرج نشط عند المستوى المرتفع

    • Timer.LOW - الخرج نشط عند المستوى المنخفض

الوسائط المفتاحية الاختيارية لأوضاع Timer.IC:

  • يمكن أن تكون polarity إحدى القيم التالية:

    • Timer.RISING - يلتقط عند الحافة الصاعدة.

    • Timer.FALLING - يلتقط عند الحافة الهابطة.

    • Timer.BOTH - يلتقط عند كلتا الحافتين.

لاحظ أن الالتقاط يعمل فقط على القناة الأساسية، وليس على القنوات التكميلية.

ملاحظات لأوضاع Timer.ENC:

  • يتطلب دبوسين، لذا سيحتاج أحد الدبوسين أو كلاهما إلى التكوين لاستخدام الدالة البديلة (AF) المناسبة للمؤقت باستخدام واجهة برمجة تطبيقات Pin.

  • اقرأ قيمة المُرمِّز باستخدام طريقة timer.counter().

  • يعمل فقط على CH1 وCH2 (وليس على CH1N أو CH2N)

  • يُتجاهل رقم القناة عند ضبط وضع المُرمِّز.

مثال PWM -- في كل OpenMV Cam من نوع STM32 تُوجَّه قناتا TIM4 رقم 1 و2 إلى دبوسي الترويسة P7 و P8 على التوالي:

timer = pyb.Timer(4, freq=1000)
ch1 = timer.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.P7,
                    pulse_width=8000)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.P8,
                    pulse_width=16000)
counter(value: int | None = None) int | None

يقرأ أو يضبط عدّاد المؤقت.

freq(value: int | float | None = None) int | float | None

يقرأ أو يضبط تردد المؤقت (يغير المقسِّم والدورة في حال الضبط).

period(value: int | None = None) int | None

يقرأ أو يضبط دورة المؤقت.

prescaler(value: int | None = None) int | None

يقرأ أو يضبط مقسِّم المؤقت.

source_freq() int

يقرأ تردد مصدر المؤقت.

الثوابت

ثوابت وضع العدّ (وسيط mode في init()):

UP: int

يعدّ من 0 تصاعديًا إلى ARR (الوضع الافتراضي).

DOWN: int

يعدّ من ARR تنازليًا إلى 0.

CENTER: int

يعدّ من 0 تصاعديًا إلى ARR ثم تنازليًا مرة أخرى إلى 0.

ثوابت وضع الكسر (وسيط brk في init()):

BRK_OFF: int

دخل الكسر معطّل.

BRK_LOW: int

دخل الكسر نشط عند المستوى المنخفض.

BRK_HIGH: int

دخل الكسر نشط عند المستوى المرتفع.

ثوابت وضع القناة (وسيط mode في channel()):

PWM: int

يكوّن القناة لخرج PWM (نشط عند المستوى المرتفع).

PWM_INVERTED: int

يكوّن القناة لخرج PWM (نشط عند المستوى المنخفض).

OC_TIMING: int

وضع توقيت مقارنة الخرج؛ لا يتم تشغيل أي دبوس.

OC_ACTIVE: int

وضع مقارنة الخرج النشط؛ يُجعل الدبوس نشطًا عند تطابق المقارنة.

OC_INACTIVE: int

وضع مقارنة الخرج غير النشط؛ يُجعل الدبوس غير نشط عند تطابق المقارنة.

OC_TOGGLE: int

وضع تبديل مقارنة الخرج؛ يبدّل الدبوس حالته عند تطابق المقارنة.

OC_FORCED_ACTIVE: int

وضع مقارنة الخرج النشط المفروض؛ يُفرض على الدبوس أن يكون نشطًا ويُتجاهل تطابق المقارنة.

OC_FORCED_INACTIVE: int

وضع مقارنة الخرج غير النشط المفروض؛ يُفرض على الدبوس أن يكون غير نشط ويُتجاهل تطابق المقارنة.

IC: int

يكوّن القناة لوضع التقاط الدخل.

ENC_A: int

وضع المُرمِّز: يتغير العدّاد فقط عندما تتغير CH1.

ENC_B: int

وضع المُرمِّز: يتغير العدّاد فقط عندما تتغير CH2.

ENC_AB: int

وضع المُرمِّز: يتغير العدّاد كلما تغيرت CH1 أو CH2.

قطبية مقارنة الخرج (وسيط polarity في channel() في أوضاع OC):

HIGH: int

الخرج نشط عند المستوى المرتفع.

LOW: int

الخرج نشط عند المستوى المنخفض.

قطبية التقاط الدخل (وسيط polarity في channel() في وضع IC):

RISING: int

يلتقط عند الحافة الصاعدة.

FALLING: int

يلتقط عند الحافة الهابطة.

BOTH: int

يلتقط عند أي من الحافتين.