- ما هي إشارة PWM؟
- برمجة PIC لتوليد PWM على دبابيس GPIO
- مخطط الرسم البياني
- محاكاة
- إعداد الأجهزة للتحكم في محرك سيرفو باستخدام متحكم PIC
يعد توليد إشارة PWM أداة حيوية في كل ترسانة المهندسين المدمجة ، فهي مفيدة جدًا للعديد من التطبيقات مثل التحكم في موضع محرك سيرفو ، وتبديل القليل من الدوائر المتكاملة الإلكترونية في المحولات / العاكسات وحتى للتحكم في سطوع LED البسيط. في الميكروكونترولر PIC يمكن إنشاء إشارات PWM باستخدام وحدات المقارنة والتقاط و PWM (CCP) عن طريق ضبط السجلات المطلوبة ، وقد تعلمنا بالفعل كيفية القيام بذلك في البرنامج التعليمي PIC PWM. لكن هناك عيبًا واحدًا كبيرًا في هذه الطريقة.
و PIC16F877A يمكن أن تولد إشارات PWM فقط على أحر RC1 وRC2، إذا أردنا استخدام وحدات CCP. لكننا قد نواجه مواقف نحتاج فيها إلى المزيد من المسامير للحصول على وظيفة PWM. على سبيل المثال في حالتي ، أريد التحكم في 6 محركات مؤازرة RC لمشروع ذراعي الروبوتية التي لا أمل فيها من وحدة CCP. في هذه السيناريوهات ، يمكننا برمجة دبابيس GPIO لإنتاج إشارات PWM باستخدام وحدات المؤقت. بهذه الطريقة يمكننا توليد أكبر عدد ممكن من إشارات PWM مع أي دبوس مطلوب. هناك أيضًا اختراقات أخرى للأجهزة مثل استخدام IC متعدد الإرسال ، ولكن لماذا تستثمر في الأجهزة بينما يمكن تحقيق الشيء نفسه من خلال البرمجة. لذلك في هذا البرنامج التعليمي سوف نتعلم كيفية تحويل دبوس PIC GPIO إلى دبوس PWM ولاختباره سنقوم بمحاكاته على البروتين باستخدام راسم الذبذبات الرقمي وأيضًاالتحكم في موضع المحرك المؤازر باستخدام إشارة PWM وتغيير دورة العمل من خلال تغيير مقياس الجهد.
ما هي إشارة PWM؟
قبل أن ندخل في التفاصيل ، دعونا نركز قليلاً على ماهية إشارات PWM. يعد تعديل عرض النبض (PWM) إشارة رقمية تستخدم بشكل شائع في دوائر التحكم. تم ضبط هذه الإشارة عالية (5 فولت) ومنخفضة (0 فولت) في وقت وسرعة محددين مسبقًا. يسمى الوقت الذي تظل فيه الإشارة عالية "في الوقت المحدد" والوقت الذي تظل خلاله الإشارة منخفضة يسمى "وقت التوقف". هناك نوعان من المعلمات الهامة لـ PWM كما هو موضح أدناه:
دورة عمل PWM
تسمى النسبة المئوية للوقت الذي تظل فيه إشارة PWM عالية (في الوقت المحدد) كدورة عمل. إذا كانت الإشارة في وضع التشغيل دائمًا ، فهي في دورة عمل بنسبة 100٪ ، وإذا كانت متوقفة عن التشغيل دائمًا ، تكون 0٪ من دورة العمل.
دورة العمل = وقت التشغيل / (وقت التشغيل + وقت الإيقاف)
اسم المتغير |
يعود الى |
PWM_Frequency |
تردد إشارة PWM |
T_TOTAL |
إجمالي الوقت المستغرق لدورة كاملة واحدة من PWM |
T_ON |
في وقت إشارة PWM |
الأنيق |
وقت إيقاف إشارة PWM |
دورة العمل |
دورة عمل إشارة PWM |
والآن ، لنقم بالحسابات.
هذه هي الصيغ القياسية حيث يكون التردد هو ببساطة مقلوب الزمن. يجب على المستخدم تحديد قيمة التردد وتحديدها بناءً على متطلبات التطبيق الخاصة به.
T_TOTAL = (1 / PWM_Frequency)
عندما يغير المستخدم قيمة دورة العمل ، يجب أن يقوم برنامجنا تلقائيًا بضبط وقت T_ON و T_OFF وفقًا لذلك. لذلك يمكن استخدام الصيغ أعلاه لحساب T_ON بناءً على قيمة Duty_Cycle و T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
نظرًا لأن إجمالي وقت إشارة PWM لدورة كاملة واحدة سيكون مجموع الوقت في الوقت المحدد ووقت الراحة. يمكننا حساب وقت الراحة T_OFF كما هو موضح أعلاه.
T_OFF = T_TOTAL - T_ON
مع وضع هذه الصيغ في الاعتبار ، يمكننا البدء في برمجة متحكم PIC. يشتمل البرنامج على PIC Timer Module و PIC ADC Module لإنشاء إشارة PWM على أساس دورة عمل متغيرة وفقًا لقيمة ADC من POT. إذا كنت جديدًا في استخدام هذه الوحدات ، فمن المستحسن بشدة قراءة البرنامج التعليمي المناسب من خلال النقر على الارتباطات التشعبية.
برمجة PIC لتوليد PWM على دبابيس GPIO
و برنامج كامل ويمكن الاطلاع على هذا البرنامج التعليمي في الجزء السفلي من موقع مثل دائما. في هذا القسم ، دعونا نفهم كيف تمت كتابة البرنامج بالفعل. مثل كل البرامج ، نبدأ بإعداد بتات التكوين. لقد استخدمت خيار طرق عرض الذاكرة لتعيينها لي.
// CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS مذبذب) #pragma config WDTE = OFF // Watchdog Timer تمكين بت (WDT معطل) #pragma config PWRTE = OFF // Power-up Timer تمكين بت (PWRT معطل) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR ممكّن) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circial Programming Enable bit (RB3 هو إدخال / إخراج رقمي ، يجب استخدام HV على MCLR للبرمجة) #pragma config CPD = إيقاف // بت حماية رمز ذاكرة EEPROM للبيانات (إيقاف حماية رمز EEPROM للبيانات) #pragma config WRT = إيقاف // Flash Program Memory Write Enable bits (Write protection off؛ يمكن كتابة كل ذاكرة البرنامج بواسطة EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection Bit (Code Protection off) // #pragma config يجب أن تسبق عبارات التكوين ملف المشروع. // استخدم تعداد المشروع بدلاً من #define لـ ON و OFF. #تضمن
ثم نذكر تردد الساعة المستخدم في الأجهزة ، وهنا يستخدم أجهزتي بلورة 20 ميجا هرتز ، يمكنك إدخال القيمة على أساس أجهزتك. تليها قيمة تردد إشارة PWM. منذ هدفي هنا هو التحكم في هواية محرك مؤازر RC الذي يتطلب تردد PWM يبلغ 50 هرتز ، قمت بتعيين 0.05 كيلو هرتز كقيمة التردد ، يمكنك أيضًا تغيير ذلك بناءً على متطلبات التطبيق الخاص بك.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0.05 // in KHz (50Hz)
الآن ، بعد أن أصبح لدينا قيمة التردد ، يمكننا حساب T_TOTAL باستخدام الصيغ التي تمت مناقشتها أعلاه. تنخفض النتيجة بمقدار 10 للحصول على قيمة الوقت بالمللي ثانية. في حالتي ، ستكون قيمة T_TOTAL 2 ملي ثانية.
int T_TOTAL = (1 / PWM_Frequency) / 10 ؛ // حساب إجمالي الوقت من التردد (بالمللي ثانية)) // 2 مللي ثانية
بعد ذلك ، نقوم بتهيئة وحدات ADC لقراءة موضع مقياس الجهد كما تمت مناقشته في البرنامج التعليمي ADC PIC الخاص بنا. بعد ذلك ، لدينا روتين خدمة المقاطعة الذي سيتم استدعاؤه في كل مرة ، وسنعود إلى هذا الموقت لاحقًا ، والآن دعنا نتحقق من الوظيفة الرئيسية.
داخل الوظيفة الرئيسية نقوم بتكوين وحدة المؤقت. هنا قمت بتكوين وحدة Timer لتجاوز كل 0.1 مللي ثانية. يمكن حساب قيمة الوقت باستخدام الصيغ أدناه
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) تأخير بالثانية و Fosc بالهرتز
في حالتي بالنسبة لتأخير 0.0001 ثانية (0.1 مللي ثانية) مع تقويم مسبق لـ 64 و Fosc لـ 20 ميجا هرتز ، يجب أن تكون قيمة السجل (TMR0) 248. لذا يبدو التكوين هكذا
/ ***** تكوين المنفذ لـ Timer ****** / OPTION_REG = 0b00000101 ؛ // Timer0 مع التكرار الخارجي و 64 كمقياس مسبق // يتيح أيضًا PULL UPs TMR0 = 248 ؛ // تحميل القيمة الزمنية لـ 0.0001 ثانية ؛ يمكن أن يكون delayValue بين 0-256 فقط TMR0IE = 1؛ // تمكين بت المقاطعة المؤقت في سجل PIE1 GIE = 1 ؛ // Enable Global Interrupt PEIE = 1 ؛ // تمكين المقاطعة الطرفية / *********** ______ *********** /
ثم يتعين علينا ضبط تكوين الإدخال والإخراج. نحن هنا نستخدم دبوس AN0 لقراءة قيمة ADC ودبابيس PORTD لإخراج إشارات PWM. لذا قم ببدء تشغيلها كدبابيس إخراج وجعلها منخفضة باستخدام أسطر التعليمات البرمجية أدناه.
/ ***** تكوين المنفذ لـ I / O ****** / TRISD = 0x00 ؛ // إرشاد MCU إلى أن جميع المسامير الموجودة على المنفذ D هي إخراج PORTD = 0x00 ؛ // تهيئة جميع المسامير إلى 0 / *********** ______ *********** /
داخل حلقة while اللانهائية ، يتعين علينا حساب قيمة الوقت المحدد (T_ON) من دورة العمل. و في الوقت المحدد و اجب تختلف دورة على أساس الموقف من POT لذلك نحن نفعل ذلك مرارا وتكرارا داخل في حين حلقة كما هو مبين أدناه. 0.0976 هي القيمة التي يجب ضربها في 1024 للحصول على 100 ولحساب T_ON قمنا بضربها في 10 للحصول على القيمة بالمللي ثانية.
بينما (1) { POT_val = (ADC_Read (0)) ؛ // اقرأ قيمة POT باستخدام ADC Duty_cycle = (POT_val * 0.0976) ؛ // الخريطة من 0 إلى 1024 إلى 0 إلى 100 T_ON = ((دورة العمل * T_TOTAL) * 10/100) ؛ // حساب الوقت باستخدام وحدة الصيغ بالمللي ثانية __delay_ms (100) ؛ }
نظرًا لأنه تم ضبط المؤقت على التدفق الزائد لكل 0.1 مللي ثانية ، فسيتم استدعاء روتين خدمة المقاطعة ISR لكل 0.1 مللي ثانية. داخل روتين الخدمة ، نستخدم متغيرًا يسمى count ونزيده لكل 0.1 مللي ثانية. بهذه الطريقة يمكننا تتبع الوقت. لمعرفة المزيد حول المقاطعات في الميكروكونترولر PIC ، اتبع الروابط
if (TMR0IF == 1) // تم تشغيل علامة Timer بسبب تجاوز سعة المؤقت -> تم ضبطه على تجاوز كل 0.1 مللي ثانية { TMR0 = 248 ؛ // قم بتحميل قيمة المؤقت TMR0IF = 0 ؛ // مسح عداد إشارة مقاطعة العد ++ ؛ // عدد الزيادات لكل 0.1 مللي ثانية -> count / 10 ستعطي قيمة العدد بالمللي ثانية }
أخيرًا ، حان الوقت لتبديل دبوس GPIO بناءً على قيمة T_ON و T_OFF. لدينا متغير العد الذي يتتبع الوقت بالمللي ثانية. لذلك نستخدم هذا المتغير للتحقق مما إذا كان الوقت أقل من الوقت المحدد ، وإذا كانت الإجابة بنعم ، فإننا نبقي دبوس GPIO قيد التشغيل وإلا نقوم بإيقاف تشغيله وإيقاف تشغيله حتى تبدأ الدورة الجديدة. يمكن القيام بذلك عن طريق مقارنته بالوقت الإجمالي لدورة PWM واحدة. يظهر رمز القيام بالشيء نفسه أدناه
if (count <= (T_ON)) // إذا كان الوقت أقل من الوقت المحدد RD1 = 1 ؛ // قم بتشغيل GPIO else RD1 = 0 ؛ // Else Turn off GPIO if (count> = (T_TOTAL * 10)) // احتفظ به مغلقًا حتى تبدأ دورة جديدة بالعد = 0 ؛
مخطط الرسم البياني
مخطط الدائرة لتوليد PWM مع دبوس GPIO الخاص بالمتحكم الدقيق PIC بسيط حقًا ، فقط قم بتشغيل PIC باستخدام مذبذب وقم بتوصيل مقياس الجهد بدبوس AN0 ومحرك مؤازر بالدبوس RD1 ، يمكننا استخدام دبوس GPIO للحصول على إشارة PWM ، لقد اخترت RD1 خارج عشوائي. يتم تشغيل كل من مقياس الجهد والمحرك المؤازر بواسطة 5 فولت والتي يتم تنظيمها من 7805 كما هو موضح أدناه في مخطط الدائرة
محاكاة
لمحاكاة المشروع ، استخدمت برنامج البروتيوس الخاص بي. قم ببناء الدائرة الموضحة أدناه واربط الكود بالمحاكاة وقم بتشغيلها. يجب أن تحصل على إشارة PWM على دبوس RD1 GPIO وفقًا لبرنامجنا ويجب التحكم في دورة عمل PWM بناءً على موضع مقياس الجهد. يوضح GIF أدناه كيف تستجيب إشارة PWM ومحرك سيرفو عندما يتم تغيير قيمة ADC من خلال مقياس الجهد.
إعداد الأجهزة للتحكم في محرك سيرفو باستخدام متحكم PIC
يتم عرض إعداد الأجهزة الكامل الخاص بي أدناه ، بالنسبة للأشخاص الذين يتابعون دروسي التعليمية ، يجب أن تبدو هذه اللوحة مألوفة لهم ، وهي نفس اللوحة التي استخدمتها في جميع دروسي التعليمية حتى الآن. يمكنك الرجوع إلى البرنامج التعليمي Blinking LED إذا كنت مهتمًا بمعرفة كيفية بنائه. بخلاف ذلك ، ما عليك سوى اتباع مخطط الدائرة أعلاه ويجب أن يعمل الجميع بشكل جيد.
قم بتحميل البرنامج وقم بتغيير مقياس الجهد وسترى المؤازرة وهي تغير الموضع بناءً على موضع مقياس الجهد. يظهر العمل الكامل للمشروع في الفيديو المقدم في نهاية هذه الصفحة. آمل أن تكون قد فهمت المشروع واستمتعت بالبناء ، إذا كانت لديك استفسارات ، فلا تتردد في نشرها على المنتدى وسأبذل قصارى جهدي في الرد.
أخطط للمضي قدمًا في هذا المشروع من خلال إضافة خيارات للتحكم في محركات مؤازرة متعددة وبالتالي بناء ذراع آلية منه ، على غرار ذراع Arduino Robotic Arm الذي قمنا ببنائه بالفعل. حتى ذلك الحين أراكم !!