اردوينو: دفع الحدود || اردوينو الموقتات: 9 خطوات

اردوينو: دفع الحدود || اردوينو الموقتات: 9 خطوات

جدول المحتويات:

Anonim

تتمتع اردوينو بقدرات وميزات رائعة بالفعل ، اللغة والسرعة وسهولة الاستخدام ولوحة التطوير الرائعة والتوثيق والسعر والقدرة على التواصل مع الكثير من الأجهزة والبرامج. لن تتعرف على مدى أهمية هذه الميزات ، حتى تستخدم Arduino مع أقصى قدرة. في السلسلة: "اردوينو: دفع الحدود" سأحاول أن أوضح كيف يمكنك زيادة قدرات اردوينو ، واستخدامها بطرق أفضل وأكثر ذكاءً ، وزيادة قدرات ومرونة وموثوقية مشاريعك ، وجعلها أسهل في إعادة تشكيلها.

هذا هو أول تعليمات في السلسلة ، يتحدث عن ميزة Arduino Timers.

في هذا التوجيه ، سأتحدث عن أجهزة ضبط الوقت Arduino ، وما هي ، وكيف تعمل ، وكيفية استخدامها ؛ إعطاء بعض الأمثلة البسيطة وإظهار بعض الفوائد لاستخدامها.

بعد هذا التوجيه ، يجب أن تكون قادرًا على إنشاء مشاريع أكبر مع المزيد من التعليمات البرمجية والتفاصيل ، وستكون لديك المزيد من القدرات لإضافتها إلى مشروعك.

أحد الأمثلة التي قمت بإجرائها باستخدام ميزة Timers في arduino ، "Plug-In" ، وهو عبارة عن مشروع يحتوي على قابس كهربائي بسيط يمكن ضبطه لمدة معينة (في مشروعي ، تكون المدد 1،2 ،.. 6 ساعات ويمكن ضبطه على أي فترات تريدها) بعد انقضاء المدة ، لن توفر القابس أي طاقة من خلالها. التي يجب أن تكون مفيدة لاستخدامها لشحن الهاتف أثناء النوم لمدة ساعتين على سبيل المثال. سيتم عرض تفاصيل هذا المشروع في التعليمات التالية. انظر تحديث

* سأفترض أن لديك معرفة جيدة بأساسيات ومفاهيم اردوينو ، وكيفية استخدامها ، حتى أتمكن من المضي قدمًا في كيفية تحسينها.

* سأقتبس بعض المعلومات في هذا الدليل من هذه المقالة: اردوينو 101: الموقتات و المقاطعات

تحديث:

تحقق من البرنامج التعليمي التالي ، وهو مشروع يعتمد على توقيت اردوينو ، اردوينو: دفع الحدود || توقيت البرنامج المساعد السلطة.

اللوازم:

الخطوة 1: ما هو اردوينو الموقت

هل فكرت كيف تعرف اردوينو الوقت! أعني ، كيف يعرف اردوينو كم يجب أن ينتظر تأخير 100 مللي ثانية على سبيل المثال ، أو كيف يجب أن يقطع إشارة 5V لإخراج إشارة PWM محددة!

تكمن الإجابة على هذا في معرفة بنية وحدات MCU ، ولن أتحدث عن البنية هنا ، يكفي أن أذكر أن لاردوينو شيء يشبه القلب! إنها تولد نبضات (تعني النبض في اردوينو شيئًا يشبه خطوة اتخذها اردوينو للقيام بمهمة) ، مع سرعة محددة ، بلورتها وسرعتها 16 ميجاهيرتز. من هذه الحقيقة يمكننا أن نقول أن النبض يأتي مع وقت محدد = (1 / 16M). هذا يعني أن هناك مدة ثابتة بين كل نبضتين. بناءً على ذلك ، إذا تم حساب النبضات باستخدام عداد ، فيمكننا الحصول على الوقت الفعلي ، من خلال معرفة عدد العدادات.

الجزء الأجهزة الذي يقوم بمهمة العد في اردوينو يسمى الموقت. إنها زيادة معاكسة بمعدل معين ، بحيث يعطي كل عدد وقتًا ، معرفة قيمة العداد تتيح لك معرفة مقدار الوقت المنقضي.

سيتم شرح التفاصيل في الخطوات التالية. لمعرفة لقد شرحت للتو كيف يعمل الموقت وكيف اردوينو استخدامه لمعرفة الوقت.

في الخطوة التالية سأتحدث عن الموقت في اردوينو.

الخطوة 2: اردوينو الموقت

الموقت في وحدة MCU عبارة عن سجل ، يتكون من عدد معين من وحدات البت ، في arduino ، وسأخذ arduino uno كمثال هنا ، وهناك 3 أجهزة توقيت تسمى: timer0 ، timer1 ، timer2. يتم تمديدها إلى الموقت 3،4 ، و 5 مع ميجا.

Timer0:

Timer0 هو مؤقت 8bit.

في العالم اردوينو ، يتم استخدام timer0 لوظائف المؤقت ، مثل delay () ، millis () و micros (). إذا قمت بتغيير سجلات timer0 ، فقد يؤثر ذلك على وظيفة مؤقت Arduino. لذلك يجب أن تعرف ما تفعله.
Timer1:
Timer1 هو مؤقت 16bit.
في عالم Arduino ، تستخدم مكتبة Servo timer1 على Arduino Uno (timer5 على Arduino Mega).
Timer2:
Timer2 هو مؤقت 8bit مثل timer0.
في عمل Arduino ، تستخدم وظيفة tone () timer2.
Timer3 ، Timer4 ، Timer5:
يتوفر الموقت 3،4،5 فقط على لوحات Arduino Mega. هذه الموقتات كلها توقيتات 16bit.

في هذه التعليمات ، سأتحدث عن استخدام المؤقت 1 و 2 كمثال على 16 بت و 8 بت مؤقت.

يجب أن تعلم أنه ، في الأساس هو سجل ، يتكون نظام المؤقت من سجلات متعددة ، وتلك التي تحتوي على العداد وتلك التي تحتوي على الإعدادات والوظائف.

يمكنك تغيير سلوك Timer من خلال سجل المؤقت. أهم سجلات الموقت هي:

TCCRx - الموقت / عداد مراقبة السجل. يمكن أن يكون محددا هنا.

TCNTx- الموقت / سجل العداد. يتم تخزين قيمة المؤقت الفعلي هنا.

OCRx - الإخراج مقارنة سجل
ICRx - سجل التقاط الإدخال (فقط لوقت 16 بت)
TIMSKx - سجل قناع الموقت / عداد. لتمكين / تعطيل المقاطعات الموقت.
TIFRx - الموقت / عداد مقاطعة سجل العلم. يشير إلى مقاطعة مؤقت معلقة.

الآن سوف أصف العملية التي سيتم إعداد المؤقت بها.

أولاً يجب أن تلاحظ ما يلي:

السجل الاول TCNTx هو السجل الذي يتعامل مع قيمة المؤقت الحقيقي ، وعندما نريد أن نعرف قيمة الوصول إلى الموقت ، سنقرأ هذا السجل. كما يمكننا استخدام هذا السجل لتحميل الموقت مع بعض القيمة ، لسبب بسيط! لضمان ضبط مدة مقاطعة المؤقت على قيمة محددة يمكننا التعامل معها ، سترى ذلك بالأمثلة.

لاحظ أن تدوين "x" يشير إلى عدد الموقت المستخدم ، (إذا عملنا مع الموقت 0 ، فإن x تساوي 0: TCNT0)

TIMSKx سيتم استخدام السجل لتمكين أو تعطيل مقاطعات المؤقت ، وسيتم توضيح تعريف المقاطعات في الخطوة التالية.

TCCRx سيتم استخدام هذا السجل لتعيين المحددات ، يمكن توضيح الواصف بعضًا من خلال عدد من التهم المحددة التي يجب على الموقت القيام بها لزيادة قيمته بمقدار 1. لذلك إذا تم تعيين المُحدد على 10 على سبيل المثال ، ثم كل 10 الموقت يسجل قيمة عداد الموقت ستزيد بمقدار 1. قيمة أكبر للوصف ، كلما طال الوقت الذي يمكن أن تحققه عداد الموقت قبل التدفق الزائد.

اختيار ساعة وتردد الموقت

يمكن اختيار مصادر مختلفة على مدار الساعة لكل مؤقت بشكل مستقل. لحساب تردد الموقت (على سبيل المثال 2Hz باستخدام timer1) ستحتاج إلى:
1. 16 ميغاهيرتز تردد وحدة المعالجة المركزية لاردوينو
2. الحد الأقصى لقيمة عداد الموقت (256 ل 8 بت ، 65536 لوقت 16 بت)
3. قم بتقسيم تردد وحدة المعالجة المركزية عبر المحدد المحدد (16000000/256 = 62500)
4. اقسم النتيجة على التردد المطلوب (62500 / 2Hz = 31250)
5. تحقق من النتيجة مقابل الحد الأقصى لقيمة عداد الموقت (31250 <65536 نجاح) إذا فشلت ، اختر محددًا أكبر.

من خلال هذه الخطوات ، يمكنك حساب تردد الموقت لأي تردد تريده ، من لعنة يمكنك تغيير الواصف إلى أي قيمة تريدها.

بالنسبة إلى مؤقت 8 بت ، تكون العملية هي نفسها ، والقيد الوحيد هو أن القيمة يجب أن تكون أقل من 256. لذلك يجب عليك استخدام محددات كبيرة ، وتردد عالي. عادة ما يكون من الأفضل استخدام مؤقت 16 بت ، في arduino mega لا توجد مشكلة في ذلك ، هناك 4 مؤقتات مع 16 بت ، المشكلة تظهر مع arduino uno ، يوجد timer1 فقط يأتي مع 16 بت ، إذا كنت تستخدم مكتبة Servo أو أي مكتبة لن تتمكن من استخدامه ، استنادًا إلى timer1 ، وستقوم الوظائف بواجهة بعضها البعض ، لذلك في بعض الأحيان سيكون عليك استخدام مؤقت 8 بت.

في هذه التعليمات سيكون هناك مثال لاستخدام مؤقت 8 بت بترددات منخفضة.

الخطوة 3: اردوينو المقاطعة

ما هي المقاطعة؟
عادةً ما يتم تشغيل البرنامج الذي يعمل على وحدة تحكم بالتعليم بالتعليم. المقاطعة هي حدث خارجي يقاطع البرنامج قيد التشغيل ويقوم بتشغيل روتين خدمة مقاطعة خاص (ISR). بعد انتهاء ISR ، يستمر البرنامج قيد التشغيل بالتعليمات التالية. "التعليمات" تعني تعليمة جهاز واحد ، وليس سطرًا من رمز C أو C ++.
قبل أن تتمكن المقاطعة المعلقة من الاتصال بـ ISR ، يجب أن تكون الشروط التالية صحيحة:
يجب تمكين المقاطعات بشكل عام
يجب تمكين قناع المقاطعة وفقًا لذلك
عمومًا يمكن تمكين / تعطيل المقاطعات مع الدالة المقاطعات () / noInterrupts (). بشكل افتراضي في مقاطعات البرامج الثابتة Arduino يتم تمكين. يتم تمكين / تعطيل أقنعة المقاطعة عن طريق إعداد / مسح البتات في سجل قناع المقاطعة (TIMSKx).
عند حدوث مقاطعة ، يتم تعيين علامة في سجل إشارة المقاطعة (TIFRx). سيتم مسح هذه المقاطعة تلقائيًا عند إدخال ISR أو عن طريق مسح البتة يدويًا في سجل إشارة المقاطعة.
يمكن استخدام وظائف Arduino attachInterrupt () و detachInterrupt () فقط لمقاطع المقاطعة الخارجية. هذه هي مصادر المقاطعة مختلفة ، لم تناقش هنا.
المقاطعات الموقت
يمكن لجهاز ضبط الوقت إنشاء أنواع مختلفة من المقاطعات. يمكن العثور على تعريفات السجل والبت في ورقة بيانات المعالج (Atmega328 أو Atmega2560) وفي ملف رأس تعريف الإدخال / الإخراج (iomx8.h لـ Arduino ، iomxx0_1.h لـ Arduino Mega في الجهاز / tools / avr / include / مجلد avr). يرمز اللاحقة x إلى رقم المؤقت (0..5) ، واللاحقة y تعني رقم الإخراج (A ، B ، C) ، على سبيل المثال TIMSK1 (سجل قناع مقاطعة timer1) أو OCR2A (مقارنة إخراج timer2 ، سجل A).
تجاوز الموقت:
تجاوز سعة المؤقت يعني أن المؤقت قد وصل إلى قيمة الحد. عند حدوث مقاطعة تجاوز سعة مؤقت ، سيتم تعيين TOVx بت تجاوز سعة المؤقت في سجل إشارة المقاطعة TIFRx. عند تمكين تجاوز سعة المؤقت المؤقت بت TOIEx في سجل قناع المقاطعة ، يتم تعيين TIMSKx ، وسيتم استدعاء ISR (TIMERx_OVF_vect) روتين خدمة مقاطعة تجاوز سعة المؤقت.
الناتج مقارنة المباراة:
عند حدوث مقاطعة مقارنة لمطابقة الإخراج ، سيتم تعيين علامة OCFxy في سجل إشارة المقاطعة TIFRx. عند تمكين الإخراج مقارنة المقاطعة بت OCIExy في سجل قناع المقاطعة تم تعيين TIMSKx ، سيتم استدعاء روتين ISR (TIMERx_COMPy_vect) خدمة مقارنة الإخراج مطابقة خدمة المقاطعة.
القبض على المدخلات الموقت:
عند حدوث مقاطعة التقاط إدخال مؤقت ، سيتم تعيين بت إشارة الالتقاط ICFx في سجل إشارة المقاطعة TIFRx. عندما تقوم مقاطعة التقاط الإدخال بتمكين بت ICIEx في سجل قناع المقاطعة ، يتم تعيين TIMSKx ، وسيتم استدعاء روتين خدمة المقاطعة لالتقاط إدخال الموقت ISR (TIMERx_CAPT_vect).

أنا شخصياً أحب استخدام ISR الفائض ، لذا فإن معظم الأمثلة ستكون على استخدامه ، مع تدوين جيد ورسوم توضيحية. من العلاجات سأذكر المقارنة بين ISR ولكن سيتم نقلها من المقال الأصلي المذكور سابقًا.

*** يرجى الرجوع إلى المقال الأصلي حيث توجد ملاحظات إضافية حول "PWM والموقت "و" المزالق "التي يمكن أن يكون لها معلومات جيدة بالنسبة لك.

الخطوة 4: وامض الصمام مع مقارنة المباراة المقاطعة

*** هذا المثال مقتبس من Arduino 101: مؤقت وقاطعات

المثال الأول يستخدم timer1 في وضع CTC ويقابل مقارنة المقارنة لتبديل مؤشر LED. تم تكوين الموقت لتردد 2Hz. يتم تبديل LED في روتين خدمة المقاطعة.

/ * Arduino 101: مؤقت وقاطع

1: Timer1 ، مقارنة بين أمثلة مقاطعة المطابقة ، مزيد من المعلومات: http://www.letmakerobots.com/node/28278 التي أنشأتها RobotFreak * /

#define ledPin 13

إعداد باطل () = (1 << WGM12) ؛ // وضع CTC TCCR1B

ISR (TIMER1_COMPA_vect) // timer مقارنة روتين خدمة المقاطعة {digitalWrite (ledPin، digitalRead (ledPin) ^ 1)؛ // تبديل دبوس LED}

حلقة باطلة () {// برنامجك هنا …}

الخطوة 5: وامض الصمام مع الموقت تجاوز السعة

*** هذا المثال مقتبس من Arduino 101: المؤقت والمقاطعات ….

*** سأضيف بعض الملاحظات في الخطوة التالية لتوضيح الأمور.

…………………………………

نفس المثال مثل من قبل ولكن الآن نستخدم مقاطعة تجاوز الموقت. في هذه الحالة ، يعمل timer1 في الوضع العادي.

يجب أن يتم تحميل الموقت مسبقًا في كل مرة في روتين خدمة المقاطعة.

/*

* Arduino 101: المؤقت والمقاطعات * 2: مثال على تجاوز مؤقت Timer1 * مزيد من بقية المقال: http://www.letmakerobots.com/node/28278 * تم إنشاؤه بواسطة RobotFreak * /

#define ledPin 13

إعداد باطل () = (1 << TOIE1) ؛ // enable timer overflow interruptts interruptts ()؛ / / تمكين جميع المقاطعات

روتين خدمة المقاطعة ISR (TIMER1_OVF_vect) // الذي يلتف دالة معرفة من قبل المستخدم يتم توفيرها بواسطة attachInterrupt {TCNT1 = 34286؛ // preload timer digitalWrite (ledPin، digitalRead (ledPin) ^ 1)؛ }

حلقة باطلة () {// برنامجك هنا …}

الخطوة 6: وميض LED مع ملاحظات تجاوز سعة الموقت

أولا أنشأنا الموقت ، وهناك سجلات رئيسية سيتم استخدامها ،

TCCRx ، لإعداد prescaler.

TCNTx ، لتحميل عداد الموقت

TIMSKx ، لتمكين المقاطعة الموقت الذي تريده.

ثم تكتب رمز ISR المقاطعة ليتم استدعاؤها.

في هذا المثال ، يتم تعيين المحددات على 256. أولاً ، المكالمات البرمجية:

TCCR1A = 0 ؛

TCCR1B = 0 ؛

هل هذا ببساطة مسح السجل presacler.

فأنت مستعد لإعداده. مع هذا الخط:

TCCR1B | = (1 << CS12) ؛

قم بالرجوع إلى الجدول ، إذا قمت بتعيين البت "CS12" على 1 والباقي يساوي 0 ، فسيتم تعيين المحدد على 256.

هنا يجب أن تلاحظ:

  • بهذه الطريقة ، تم تعيين المحددات على قيمة ، أنت تشير إلى الجدول إلى تكوين CS12،11،10 ، وقمت بإعداده.
  • يمكن ملء السجل بالقيم بطريقتين:

    * بإعطائها قيمة مباشرة مثل: "TCCR1A = 0؛" بهذه الطريقة ، يجب عليك معرفة رقم بت التسجيل ومعرفة الطريقة التي تريد تعبئتها ثم تحويل البتات إلى عشري أو HEX ثم تعيينه على السجل.

    * الطريقة الأخرى هي ملء جزء واحد في وقت واحد. ويمكن القيام بذلك مع الرياضيات bitwise.

    لقراءة حول الرياضيات bitwise: عملية Bitwise

    لمعرفة bitwise في اردوينو: Bitwise

  • يمكننا القيام بذلك عن طريق القيام بحركة bitwise الرياضية لتغيير الحالة الرقمية للبت إلى 0 أو 1 ، وذلك باستخدام عوامل التشغيل bitwise.
  • المشغل (|) يعني "أو" ، في الرقم الرقمي أي شيء مقارنة بـ "أو" عامل التشغيل مع "1" والنتيجة هي 1 ، لذلك سوف نستخدم هذا لتغيير الحالة الرقمية لبعض الشيء إلى 1. لعنة العملية (| =) يشبه عملية الجمع أو الطرح عندما نقول (x + = 1 كمثال).
  • المشغل (<<) يحول قيمة معينة برقم معين إلى اليسار ، مثل هذا (1 << 5: سيتم نقل القيمة 1 بمقدار 5 بت)
  • وبالتالي فإن العملية TCCR1B | = (1 << CS12) ؛ اضبط بت CS12 في سجل TCCR1B على رقم رقمي 1.
  • إذا كنت تريد مسح بعض الشيء (املأ 0) فإن العملية تتحدى قليلاً ،
  • سنستخدم المشغل وليس | ، إذا استخدمنا (|) ، فإن أي شيء يتم مقارنته بـ "أو" بـ 0 ، لا يتأثر ، ولكن يتم مسح شيء مقارنة بـ "و" مع 0 إلى 0.
  • وبالتالي ستكون العملية: TCCR1B & = (0 << CS12) ؛

الآن نقوم بتحميل التحميل المسبق للوقت إذا أردنا ذلك ، يمنحك مؤقت التحميل المسبق القدرة على التحكم في إرادة الموقت بالتدفق ، لذلك يمكنك التحكم في تكرار ISR.

للتحميل المسبق لتردد ISR الفائض ، نملأ TCNTx reg مباشرة بالقيمة. يتم حساب القيمة باستخدام المعادلة الرياضية:

65536-16MHz / و prescaler / هرتز

للوقت 16 بت ، و:

256-16MHz / و prescaler / هرتز

لمدة 8 بت الموقت.

في هذا المثال ، المحدد هو 256 ، والتردد هو 2Hz. اقسم 16MHz على 256

ثم قسّم النتيجة على التردد. ثم ملء النتيجة في السجل.

آخر شيء فعله هو تمكين مقاطعة تجاوز السعة. أنت الآن جاهز لكتابة ISR لك.

ISR هي نوع خاص من الوظائف يسمى بروتين المقاطعة ، يجب أن يكون اسم مقاطعة المؤقت اسمًا صحيحًا ورقم (x): TIMERx_OVF_vect ، في هذا المثال ، نستخدم المؤقت 1 لذلك TIMER1_OVF_vect.

يجب أن تكون وظيفة ISR قصيرة وبسيطة ، ولا يمكنك استخدام "delay ()" بداخلها ، يمكنك الاتصال بوظيفة أو استخدام أي عضو بالمكتبة تمامًا مثل الوظائف الأخرى ، ولعنة أي شيء ستستخدمه داخلها يجب الإعلان عنه ضمن نطاقه. ومع ذلك ، إذا قمت بالاتصال بوظيفة أو عضو في المكتبة يستخدم التأخير في إجراءها (مثل مكتبة dht11) ، فلن يتم تنفيذ التأخير داخل الوظيفة التي تم الاتصال بها وسيتم استدعاء الوظيفة بدونها ، والنتيجة في أغلب الأحيان لن تكون منطقية (في حالة dht11 ستكون القراءات خاطئة وعشوائية للغاية).

لاحظ أن هناك وظائف "noInterrupts" و "المقاطعات" التي تم استدعاؤها قبل وبعد إجراء إعداد المؤقت ، فقد مات للتو للتأكد من إيقاف تشغيل جميع المقاطعات غير الضرورية ، ثم قام بتمكين جميع المقاطعات التي تم إعدادها.

………..

في المقال الأصلي ، هناك المزيد من exmple يمكنك العودة إليها وقراءتها.

في الخطوات التالية ، سأقدم المزيد من الأمثلة التي صنعتها لنفسي والتي يمكن أن تساعدك على تحسين الترميز ، فهي تشبه بعض الطرق والحيل التي يمكنك استخدامها مع أجهزة ضبط الوقت لتحسين الترميز والمشاريع.

الخطوة 7: ثواني العداد

في بعض المشاريع ، قد ترغب في إنشاء عداد يقوم بحساب الوقت من بداية الحدث. الثواني من بداية البرنامج على سبيل المثال. من لعنة هناك (millis ()) وظيفة في لغة اردوينو التي تحصل على الوقت im ms من بداية المشروع ، ولكن في بعض الأحيان لا يمكننا استخدامه في إجراءاتنا وفي بعض الأحيان يكون من الصعب استخدامها بالطريقة الصحيحة. هذه طريقة بديلة لحساب الثواني من بداية البرنامج أو أي حدث.

في الواقع ، سوف تكون قادرًا على حساب أي معدل للوقت وليس فقط للثواني ، فقط من خلال معالجة معلمات الكود بالطريقة الصحيحة ، سأستخدم الثواني كمثال.

في هذا المثال ، سأستخدم timer1 (16 بت) لإنشاء مقاطعة بتردد 1Hz (مدة ثانية واحدة). في ISR سيكون هناك متغير عداد عالمي ، سيتم استخدامه لحساب الثواني في ISR ثم استخدامه في الكود الرئيسي.

الإجراء بسيط ، وحساب مؤقت التحميل المسبق بسيط للغاية.

int secondCounter = 0 ؛

إعداد باطل () = (1 << TOIE1) ؛ // enable timer overflow interruptts interruptts ()؛ // enable all interrupts // ***** ISR (TIMER1_OVF_vect) // روتين خدمة المقاطعة الذي يلتف دالة معرّفة من قِبَل المستخدم تم توفيرها بواسطة attachInterrupt {TCNT1 = 3036؛ // preload timer secondCounter ++؛ } حلقة فارغة() { }

الخطوة 8: العداد الثاني

سأعرض هنا بعض استخدامات العداد الثاني بواسطة جهاز ضبط الوقت.

  • أحد الاستخدامات هو تشغيل رمز آخر في الخلفية يحتاج إلى استدعاء بتردد معين.

    يمكنك فقط إضافة وظائفك في ISR ، مثال على ذلك هو وميض مؤشر LED ، أو يمكنك استخدام وظيفة Serial.println لطباعة الثواني من بداية الكود كوظيفة خلفية.

  • باستخدام هذا العداد ، يمكنك إجراء إجراء يجعل أكوادك تكررها بنفسك لمدة محددة.

    انظر الكود التالي ، يرجى قراءة الملاحظات بعناية.

int secondCounter = 0 ؛ مدة int = 5 ؛ // يمكنك ضبط أي مدة تريدها. // لعنة أنه من المنطقي تعيين مدة أكبر من "الكود" الخاص بك ، وإلا فلن تعمل هذه الطريقة كما ينبغي لإلغاء الإعداد () = (1 << TOIE1) ؛ // enable timer overflow interruptts interruptts ()؛ // enable all interrupts // ***** ISR (TIMER1_OVF_vect) // روتين خدمة المقاطعة الذي يلتف دالة معرّفة من قِبَل المستخدم تم توفيرها بواسطة attachInterrupt {TCNT1 = 3036؛ // preload timer secondCounter ++؛ if (secondCounter == المدة) {secondCounter = 0؛ } // ليست الطريقة الوحيدة للقيام بذلك ، يمكنك استخدام عامل التشغيل٪ (mod) والسماح بزيادة عداد الوقت بشكل طبيعي ، مع الوضع يمكنك تنفيذ الشرط (secondCounter٪ المدة == 0)} حلقة باطلة () { إذا كان (secondCounter == 0) // في كل مرة يصل العداد إلى المدة (5) ، فإنه يعود إلى 0 وتكون الحالة صحيحة. { //الشفرة } }

  • يمكنك استخدامه لإجراء إجراء من التعليمات البرمجية ، مما يجعل مشروعك يعمل خلال مدة محددة من بدء تشغيل الرمز ، أو من بعض الأحداث. على سبيل المثال ، يمكنك عمل رمز لإضاءة المنزل في الليل وإيقاف تشغيله في النهار ، لتمثيل الوقت في اليوم بالثواني ، ويمكنك إيقاف تشغيل الضوء من الثانية من الثانية (6 صباحًا) إلى الثانية عشرة (6 مساءً) ، وكرر الإجراء. انظر الكود التالي:

int secondCounter = 0 ؛

مدة int = 24 ؛ // يمكنك ضبط أي مدة تريدها. int time1 = 6 ؛ int time2 = 18 ؛ علم منطقي 1 = 0 ؛ علم منطقي 2 = 0 ؛ كثافة العمليات الخفيفة = 13 ؛ إعداد باطل () = (1 << CS10) ؛ // 1024 prescaler TIMSK1 ISR (TIMER1_OVF_vect) // روتين خدمة المقاطعة الذي يلتف دالة معرفة بواسطة المستخدم يتم توفيرها بواسطة attachInterrupt {TCNT1 = 3036؛ // preload timer secondCounter ++؛ إذا كان (secondCounter == المدة) // عندما ينتهي اليوم ، فابدأ من عداد الموقت من الصفر. {secondCounter = 0؛ } if (secondCounter> = time1 && secondCounter <= time2) // day time {flag1 = 1؛ / / تنشيط حالة المهمة 1 (وقت اليوم) flag2 = 0 ؛ } else // night time {flag1 = 0؛ علم 2 = 1 ؛ / / تنشيط حالة المهمة 2 (وقت الليل)}} حلقة باطلة () {// flag1 ، وسيتم تغيير 2 في الخلفية ، عندما يتم تعيين علامة true / 1 يتم تشغيل (بينما). بينما (flag1) // day time - أطفئ الأنوار {digitalWrite (lightPin، 0)؛ } بينما (flag2) // وقت الليل - قم بتشغيل الأنوار {digitalWrite (lightPin، 1)؛ }}

الخطوة 9: إعداد 8 بت الموقت.

قيمة الحد الأقصى للوقت 8 بت هي 255 (0-255) ، ولا يمكنك تجاوز هذه القيمة ، وإذا قمت بذلك ، فسيقوم السجل بإجراء تجاوز سعة (إذا أعطيته قيمة تساوي 256 على سبيل المثال ، فسوف يتجاوز التدفق والقيمة الفعلية القيمة داخله ستكون 0)

للتعامل مع هذه القيمة الصغيرة ، علينا أن نستخدم الوصفات الطبية المناسبة والتردد ، واستخدام خدعة صغيرة!

الحد الأقصى لوصف الواصف الذي يمكن استخدامه هو 1024 ، إذا كان التكرار مرتفعًا بما يكفي لجعل النتيجة <255 ، فلا بأس ، ولكن ماذا لو أردنا تحقيق تردد صغير! لدينا لزيادة prescaler لدينا. الشيء الذي يمكننا القيام به لزيادة هذه القيمة ، هو زيادتها يدويًا!

في ISR ، يمكنك إضافة عداد فرعي ، عندما تصل العداد إلى بعض القيمة ، تزداد العداد الرئيسي. انظر المثال التالي.

int secondCounter = 0 ؛

int timerCounter = 0 ؛ مدة int = 24 ؛ // يمكنك ضبط أي مدة تريدها. int time1 = 6 ؛ int time2 = 18 ؛ علم منطقي 1 = 0 ؛ علم منطقي 2 = 0 ؛ كثافة العمليات الخفيفة = 13 ؛ إعداد باطل () = (1 << CS10) ؛ // 1024 prescaler TIMSK2 ISR (TIMER2_OVF_vect) // روتين خدمة المقاطعة الذي يلتف دالة معرفة من قبل المستخدم يتم توفيرها بواسطة attachInterrupt {TCNT2 = 101؛ // preload timer timerCounter ++؛ إذا كان (timerCounter == 1000) // لكل 1000 حساب مؤقت يوفر زيادة ثانية واحدة.. {secondCounter ++؛ timerCounter = 0 ؛ Serial.println (secondCounter) ؛ // لإظهار الوقت على الشاشة التسلسلية إذا (secondCounter == 24) {secondCounter = 0؛ } if (secondCounter> = 7 && secondCounter <= 20) // activate system // إذا كنت ترغب في تغيير أوقات التغير 7 و 20. {flag1 = 1 ؛ flag2 = 0 ؛ } else // deactivate system {flag1 = 0؛ علم 2 = 1 ؛ }}} void loop () {// flag1 ، وسيتم تغيير 2 في الخلفية ، عندما يتم تعيين علامة true / 1 يتم تشغيلها (بينما). بينما (flag1) // day time - أطفئ الأنوار {digitalWrite (lightPin، 0)؛ } بينما (flag2) // وقت الليل - قم بتشغيل الأنوار {digitalWrite (lightPin، 1)؛ }}