ما هو الميكروكونترولر Microcontroller ؟
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 5
صفحة 1 من اصل 5 • 1, 2, 3, 4, 5
ما هو الميكروكونترولر Microcontroller ؟
ما هو الميكروكونترولر Microcontroller ؟
الميكروكونترولر هو كمبيوتر صغير مدمج فى شكل دائرة متكاملة (شريحة) واحدة ، فهو يحتوى بداخلة ، فى الأساس ، على وحدة معالجة مركزية CPU وذاكرات ( ذاكرة البرنامج من نوع الفلاش Flash ، وذاكرة البيانات من نوع RAM ، وذاكرة البيانات الثابتة من نوع EEPROM ) ، ووحدات (منافذ) الدخل / الخرج I/O Ports بالإضافة إلى العديد من الوحدات الأخرى كما هو موضح بالشكل التالى :
وحدة المعالجة المركزية هى قلب الميكروكونترولر ، وهى الجزء الخاص بتنفيذ التعليمات من برنامج المستخدم .
ذاكرة البرنامج الفلاش Flash هى المكان الذى يتم فيه حفظ البرنامج ، وذاكرة البيانات RAM هى مواقع حفظ البيانات المتغيرة أثناء تشغيل البرنامج ، كل موقع من مواقع هذه الذاكرة مكون من بايت واحد ( البايت مكون من 8 بتات bit0-bit7 ) ، هذه المواقع تسمى "السجلات Registers وهى مقسمة إلى جزأين : "سجلات الوظائف الخاصة" SFR ، وسجلات الوظائف العامة GPR . كل سجل من سجلات الوظائف الخاصة يقوم بوظيفة محددة ، فعلى سبيل المثال "سجلات التحكم فى اتجاه منافذ الدخل / الخرج" وتسمى TRISx ، كل منفذ له سجل تحكم خاص به ( TRISAالسجل للمنفذ PORTA والسجل TRISB للمنفذ PORTB وهكذا) . كل سجل TRIS مكون من 8 بتات وكل بت تتحكم فى اتجاه طرف منفذ دخل/خرج ، فعندما تكون بت السجل TRIS بواحد “1” فإن ذلك يجعل طرف المنفذ المناظر يعمل كدخل Input (لاحظ الحرف “I” وقيمة الواحد “1” )، وعندما تكون بت السجل TRIS بصفر “0” فإن ذلك سوف يجعل طرف المنفذ المناظر يعمل كخرج Output ( لاحظ الحرف “O” وقيمة الصفر “0” ) .
ذاكرة البيانات الثابتة من النوع EEPROM تحتفظ بالبيانات التى بداخلها حتى مع غياب القدرة الكهربية عن الميكروكونترولر على خلاف البيانات التى يتم حفظها فى ذاكرة RAM فإنه يتم محوها (فقدها) بمجرد غياب القدرة أو حتى إعادة تشغيل الميكروكونترولر .
وحدات الدخل/الخرج هى وسيلة الربط Interface بين العالم الخارجى وداخل الميكروكونترولر . وحدات أو منافذ الدخل / الخرج يمكن أن تستقبل بيانات (مداخل) ، أو ترسل بيانات (مخارج ) أو تقوم بوظيفة خاصة تبعا لسجلات التحكم الموجودة بذاكرة RAM .
برنامج الميكروكونترولر هو مجموعة من التعليمات التى يتم تنفيذها عن طريق وحدة المعالجة المركزية . لغة البرمجة التى سوف نستخدمها هى لغة السى مع المترجم ميكروسى برو والتى سوف نتناولها لاحقا .
بعد كتابة البرنامج وترجمته نحصل على ملف بالامتداد "هكس" (.hex) وهو الذى يتم تحميله داخل ذاكرة البرنامج للميكروكونترولر عن طريق جهاز برمجة خاص بذلك .
الميكروكونترولر هو كمبيوتر صغير مدمج فى شكل دائرة متكاملة (شريحة) واحدة ، فهو يحتوى بداخلة ، فى الأساس ، على وحدة معالجة مركزية CPU وذاكرات ( ذاكرة البرنامج من نوع الفلاش Flash ، وذاكرة البيانات من نوع RAM ، وذاكرة البيانات الثابتة من نوع EEPROM ) ، ووحدات (منافذ) الدخل / الخرج I/O Ports بالإضافة إلى العديد من الوحدات الأخرى كما هو موضح بالشكل التالى :
وحدة المعالجة المركزية هى قلب الميكروكونترولر ، وهى الجزء الخاص بتنفيذ التعليمات من برنامج المستخدم .
ذاكرة البرنامج الفلاش Flash هى المكان الذى يتم فيه حفظ البرنامج ، وذاكرة البيانات RAM هى مواقع حفظ البيانات المتغيرة أثناء تشغيل البرنامج ، كل موقع من مواقع هذه الذاكرة مكون من بايت واحد ( البايت مكون من 8 بتات bit0-bit7 ) ، هذه المواقع تسمى "السجلات Registers وهى مقسمة إلى جزأين : "سجلات الوظائف الخاصة" SFR ، وسجلات الوظائف العامة GPR . كل سجل من سجلات الوظائف الخاصة يقوم بوظيفة محددة ، فعلى سبيل المثال "سجلات التحكم فى اتجاه منافذ الدخل / الخرج" وتسمى TRISx ، كل منفذ له سجل تحكم خاص به ( TRISAالسجل للمنفذ PORTA والسجل TRISB للمنفذ PORTB وهكذا) . كل سجل TRIS مكون من 8 بتات وكل بت تتحكم فى اتجاه طرف منفذ دخل/خرج ، فعندما تكون بت السجل TRIS بواحد “1” فإن ذلك يجعل طرف المنفذ المناظر يعمل كدخل Input (لاحظ الحرف “I” وقيمة الواحد “1” )، وعندما تكون بت السجل TRIS بصفر “0” فإن ذلك سوف يجعل طرف المنفذ المناظر يعمل كخرج Output ( لاحظ الحرف “O” وقيمة الصفر “0” ) .
ذاكرة البيانات الثابتة من النوع EEPROM تحتفظ بالبيانات التى بداخلها حتى مع غياب القدرة الكهربية عن الميكروكونترولر على خلاف البيانات التى يتم حفظها فى ذاكرة RAM فإنه يتم محوها (فقدها) بمجرد غياب القدرة أو حتى إعادة تشغيل الميكروكونترولر .
وحدات الدخل/الخرج هى وسيلة الربط Interface بين العالم الخارجى وداخل الميكروكونترولر . وحدات أو منافذ الدخل / الخرج يمكن أن تستقبل بيانات (مداخل) ، أو ترسل بيانات (مخارج ) أو تقوم بوظيفة خاصة تبعا لسجلات التحكم الموجودة بذاكرة RAM .
برنامج الميكروكونترولر هو مجموعة من التعليمات التى يتم تنفيذها عن طريق وحدة المعالجة المركزية . لغة البرمجة التى سوف نستخدمها هى لغة السى مع المترجم ميكروسى برو والتى سوف نتناولها لاحقا .
بعد كتابة البرنامج وترجمته نحصل على ملف بالامتداد "هكس" (.hex) وهو الذى يتم تحميله داخل ذاكرة البرنامج للميكروكونترولر عن طريق جهاز برمجة خاص بذلك .
رد: ما هو الميكروكونترولر Microcontroller ؟
السجلات Register :
السجلات هى مكان داخل الميكروكونترولر PIC (الكومبيوتر) والتى تستخدم فى الكتابة إليها أو القراءة منها أو الاثنين معا . يمكنك أن تفكر فى السجل كقطعة من الورق حيث يمكنك قراءة ما بها والكتابة عليها .
تقسم ذاكرة الميكروكونترولر PIC إلى تتابع من السجلات . كل سجل لع عنوانه الذى يحدد موقعه . يمكن تصنيف السجلات فى الميكروكونترولر PIC ، تبعا لنوع العمل والاستخدام إلى فئتين :
سجلات الأغراض العامة General Purpose Registers (GPR) :
سجلات الأغراض العامة هى جزء صغير من ذاكرة RAM والتى يمكن الوصول إليها بشكل أسرع من باقى الذاكرة . الشكل التالى يبين خريطة السجلات للميكروكونترولر PIC16F877A وفيها تظهر سجلات الأغراض العامة .
سجلات الوظائف الخاصة Special Function Registers (SFR) :
سجلات الوظائف الخاصة هى أيضا سجلات ذاكرة RAM . والتى تستخدم لوظائف خاصة محددة . هذه السجلات تقوم بتنفيذ وظائف محددة داخل شريحة الميكروكونترولر PIC . فكل وظيفة خاصة داخل الميكروكونترولر يتم التحكم فيها عن طريق هذه السجلات . من ضمن هذه السجلات سجلات المنافذ PORT وسجلات التحكم فى اتجاه المنافذ TRIS وغيرها .
لا تنزعج ، فذلك للتوضيح فقط وللتعرف على قطعة داخل الميكروكونترولر PIC ، وسوف نتناول الكثير منها لاحقا .
السجلات هى مكان داخل الميكروكونترولر PIC (الكومبيوتر) والتى تستخدم فى الكتابة إليها أو القراءة منها أو الاثنين معا . يمكنك أن تفكر فى السجل كقطعة من الورق حيث يمكنك قراءة ما بها والكتابة عليها .
تقسم ذاكرة الميكروكونترولر PIC إلى تتابع من السجلات . كل سجل لع عنوانه الذى يحدد موقعه . يمكن تصنيف السجلات فى الميكروكونترولر PIC ، تبعا لنوع العمل والاستخدام إلى فئتين :
سجلات الأغراض العامة General Purpose Registers (GPR) :
سجلات الأغراض العامة هى جزء صغير من ذاكرة RAM والتى يمكن الوصول إليها بشكل أسرع من باقى الذاكرة . الشكل التالى يبين خريطة السجلات للميكروكونترولر PIC16F877A وفيها تظهر سجلات الأغراض العامة .
سجلات الوظائف الخاصة Special Function Registers (SFR) :
سجلات الوظائف الخاصة هى أيضا سجلات ذاكرة RAM . والتى تستخدم لوظائف خاصة محددة . هذه السجلات تقوم بتنفيذ وظائف محددة داخل شريحة الميكروكونترولر PIC . فكل وظيفة خاصة داخل الميكروكونترولر يتم التحكم فيها عن طريق هذه السجلات . من ضمن هذه السجلات سجلات المنافذ PORT وسجلات التحكم فى اتجاه المنافذ TRIS وغيرها .
لا تنزعج ، فذلك للتوضيح فقط وللتعرف على قطعة داخل الميكروكونترولر PIC ، وسوف نتناول الكثير منها لاحقا .
رد: ما هو الميكروكونترولر Microcontroller ؟
برنامجك الأول مع الميكروكونترولر PIC والمترجم ميكروسى برو :
مرحبا بك فى عالم الميكروكونترولر PIC . إذا كنت مبتدىء فى مجال الميكروكونترولر وترغب فى خوض غمار هذا المجال فأنت فى المكان الصحيح . المترجم ميكروسى MikroC هو أفضل مترجم للمبتدئين لأنه يحتوى على دوال (وظائف) functions من أجل معظم المهام الشائعة الاستخدام .
سوف تحتاج إلى برنامج المترجم ميكروسى برو لتحرير وترجمة البرنامج والحصول على الملف HEX ، وبرنامج بروتيس Proteus لرسم الدائرة الكهربية وتحميل الملف HEX بغرض إجراء محاكاة البرنامج .
البداية مع المترجم ميكروسى برو MikroC Pro :
يمكنك تحميل الإصدار المجانى من المترجم ميكروسى برو من موقع mikroElectronika ، هذا الإصدار محدود ببرنامج حتى 2k وهى كافية لمعظم التطبيقات التى سوف نقوم بالعمل عليها .
• قم بتنزيل وتثبيت برنامج المترجم ميكروسى برو .
• قم بإنشاء مجلد لهذا المشروع فى أى مسار لمكان على الكمبيوتر ترغب فى حفظ أعمالك عليه .
• قم بفتح (تشغيل برنامج الميكروسى برو تظهر لك نافذة الترحيب التالية :
• انقر على أيقونة New Project أو من القائمة Project اختار New Project ، تظهر لك نافذة معالج المشروع الجديد كما يلى :
• انقر على "التالى" Next ، تظهر لك نافذة لأول خطوة وهى إعدادات البرنامج كما يلى :
• الخطوة الأولى : أدخل اسم المشروع ، ومسار المجلد الذى تم إنشاؤه سابقا (يمكنك إنشاؤه حاليا) ، والميكروكونترولر المستخدم ، وتردد الساعة ثم انقر Next . تردد الساعة هو تردد المذبذب المستخدم مع الميكروكونترولر . هنا سوف نستخدم الميكروكونترولر PIC16F877A مع كريستال بتردد 4MHz .
• الخطوة الثانية : هنا يمكنك إضافة إى ملفات لبرامج فرعية أو ملفات رأس معرفة بمعرفة المستخدم وذلك فى المشاريع الكبيرة . وحيث أننا نتعامل مع مشروع بسيط لوميض ليد ، يمكنك إغفال هذه الخطوة وانقر Next .
• الخطوة الثالثة : هنا يمكنك إضافة (ضم) المكتبات المدمجة فى المترجم ميكروسى مثل UART, PWM, LCD etc ، يمكنك ضم جميع المكتبات (الوضع الافتراضى وهو الذى سوف نعمل عليه ) أو عدم ضم أى مكتبة على أن يتم ضم المكتبة المحددة المطلوبة فى وقت لاحق . بعد ذلك انقر Next .
• الخطوة الرابعة : انقر Finish لإنهاء معالج المشروع الجديد .
• عندئذ سوف ترى "المحرر" editor ، حيث يمكنك إدخال كود لغة السى .
المترجم يقدم لك المحرر ومكتوب فيه بالفعل الجزء الأساسى لأى برنامج مكتوب بلغة السى ، والذى يسمى بالدالة الرئيسية main ، حيث يبدأ البرنامج الفعلى . لاحظ أن الدالة الرئيسية مكون من اسم الدالة main وقوس بداية تعليمات جسم الدالة وقوس نهاية تعليمات جسم الدالة :
void main() {
{
إذا قمت بترجمة هذا الجزء فسوف يقوم المترجم بترجمته بنجاح ، لكن هذا الجزء لا يجعل الميكروكونترولر يقوم بفعل شىء ما .
وظيفة الدالة الرئيسية هى إخبار المترجم بمكان بداية ترجمة تعليمات البرنامج .
مرحبا بك فى عالم الميكروكونترولر PIC . إذا كنت مبتدىء فى مجال الميكروكونترولر وترغب فى خوض غمار هذا المجال فأنت فى المكان الصحيح . المترجم ميكروسى MikroC هو أفضل مترجم للمبتدئين لأنه يحتوى على دوال (وظائف) functions من أجل معظم المهام الشائعة الاستخدام .
سوف تحتاج إلى برنامج المترجم ميكروسى برو لتحرير وترجمة البرنامج والحصول على الملف HEX ، وبرنامج بروتيس Proteus لرسم الدائرة الكهربية وتحميل الملف HEX بغرض إجراء محاكاة البرنامج .
البداية مع المترجم ميكروسى برو MikroC Pro :
يمكنك تحميل الإصدار المجانى من المترجم ميكروسى برو من موقع mikroElectronika ، هذا الإصدار محدود ببرنامج حتى 2k وهى كافية لمعظم التطبيقات التى سوف نقوم بالعمل عليها .
• قم بتنزيل وتثبيت برنامج المترجم ميكروسى برو .
• قم بإنشاء مجلد لهذا المشروع فى أى مسار لمكان على الكمبيوتر ترغب فى حفظ أعمالك عليه .
• قم بفتح (تشغيل برنامج الميكروسى برو تظهر لك نافذة الترحيب التالية :
• انقر على أيقونة New Project أو من القائمة Project اختار New Project ، تظهر لك نافذة معالج المشروع الجديد كما يلى :
• انقر على "التالى" Next ، تظهر لك نافذة لأول خطوة وهى إعدادات البرنامج كما يلى :
• الخطوة الأولى : أدخل اسم المشروع ، ومسار المجلد الذى تم إنشاؤه سابقا (يمكنك إنشاؤه حاليا) ، والميكروكونترولر المستخدم ، وتردد الساعة ثم انقر Next . تردد الساعة هو تردد المذبذب المستخدم مع الميكروكونترولر . هنا سوف نستخدم الميكروكونترولر PIC16F877A مع كريستال بتردد 4MHz .
• الخطوة الثانية : هنا يمكنك إضافة إى ملفات لبرامج فرعية أو ملفات رأس معرفة بمعرفة المستخدم وذلك فى المشاريع الكبيرة . وحيث أننا نتعامل مع مشروع بسيط لوميض ليد ، يمكنك إغفال هذه الخطوة وانقر Next .
• الخطوة الثالثة : هنا يمكنك إضافة (ضم) المكتبات المدمجة فى المترجم ميكروسى مثل UART, PWM, LCD etc ، يمكنك ضم جميع المكتبات (الوضع الافتراضى وهو الذى سوف نعمل عليه ) أو عدم ضم أى مكتبة على أن يتم ضم المكتبة المحددة المطلوبة فى وقت لاحق . بعد ذلك انقر Next .
• الخطوة الرابعة : انقر Finish لإنهاء معالج المشروع الجديد .
• عندئذ سوف ترى "المحرر" editor ، حيث يمكنك إدخال كود لغة السى .
المترجم يقدم لك المحرر ومكتوب فيه بالفعل الجزء الأساسى لأى برنامج مكتوب بلغة السى ، والذى يسمى بالدالة الرئيسية main ، حيث يبدأ البرنامج الفعلى . لاحظ أن الدالة الرئيسية مكون من اسم الدالة main وقوس بداية تعليمات جسم الدالة وقوس نهاية تعليمات جسم الدالة :
- الكود:
void main() {
}
void main() {
{
إذا قمت بترجمة هذا الجزء فسوف يقوم المترجم بترجمته بنجاح ، لكن هذا الجزء لا يجعل الميكروكونترولر يقوم بفعل شىء ما .
وظيفة الدالة الرئيسية هى إخبار المترجم بمكان بداية ترجمة تعليمات البرنامج .
رد: ما هو الميكروكونترولر Microcontroller ؟
قبل كتابة برنامجك الأول يجب أن تكون ملما بما يلى :
• أطراف الميكروكونترولر PIC تكون مقسمة إلى "منافذ" PORTS تحتوى على مجموعة من "أطراف الدخل/الخرج .
• فى الميكروكونترولر PIC16F ، يوجد 2 سجل register ، كل سجل مكون من بايت أى 8 بت ، مرتبطة بكل منفذ ، السجل TRIS والسجل PORT ، على سبيل المثال : TRISB, PORTB و TRISC, PORTC وهكذا .
• الكلمة TRIS تعنى "حالات ثلاثة" Tri-State، والسجل TRIS هو المعنى بتحديد اتجاه كل طرف من أطراف الدخل/الخرج . وجود المنطق “1” فى بت محددة من بتات السجل TRIS يجعل الطرف المناظر "مدخل" Input ، ووجود المنطق “0” فى بت محددة من بتات السجل TRIS يجعل الطرف المناظر "مخرج" Output .
• السجلات PORT تستخدم لقراءة البيانات من أو كتابة البيانات إلى أطراف الدخل /الخرج . كتابة المنطق “1” فى بت معينة من بتات السجل PORT تجعل الطرف المناظر عند "المنطق المرتفع" (VDD) ، وكتابة المنطق “0” فى بت من بتات السجل PORT تجعل الطرف المناظر عند "المنطق المنخفض" (VSS) ، وذلك إذا كان هذا الطرف "مخرج" Output ( البت المناظرة من السجل TRIS بصفر “0” ) .
• السجل PORT يمكن أن يستخدم لقراءة البيانات الرقمية من طرف "مدخل". المنطق “1” عند طرف المدخل يشير إلى أن هذا الطرف عند الحالة المنطقية المرتفعة (VDD) Logic High ، والمنطق “0” عند طرف المدخل يشير إلى أن هذا الطرف عند الحالة المنطقية المنخفضة (VSS) Logic Low .
• يمكنك الكتابة إلى السجل PORT والسجل TRIS ككل (كبايت 8-bit ) أو ألى كل بت بشكل منفصل (بت ببت bit by bit ) :
مثال على طريقة الكتابة إلى البتات (بت ببت) :
ملاحظات :
• لعلك لاحظت وجود "فاصلة منقوطة" ( عند نهاية كل تعليمة (أمر) . هذه الفاصلة المنقوطة مهمة فى لغة السى حيث يتعرف عليها المترجم فيعلم مكان انتهاء التعليمة ويبدأ فى ترجمتها وينتقل إلى [/code] التعليمة التالية وهكذا .
• للإشارة إلى البت المحددة بالسجل يمكن استخدام الصيغة TRISC.F0 أو الصيغة TRISC.B0 .
• علامة التساوى (=) هنا تسمى علامة "تخصيص" ، بمعنى كتابة أو إرسال “1” إلى البت TRISC.F0 ، على سبيل المثال .
وللكتابة إلى السجل ككل (بايت) :
يجب أن تكون ملما بالمفاهيم التالية عند البرمجة بلغة السى :
• العدد الثنائى binary يشار إليه بالبادئة “0b” .
• العدد الثمانى octal يشار إليه بالبادئة “0” .
• العدد السداسى عشر hexadecimal يشار إليه بالبادئة “0x”.
• العدد العشرى decimal يكون بدون بادئة .
إليك بعض الأمثلة :
برنامجك الأول :
البرنامج التالى يقوم بعمل وميض ليد Led Blink بتأخير زمنى قيمته واحد ثانية :
ملحوظة : الدالة Delay_ms هى دالة ضمن مكتبة المترجم ميكروسى برو والتى توفر تأخير بالملى ثانية .
• أدخل البرنامج السابق بنافذة المحرر للمترجم ميكروسى برو .
• احفظ المشروع .
• قم بترجمة المشروع من خلال النقر على Build >> Build (or Ctrl+F9) .
• سوف يتم توليد الملف التنفيذى بالامتداد hex فى مجلد المشروع . أنت بحاجة إلى تحميل (كتابة) هذا الملف إلى الميكروكونترولر باستخدام جهاز برمجة أو تحميله فى برنامج ISIS بغرض المحاكاة .
الدائرة الكهربية :
الطرف VDD والطرف VSS للميكروكونترولر PIC تكون متصلة بكل من +5V و GND على الترتيب لتوفير القدرة اللازمة لعمل الميكروكونترولر . الكريستال 4MHz تستخدم لتوفير الساعة اللازمة للميكروكونترولر . المكثفات 22Pf تقوم بعمل تنظيم (تثبيت) لذبذبات الكريستال . يتم توصيل الليد LED بالبت bit0 للمنفذ PORTB (تسمى RB0) ويتم توصيل مقاومة 330 أوم على التوالى مع الليد للحد من التيار المار خلال الليد .
يمكنك محاكاة العمل باستخدام برنامج Proteus . لا تنسى إعداد تردد الساعة وأن تضيف ملف hex الموجود فى مجلد المشروع وذلك عن طريق تحرير خصائص الميكروكونترولر وذلك بالنقر المزدوج على الميكروكونترولر فتظهر لك نافذة كما هو مبين بالشكل التالى :
هذا البرنامج يقوم بتوصيل on لليد المتصل بالطرف RB0 من المنفذ PORTB للميكروكونترولر PIC16F877A . وبعد تأخير 1000 ملى ثانية (واحد ثانية) يتم فصل off الليد ، ثم التأخير واحد ثانية مرة أخرى ويتكرر العمل السابق بشكل غير منتهى بفعل الدالة while(1) .
لا تقلق إذا كنت لا تفهم عمل هذا البرنامج فى هذه المرحلة ، حيث أن كل شىء سوف يكون واضحا كلما تقدمنا.
• أطراف الميكروكونترولر PIC تكون مقسمة إلى "منافذ" PORTS تحتوى على مجموعة من "أطراف الدخل/الخرج .
• فى الميكروكونترولر PIC16F ، يوجد 2 سجل register ، كل سجل مكون من بايت أى 8 بت ، مرتبطة بكل منفذ ، السجل TRIS والسجل PORT ، على سبيل المثال : TRISB, PORTB و TRISC, PORTC وهكذا .
• الكلمة TRIS تعنى "حالات ثلاثة" Tri-State، والسجل TRIS هو المعنى بتحديد اتجاه كل طرف من أطراف الدخل/الخرج . وجود المنطق “1” فى بت محددة من بتات السجل TRIS يجعل الطرف المناظر "مدخل" Input ، ووجود المنطق “0” فى بت محددة من بتات السجل TRIS يجعل الطرف المناظر "مخرج" Output .
• السجلات PORT تستخدم لقراءة البيانات من أو كتابة البيانات إلى أطراف الدخل /الخرج . كتابة المنطق “1” فى بت معينة من بتات السجل PORT تجعل الطرف المناظر عند "المنطق المرتفع" (VDD) ، وكتابة المنطق “0” فى بت من بتات السجل PORT تجعل الطرف المناظر عند "المنطق المنخفض" (VSS) ، وذلك إذا كان هذا الطرف "مخرج" Output ( البت المناظرة من السجل TRIS بصفر “0” ) .
• السجل PORT يمكن أن يستخدم لقراءة البيانات الرقمية من طرف "مدخل". المنطق “1” عند طرف المدخل يشير إلى أن هذا الطرف عند الحالة المنطقية المرتفعة (VDD) Logic High ، والمنطق “0” عند طرف المدخل يشير إلى أن هذا الطرف عند الحالة المنطقية المنخفضة (VSS) Logic Low .
• يمكنك الكتابة إلى السجل PORT والسجل TRIS ككل (كبايت 8-bit ) أو ألى كل بت بشكل منفصل (بت ببت bit by bit ) :
مثال على طريقة الكتابة إلى البتات (بت ببت) :
- الكود:
[left]TRISC.F0 = 1; //Makes 0th bit of PORTC Input
TRISC.F5 = 0; //Makes 5th bit of PORTC Output
PORTB.F3 = 1; //Makes 3ed bit of PORTB at Logic High
PORTB.F7 = 0; //Makes 7th bit of PORTB at Logic Low [/left]
ملاحظات :
• لعلك لاحظت وجود "فاصلة منقوطة" ( عند نهاية كل تعليمة (أمر) . هذه الفاصلة المنقوطة مهمة فى لغة السى حيث يتعرف عليها المترجم فيعلم مكان انتهاء التعليمة ويبدأ فى ترجمتها وينتقل إلى [/code] التعليمة التالية وهكذا .
• للإشارة إلى البت المحددة بالسجل يمكن استخدام الصيغة TRISC.F0 أو الصيغة TRISC.B0 .
• علامة التساوى (=) هنا تسمى علامة "تخصيص" ، بمعنى كتابة أو إرسال “1” إلى البت TRISC.F0 ، على سبيل المثال .
وللكتابة إلى السجل ككل (بايت) :
يجب أن تكون ملما بالمفاهيم التالية عند البرمجة بلغة السى :
• العدد الثنائى binary يشار إليه بالبادئة “0b” .
• العدد الثمانى octal يشار إليه بالبادئة “0” .
• العدد السداسى عشر hexadecimal يشار إليه بالبادئة “0x”.
• العدد العشرى decimal يكون بدون بادئة .
إليك بعض الأمثلة :
- الكود:
[left]PORTB = 0xFF; //Makes all pins of PORTB Logic High
TRISC = 0x00; //Makes all pins of TRISC Output
PORTD = 128; //Makes 7th bit of PORTD Logic High
[/left]
برنامجك الأول :
البرنامج التالى يقوم بعمل وميض ليد Led Blink بتأخير زمنى قيمته واحد ثانية :
- الكود:
[left]void main()
{
TRISB.F0 = 0; //Makes PORTB0 or RB0 Output Pin
PORTB=0; //LED OFF
while(1) //Infinite Loop
{
PORTB.F0 = 1; //LED ON
Delay_ms(1000); //1 Second Delay
PORTB.F0 = 0; //LED OFF
Delay_ms(1000); //1 Second Delay
}
} [/left]
ملحوظة : الدالة Delay_ms هى دالة ضمن مكتبة المترجم ميكروسى برو والتى توفر تأخير بالملى ثانية .
• أدخل البرنامج السابق بنافذة المحرر للمترجم ميكروسى برو .
• احفظ المشروع .
• قم بترجمة المشروع من خلال النقر على Build >> Build (or Ctrl+F9) .
• سوف يتم توليد الملف التنفيذى بالامتداد hex فى مجلد المشروع . أنت بحاجة إلى تحميل (كتابة) هذا الملف إلى الميكروكونترولر باستخدام جهاز برمجة أو تحميله فى برنامج ISIS بغرض المحاكاة .
الدائرة الكهربية :
الطرف VDD والطرف VSS للميكروكونترولر PIC تكون متصلة بكل من +5V و GND على الترتيب لتوفير القدرة اللازمة لعمل الميكروكونترولر . الكريستال 4MHz تستخدم لتوفير الساعة اللازمة للميكروكونترولر . المكثفات 22Pf تقوم بعمل تنظيم (تثبيت) لذبذبات الكريستال . يتم توصيل الليد LED بالبت bit0 للمنفذ PORTB (تسمى RB0) ويتم توصيل مقاومة 330 أوم على التوالى مع الليد للحد من التيار المار خلال الليد .
يمكنك محاكاة العمل باستخدام برنامج Proteus . لا تنسى إعداد تردد الساعة وأن تضيف ملف hex الموجود فى مجلد المشروع وذلك عن طريق تحرير خصائص الميكروكونترولر وذلك بالنقر المزدوج على الميكروكونترولر فتظهر لك نافذة كما هو مبين بالشكل التالى :
هذا البرنامج يقوم بتوصيل on لليد المتصل بالطرف RB0 من المنفذ PORTB للميكروكونترولر PIC16F877A . وبعد تأخير 1000 ملى ثانية (واحد ثانية) يتم فصل off الليد ، ثم التأخير واحد ثانية مرة أخرى ويتكرر العمل السابق بشكل غير منتهى بفعل الدالة while(1) .
لا تقلق إذا كنت لا تفهم عمل هذا البرنامج فى هذه المرحلة ، حيث أن كل شىء سوف يكون واضحا كلما تقدمنا.
رد: ما هو الميكروكونترولر Microcontroller ؟
فيما يلى بعض مفاهيم البرمجة :
التعليقات Comments
تستخدم التعليقات فى البرامج لتوضيح عمل البرنامج . على لرغم من أن استخدام التعليقات هو أمر اختيارى ، إلا أنه من المستحسن وبشدة أن تستخدم العديد من التعليقات قدر الممكن فى برامجك ، حيث أن التعليقات تجعل برامجك قابلة للقراءة وسهلة الصيانة . تخيل كيف أنه سيكون من الصعب كتابة برنامج معقد بدون أى تعليقات ، ثم محاولة تعديله بعد عدة أشهر . يتم تجاهل جميع التعليقات بواسطة المترجم .
فى المترجم ميكروسى برو ، يمكن أن تكون التعليقات نوعين : "التعليقات الطويلة" ، و"التعليقات القصيرة" .
التعليقات الطويلة :
تبدأ التعليقات الطويلة بزوج الحروف ( /* ) وتنتهى بزوج الحروف ( */ ) . عادة تستخدم التعليقات الطويلة فى بداية البرنامج لوصف تفاصيل البرنامج ، مثل ما يقوم به البرنامج ، وأى نوع من الهاردوير يستخدم ، ومن هو المؤلف ، وتاريخ إنشاء البرنامج ، واسم ملف البرنامج ، وتاريخ الإصدار ، وهلم جرا (كما هو مبين بالشكل أدناه) . كما تستخدم التعليقات الطويلة أيضا بداخل البرنامج لوصف عمل جزء من البرنامج ، على سبيل المثال بارامترات (أدلة ، معلمات) الدوال ، والخوارزمية (إسلوب البرمجة) المستخدمة وهلم جرا .
التعليقات القصيرة :
تبدأ التعليقات القصيرة بزوج الحروف ( // ) . لا يتم إنهاء التعليقات القصيرة بحروف ، ويمكن استخدامها فى سطر واحد فقط ، بدءا من أى مكان بالسطر وحتى نهايته فقط . عموما ، تستخدم التعليقات القصيرة بعد عبارات البرنامج لتصف ما تقوم به العبارة ( كما هو مبين بالشكل أدناه) .
بداية ونهاية البرنامج :
فى الميكروسى برو :
• "يبدأ البرنامج" بالدالة الرئيسية :
void main()
• بعدها ، يتم استخدام قوس الفتح المجعد ( { ) للإشارة (لبيان) إلى بداية "جسم البرنامج" .
• يتم إنهاء البرنامج بقوس الغلق المجعد ( } ) . وبالتالى يكون هيكل بناء البرنامج بالصيغة التالية :
• يتكون جسم البرنامج من عبارات statements . كل عبارة برنامج يجب أن تنتهى بحرف الفاصلة المنقوطة ( ; ) للإشارة إلى نهاية العبارة ، وإلا يتم توليد خطأ بواسطة المترجم .
أمثلة :
لتكرار البرنامج دون توقف تستخدم حلقة تكرار غير منتهى بالصيغة :
المسافات (المساحات) البيضاء :
تتكون المسافات (المساحات) البيضاء فى البرنامج من "المسافات" spaces ، و "التبويبات" tabs ، ،وحروف "السطر الجديد" newline ، و"الفراغات" blanks . يتم تجاهل هذه الحروف من قبل المترجم . وبالتالى فإن السطور التالية متطابقة :
فى بعض التطبيقات ، قد يكون لدينا سلسلة نصية طويلة والتى قد نرغب فى تمديدها على عدة أسطر . يتم استخدام الشرطة المائلة للخلف ( \ ) لربط السلاسل النصية الممتدة على عدة أسطر . على سبيل المثال :
تترجم على أنها :
التعليقات Comments
تستخدم التعليقات فى البرامج لتوضيح عمل البرنامج . على لرغم من أن استخدام التعليقات هو أمر اختيارى ، إلا أنه من المستحسن وبشدة أن تستخدم العديد من التعليقات قدر الممكن فى برامجك ، حيث أن التعليقات تجعل برامجك قابلة للقراءة وسهلة الصيانة . تخيل كيف أنه سيكون من الصعب كتابة برنامج معقد بدون أى تعليقات ، ثم محاولة تعديله بعد عدة أشهر . يتم تجاهل جميع التعليقات بواسطة المترجم .
فى المترجم ميكروسى برو ، يمكن أن تكون التعليقات نوعين : "التعليقات الطويلة" ، و"التعليقات القصيرة" .
التعليقات الطويلة :
تبدأ التعليقات الطويلة بزوج الحروف ( /* ) وتنتهى بزوج الحروف ( */ ) . عادة تستخدم التعليقات الطويلة فى بداية البرنامج لوصف تفاصيل البرنامج ، مثل ما يقوم به البرنامج ، وأى نوع من الهاردوير يستخدم ، ومن هو المؤلف ، وتاريخ إنشاء البرنامج ، واسم ملف البرنامج ، وتاريخ الإصدار ، وهلم جرا (كما هو مبين بالشكل أدناه) . كما تستخدم التعليقات الطويلة أيضا بداخل البرنامج لوصف عمل جزء من البرنامج ، على سبيل المثال بارامترات (أدلة ، معلمات) الدوال ، والخوارزمية (إسلوب البرمجة) المستخدمة وهلم جرا .
التعليقات القصيرة :
تبدأ التعليقات القصيرة بزوج الحروف ( // ) . لا يتم إنهاء التعليقات القصيرة بحروف ، ويمكن استخدامها فى سطر واحد فقط ، بدءا من أى مكان بالسطر وحتى نهايته فقط . عموما ، تستخدم التعليقات القصيرة بعد عبارات البرنامج لتصف ما تقوم به العبارة ( كما هو مبين بالشكل أدناه) .
بداية ونهاية البرنامج :
فى الميكروسى برو :
• "يبدأ البرنامج" بالدالة الرئيسية :
void main()
• بعدها ، يتم استخدام قوس الفتح المجعد ( { ) للإشارة (لبيان) إلى بداية "جسم البرنامج" .
• يتم إنهاء البرنامج بقوس الغلق المجعد ( } ) . وبالتالى يكون هيكل بناء البرنامج بالصيغة التالية :
- الكود:
void main()
{
Program body
}
• يتكون جسم البرنامج من عبارات statements . كل عبارة برنامج يجب أن تنتهى بحرف الفاصلة المنقوطة ( ; ) للإشارة إلى نهاية العبارة ، وإلا يتم توليد خطأ بواسطة المترجم .
أمثلة :
- الكود:
k = 50; //correct
i = k+5; //correct
k = 50 //error
لتكرار البرنامج دون توقف تستخدم حلقة تكرار غير منتهى بالصيغة :
- الكود:
while(1) {
………
………
}
المسافات (المساحات) البيضاء :
تتكون المسافات (المساحات) البيضاء فى البرنامج من "المسافات" spaces ، و "التبويبات" tabs ، ،وحروف "السطر الجديد" newline ، و"الفراغات" blanks . يتم تجاهل هذه الحروف من قبل المترجم . وبالتالى فإن السطور التالية متطابقة :
- الكود:
k = 20; p = 50;
or
k = 20;
p = 50;
or
k = 20;
p =50;
or
k=20;
p=
20;
فى بعض التطبيقات ، قد يكون لدينا سلسلة نصية طويلة والتى قد نرغب فى تمديدها على عدة أسطر . يتم استخدام الشرطة المائلة للخلف ( \ ) لربط السلاسل النصية الممتدة على عدة أسطر . على سبيل المثال :
- الكود:
"My new mikroC\
Compiler"
تترجم على أنها :
- الكود:
"My new mikroC Compiler"
رد: ما هو الميكروكونترولر Microcontroller ؟
المتغيرات Variables :
المتغير هو مجرد مكان (وعاء) لحفط قيم لبيانات من نوع معين . مكان الحفظ هو مواقع ذاكرة RAM والنوع يمكن أن يكون لأحرف Character أو أعداد صحيحة Integers (بدون علامة عشرية) أو أعداد بعلامة أو نقطة عشرية تسمى Float .
يمكن تصنيف المتغيرات تبعا "لنوع البيانات" التى تخزنها بداخلها :
1- متغير يحفظ بيانات لعدد صحيح integer ، ويشار إليه بكلمة “int” .
2- متغير يحفظ بيانات لحرف character ، ويشار إليه بكلمة “char” .
3- متغير يحفظ بيانات لعدد بنقطة عشرية float ، ويشار إليه بكلمة “float” .
4- متغير يحفظ بيانات عدد بنقطة عشرية "مضاعف" double ، ويشار إليه بكلمة double .
كما يمكن تصنيف المتغيرات تبعا لعدد المتغيرات التى يمكن أن تحفظها :
1- متغيرات تحفظ "قيمة مفردة" فى نفس الوقت ومن أى نوع من البيانات ، وتسمى متغيرات عادية .
2-متغيرات تحفظ "قيم متعددة" من نفس نوع البيانات وتسمى "المصفوفات" Array .
3-متغيرات تحفظ "قيم متعددة" من أنواع مختلفة من البيانات وتسمى "الهياكل" Structure .
بيانات الأعداد الصحيحة Integer Type :
النوع char والنوع int ، وتعديلاتها ، تعتبر أنواع لبيانات أعداد صحيحة . يمكن إنشاء التعديلات باستخدام واحد من بادئات التعديل التالية : short , long , signed , unsigned . الجدول التالى يبين أنواع بيانات الأعداد الصحيحة ، يمكن إهمال الكلمات الموجودة بين الأقواس :
• فى حالة غياب البادئة unsigned فيفترض تلقائيا النوع signed لبيانات أنواع العدد الصحيح ، على سبيل المثال int تعنى signed int. الاستثناء الوحيد هو char حيث يكون unsigned فى الوضع الافتراضى وتقتصر على كتابة char.
• الكلمات signed و unsigned عندما يتم استخدامها فى حد ذاتها ، تعنى signed int و unsigned int على الترتيب ، على سبيل المثال unsigned تعنى unsigned int .
• كلمات التعديل short و long يمكن فقط تطبيقها على النوع int .
• الكلمات short و long عند استخدامها فى حد ذاتها ، تعنى short int و long int على ، سبيل المثال short تعنى signed short int .
بيانات الأعداد الحقيقية (التى تحتوى على نقطة عشرية)من نوع Float point :
الأنواع float و double مع النوع long double تعتبر أنواع الأعداد الحقيقية التى تحتوى على نقطة عشرية وتسمى float . المترجم ميكروسى برو يعتبر الثلاثة أنواع من نفس النوع ، كما هو مبين بالجدول التالى :
عامل التخصيص (التعيين) Assignment Operator :
• يستخدم عامل التخصيص لتخصيص (تعيين) قيمة إلى متغير .
• عامل التخصيص يشار إليه بعلامة التساوى “=” .
• عامل التخصيص يتعامل مع قيمتان ، قيمة على جانبه الأيسر ، وقيمة على جانبه الأيمن ، ويقوم العامل بنسخ القيمة التى على جانبه الأيمن إلى القيمة التى على جانبه الأيسر .
إعلان المتغير Variable Declaration :
مفهوم إعلان المتغير هو إعطاء أمر للمترجم لكى يقوم بحجز مواقع ذاكرة تتناسب مع نوع البيانات التى يقوم هذا المتغير بتخزينها .
صيغ إعلان المتغير :
الصيغة الأولى : نوع البيانات يليه اسم المتغير .
[codedataType variableName;] [/code]
هذه الصيغة تعلن عن متغير ، فهى تعلن عن نوع بياناته ، وحجز ذاكرة له وإطلاق اسم على هذه الذاكرة . هذه الصيغة لا تذكر شيئا حول القيمة الموجودة بالذاكرة .
الصيغة الثانية : نوع البيانات ، يليه اسم المتغير ، ثم تخصيص قيمة لهذا المتغير .
هذه الصيغة تعلن عن المتغير ، وتعلن عن نوع بياناته ، وتحجز ذاكرة له ، وتضع قيمة ابتدائية فى هذه الذاكرة .
الصيغة الثالثة :
هذه الصيغة تعلن عن متغيرين ، والاثنين من نفس النوع من البيانات ، وتحجز ذاكرة لكل منهما ، ولكنها لا تضع أى شىء فى أى من المتغيرين . يمكن القيام بعمل ذلك مع أكثر من متغيرين ، إذا أرد ذلك .
الصيغة الرابعة :
هذه الصيغة تعلن عن متغيرين ، كلاهما له نفس نوع البيانات ، وتحجز الذاكرة اللازمة ، وتضع قيمة ايتدائية فى كل متغير . يمكنك كتابة الصيغة فى سطر واحد ، كما يمكنك إعلان أكثر من متغيرين بنفس الطريقة .
لعلك لاحظت الفاصلة “,” الموجودة بين المتغيرات ، والفاصلة المنقوطة “;” فى نهاية عبارة الإعلان .
فيما يلى أمثلة للأنواع المختلفة من المتغيرات :
• المتغيرات :
هى متغيرات "بدون إشارة" 8 بت ، تحتل "واحد بايت" فقط من الذاكرة ولها قيم فى المدى من (0) إلى (255) .
فى المثال التالى ، المتغير Sum يخصص (يعين) له القيمة (255) :
• والمتغيرات :
هى متغيرات "بدون إشارة" 16 بت ، تحتل "2 بايت" من الذاكرة ولها قيم فى المدى من (0) إلى (65 535) . فى المثال التالى ، المتغير Total يخصص له القيمة (64 500) :
• والمتغيرات :
هى متغيرات بدون إشارة 32 بت ، تحتل 4 بايت من الذاكرة ولها قيم فى المدى من (0) إلى
4 294 967 295 . فى المثال التالى ، المتغير Sum يخصص له القيمة 4 200 000 000 :
• والمتغيرات :
هى متغيرات "بإشارة" 8 بت ، نحتل واحد بايت فقك من الذاكرة ولها قيم فى المدة من (-128) إلى (+127) . فى المثال التالى المتغير Total يخصص له القيمة (-40) :
• والمتغيرات :
هى متغيرات بإشارة 16 بت ، تحتل 2 بايت من الذاكرة ولها قيم فى المدى من (-32 768) إلى (+32 767) . فى المثال التالى ، المتغير Sum يخصص له القيمة (-31 500) :
• والمتغيرات :
هى متغيرات بإشار 32 بت ، تحتل 4 بايت من الذاكرة ولها قيم فى المدى من (-2 147 483 648) إلى
(+2 147 483 647) . فى المثال التالى ، المتغير Sum يخصص له القيمة (2 050 480 000) :
• أنواع بيانات العدد الحقيقى هى : float, double , long double . فى المثال التالى ، المتغير Volume يخصص له القيمة (23.45) :
أسماء المتغيرات:
• فى المترجم ميكروسى برو ، أسماء المتغيرات يمكن أن تبدأ بحرف أو الشرطة السفلية ( _ ) .
• أسماء المتغير يمكن أن تتضمن أى حرف من ( a ) إلى ( z ) ومن ( A ) إلى ( Z ) والأرقام من ( 0 ) إلى ( 9 ) .
• اسم المتغير يمكن أن يكون بطول حتى 31 حرف .
• بعض أمثلة أسماء المتغير الصحيحة :
• وفيما يلى بعض الأمثلة لأسماء متغير غير صحيحة :
• الأسماء حساسة لحالة الحرف وبالتالى فإن المتغيرات بأسماء بحروف صغيرة تختلف عن المتغيرات بأسماء بحروف كبيرة . وبالتالى فأن المتغيرات التالية جميعها مختلفة :
الأسماء المحجوزة :
فى المترجم ميكروسى برو يتم حجز بعض الأسماء من أجل المترجم ، وهذه الأسماء لا يمكن أن تستخدم كأسماء للمتغيرات . الجدول أدناه يعطى قائمة بهذه الأسماء المحجوزة .
يمكن تقسيم المتغيرات إلى :
• متغيرات عمومية Global
• متغيرات محلية Local
المتغيرات العمومية Global : هى التى يتم إعلانها عند بداية البرنامج خارج أى دالة ، مجال هذه المتغيرات يكون عمومى global وهذا يعنى أنه يمكن الوصول إليها واستخدامها فى أى مكان بالبرنامج وفى داخل جميع الدوال . هذا النوع يستهلك الذاكرة نظرا لوجودة طوال البرنامج .
المتغيرات المحلية Local : هى التى يتم إعلانها داخل دالة ، ويكون مجالها محلى وهذا يعنى أنه يمكن الوصول إليها واستخدامها فقط داخل الدالة حيث تم إعلانها . هذا النوع يوفر من الذاكرة حيث يتم تحرير الذاكرة بعد نهاية الدالة .
المتغير هو مجرد مكان (وعاء) لحفط قيم لبيانات من نوع معين . مكان الحفظ هو مواقع ذاكرة RAM والنوع يمكن أن يكون لأحرف Character أو أعداد صحيحة Integers (بدون علامة عشرية) أو أعداد بعلامة أو نقطة عشرية تسمى Float .
يمكن تصنيف المتغيرات تبعا "لنوع البيانات" التى تخزنها بداخلها :
1- متغير يحفظ بيانات لعدد صحيح integer ، ويشار إليه بكلمة “int” .
2- متغير يحفظ بيانات لحرف character ، ويشار إليه بكلمة “char” .
3- متغير يحفظ بيانات لعدد بنقطة عشرية float ، ويشار إليه بكلمة “float” .
4- متغير يحفظ بيانات عدد بنقطة عشرية "مضاعف" double ، ويشار إليه بكلمة double .
كما يمكن تصنيف المتغيرات تبعا لعدد المتغيرات التى يمكن أن تحفظها :
1- متغيرات تحفظ "قيمة مفردة" فى نفس الوقت ومن أى نوع من البيانات ، وتسمى متغيرات عادية .
2-متغيرات تحفظ "قيم متعددة" من نفس نوع البيانات وتسمى "المصفوفات" Array .
3-متغيرات تحفظ "قيم متعددة" من أنواع مختلفة من البيانات وتسمى "الهياكل" Structure .
بيانات الأعداد الصحيحة Integer Type :
النوع char والنوع int ، وتعديلاتها ، تعتبر أنواع لبيانات أعداد صحيحة . يمكن إنشاء التعديلات باستخدام واحد من بادئات التعديل التالية : short , long , signed , unsigned . الجدول التالى يبين أنواع بيانات الأعداد الصحيحة ، يمكن إهمال الكلمات الموجودة بين الأقواس :
• فى حالة غياب البادئة unsigned فيفترض تلقائيا النوع signed لبيانات أنواع العدد الصحيح ، على سبيل المثال int تعنى signed int. الاستثناء الوحيد هو char حيث يكون unsigned فى الوضع الافتراضى وتقتصر على كتابة char.
• الكلمات signed و unsigned عندما يتم استخدامها فى حد ذاتها ، تعنى signed int و unsigned int على الترتيب ، على سبيل المثال unsigned تعنى unsigned int .
• كلمات التعديل short و long يمكن فقط تطبيقها على النوع int .
• الكلمات short و long عند استخدامها فى حد ذاتها ، تعنى short int و long int على ، سبيل المثال short تعنى signed short int .
بيانات الأعداد الحقيقية (التى تحتوى على نقطة عشرية)من نوع Float point :
الأنواع float و double مع النوع long double تعتبر أنواع الأعداد الحقيقية التى تحتوى على نقطة عشرية وتسمى float . المترجم ميكروسى برو يعتبر الثلاثة أنواع من نفس النوع ، كما هو مبين بالجدول التالى :
عامل التخصيص (التعيين) Assignment Operator :
• يستخدم عامل التخصيص لتخصيص (تعيين) قيمة إلى متغير .
• عامل التخصيص يشار إليه بعلامة التساوى “=” .
• عامل التخصيص يتعامل مع قيمتان ، قيمة على جانبه الأيسر ، وقيمة على جانبه الأيمن ، ويقوم العامل بنسخ القيمة التى على جانبه الأيمن إلى القيمة التى على جانبه الأيسر .
إعلان المتغير Variable Declaration :
مفهوم إعلان المتغير هو إعطاء أمر للمترجم لكى يقوم بحجز مواقع ذاكرة تتناسب مع نوع البيانات التى يقوم هذا المتغير بتخزينها .
صيغ إعلان المتغير :
الصيغة الأولى : نوع البيانات يليه اسم المتغير .
[codedataType variableName;] [/code]
هذه الصيغة تعلن عن متغير ، فهى تعلن عن نوع بياناته ، وحجز ذاكرة له وإطلاق اسم على هذه الذاكرة . هذه الصيغة لا تذكر شيئا حول القيمة الموجودة بالذاكرة .
الصيغة الثانية : نوع البيانات ، يليه اسم المتغير ، ثم تخصيص قيمة لهذا المتغير .
- الكود:
dataType variableName = initialValue ;
هذه الصيغة تعلن عن المتغير ، وتعلن عن نوع بياناته ، وتحجز ذاكرة له ، وتضع قيمة ابتدائية فى هذه الذاكرة .
الصيغة الثالثة :
- الكود:
dataType variableNameOne, variableNameTwo ;
هذه الصيغة تعلن عن متغيرين ، والاثنين من نفس النوع من البيانات ، وتحجز ذاكرة لكل منهما ، ولكنها لا تضع أى شىء فى أى من المتغيرين . يمكن القيام بعمل ذلك مع أكثر من متغيرين ، إذا أرد ذلك .
الصيغة الرابعة :
- الكود:
dataType variableNameOne = initialValueOne,
variableNameTwo = initialValueTwo ;
هذه الصيغة تعلن عن متغيرين ، كلاهما له نفس نوع البيانات ، وتحجز الذاكرة اللازمة ، وتضع قيمة ايتدائية فى كل متغير . يمكنك كتابة الصيغة فى سطر واحد ، كما يمكنك إعلان أكثر من متغيرين بنفس الطريقة .
لعلك لاحظت الفاصلة “,” الموجودة بين المتغيرات ، والفاصلة المنقوطة “;” فى نهاية عبارة الإعلان .
فيما يلى أمثلة للأنواع المختلفة من المتغيرات :
• المتغيرات :
- الكود:
unsigned char
or
unsigned short int
هى متغيرات "بدون إشارة" 8 بت ، تحتل "واحد بايت" فقط من الذاكرة ولها قيم فى المدى من (0) إلى (255) .
فى المثال التالى ، المتغير Sum يخصص (يعين) له القيمة (255) :
- الكود:
unsigned char Sum = 225;
or
unsigned char Sum;
Sum = 225;
• والمتغيرات :
- الكود:
unsigned int
هى متغيرات "بدون إشارة" 16 بت ، تحتل "2 بايت" من الذاكرة ولها قيم فى المدى من (0) إلى (65 535) . فى المثال التالى ، المتغير Total يخصص له القيمة (64 500) :
- الكود:
unsigned int Total = 64500;
• والمتغيرات :
- الكود:
unsigned long int
هى متغيرات بدون إشارة 32 بت ، تحتل 4 بايت من الذاكرة ولها قيم فى المدى من (0) إلى
4 294 967 295 . فى المثال التالى ، المتغير Sum يخصص له القيمة 4 200 000 000 :
- الكود:
unsigned long int Sum = 4200000000;
• والمتغيرات :
- الكود:
signed char
or
signed short int
هى متغيرات "بإشارة" 8 بت ، نحتل واحد بايت فقك من الذاكرة ولها قيم فى المدة من (-128) إلى (+127) . فى المثال التالى المتغير Total يخصص له القيمة (-40) :
- الكود:
signed char Total = -40;
• والمتغيرات :
- الكود:
signed int
هى متغيرات بإشارة 16 بت ، تحتل 2 بايت من الذاكرة ولها قيم فى المدى من (-32 768) إلى (+32 767) . فى المثال التالى ، المتغير Sum يخصص له القيمة (-31 500) :
- الكود:
signed int Sum = -31500;
• والمتغيرات :
- الكود:
signed long int
هى متغيرات بإشار 32 بت ، تحتل 4 بايت من الذاكرة ولها قيم فى المدى من (-2 147 483 648) إلى
(+2 147 483 647) . فى المثال التالى ، المتغير Sum يخصص له القيمة (2 050 480 000) :
- الكود:
signed long int Sum = 2050480000;
• أنواع بيانات العدد الحقيقى هى : float, double , long double . فى المثال التالى ، المتغير Volume يخصص له القيمة (23.45) :
- الكود:
float Volume = 23.45;
or
float Volume;
Volume = 23.45;
أسماء المتغيرات:
• فى المترجم ميكروسى برو ، أسماء المتغيرات يمكن أن تبدأ بحرف أو الشرطة السفلية ( _ ) .
• أسماء المتغير يمكن أن تتضمن أى حرف من ( a ) إلى ( z ) ومن ( A ) إلى ( Z ) والأرقام من ( 0 ) إلى ( 9 ) .
• اسم المتغير يمكن أن يكون بطول حتى 31 حرف .
• بعض أمثلة أسماء المتغير الصحيحة :
- الكود:
Total
Sum
Average
My_Variable
username
MaxTotal
_Name
• وفيما يلى بعض الأمثلة لأسماء متغير غير صحيحة :
- الكود:
%name
?Total
7Sum
(Max
12count
• الأسماء حساسة لحالة الحرف وبالتالى فإن المتغيرات بأسماء بحروف صغيرة تختلف عن المتغيرات بأسماء بحروف كبيرة . وبالتالى فأن المتغيرات التالية جميعها مختلفة :
- الكود:
Total
total
ToTal
TotaL
TOTAL
TOTal
الأسماء المحجوزة :
فى المترجم ميكروسى برو يتم حجز بعض الأسماء من أجل المترجم ، وهذه الأسماء لا يمكن أن تستخدم كأسماء للمتغيرات . الجدول أدناه يعطى قائمة بهذه الأسماء المحجوزة .
يمكن تقسيم المتغيرات إلى :
• متغيرات عمومية Global
• متغيرات محلية Local
المتغيرات العمومية Global : هى التى يتم إعلانها عند بداية البرنامج خارج أى دالة ، مجال هذه المتغيرات يكون عمومى global وهذا يعنى أنه يمكن الوصول إليها واستخدامها فى أى مكان بالبرنامج وفى داخل جميع الدوال . هذا النوع يستهلك الذاكرة نظرا لوجودة طوال البرنامج .
المتغيرات المحلية Local : هى التى يتم إعلانها داخل دالة ، ويكون مجالها محلى وهذا يعنى أنه يمكن الوصول إليها واستخدامها فقط داخل الدالة حيث تم إعلانها . هذا النوع يوفر من الذاكرة حيث يتم تحرير الذاكرة بعد نهاية الدالة .
رد: ما هو الميكروكونترولر Microcontroller ؟
الثوابت :
الثوابت مهمة جدا فى برمجة الميكروكونترولر PIC مع المترجم ميكروسى برو ، وخاصة إذا كانت ذاكرة البيانات RAM لها حجم محدود . يتم تخزين المتغيرات الثابتة فى ذاكرة البرنامج (الفلاش) ، وبالتالى توفير تحرير مساحة ذاكرة بيانات RAM المحدودة . الثوابت أو القيم المحددة تمثل قيم ثابتة لعدد أو لحرف .
فى المترجم ميكروسى برو ، يمكن أن تكون الثوابت : حروف ، أعداد صحيحة ، أعداد حقيقية ، سلاسل نصية ، ومتغيرات التعداد المرتبة .
الثوابت الحرفية Character Constants :
الثابت الحرفى يحتل بايت واحد من ذاكرة البرنامج . يتم إعلان (تعريف) الثابت عن طريق تحديد الحرف بين علامتى اقتباس فردية 'F'. فى المثال التالى ، يتم إعلان الثابت المسمى FirstName كحرف ثابت وتخصيص القيمة ‘D’ له بالصيغة التالية :
ثوابت العدد الصحيح Integer Constants :
• ثوابت العدد الصحيح تحتل 2 بايت من ذاكرة البرنامج . هذه الثوابت يمكن تحديدها باستخدام الأساس العشرى ، أو السداسى عشر ، أو الثمانى ، أو الثنائى . نوع بيانات الثابت يتم اشتقاقه بواسطة المترجم تلقائيا ، استنادا على قيمة الثابت . على سبيل المثال ، الثابت بالقيمة (130) يتم حفظه كنوع حرفى بدون إشارة unsigned char ، والثابت بالقيمة 12 000 يتم حفظه كعدد صحيح بدون إشارة unsigned int ، والثابت بالقيمة -22 500)) يتم حفظه كعدد صحيح بإشارة signed int .
فى المثال التالى يتم تعريف كل من MIN و MAX كثوابت بالقيمة (0) و (200) على الترتيب :
• الأعداد السداسية عشر لها مدى من (0) إلى (9) ومن (A) إلى (F) . يتم تحديد الثوابت السداسية عشر عن طريق إدراج الحروف (0x) أو (0X) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MAX ليكون له القيمة السداسية عشر (FFF) :
• الأعداد الثمانية لها مدى من (0) إلى (7) . يتم تحديد الثوابت الثمانية عن طريق إدراج الرقم صفر (0) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MAX ليكون له القيمة الثمانية (177) :
• الأعداد الثنائية يمكن أن تكون (0) أو (1) . يتم تحديد هذه الأعداد عن طريق إدراج الحروف (0b) أو (0B) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MIN ليكون له القيمة الثنائية
(01 101 111) :
ثوابت الأعداد الحقيقية Floating Point Constants :
ثوابت الأعداد الحقيقية هى ثوابت أعداد غير صحيحة لها جزء عشرى ، ونقطة (علامة عشرية) ، وجزء كسرى . بالإضافة إلى ذلك ، من أجل الأعداد الكبيرة جدا أو الأعداد الصغيرة جدا يمكن تحديد الجزء الأسى عن طريق إدراج الحرف ( e ) أو الحرف ( E ) مع قيمة الأس فى نهاية العدد . فى المثال التالى ، الثابت MIN يعطى القيمة 0.15E-2 والمتغير MAX يعطى القيمة 25.5E10 :
ثوابت السلسلة النصية String Constants :
تتكون ثوابت السلسة النصية من مجوعات من الحروف محاطة بعلامتى اقتباس مزدوجة ("..") . فيما يلى مثال لثابت سلسلة نصية :
كما سوف نرى لاحقا أن السلاسل النصية تصنع من مصفوفات الحروف .
الثوابت مهمة جدا فى برمجة الميكروكونترولر PIC مع المترجم ميكروسى برو ، وخاصة إذا كانت ذاكرة البيانات RAM لها حجم محدود . يتم تخزين المتغيرات الثابتة فى ذاكرة البرنامج (الفلاش) ، وبالتالى توفير تحرير مساحة ذاكرة بيانات RAM المحدودة . الثوابت أو القيم المحددة تمثل قيم ثابتة لعدد أو لحرف .
فى المترجم ميكروسى برو ، يمكن أن تكون الثوابت : حروف ، أعداد صحيحة ، أعداد حقيقية ، سلاسل نصية ، ومتغيرات التعداد المرتبة .
الثوابت الحرفية Character Constants :
الثابت الحرفى يحتل بايت واحد من ذاكرة البرنامج . يتم إعلان (تعريف) الثابت عن طريق تحديد الحرف بين علامتى اقتباس فردية 'F'. فى المثال التالى ، يتم إعلان الثابت المسمى FirstName كحرف ثابت وتخصيص القيمة ‘D’ له بالصيغة التالية :
- الكود:
const FirstName;
FirstName = ‘D’;
ثوابت العدد الصحيح Integer Constants :
• ثوابت العدد الصحيح تحتل 2 بايت من ذاكرة البرنامج . هذه الثوابت يمكن تحديدها باستخدام الأساس العشرى ، أو السداسى عشر ، أو الثمانى ، أو الثنائى . نوع بيانات الثابت يتم اشتقاقه بواسطة المترجم تلقائيا ، استنادا على قيمة الثابت . على سبيل المثال ، الثابت بالقيمة (130) يتم حفظه كنوع حرفى بدون إشارة unsigned char ، والثابت بالقيمة 12 000 يتم حفظه كعدد صحيح بدون إشارة unsigned int ، والثابت بالقيمة -22 500)) يتم حفظه كعدد صحيح بإشارة signed int .
فى المثال التالى يتم تعريف كل من MIN و MAX كثوابت بالقيمة (0) و (200) على الترتيب :
- الكود:
const MIN = 0;
const MAX = 200;
• الأعداد السداسية عشر لها مدى من (0) إلى (9) ومن (A) إلى (F) . يتم تحديد الثوابت السداسية عشر عن طريق إدراج الحروف (0x) أو (0X) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MAX ليكون له القيمة السداسية عشر (FFF) :
- الكود:
const MAX = 0xFFF;
• الأعداد الثمانية لها مدى من (0) إلى (7) . يتم تحديد الثوابت الثمانية عن طريق إدراج الرقم صفر (0) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MAX ليكون له القيمة الثمانية (177) :
- الكود:
const MAX = 0177;
• الأعداد الثنائية يمكن أن تكون (0) أو (1) . يتم تحديد هذه الأعداد عن طريق إدراج الحروف (0b) أو (0B) أمام العدد . فى المثال التالى ، يتم تعريف الثابت MIN ليكون له القيمة الثنائية
(01 101 111) :
- الكود:
const MIN = 0b01101111;
ثوابت الأعداد الحقيقية Floating Point Constants :
ثوابت الأعداد الحقيقية هى ثوابت أعداد غير صحيحة لها جزء عشرى ، ونقطة (علامة عشرية) ، وجزء كسرى . بالإضافة إلى ذلك ، من أجل الأعداد الكبيرة جدا أو الأعداد الصغيرة جدا يمكن تحديد الجزء الأسى عن طريق إدراج الحرف ( e ) أو الحرف ( E ) مع قيمة الأس فى نهاية العدد . فى المثال التالى ، الثابت MIN يعطى القيمة 0.15E-2 والمتغير MAX يعطى القيمة 25.5E10 :
- الكود:
const MIN = 0.15E-2;
const MAX = 25.5E10;
ثوابت السلسلة النصية String Constants :
تتكون ثوابت السلسة النصية من مجوعات من الحروف محاطة بعلامتى اقتباس مزدوجة ("..") . فيما يلى مثال لثابت سلسلة نصية :
- الكود:
"This is a string"
كما سوف نرى لاحقا أن السلاسل النصية تصنع من مصفوفات الحروف .
رد: ما هو الميكروكونترولر Microcontroller ؟
الوصول إلى بتات السجلات :
هناك العديد من الحالات حيث قد نرغب فى الوصول إلى البتات الفردية لسجل 8 بت .
إذا أردنا الوصول إلى بت لسجل داخلى بالميكروكونترولر :
• إذا كنا نعرف اسم بت السجل المراد الوصول إليها ، عندئذ يمكننا ببساطة "كتابة اسم البت ويتم تحديدها set (جعلها بواحد) أو مسحها clear (تصفيرها) كما هو مطلوب . فيما يلى مثال على ذلك :
• يمكننا أيضا استخدام معرفات البتات B0, B1, . . . . B7 أو F0, F1, . . . . . F7 ، باعتبار أن (0) هى البت الأدنى قيمة LSB (أقصى اليمين) ، و (7) هى البت الأقصى قيمة MSB . فيما يلى مثال ، لتحديد البت bit 0 بالسجل INCON نستخدم الصيغة التالية :
ولتحديد البت bit 3 يمكن كتابة مايلى :
البت من نوع sbit :
المترجم ميكروسى برو به نوع من بيانات البتات يسمى sbit ، والذى يوفر "الوصول إلى البتات الخاصة بسجلات الوظائف الخاصة SFRs الداخلية للميكروكونترولر " . يمكنك الوصول إلى البتات الداخلية للسجلات كما فى الأمثلة التالية :
أو بدلا من ذلك ومكافىء له :
البت من نوع bit :
المترجم ميكروسى برو يدعم أيضا "تعريف بت واحدة باستخدام النوع bit . فيما يلى مثال يوضح ذلك :
هناك العديد من الحالات حيث قد نرغب فى الوصول إلى البتات الفردية لسجل 8 بت .
إذا أردنا الوصول إلى بت لسجل داخلى بالميكروكونترولر :
• إذا كنا نعرف اسم بت السجل المراد الوصول إليها ، عندئذ يمكننا ببساطة "كتابة اسم البت ويتم تحديدها set (جعلها بواحد) أو مسحها clear (تصفيرها) كما هو مطلوب . فيما يلى مثال على ذلك :
- الكود:
GIE_bit = 0; //Clear GIE bit
• يمكننا أيضا استخدام معرفات البتات B0, B1, . . . . B7 أو F0, F1, . . . . . F7 ، باعتبار أن (0) هى البت الأدنى قيمة LSB (أقصى اليمين) ، و (7) هى البت الأقصى قيمة MSB . فيما يلى مثال ، لتحديد البت bit 0 بالسجل INCON نستخدم الصيغة التالية :
- الكود:
INTCON.B0 = 1; //Set bit 0 of register INTCON
ولتحديد البت bit 3 يمكن كتابة مايلى :
- الكود:
INTCON.F3 = 1; //Set bit 3 of register INTCON
البت من نوع sbit :
المترجم ميكروسى برو به نوع من بيانات البتات يسمى sbit ، والذى يوفر "الوصول إلى البتات الخاصة بسجلات الوظائف الخاصة SFRs الداخلية للميكروكونترولر " . يمكنك الوصول إلى البتات الداخلية للسجلات كما فى الأمثلة التالية :
- الكود:
sbit LEDA at PORTA.B0; //LEDA is assigned to bit 0 of PORT A
sbit LEDB at PORTA.B7; //LEDB is assigned to bit 7 of PORT A
أو بدلا من ذلك ومكافىء له :
- الكود:
sbit LEDA at RA0_bit; //LEDA is assigned to bit 0 of PORT A
sbit LEDB at RA7_bit; //LEDB is assigned to bit 7 of PORT A
البت من نوع bit :
المترجم ميكروسى برو يدعم أيضا "تعريف بت واحدة باستخدام النوع bit . فيما يلى مثال يوضح ذلك :
- الكود:
bit xf;
رد: ما هو الميكروكونترولر Microcontroller ؟
المصفوفات Arrays :
المصفوقات الرقمية :
أثناء تطوير (إنشاء) البرنامج ، عادة ما يكون هناك حاجة (ضرورة) لمعالجة العديد من "بنود البيانات من نفس النوع" . على سبيل المثال ، برنامج مصمم لقراءة أعمار 50 طالب فى حجرة صف ، فقد يتبادر للذهن من أول وهلة أننا بحاجة لاستخدام 50 متغير منفصل من نوع الأعداد الصحيحة . لكن ، مثل هذا النهج يجعل من الصعب معالجة البيانات ، حيث أنه علينا الوصول لكل عدد صحيح بشكل منفصل . علاوة على ذلك ، إذا زاد عدد الصف إلى 70 طالب ، على سبيل المثال ، عنئذ علينا إدخال 20 عدد صحيح أخرى و20 عبارة أخرى لمعالجة المدخلات الجديدة .
الحل لهذه المشكلة هو استخدام المصفوفة array كوسيلة سهلة لجمع البنود ذات الصلة تحت اسم متغير واحد . يتم إعلان (تعريف) المصفوفة عن طريق " تحديد اسمها ، ونوع وعدد عناصرها " التى عليها تخزينها . على سبيل المثال ، فيما يلى صيغة إعلان مصفوفة "أعداد صحيحة بدون إشارة" ، تسمى Average ، وبها خمس عناصر :
يتم حفظ المصفوفة فى أماكن (مواقع) ذاكرة متتابعة (متسلسلة) كما هو موضح بالشكل التالى :
فى هذا المثال ، أول عنصر "رقمه المسلسل صفر " index 0 ، وآخر عنصر رقمه المسلسل (4) . يتم عنونة عناصر المصفوفة عن طريق "كتابة اسم المصفوفة متبوعا بقوسين مربعين ( […] ) بداخلهما الرقم المسلسل للعنصر المحدد" . على سبيل المثال ، لتحديد "العنصر الثالث" بالمصفوفة بالقيمة "120" يمكن كتابة مايلى :
بالمثل ، على سبيل المثال ، لنسخ محتويات العنصر الثالت من المصفوفة إلى متغير يسمى MyValue يمكننا كتابة ما يلى :
كلما واجه المترجم تعريف لمصفوفة ، يتم تنفيذ عملية حسابية لتحديد متطلبات تخزين كل عنصر .
يمكن "تهيئة البداية" لمحتويات المصفوفة خلال إعلان المصفوفة عن طريق تحديد عناصر المصفوفة ، مفصولة بفواصل ، ومحاطة بأقواس مجعدة ( {..,..,..} ) . فيما يلى مثال لمصفوفة تسمى numbers ، بها 10 عناصر ، وفيها العنصر الأول numbers[0] = 0 ، والعنصر الثانى numbers[1] = وهلم جرا :
يمكن إعلان نفس المصفوفة ، بدون تحديد "حجم المصفوفة" كما يلى . هنا ، "يحدد المترجم" حجم المصفوفة و "يخصص" عدد البايتات المطلوبة بالذاكرة :
لاحظ أنه ليس من الضرورى "التهيئة الابتدائية" لجميع عناصر المصفوفة . على سبيل المثال ، يمكننا التهيئة الابتدائية للعناصر الثلاثة الأولى فقط من المصفوفة وترك باقى العناصر بدون تهيئة ابتدائية ليكون التعريف كما يلى :
فى هذه الحالة تم التهيئة الابتدائية للعناصر [0] , [1] , [2] ، على الرغم من أنه سوف يتم حجز تخزين لعشر عناصر . هنا ، أى عناصر متبقية بدون تهيئة ابتدائية يتم تهيئتها ضمنيا بصفر .
ملحوظة :
من الخطأ أن يكون هناك عناصر أكثر من تعريف حجم المصفوفة . على سبيل المثال ، التعريف التالى سوف يولد خطأ للمترجم :
كلما تم تهيئة مصفوفة ، فإن المترجم ينسخ البيانات المحددة إلى عناصر المصفوفة . فإذا حدث وكانت المصفوفة داخل دالة ، عندئذ فى كل مرة يتم استدعاء الدالة ، سوف يتم إعادة تحميل عناصر المصفوفة ، مما يتسبب فى تأخير لا لزوم له . لهذا السبب ، يجب أن نستخدم الكلمة الخاصة static لإجبار عناصر المصفوفة ليتم تحميلها مرة واحدة فقط عند بداية البرنامج ، كما يلى :
المصفوفات ذات الأبعاد المتعددة :
فى المترجم ميكروسى برو ، يمكننا أيضا إعلان المصفوفة ذات الأبعاد المتعددة . تستخدم مثل هذه المصفوفات عادة فى العمليات الحسابية ، مثل حسابات المتجه والمصفوفات .
يتم إعلان المصفوفات ذات الأبعاد المتعددة عن طريق تحديد "نوع البيانات" ، و "اسم المصفوفة" و "حجم كل بعد بالمصفوفة" . فى المثال التالى ، يتم تعريف مصفوفة ذات بعدين باسم MyMatrix ، بها "ثلاثة صفوف" و "عمودين" :
هذه المصفوفة لها البناء التالى : المصفوفة بها أجمالى 6 عناصر . العنصر الأول من المصفوفة هو
MyMatrix[0][0] ، والعنصر الأخير هو MyMatrix[2][1] ، كما فى الجدول التالى :
يمكن التهيئة الابتدائية للمصفوفة ذات الأبعاد المتعددة كما سبق ، عن طريق تحديد العناصر داخل أقواس مجعدة ومفصولة بفواصل ، كما فى المثال التالى :
فى المثال السابق لدينا "2 صف" و "3 عامود" . قيمة كل عنصر يمكن بيانها كما يلى :
حجم "البعد الأول" اختيارى ويمكن أن يترك فارغا ، كما هو مبين فيما بعد للمثال أعلاه . يقوم المترجم بالملىء بالحجم الصحيح خلال الترجمة :
مصفوفات الحروف Character Arrays :
يتم إعلان مصفوفات الحروف بطريقة مشابهة لإعلان مصفوفات الأرقام ، حيث يتم فصل كل حرف بفاصلة واحاطتها داخل زوج من الأقواس المعرجة . فى المثال التالى ، مصفوفة الحروف MyName بها أربعة عناصر :
كما سبق ، يمكننا ترك حجم المصفوفة فارغا كما يلى :
السلاسل النصية Strings :
السلاسل النصية هى مصفوفات حروف تنتهى بحرف NULL ( قيمته بالسداسى عشر 0x0 ويكتب "\0" ) . فى المثال أدناه ، MyName هى سلسلة نصية ( مصفوفة حروف) بها خمس عناصر ، بما فى ذلك حرف الانتهاء NULL :
كما ترى من المثال أعلاه ، علينا الفصل بين كل حرف باستخدام الفاصلة وإنهاء السلسلة النصية بحرف NULL .
الطريقة البديلة والأسهل لإعلان نفس السلسة النصية تكون بالشكل التالى :
هنا ، يتم إنهاء الحروف تلقائيا بحرف NULL وهذا الخيار الثانى هو الأكثر قابلية للقراءة ، وخاصة عندما يكون المطلوب هو إعلان سلسلة طويلة . بالإضافة إلى ذلك ، سوف لن يتم إنهاء السلسة النصية بشكل صحيح إذا نسينا إدراج حرف NULL .
مثال على مصفوفات السلاسل النصية Arrays of Strings :
هناك العديد من التطبيقات ، حيث أننا قد نرغب فى إنشاء مصفوفات من السلاسل النصية فى برامجنا . فى المثال التالى ، المصفوفة Days تخزن أيام الأسبوع . لاحظ أن تحديد حجم البعد الأول "اختيارى" .
فى المثال أعلاه ، يتم تعيين (تحديد) حجم البعد الأول تلقائيا عن طريق المترجم ليكون 7 عناصر . يتم تعيين حجم البعد الثانى ليكون 10 عناصر ، والذى هو حجم أطول كلمة فى المصفوفة . لاحظ أن كل كلمة فى المصفوفة هى سلسلة نصية ومن ثم يتم إنهاؤها بحرف NULL .
الشكل التالى يبين بناء هذه المصفوفة :
ثابت السلاسل النصية Constant Strings :
فى العديد من التطبيقات قد يكون هناك حاجة لإنشاء "سلاسل نصية طويلة ثابتة" فى ذاكرة البرنامج الفلاش بالميكروكونترولر . مثل هذه السلاسل يمكن إنشاؤها كثابت لسلسلة نصية لتوفير مساحة فى ذاكرة البيانات RAM .
ملاحظات على الأحرف ومصفوفة الأحرف :
• تخزين الأحرف يختلف قليلا عن تخزين الأعداد . "الأحرف" characters فى لغة السى هى الحروف الهجائية المنفصلة letters ، والأعداد numbers والرموز الخاصة . يتم تخزين هذه الأحرف باستخدان بايت واحد أى 8 بت باستخدام "قيم" رموز أحرف كود أسكى . ومن ثم عندما نخزن الحرف ‘A’ فى متغير ، فإن لغة السى تخزن قيمة كود أسكى للحرف ‘A’ ، والتى هى العدد الصحيح 65 . لذلك يكون من الصحيح تماما ، فى لغة السى ، كتابة ما يلى :
النتيجة result سوف تكون الآن العدد العشرى 97 ، والتى هى قيمة كود أسكى للحرف ‘a’ .
فى لغة السى يتم تخزين الأحرف المنفصلة فى شكل مصفوفة بالشكل التالى :
لاحظ استخدام علامة التنصيص المفردة ‘A’ .
يتم تخزين مجموعة من الأحرف ، تسمى فى لغة السى "سلسلة" string ، بالشكل التالى :
هذا يعنى ، إعلان المتغيرcallsign بطول 6 عناصر مع تخصيص القيمة الابتدائية 9w2gu لهذه العناصر .
لعلك لاحظت أن القيمة الابتدائية 9w2gu موكنة من خمس أحرف فقط فلماذا حددنا العناصر 6 عناصر ؟
المترجم يحتاج إلى أن يعرف متى يتم إنهاء السلسلة ، يقوم المترجم بعمل ذلك عن طريق إضافة الحرف ‘\0’ ، يسمى حرف NUL ، عند نهاية السلسلة .
أيضا يمكن إعلان السلسلة عن طريق بدايتها ونهايتها بعلامة التنصيص المزدوجة “..” ، فى هذه الحالة لا تحتاج السلسة للأقواس { } المستخدمة من أجل مصفوفة البعد الواحد . لذلك كن حذرا عند إعلان السلاسل .
لإعلان وتخصيص قيمة ابتدائية لمصفوفة متغيرات سلسلة أحرف نستخدم الشكل التالى :
إذا تم الإعلان بالشكل التالى :
سوف يتم طباعة 9w2dt فقط ، أو طباعة نتيجة غير مرغوب فيها ، تذكر أنك تحتاج إلى تحديد حيز لحرف NUL أيضا . الشكل التالى يوضح مصفوفة الحروف .
مصفوفات الأحرف متعددة الأبعاد :
فى هذه الصيغة يتم إنشاء مصفوفة لها 7 صفوف rows ، وبكل صف 4 أحرف ، كما فى الشكل التالى :
لعرض يوم الجمعة Friday ، سوف يجب علينا تحديد فقط عنصر الصف كما يلى :
هذا سوف يتم عرض Fri على وحدة العرض LCD .
المصفوقات الرقمية :
أثناء تطوير (إنشاء) البرنامج ، عادة ما يكون هناك حاجة (ضرورة) لمعالجة العديد من "بنود البيانات من نفس النوع" . على سبيل المثال ، برنامج مصمم لقراءة أعمار 50 طالب فى حجرة صف ، فقد يتبادر للذهن من أول وهلة أننا بحاجة لاستخدام 50 متغير منفصل من نوع الأعداد الصحيحة . لكن ، مثل هذا النهج يجعل من الصعب معالجة البيانات ، حيث أنه علينا الوصول لكل عدد صحيح بشكل منفصل . علاوة على ذلك ، إذا زاد عدد الصف إلى 70 طالب ، على سبيل المثال ، عنئذ علينا إدخال 20 عدد صحيح أخرى و20 عبارة أخرى لمعالجة المدخلات الجديدة .
الحل لهذه المشكلة هو استخدام المصفوفة array كوسيلة سهلة لجمع البنود ذات الصلة تحت اسم متغير واحد . يتم إعلان (تعريف) المصفوفة عن طريق " تحديد اسمها ، ونوع وعدد عناصرها " التى عليها تخزينها . على سبيل المثال ، فيما يلى صيغة إعلان مصفوفة "أعداد صحيحة بدون إشارة" ، تسمى Average ، وبها خمس عناصر :
- الكود:
unsigned int Average[5];
يتم حفظ المصفوفة فى أماكن (مواقع) ذاكرة متتابعة (متسلسلة) كما هو موضح بالشكل التالى :
فى هذا المثال ، أول عنصر "رقمه المسلسل صفر " index 0 ، وآخر عنصر رقمه المسلسل (4) . يتم عنونة عناصر المصفوفة عن طريق "كتابة اسم المصفوفة متبوعا بقوسين مربعين ( […] ) بداخلهما الرقم المسلسل للعنصر المحدد" . على سبيل المثال ، لتحديد "العنصر الثالث" بالمصفوفة بالقيمة "120" يمكن كتابة مايلى :
- الكود:
Average[2] = 120;
بالمثل ، على سبيل المثال ، لنسخ محتويات العنصر الثالت من المصفوفة إلى متغير يسمى MyValue يمكننا كتابة ما يلى :
- الكود:
MyValue = Average[2];
كلما واجه المترجم تعريف لمصفوفة ، يتم تنفيذ عملية حسابية لتحديد متطلبات تخزين كل عنصر .
يمكن "تهيئة البداية" لمحتويات المصفوفة خلال إعلان المصفوفة عن طريق تحديد عناصر المصفوفة ، مفصولة بفواصل ، ومحاطة بأقواس مجعدة ( {..,..,..} ) . فيما يلى مثال لمصفوفة تسمى numbers ، بها 10 عناصر ، وفيها العنصر الأول numbers[0] = 0 ، والعنصر الثانى numbers[1] = وهلم جرا :
- الكود:
unsigned int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
يمكن إعلان نفس المصفوفة ، بدون تحديد "حجم المصفوفة" كما يلى . هنا ، "يحدد المترجم" حجم المصفوفة و "يخصص" عدد البايتات المطلوبة بالذاكرة :
- الكود:
unsigned int numbers[ ] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
لاحظ أنه ليس من الضرورى "التهيئة الابتدائية" لجميع عناصر المصفوفة . على سبيل المثال ، يمكننا التهيئة الابتدائية للعناصر الثلاثة الأولى فقط من المصفوفة وترك باقى العناصر بدون تهيئة ابتدائية ليكون التعريف كما يلى :
- الكود:
int MyNumbers[10] = {0, 2, 5};
فى هذه الحالة تم التهيئة الابتدائية للعناصر [0] , [1] , [2] ، على الرغم من أنه سوف يتم حجز تخزين لعشر عناصر . هنا ، أى عناصر متبقية بدون تهيئة ابتدائية يتم تهيئتها ضمنيا بصفر .
ملحوظة :
من الخطأ أن يكون هناك عناصر أكثر من تعريف حجم المصفوفة . على سبيل المثال ، التعريف التالى سوف يولد خطأ للمترجم :
- الكود:
int numbers[2] = {0, 3, 7, 8, 9};
كلما تم تهيئة مصفوفة ، فإن المترجم ينسخ البيانات المحددة إلى عناصر المصفوفة . فإذا حدث وكانت المصفوفة داخل دالة ، عندئذ فى كل مرة يتم استدعاء الدالة ، سوف يتم إعادة تحميل عناصر المصفوفة ، مما يتسبب فى تأخير لا لزوم له . لهذا السبب ، يجب أن نستخدم الكلمة الخاصة static لإجبار عناصر المصفوفة ليتم تحميلها مرة واحدة فقط عند بداية البرنامج ، كما يلى :
- الكود:
static int numbers[2] = {0, 5};
المصفوفات ذات الأبعاد المتعددة :
فى المترجم ميكروسى برو ، يمكننا أيضا إعلان المصفوفة ذات الأبعاد المتعددة . تستخدم مثل هذه المصفوفات عادة فى العمليات الحسابية ، مثل حسابات المتجه والمصفوفات .
يتم إعلان المصفوفات ذات الأبعاد المتعددة عن طريق تحديد "نوع البيانات" ، و "اسم المصفوفة" و "حجم كل بعد بالمصفوفة" . فى المثال التالى ، يتم تعريف مصفوفة ذات بعدين باسم MyMatrix ، بها "ثلاثة صفوف" و "عمودين" :
- الكود:
int MyMatrix[3][2];
هذه المصفوفة لها البناء التالى : المصفوفة بها أجمالى 6 عناصر . العنصر الأول من المصفوفة هو
MyMatrix[0][0] ، والعنصر الأخير هو MyMatrix[2][1] ، كما فى الجدول التالى :
يمكن التهيئة الابتدائية للمصفوفة ذات الأبعاد المتعددة كما سبق ، عن طريق تحديد العناصر داخل أقواس مجعدة ومفصولة بفواصل ، كما فى المثال التالى :
- الكود:
int numbers[2][3] = { {0, 2, 5}, {6, 8, 5} };
فى المثال السابق لدينا "2 صف" و "3 عامود" . قيمة كل عنصر يمكن بيانها كما يلى :
حجم "البعد الأول" اختيارى ويمكن أن يترك فارغا ، كما هو مبين فيما بعد للمثال أعلاه . يقوم المترجم بالملىء بالحجم الصحيح خلال الترجمة :
- الكود:
int numbers[ ][3] = { { 0, 2, 5}, {6, 8, 5} };
مصفوفات الحروف Character Arrays :
يتم إعلان مصفوفات الحروف بطريقة مشابهة لإعلان مصفوفات الأرقام ، حيث يتم فصل كل حرف بفاصلة واحاطتها داخل زوج من الأقواس المعرجة . فى المثال التالى ، مصفوفة الحروف MyName بها أربعة عناصر :
- الكود:
unsigned char MyName[4] = {‘J’, ‘O’, ‘H’, ‘N’};
كما سبق ، يمكننا ترك حجم المصفوفة فارغا كما يلى :
- الكود:
unsigned char MyName[ ] = {‘J’, ‘O’, ‘H’, ‘N’};
السلاسل النصية Strings :
السلاسل النصية هى مصفوفات حروف تنتهى بحرف NULL ( قيمته بالسداسى عشر 0x0 ويكتب "\0" ) . فى المثال أدناه ، MyName هى سلسلة نصية ( مصفوفة حروف) بها خمس عناصر ، بما فى ذلك حرف الانتهاء NULL :
- الكود:
unsigned char MyName[ ] = {‘J’, ‘O’, ‘H’, ‘N’, ‘\0’};
كما ترى من المثال أعلاه ، علينا الفصل بين كل حرف باستخدام الفاصلة وإنهاء السلسلة النصية بحرف NULL .
الطريقة البديلة والأسهل لإعلان نفس السلسة النصية تكون بالشكل التالى :
- الكود:
unsigned char MyName[ ] = “JOHN”;
هنا ، يتم إنهاء الحروف تلقائيا بحرف NULL وهذا الخيار الثانى هو الأكثر قابلية للقراءة ، وخاصة عندما يكون المطلوب هو إعلان سلسلة طويلة . بالإضافة إلى ذلك ، سوف لن يتم إنهاء السلسة النصية بشكل صحيح إذا نسينا إدراج حرف NULL .
مثال على مصفوفات السلاسل النصية Arrays of Strings :
هناك العديد من التطبيقات ، حيث أننا قد نرغب فى إنشاء مصفوفات من السلاسل النصية فى برامجنا . فى المثال التالى ، المصفوفة Days تخزن أيام الأسبوع . لاحظ أن تحديد حجم البعد الأول "اختيارى" .
- الكود:
char Days[ ][10] = { “Monday”,
“Tuesday”,
“Wednesday”,
“Thursday”,
“Friday”,
“Saturday”,
“Sunday”
};
فى المثال أعلاه ، يتم تعيين (تحديد) حجم البعد الأول تلقائيا عن طريق المترجم ليكون 7 عناصر . يتم تعيين حجم البعد الثانى ليكون 10 عناصر ، والذى هو حجم أطول كلمة فى المصفوفة . لاحظ أن كل كلمة فى المصفوفة هى سلسلة نصية ومن ثم يتم إنهاؤها بحرف NULL .
الشكل التالى يبين بناء هذه المصفوفة :
ثابت السلاسل النصية Constant Strings :
فى العديد من التطبيقات قد يكون هناك حاجة لإنشاء "سلاسل نصية طويلة ثابتة" فى ذاكرة البرنامج الفلاش بالميكروكونترولر . مثل هذه السلاسل يمكن إنشاؤها كثابت لسلسلة نصية لتوفير مساحة فى ذاكرة البيانات RAM .
- الكود:
const unsigned char Text[ ] = “This is the main menu of the program”;
ملاحظات على الأحرف ومصفوفة الأحرف :
• تخزين الأحرف يختلف قليلا عن تخزين الأعداد . "الأحرف" characters فى لغة السى هى الحروف الهجائية المنفصلة letters ، والأعداد numbers والرموز الخاصة . يتم تخزين هذه الأحرف باستخدان بايت واحد أى 8 بت باستخدام "قيم" رموز أحرف كود أسكى . ومن ثم عندما نخزن الحرف ‘A’ فى متغير ، فإن لغة السى تخزن قيمة كود أسكى للحرف ‘A’ ، والتى هى العدد الصحيح 65 . لذلك يكون من الصحيح تماما ، فى لغة السى ، كتابة ما يلى :
- الكود:
result = ‘A’ + 32;
النتيجة result سوف تكون الآن العدد العشرى 97 ، والتى هى قيمة كود أسكى للحرف ‘a’ .
فى لغة السى يتم تخزين الأحرف المنفصلة فى شكل مصفوفة بالشكل التالى :
- الكود:
char MenuOption[4] = {‘A’, ‘E’, ‘D’, ‘Q’};
لاحظ استخدام علامة التنصيص المفردة ‘A’ .
يتم تخزين مجموعة من الأحرف ، تسمى فى لغة السى "سلسلة" string ، بالشكل التالى :
- الكود:
char callsign[6] = “9w2gu”;
هذا يعنى ، إعلان المتغيرcallsign بطول 6 عناصر مع تخصيص القيمة الابتدائية 9w2gu لهذه العناصر .
لعلك لاحظت أن القيمة الابتدائية 9w2gu موكنة من خمس أحرف فقط فلماذا حددنا العناصر 6 عناصر ؟
المترجم يحتاج إلى أن يعرف متى يتم إنهاء السلسلة ، يقوم المترجم بعمل ذلك عن طريق إضافة الحرف ‘\0’ ، يسمى حرف NUL ، عند نهاية السلسلة .
أيضا يمكن إعلان السلسلة عن طريق بدايتها ونهايتها بعلامة التنصيص المزدوجة “..” ، فى هذه الحالة لا تحتاج السلسة للأقواس { } المستخدمة من أجل مصفوفة البعد الواحد . لذلك كن حذرا عند إعلان السلاسل .
لإعلان وتخصيص قيمة ابتدائية لمصفوفة متغيرات سلسلة أحرف نستخدم الشكل التالى :
- الكود:
char callsign[] = “9W2DTR”; // let compiler find the size
char handle[7] = ”Dexter”; // max char handle is 6 and 1 for ’\0’ NUL
لعرض محتويات السلسلة ، فقط يتم استخدام اسم المتغير كما يلى :
Lcd_Out(1,1,callsign);
إذا تم الإعلان بالشكل التالى :
- الكود:
char callsign[6];
callsign = “9w2dtr”
سوف يتم طباعة 9w2dt فقط ، أو طباعة نتيجة غير مرغوب فيها ، تذكر أنك تحتاج إلى تحديد حيز لحرف NUL أيضا . الشكل التالى يوضح مصفوفة الحروف .
مصفوفات الأحرف متعددة الأبعاد :
- الكود:
char dow[7][4] = {“Mon”, “Tue”, “Wed”, “Thu”, “Fri”, “Sat”, “Sun”};
فى هذه الصيغة يتم إنشاء مصفوفة لها 7 صفوف rows ، وبكل صف 4 أحرف ، كما فى الشكل التالى :
لعرض يوم الجمعة Friday ، سوف يجب علينا تحديد فقط عنصر الصف كما يلى :
- الكود:
lcd_out(1,1,dow[4]);
هذا سوف يتم عرض Fri على وحدة العرض LCD .
العوامل والمترجم ميكروسى برو C Operators :
العوامل والمترجم ميكروسى برو C Operators :
العوامل operators هى رموز تطبق على المتغيرات للقيام ببعض العمليات . على سبيل المثال ، رمز الجمع “+” هو عامل ويتسبب فى تغيير قيمة المتغير . فى المترجم ميكروسى برو يمكن تصنيف العوامل على أنها "أحادية" unary أو "ثنائية" binary . العوامل الأحادية تتطلب متغير واحد فقط وتعمل على هذا المتغير ، على سبيل المثال تغيير إشارة المتغير . ومن الجهة الأخرى ، العوامل الثنائية تعمل على متغيرين ، على سبيل المثال جمع عددين .
العوامل فى الميكروسى برو يمكن أن تكون عوامل رياضية arithmetical ، عوامل منطقية logical ، عوامل مختصة بالبت bitwise ، عوامل العلاقات (المقارنة) relational ، عوامل التخصيص أو التعيين assignment . فى هذه الجزء سوف نتناول هذه العوامل بالتفصيل ونتعرف على كيفية استخدامها فى البرامج .
العوامل الرياضية Arithmetic Operators :
تستخدم العوامل الرياضية فى إجراء العمليات الحسابية . الجدول المبين أدناه يوضح قائمة بالعوامل الرياضية . جميعنا نعرف عوامل الجمع والطرح والضرب . باقى العوامل الرياضية تحتاج لبعض الشرح والفهم قبل استخدامها .
معامل "القسمة" “\” يقوم بقسمة عددين . إذا كانت الأعداد حقيقية (عدد حقيقى وكسر عشرى) ، عندئذ فإن استخدام رياضة الكسور العشرية floating point سوف تعطى نتائج صحيحة . ولكن ، إذا كان العدديت أعداد صحيحة integer ، فإن القسمة قد تعطى نتائج خاظئة ، كما هو مبين بالمثال التالى :
• نتيجة قسمة عددين صحيحين تكون عدد صحيح ، ويتم التخلص من باقى القسمة ، كما فى المثال التالى :
عامل "الباقى" “%” يستخدم للحصول على الباقى بعد أن يتم قسمة عددين صحيحين . فى المثال التالى ، العددين 5 و 7 يتم قسمتهما باستخدام عامل الباقى والنتيجة تكون 2 وهى الباقى (فى حين أن خارج القسمة يكون 1 )
عامل التزايد التلقائى “++” يستخدم فى تزايد قيمة المتغير بواحد “1” ، بدون استخدام عامل التخصيص “=” ، كما فى المثال التالى :
بالمثل ، عامل "التناقص" التلقائى “--" يستخدم فى تناقص قيمة المتغير بواحد “1” ، بدون استخدام عامل التخصيص ، كما فى المثال التالى :
فى المثال التالى ، يتم تزايد المتغير Sum ثم بعد ذلك التخصيص إلى المتغير Total . نتيجة لذلك ، فى نهاية المطاف ، المتغير Sum يحتوى على “11” والمتغير Total يحتوى على “11” (التزايد أولا (قبل) ، ثم التخصيص) .
ملحوظة :
يمكن استخدام العوامل الرياضية من أجل التعامل مع الأحرف ، كما فى المثال التالى :
العوامل operators هى رموز تطبق على المتغيرات للقيام ببعض العمليات . على سبيل المثال ، رمز الجمع “+” هو عامل ويتسبب فى تغيير قيمة المتغير . فى المترجم ميكروسى برو يمكن تصنيف العوامل على أنها "أحادية" unary أو "ثنائية" binary . العوامل الأحادية تتطلب متغير واحد فقط وتعمل على هذا المتغير ، على سبيل المثال تغيير إشارة المتغير . ومن الجهة الأخرى ، العوامل الثنائية تعمل على متغيرين ، على سبيل المثال جمع عددين .
العوامل فى الميكروسى برو يمكن أن تكون عوامل رياضية arithmetical ، عوامل منطقية logical ، عوامل مختصة بالبت bitwise ، عوامل العلاقات (المقارنة) relational ، عوامل التخصيص أو التعيين assignment . فى هذه الجزء سوف نتناول هذه العوامل بالتفصيل ونتعرف على كيفية استخدامها فى البرامج .
العوامل الرياضية Arithmetic Operators :
تستخدم العوامل الرياضية فى إجراء العمليات الحسابية . الجدول المبين أدناه يوضح قائمة بالعوامل الرياضية . جميعنا نعرف عوامل الجمع والطرح والضرب . باقى العوامل الرياضية تحتاج لبعض الشرح والفهم قبل استخدامها .
معامل "القسمة" “\” يقوم بقسمة عددين . إذا كانت الأعداد حقيقية (عدد حقيقى وكسر عشرى) ، عندئذ فإن استخدام رياضة الكسور العشرية floating point سوف تعطى نتائج صحيحة . ولكن ، إذا كان العدديت أعداد صحيحة integer ، فإن القسمة قد تعطى نتائج خاظئة ، كما هو مبين بالمثال التالى :
- الكود:
int x, y, z;
x = 3;
y = 4;
z = x/y; //The result is 0
• نتيجة قسمة عددين صحيحين تكون عدد صحيح ، ويتم التخلص من باقى القسمة ، كما فى المثال التالى :
- الكود:
7 / 4; /* equals 1 */
7 * 3 / 4; /* equals 5 */
/* but: */
7. * 3. / 4.; /* equals 5.25 because we are working with floats */
عامل "الباقى" “%” يستخدم للحصول على الباقى بعد أن يتم قسمة عددين صحيحين . فى المثال التالى ، العددين 5 و 7 يتم قسمتهما باستخدام عامل الباقى والنتيجة تكون 2 وهى الباقى (فى حين أن خارج القسمة يكون 1 )
- الكود:
int x, y, z;
x = 5;
y = 7;
z = 7 % 5; //z = 2 (the remainder)
عامل التزايد التلقائى “++” يستخدم فى تزايد قيمة المتغير بواحد “1” ، بدون استخدام عامل التخصيص “=” ، كما فى المثال التالى :
- الكود:
int x;
x = 5;
x++; //x = 6
بالمثل ، عامل "التناقص" التلقائى “--" يستخدم فى تناقص قيمة المتغير بواحد “1” ، بدون استخدام عامل التخصيص ، كما فى المثال التالى :
- الكود:
int x;
x = 8;
x--; //x = 7
- الكود:
int Sum, Total;
Sum = 10;
Total = Sum++; //Total = 10, Sum = 11
فى المثال التالى ، يتم تزايد المتغير Sum ثم بعد ذلك التخصيص إلى المتغير Total . نتيجة لذلك ، فى نهاية المطاف ، المتغير Sum يحتوى على “11” والمتغير Total يحتوى على “11” (التزايد أولا (قبل) ، ثم التخصيص) .
- الكود:
int Sum, Total;
Sum = 10;
Total = ++Sum; //Total = 11; Sum = 11
ونفس الشىء يحدث عندما نستخدم عامل التناقص ، كما فى المثال التالى :
int Sum, Total;
Sum = 10;
Total = Sum--; //Total 10, Sum = 9
Total = --Sum; //Total = 8, Sum = 8
ملحوظة :
يمكن استخدام العوامل الرياضية من أجل التعامل مع الأحرف ، كما فى المثال التالى :
- الكود:
'A' + 32; /* equals 'a' */
'G' - 'A' + 'a'; /* equals 'g' */
رد: ما هو الميكروكونترولر Microcontroller ؟
العوامل المنطقية Logical Operators :
تستخدم العوامل المنطقية فى العمليات المنطقية والرياضية . الجدول أدناه يبين قائمة بالعوامل المنطقية بالميكروسى برو :
فيما يلى مثال لاستخدام العوامل المنطقية :
معاملات العوامل المنطقية إما أن تكون صواب true أو خطأ false ، بعبارة أخرى قيمة "غير الصفر " أو قيمة "الصفر" . نتيجة (راجع أو مردود) العوامل المنطقية دائما تكون “1” أو “0” .
نتيجة (راجع أو مردود) العامل المنطقى AND && يكون بواحد “1” فقط إذا كان تقييم معامليه بقيمة "غير الصفر" . إذا كان تقييم المعامل الأول false فلن يتم تقييم العامل الثانى ، كما فى المثال التالى :
نتيجة العامل المنطقى OR || تكون بواحد “1” إذا كان تقييم أى من معامليه بقيمة غير الصفر ، وإلا كانت النتيجة بصفر . إذا كان تقييم المعامل الأول true ، فإن العامل الثانى لن يتم تقييمه ، كما فى المثال التالى :
تستخدم العوامل المنطقية فى العمليات المنطقية والرياضية . الجدول أدناه يبين قائمة بالعوامل المنطقية بالميكروسى برو :
فيما يلى مثال لاستخدام العوامل المنطقية :
- الكود:
Assume x = 10, y = -2
x > 0 && y < 0 //Returns TRUE (1)
x > 0 //Returns TRUE (1)
y < 0 //Returns TRUE (1)
x > 0 || y < 0 //Returns TRUE (1)
x < 0 //Returns FALSE (0)
معاملات العوامل المنطقية إما أن تكون صواب true أو خطأ false ، بعبارة أخرى قيمة "غير الصفر " أو قيمة "الصفر" . نتيجة (راجع أو مردود) العوامل المنطقية دائما تكون “1” أو “0” .
نتيجة (راجع أو مردود) العامل المنطقى AND && يكون بواحد “1” فقط إذا كان تقييم معامليه بقيمة "غير الصفر" . إذا كان تقييم المعامل الأول false فلن يتم تقييم العامل الثانى ، كما فى المثال التالى :
- الكود:
a > b && c < d; /* reads as (a > b) && (c < d) */
/* if (a > b) is false (0), (c < d) will not be evaluated */
نتيجة العامل المنطقى OR || تكون بواحد “1” إذا كان تقييم أى من معامليه بقيمة غير الصفر ، وإلا كانت النتيجة بصفر . إذا كان تقييم المعامل الأول true ، فإن العامل الثانى لن يتم تقييمه ، كما فى المثال التالى :
- الكود:
a && b || c && d; /* reads as: (a && b) || (c && d) */
/* if (a && b) is true (1), (c && d) will not be evaluated */
رد: ما هو الميكروكونترولر Microcontroller ؟
العوامل المختصة بالبتات Bitwise Operators :
بالإضافة إلى العوامل الرياضية والمنطقية ، فإن العوامل المختصة بالبتات تستخدم فى تعديل بتات المتغير ، كل بت على حدة . الجدول أدناه يبين العوامل المختصة بالبتات فى الميكروسى برو .
هذه العوامل يمكن أن تستخدم فقط مغ المتغيرات من نوع العدد الصحيح .
العامل “&” يقوم بإجراء عملية AND على البتات (كل على حدة) الخاصة بعامليه . كل بت للمعامل الأول يتم عمل AND لها مع البت المناظرة للمعامل الثانى . البت الناتجة تكون واحد “1” فقط إذا كانت كل من البتين المناظرين بواحد “1” ، وإلا كانت النتيجة بصفر “0” ، كما فى المثال التالى :
العامل “|” يقوم بإجراء عملية OR على بتات معاملية (كل بت على حدة ) . كل بت من المعامل الأول يتم عمل OR لها مع البت المناظرى للمعامل الثانى . البت الناتجة تكون بواحد “1” إذا كان أى من البتات المناظرة بواحد “1” ، وإلا فإن البت الناتجة تكون بصفر ، كما فى المثال التالى :
العامل “^” يقوم بإجراء عملية XOR على بتات معامليه (كل بت على حدة ) ، كل بت من المعامل الأول يتم عمل XOR لها مع البت المناظرة للمعامل الثانى . البت الناتجة تكون بواحد “1” إذا كان أحد البتين فقط بواحد “1” ، وإلا فإن البت الناتجة تكون بصفر ، كما فى المثال التالى :
العامل “~” يقوم بإجراء عملية "تكملة" complement لبتات معامله (أحادى المعامل) . كل بت على حدة يتم "تكملتها" أى الصفر “0” يصبح واحد “1” والواحد “1” يصبح صفر “0” ، كما فى المثال التالى :
العامل “<<” يقوم بإجراء عملية "إزاحة" shift جهة "اليسار" . يتم عمل إزاحة لمعامله (أحادى المعامل) لجهة اليسار بعدد “n” من البتات ، حيث “n” يتم تحديدها بمعرفة المبرمج . يتم ملو بتات الجانب الأيمن للمتغير أى البتات ذات القيمة الأدنى LSB بأصفار ، فى حين يتم فقد البتات الموجودة على الجانب الأيسر للمتغير أى البتات ذات القيمة الأقصى MSB .
إزاحة المتغير إلى جهة اليسار بواحد بت هو نفسه مثل الضرب فى “2” ، وإزاحة المتغير إلى جهة اليسار “2” بت هو نفسه مثل الضرب فى “4” وهكذا ، لكن عملية الإزاحة تكون أسرع بكثير كما فى المثال التالى :
الشكل التالى يبين العملية الفعلية للإزاحة جهة اليسار ، المبينة فى المثال السابق :
العامل “>>” يقوم بعملية إزاحة جهة اليمين . يتم عمل إزاحة لجهة اليمين لبتات معامله (أحادى المعامل) “n” من البتات ، حيث “n” يتم تحديدها بمعرفة المبرمج . بتات الجانب الأيسر للمتغير أى البتات ذات القيمة القصوى MSB يتم ملوها بأصفار ، فى حين أن بتات الجانب الأيمن للمتغير أى البتات ذات القيمة الأدنى LSB يتم فقدها .
إزاحة المتغير لجهة اليمين بواحد بت هو نفسه قسمة المتغير على “2” ، وإزاحة المتغير “2” بت هو نفسه قسمة المتغير على “4” وهكذا ، لكن عامل الزحزحة يكون أسرع بكثير، كما فى المثال التالى :
int x, y;
x = 12;
y = x >> 2; //y = 3
الشكل التالى يبين العملية الفعلية للإزاحة جهة اليمين ، المبينة فى المثال السابق :
بالإضافة إلى العوامل الرياضية والمنطقية ، فإن العوامل المختصة بالبتات تستخدم فى تعديل بتات المتغير ، كل بت على حدة . الجدول أدناه يبين العوامل المختصة بالبتات فى الميكروسى برو .
هذه العوامل يمكن أن تستخدم فقط مغ المتغيرات من نوع العدد الصحيح .
العامل “&” يقوم بإجراء عملية AND على البتات (كل على حدة) الخاصة بعامليه . كل بت للمعامل الأول يتم عمل AND لها مع البت المناظرة للمعامل الثانى . البت الناتجة تكون واحد “1” فقط إذا كانت كل من البتين المناظرين بواحد “1” ، وإلا كانت النتيجة بصفر “0” ، كما فى المثال التالى :
- الكود:
int x, y, z;
x = 0xF0E0; //x = “1111 0000 1110 0000”
y = 0x0F71; //y = “0000 1111 0111 0001”
z = x & y; //z = “0000 0000 0110 0000” i.e. 0x0060
العامل “|” يقوم بإجراء عملية OR على بتات معاملية (كل بت على حدة ) . كل بت من المعامل الأول يتم عمل OR لها مع البت المناظرى للمعامل الثانى . البت الناتجة تكون بواحد “1” إذا كان أى من البتات المناظرة بواحد “1” ، وإلا فإن البت الناتجة تكون بصفر ، كما فى المثال التالى :
- الكود:
int x, y, z;
x = 0xF0E0; //x = “1111 0000 1110 0000”
y = 0x0F71; //y = “0000 1111 0111 0001”
z = x j y; //z = “1111 1111 1111 0001” i.e. 0xFFF1
العامل “^” يقوم بإجراء عملية XOR على بتات معامليه (كل بت على حدة ) ، كل بت من المعامل الأول يتم عمل XOR لها مع البت المناظرة للمعامل الثانى . البت الناتجة تكون بواحد “1” إذا كان أحد البتين فقط بواحد “1” ، وإلا فإن البت الناتجة تكون بصفر ، كما فى المثال التالى :
- الكود:
int x, y, z;
x = 0xF0E0; //x = “1111 0000 1110 0000”
y = 0x0F71; //y = “0000 1111 0111 0001”
z = x ^ y; //z = “1111 1111 1001 0001” i.e. 0xFF91
العامل “~” يقوم بإجراء عملية "تكملة" complement لبتات معامله (أحادى المعامل) . كل بت على حدة يتم "تكملتها" أى الصفر “0” يصبح واحد “1” والواحد “1” يصبح صفر “0” ، كما فى المثال التالى :
- الكود:
int x, y;
x = 0xF0E0; //x = “1111 0000 1110 0000”
y = ~x ; //y = “0000 1111 0001 1111” i.e. 0x0F1F
العامل “<<” يقوم بإجراء عملية "إزاحة" shift جهة "اليسار" . يتم عمل إزاحة لمعامله (أحادى المعامل) لجهة اليسار بعدد “n” من البتات ، حيث “n” يتم تحديدها بمعرفة المبرمج . يتم ملو بتات الجانب الأيمن للمتغير أى البتات ذات القيمة الأدنى LSB بأصفار ، فى حين يتم فقد البتات الموجودة على الجانب الأيسر للمتغير أى البتات ذات القيمة الأقصى MSB .
إزاحة المتغير إلى جهة اليسار بواحد بت هو نفسه مثل الضرب فى “2” ، وإزاحة المتغير إلى جهة اليسار “2” بت هو نفسه مثل الضرب فى “4” وهكذا ، لكن عملية الإزاحة تكون أسرع بكثير كما فى المثال التالى :
- الكود:
int x, y;
x = 3;
y = x << 2; //y = 12
الشكل التالى يبين العملية الفعلية للإزاحة جهة اليسار ، المبينة فى المثال السابق :
العامل “>>” يقوم بعملية إزاحة جهة اليمين . يتم عمل إزاحة لجهة اليمين لبتات معامله (أحادى المعامل) “n” من البتات ، حيث “n” يتم تحديدها بمعرفة المبرمج . بتات الجانب الأيسر للمتغير أى البتات ذات القيمة القصوى MSB يتم ملوها بأصفار ، فى حين أن بتات الجانب الأيمن للمتغير أى البتات ذات القيمة الأدنى LSB يتم فقدها .
إزاحة المتغير لجهة اليمين بواحد بت هو نفسه قسمة المتغير على “2” ، وإزاحة المتغير “2” بت هو نفسه قسمة المتغير على “4” وهكذا ، لكن عامل الزحزحة يكون أسرع بكثير، كما فى المثال التالى :
int x, y;
x = 12;
y = x >> 2; //y = 3
الشكل التالى يبين العملية الفعلية للإزاحة جهة اليمين ، المبينة فى المثال السابق :
رد: ما هو الميكروكونترولر Microcontroller ؟
عوامل العلاقة أو المقارتة Relational Operators :
تستخدم عوامل العلاقة فى العمليات "الشرطية" ، اختبار التساوى أو عدم التساوى ، والتى تغير مسار التحكم فى البرنامج .
يكون العائد (النتيجة) بواحد “1” إذا كان تقييم عملية العلاقة "صواب" TRUE ، وإلا فإن العائد يكون بصفر “0” .
الجدول التالى يبين قائمة بعوامل العلاقة بالميكروسى برو .
هذه العوامل شائعة الاستخدام فى جميع لغات البرمجة ، لكن الرموز المستخدمة قد تتغير .
من المهم أن تلاحظ أن عامل "التكافىء" “==” يتكون من علامتى تساوى . الخطأ الشائع هو استخدام علامة تساوى واحدة “=” كعامل علاقة ، والذى سوف يترجم على أنه عامل تخصيص .
فيما يلى بعض الأمثلة لاستخدام عوامل العلاقة :
تستخدم عوامل العلاقة فى العمليات "الشرطية" ، اختبار التساوى أو عدم التساوى ، والتى تغير مسار التحكم فى البرنامج .
يكون العائد (النتيجة) بواحد “1” إذا كان تقييم عملية العلاقة "صواب" TRUE ، وإلا فإن العائد يكون بصفر “0” .
الجدول التالى يبين قائمة بعوامل العلاقة بالميكروسى برو .
هذه العوامل شائعة الاستخدام فى جميع لغات البرمجة ، لكن الرموز المستخدمة قد تتغير .
من المهم أن تلاحظ أن عامل "التكافىء" “==” يتكون من علامتى تساوى . الخطأ الشائع هو استخدام علامة تساوى واحدة “=” كعامل علاقة ، والذى سوف يترجم على أنه عامل تخصيص .
فيما يلى بعض الأمثلة لاستخدام عوامل العلاقة :
- الكود:
x = 20;
x > 10; //Returns 1 (TRUE)
x <= 0; //Returns 0 (FALSE)
x != 5; //Returns 1 (TRUE)
رد: ما هو الميكروكونترولر Microcontroller ؟
عامل التخصيص Assignment Operator :
يستخدم عامل التخصيص “=” لتخصيص (تعيين) نتيجة التعبير إلى متغير ، ويسمى التخصيص البسيط . الشكل العام لعملية التخصيص يكون كما يلى :
فى المثال التالى ، مجموع المتغيرين a و b يتم تخصيصه إلى المتغير c :
المترجم ميكروسى برو يعتمد أيضا عمليات "التخصيص المركب" ، وتستخدم عندما يظهر المتغير على كل من الجانب الأيسر والجانب الأيمن لعامل التخصيص . على سبيل المثال ، اعتبر التعبير أدناه ، حيث يتم إضافة المتغير a إلى المتغير b ويتم تخزين النتيجة مرة أخرى فى المتغير a :
باستخدام عامل التخصيص المركب ، يمكننا كتابة العبارة السابقة بالشكل الآتى :
قيما يلى عوامل التخصيص المفيدة الأخرى :
ملاحظة : ترك مسافة بين العوامل ، مثل ‘+ =’ يؤدى إلى ظهور خطأ عند الترجمة .
يستخدم عامل التخصيص “=” لتخصيص (تعيين) نتيجة التعبير إلى متغير ، ويسمى التخصيص البسيط . الشكل العام لعملية التخصيص يكون كما يلى :
- الكود:
variable = expression;
فى المثال التالى ، مجموع المتغيرين a و b يتم تخصيصه إلى المتغير c :
- الكود:
c = a + b;
المترجم ميكروسى برو يعتمد أيضا عمليات "التخصيص المركب" ، وتستخدم عندما يظهر المتغير على كل من الجانب الأيسر والجانب الأيمن لعامل التخصيص . على سبيل المثال ، اعتبر التعبير أدناه ، حيث يتم إضافة المتغير a إلى المتغير b ويتم تخزين النتيجة مرة أخرى فى المتغير a :
- الكود:
a = a + b;
باستخدام عامل التخصيص المركب ، يمكننا كتابة العبارة السابقة بالشكل الآتى :
- الكود:
a += b;
قيما يلى عوامل التخصيص المفيدة الأخرى :
- الكود:
-= subtraction
*= multiplication
/= division
&= AND
|= OR
>>= right shift
<<= left shift
^= exclusive OR
ملاحظة : ترك مسافة بين العوامل ، مثل ‘+ =’ يؤدى إلى ظهور خطأ عند الترجمة .
رد: ما هو الميكروكونترولر Microcontroller ؟
التحكم فى سير البرنامج :
يتم تنفيذ معظم عبارات statements البرنامج بشكل "متتابع" sequentially ، عبارة تلو الأخرى . هناك الكثير من الحالات التى يتطلب البرنامج "اتخاد قرار" حول العملية التى يتم تنفيذها فى الخطوة التالية . يمكن تعديل التحكم فى سير فى البرنامج باستخدام "عبارات التحكم فى سير البرنامج" . هذه العبارات تتضمن تعجيل السير بناء على "الاختيار" ، والتعديل الغير مشروط للسير ، وعبارات التكرار iteration . فى هذا الجزء ، سوف نتناول هذه العبارات التى تعدل من مسار التحكم فى البرنامج .
عبارات الاختيار Selection Statements :
تستند عبارات الاختيار على التعديل "المشروط" للتحكم فى سير البرنامج . على سبيل المثال ، إذا تم تقييم "شرط" بالقيمة TRUE ، عندئذ يتم تنفيذ جزء معين من البرنامج ، وإلا يتم تنفيذ جزء مختلف .
هناك عبارتين للاختيار : عبارات “if-else” وعبارة “switch-case” .
عبارات الاختيار if-else :
عبارة if :
عبارة “if” الأساسية لها الشكل التالى ، حيث التعبير expression عادة يتضمن عوامل منطقية أو عوامل علاقات مقارنة :
• تستخدم عبارة if عندما يكون المطلوب تنفيذ عبارة ما "إذا تحقق شرط معين" .
• عبارة if تقييم (تختبر) تعبير الشرط expression الموجود داخل القوسين ( …) .
• إذا كانت نتيجة تقييم تعبير الشرط true ( قيمة غير صفرية) ، يتم تنفيذ العبارة statement (جسم if ) .
• إذا كانت نتيجة تقييم تعبير الشرط false(0) ، يتم تخطى تنفيذ العبارة statement (جسم if ) .
• لمعرفة المزيد عن تقييم تعبير الشرط ، راجع العوامل المنطقية وعوامل العلاقة .
فى المثال التالى ، إذا كان المتغير “p” يساوى “10” ، عندئذ فإن المتغير “k” يتم تزايده بواحد :
عبارة if…else :
الصيغة العامة :
• تستخدم عبارة if…else عندما يكون المطلوب تنفيذ عبارة ما statement1 عندما يتحقق شرط expression ، أوتنفيذ عبارة مختلفة statement2 إذا لم يتحقق هذا الشرط .
• عبارة “if” يمكن أن تستخدم مع “else” ، بحيث إذا كان تقييم تعبير الشرط expression بالقيمة true يتم تنفيذ العبارة التى تلى if (جسم if ) وتخطى تنفيذ العبارة التى تلى else .
• أما إذا كان تقييم التعبير expression بالقيمة false ، عندئذ يتم تخطى تنفيذ العبارة التى تلى if العبارة ، ويتم تنفيذ العبارة التى تلى “else” (جسم else) .
فى المثال التالى ، إذا كان المتغير Total يساوى MAX ، عندئذ يتم تزايد المتغير Sum بواحد ، وإلا (وأن لم يكن يساويه) يتم تناقص المتغير Sum بواحد :
• فى بعض التطبيقات ، قد نحتاج إلى تنفيذ أكثر من عبارة واحدة إذا كان الشرط TRUE أو FALSE . يتم تنفيذ ذلك بضم تلك العبارات داخل زوج من الأقواس “{}” ، كما هو مبين فى المثال التالى :
عبارة if…else المتداخلة ( عبارة if…else lf…else ):
عبارة if…else تنفذ كودين مختلفين بناء على كون اختبار الشرط بالقيمة true أو false . أحيانا يكون الاختيار من أكثر من احتمالين .
عبارة if…else المتداخلة تسمح لك بالتحقق من شروط متعددة وتنفيذ أكواد مختلفة لأكثر من شرطين .
صيغة عبارة if…else المتداخلة :
• عبارة if…else if…else تسمح لك بتنفيذ بلوك كود من بين بلوكات الأكواد الكثيرة المختلفة . إذا كنت تختبر شرط لمتغير واحد فإنه من الأفضل استخدام عبارة switch . عبارة switch غالبا ما تكون أسرع ، وواضحة البناء ، وسهلة الفهم .
يتم تنفيذ معظم عبارات statements البرنامج بشكل "متتابع" sequentially ، عبارة تلو الأخرى . هناك الكثير من الحالات التى يتطلب البرنامج "اتخاد قرار" حول العملية التى يتم تنفيذها فى الخطوة التالية . يمكن تعديل التحكم فى سير فى البرنامج باستخدام "عبارات التحكم فى سير البرنامج" . هذه العبارات تتضمن تعجيل السير بناء على "الاختيار" ، والتعديل الغير مشروط للسير ، وعبارات التكرار iteration . فى هذا الجزء ، سوف نتناول هذه العبارات التى تعدل من مسار التحكم فى البرنامج .
عبارات الاختيار Selection Statements :
تستند عبارات الاختيار على التعديل "المشروط" للتحكم فى سير البرنامج . على سبيل المثال ، إذا تم تقييم "شرط" بالقيمة TRUE ، عندئذ يتم تنفيذ جزء معين من البرنامج ، وإلا يتم تنفيذ جزء مختلف .
هناك عبارتين للاختيار : عبارات “if-else” وعبارة “switch-case” .
عبارات الاختيار if-else :
عبارة if :
عبارة “if” الأساسية لها الشكل التالى ، حيث التعبير expression عادة يتضمن عوامل منطقية أو عوامل علاقات مقارنة :
- الكود:
if(expression) statement;
• تستخدم عبارة if عندما يكون المطلوب تنفيذ عبارة ما "إذا تحقق شرط معين" .
• عبارة if تقييم (تختبر) تعبير الشرط expression الموجود داخل القوسين ( …) .
• إذا كانت نتيجة تقييم تعبير الشرط true ( قيمة غير صفرية) ، يتم تنفيذ العبارة statement (جسم if ) .
• إذا كانت نتيجة تقييم تعبير الشرط false(0) ، يتم تخطى تنفيذ العبارة statement (جسم if ) .
• لمعرفة المزيد عن تقييم تعبير الشرط ، راجع العوامل المنطقية وعوامل العلاقة .
فى المثال التالى ، إذا كان المتغير “p” يساوى “10” ، عندئذ فإن المتغير “k” يتم تزايده بواحد :
- الكود:
if(p == 10) k++;
ونظرا لأن المسافات البيضاء يتم إهمالها فى لغة السى فيمكن وضع العبارة statement فى سطر مختلف كما يلى :
if(p == 10)
k++;
عبارة if…else :
الصيغة العامة :
- الكود:
if (expression) statement1 else statement2
• تستخدم عبارة if…else عندما يكون المطلوب تنفيذ عبارة ما statement1 عندما يتحقق شرط expression ، أوتنفيذ عبارة مختلفة statement2 إذا لم يتحقق هذا الشرط .
• عبارة “if” يمكن أن تستخدم مع “else” ، بحيث إذا كان تقييم تعبير الشرط expression بالقيمة true يتم تنفيذ العبارة التى تلى if (جسم if ) وتخطى تنفيذ العبارة التى تلى else .
• أما إذا كان تقييم التعبير expression بالقيمة false ، عندئذ يتم تخطى تنفيذ العبارة التى تلى if العبارة ، ويتم تنفيذ العبارة التى تلى “else” (جسم else) .
فى المثال التالى ، إذا كان المتغير Total يساوى MAX ، عندئذ يتم تزايد المتغير Sum بواحد ، وإلا (وأن لم يكن يساويه) يتم تناقص المتغير Sum بواحد :
- الكود:
if(Total == MAX) Sum++; else Sum–;
العبارة السابقة عادة يتم كتابتها بالشكل التالى :
if(Total == MAX)
Sum++;
else
Sum–;
• فى بعض التطبيقات ، قد نحتاج إلى تنفيذ أكثر من عبارة واحدة إذا كان الشرط TRUE أو FALSE . يتم تنفيذ ذلك بضم تلك العبارات داخل زوج من الأقواس “{}” ، كما هو مبين فى المثال التالى :
- الكود:
if(Cnt > Sum)
{
i = k + 4;
j = j*2;
}
if(i == 10 && Cnt < 100)
{
r1 = 2*x;
r2 = i + 4;
}
else
{
r1 = 0;
r2 = 0;
}
عبارة if…else المتداخلة ( عبارة if…else lf…else ):
عبارة if…else تنفذ كودين مختلفين بناء على كون اختبار الشرط بالقيمة true أو false . أحيانا يكون الاختيار من أكثر من احتمالين .
عبارة if…else المتداخلة تسمح لك بالتحقق من شروط متعددة وتنفيذ أكواد مختلفة لأكثر من شرطين .
صيغة عبارة if…else المتداخلة :
- الكود:
if (testExpression1)
{
// statements to be executed if testExpression1 is true
}
else if(testExpression2)
{
// statements to be executed if testExpression1 is false and testExpression2 is true
}
else if (testExpression 3)
{
// statements to be executed if testExpression1 and testExpression2 is false and testExpression3 is true
}
.
.
else
{
// statements to be executed if all test expressions are false
}
• عبارة if…else if…else تسمح لك بتنفيذ بلوك كود من بين بلوكات الأكواد الكثيرة المختلفة . إذا كنت تختبر شرط لمتغير واحد فإنه من الأفضل استخدام عبارة switch . عبارة switch غالبا ما تكون أسرع ، وواضحة البناء ، وسهلة الفهم .
رد: ما هو الميكروكونترولر Microcontroller ؟
عبارات الاختيار باستخدام switch :
هناك حالات حيث قد نرغب فى القيام بعمل اختبارات شروط متعددة الطرق . على سبيل المثال ، فى تطبيق نوع القائمة menu ، اختيار المستخدم يتم عن طريق مقارنة عدد من الخيارات ، ويتم القيام بفعل مختلف مع كل خيار . مثل هذا البرنامج يمكن أن يتم كتابته عاديا باستخدام عبارات الاختيار من النوع if…else . ومع ذلك ، عندما يكون هناك خيارات كثيرة ، فإن استخدام if…else يجعل البرنامج صعب القراءة .
عادة تستخدم عبارة switch فى اختبارات الشروط متعددة الطرق . الشكل العام لهذه العبارة كما يلى :
عبارة switch تعمل على النحو التالى :
فى البداية يتن تقييم (اختبار) المتغير condition .
إذا كان المتغير condition يساوى condition 1 ، عنئذ يتم تنفيذ العبارات التابعة للحالة condition 1 .
وإذا كان المتغير condition يساوى condition 2 ، عندئذ يتم تنفيذ العبارات التابعة للحالة condition 2 .
هذه العملية تستمر حتى الحالة condition n ، حيث إذا كان المتغير condition يساوى condition n ، عندئذ يتم تنفيذ العبارات التابعة للحالة condition n .
إذا كان المتغير condition لا يساوى أى من الحالات conditions 1 إلى n ، عندئذ يتم تنفيذ العبارات التابعة للحالة الافتراضية default .
لاحظ استخدام عبارات break فى كل بلوك حتى نتأكد من العودة إلى نهاية عبارات switch ( بعد قوس الإغلاق) ويتم القفز خارج بلوك الاختيار . بدون عبارات break ، فإن البرنامج سوف يستمر فى تنفيذ تلك العبارات المصاحبة للحالة التالية . عبارة break الأخيرة ليست إجبارية ، لأن بلوك switch يغلق بعد هذه العبارة . الحالة الافتراضية default هى خيار ويمكن تجنبها إذا كنا متأكدين من أن المتغير condition سوف يكون مساويا لواحد من conditions 1 إلى n .
المثال التالى يوضح جزء من برنامج تم تنفيذه باستخدام كل من عبارات الاختيار if…else و switch . وظيفيا ، الكودان يساوى كل منهما الآخر .
المثال المبين أدناه ، يبين كيفية استخدام عبارة الاختيار switch .
المطلوب كتابة كود برنامج يستخدم عبارة switch لتحويل الحروف السداسية عشر من A إلى F إلى مكافئها العشرى . افرض أن حرف الدخل يتم تخزينه فى متغير يسمى chr ، والخرج يتم تخزينه فى المتغير y .
الحل : لعلك تتذكر أن المكافئات العشرية للأرقام السداسية عشر هى :
كود البرنامج المطلوب يكون بالشكل التالى :
هناك حالات حيث قد نرغب فى القيام بعمل اختبارات شروط متعددة الطرق . على سبيل المثال ، فى تطبيق نوع القائمة menu ، اختيار المستخدم يتم عن طريق مقارنة عدد من الخيارات ، ويتم القيام بفعل مختلف مع كل خيار . مثل هذا البرنامج يمكن أن يتم كتابته عاديا باستخدام عبارات الاختيار من النوع if…else . ومع ذلك ، عندما يكون هناك خيارات كثيرة ، فإن استخدام if…else يجعل البرنامج صعب القراءة .
عادة تستخدم عبارة switch فى اختبارات الشروط متعددة الطرق . الشكل العام لهذه العبارة كما يلى :
- الكود:
switch (condition)
{
case condition 1:
statements;
break;
case condition 2:
statements;
break;
....................
....................
case condition n:
statements;
break;
default:
statements;
break;
}
عبارة switch تعمل على النحو التالى :
فى البداية يتن تقييم (اختبار) المتغير condition .
إذا كان المتغير condition يساوى condition 1 ، عنئذ يتم تنفيذ العبارات التابعة للحالة condition 1 .
وإذا كان المتغير condition يساوى condition 2 ، عندئذ يتم تنفيذ العبارات التابعة للحالة condition 2 .
هذه العملية تستمر حتى الحالة condition n ، حيث إذا كان المتغير condition يساوى condition n ، عندئذ يتم تنفيذ العبارات التابعة للحالة condition n .
إذا كان المتغير condition لا يساوى أى من الحالات conditions 1 إلى n ، عندئذ يتم تنفيذ العبارات التابعة للحالة الافتراضية default .
لاحظ استخدام عبارات break فى كل بلوك حتى نتأكد من العودة إلى نهاية عبارات switch ( بعد قوس الإغلاق) ويتم القفز خارج بلوك الاختيار . بدون عبارات break ، فإن البرنامج سوف يستمر فى تنفيذ تلك العبارات المصاحبة للحالة التالية . عبارة break الأخيرة ليست إجبارية ، لأن بلوك switch يغلق بعد هذه العبارة . الحالة الافتراضية default هى خيار ويمكن تجنبها إذا كنا متأكدين من أن المتغير condition سوف يكون مساويا لواحد من conditions 1 إلى n .
المثال التالى يوضح جزء من برنامج تم تنفيذه باستخدام كل من عبارات الاختيار if…else و switch . وظيفيا ، الكودان يساوى كل منهما الآخر .
- الكود:
if(x == 1) switch(x)
statement1; {
else if(x == 2) case 1:
statement2; statement1;
else if(x == 3) break;
statement3; case 2:
else statement2;
statement4; break;
case 3:
statement3;
break;
default:
statement4;
}
المثال المبين أدناه ، يبين كيفية استخدام عبارة الاختيار switch .
المطلوب كتابة كود برنامج يستخدم عبارة switch لتحويل الحروف السداسية عشر من A إلى F إلى مكافئها العشرى . افرض أن حرف الدخل يتم تخزينه فى متغير يسمى chr ، والخرج يتم تخزينه فى المتغير y .
الحل : لعلك تتذكر أن المكافئات العشرية للأرقام السداسية عشر هى :
كود البرنامج المطلوب يكون بالشكل التالى :
- الكود:
switch (chr)
{
case ‘A’:
y = 10;
break;
case ‘B’:
y = 11;
break;
case ‘C’:
y = 12;
break;
case ‘D’:
y = 13;
break;
case ‘E’:
y = 14;
break;
case ‘F’:
y = 15;
break;
}
رد: ما هو الميكروكونترولر Microcontroller ؟
عبارات التكرار Repetition Statements :
هناك لبنة أساسية أخرى فى أى لغة برمجة وهى "التكرار" repetition، أو بناء الحلقة . فيها يتم تنفيذ واحد أو مجموعة من التعليمات مرارا وتكرارا ، حتى يتم استيفاء (تحقيق) بعض الشروط . فى الأساس ، المترجم ميكروسى برو يدعم ثلاثة أنواع من عبارات التكرار وهى حلقة while ، وحلقة do – while ، وحلقة for .
عبارة while :
الشكل العام لعبارة while كما يلى :
هنا ، يتم تنفيذ العبارة statement طالما أن تعبير الشرط expression صواب (متحقق) true . بشكل عام ، يكون عدد العبارات أكثر من واحدة ، ويتم استخدام زوج من الأقواس {..} لاحتواء العبارات كما يلى :
كيف تعمل حلقة while ؟
عند الوصول إلى حلقة while ، يتم تقييم (اختبار) تعبير الشرط expression .
• إذا كان تقييم تعبير الشرط true (غير صفرى) يتم تنفيذ كود عبارات "جسم الحلقة" statements .
• يتم تقييم تعبير الشرط مرة أخرى ، وتتكرر العملية حتى يكون التقييم false ، عندئذ لا يتم تنفيذ جسم الحلقة ويتم تخطيها إلى العبارة التى تلى قوس الغلق مباشرة .
فى المثال التالى ، يتم تشكيل حلقة ، باستخدام عبارة while ، تتكرر 10 مرات . متغير التحكم فى الحلقة هو “i" ويتم إعداده فى الحالة الابتدائية بالقيمة “0” قبل دخول الحلقة . يتم تنفيذ العبارات statements طالما أن “i" أقل من “10” . لاحظ أنه داخل الحلقة ، عداد الحلقة “i" يتم تزايده بواحد “1” عند كل تكرار .
مثال :
اكتب برنامج يقوم بإعداد مصفوفة أعداد صحيحة integer تسمى MyArray "بأصفار" ، على فرض أن المصفوفة لها 10 عناصر .
الحل :
فيما يلى البرنامج المطلوب :
عندما يتم استخدام عبارة while ، من المهم التأكد من أن الشرط الذى يحافظ على الحلقة "يتغير داخل الحلقة" ، وإلا تم تشكيل حلقة لا نهائية . فيما يلى البرنامج أعلاه مكتوب خطأ والذى لن ينهى الحلقة أبدا . يقوم هذا البرنامج بإعداد الابتدائى لعناصر المصفوفة بأصفار بشكل متكرر .
• فى بعض الأحيان قد بكون من الضرورى إنشاء حلقات لانهائية فى البرنامج . يمكن تحقيق ذلك بسهولة باستخدام عبارة while ، كما هو موضح أدناه :
هنا ، شرط تكرار الحلقة متحقق بصفة دائمة لأن تقييم “1” تكون true (غير صفرية) .
هناك لبنة أساسية أخرى فى أى لغة برمجة وهى "التكرار" repetition، أو بناء الحلقة . فيها يتم تنفيذ واحد أو مجموعة من التعليمات مرارا وتكرارا ، حتى يتم استيفاء (تحقيق) بعض الشروط . فى الأساس ، المترجم ميكروسى برو يدعم ثلاثة أنواع من عبارات التكرار وهى حلقة while ، وحلقة do – while ، وحلقة for .
عبارة while :
الشكل العام لعبارة while كما يلى :
- الكود:
while(expression) statement;
هنا ، يتم تنفيذ العبارة statement طالما أن تعبير الشرط expression صواب (متحقق) true . بشكل عام ، يكون عدد العبارات أكثر من واحدة ، ويتم استخدام زوج من الأقواس {..} لاحتواء العبارات كما يلى :
- الكود:
while(expression)
{
statements;
}
كيف تعمل حلقة while ؟
عند الوصول إلى حلقة while ، يتم تقييم (اختبار) تعبير الشرط expression .
• إذا كان تقييم تعبير الشرط true (غير صفرى) يتم تنفيذ كود عبارات "جسم الحلقة" statements .
• يتم تقييم تعبير الشرط مرة أخرى ، وتتكرر العملية حتى يكون التقييم false ، عندئذ لا يتم تنفيذ جسم الحلقة ويتم تخطيها إلى العبارة التى تلى قوس الغلق مباشرة .
فى المثال التالى ، يتم تشكيل حلقة ، باستخدام عبارة while ، تتكرر 10 مرات . متغير التحكم فى الحلقة هو “i" ويتم إعداده فى الحالة الابتدائية بالقيمة “0” قبل دخول الحلقة . يتم تنفيذ العبارات statements طالما أن “i" أقل من “10” . لاحظ أنه داخل الحلقة ، عداد الحلقة “i" يتم تزايده بواحد “1” عند كل تكرار .
- الكود:
i = 0;
while(i < 10)
{
statements;
i++;
}
مثال :
اكتب برنامج يقوم بإعداد مصفوفة أعداد صحيحة integer تسمى MyArray "بأصفار" ، على فرض أن المصفوفة لها 10 عناصر .
الحل :
فيما يلى البرنامج المطلوب :
- الكود:
void main()
{
unsigned char i;
int MyArray[10];
i = 0;
while(i < 10)
{
MyArray[i] = 0;
i++;
}
}
عندما يتم استخدام عبارة while ، من المهم التأكد من أن الشرط الذى يحافظ على الحلقة "يتغير داخل الحلقة" ، وإلا تم تشكيل حلقة لا نهائية . فيما يلى البرنامج أعلاه مكتوب خطأ والذى لن ينهى الحلقة أبدا . يقوم هذا البرنامج بإعداد الابتدائى لعناصر المصفوفة بأصفار بشكل متكرر .
- الكود:
void main()
{
unsigned char i;
int MyArray[10];
i = 0;
while(i < 10)
{
MyArray[i] = 0;
}
}
• فى بعض الأحيان قد بكون من الضرورى إنشاء حلقات لانهائية فى البرنامج . يمكن تحقيق ذلك بسهولة باستخدام عبارة while ، كما هو موضح أدناه :
- الكود:
while(1)
{
statements;
}
هنا ، شرط تكرار الحلقة متحقق بصفة دائمة لأن تقييم “1” تكون true (غير صفرية) .
رد: ما هو الميكروكونترولر Microcontroller ؟
عبارة do – while :
هذه العبارات هى اختلاف مفيد لعبارة while . الشكل العام لعبارة do – while يكون كما يلى
هنا ، يتم تنفيذ العبارات statements طالما أن التعبير expression يكون true . التعبير expression عادة يحتوى على عبارات منطقية وعبارات علاقات .
فى المثال التالى ، يتم إنهاء الحلقة بعد التكرار 10 مرات
لاحظ ، مرة أخرى ، أن الشرط الذى يحافظ على الحلقة يتم تغيره داخل الحلقة ، بحيث يتم إنهاء الحلقة بعد العدد المطلوب من التكرارات .
هناك اختلاف بين عبارة while وعبارة do – while . العبارات statements داخل حلقة while قد لا يتم تنفيذها أبدا إذا كان الشرط false . على الجانب الآخر ، العبارات statements داخل حلقة do – while يتم تنفيذها "مرة واحدة" على على الأقل ، وذلك لأنه يتم اختبار الشرط عند نهاية الحلقة .
الأمثلة التالية توضح كيفية بناء حلقة do – while واستخدامها فى البرامج :
مثال 1 :
اكتب برنامج للإعداد الابتدائى لمصفوفة أعداد صحيحة integer تسمى MyArray ، بأحاد “1s” . افترض أن المصفوفة بها 100 عنصر .
الحل : البرنامج المطلوب يكون كما يلى :
مثال 2 :
اكتب كود حلقة باستخدام عبارة do – while لنسخ سلسلة string تسمى “B” إلى سلسلة أخرى تسمى “A” .
الحل :
تذكر أن السلسلة هى مصفوفة أحرف تنتهى بحرف NULL(\0) . حلقة do – while أدناه سوف تنسخ محتويات السلسلة B إلى السلسلة A ، بما فى ذلك حرف الانتهاء NULL .
لاحظ أنه يتم تزايد “i” بعد أن يتم استخدام قيمتها كمرجع للسلسلة B .
عند استخدام عبارة do – while ، من المهم التأكد من أن الشرظ الذى يحافظ على الحلقة يتم تغيره داخل الحلقة ، وإلا يتم تشكيل حلقة لانهائية . فيما يلى البرنامج أعلاه مكتوب بخطأ والذى يؤدى إلى عدم إنتهاء الحلقة مطلقا . البرنامج يتكرر فى الإعداد الابتدائى لعناصر المصفوفة بالآحاد :
• احيانا يكون من الضرورى إنشاء حلقات لانهائية . يمكن تحقيق ذلك بسهولة باستخدام عبارة do – while كما يلى :
مثال :
اكتب برنامج لضرب مصفوفتان أعداد صحيحة اسمهما X و Y كل منهما له 10 عناصر ، وخزن المجموع فى متغير نوع العدد الصحيح والمسمى Sum .
الحل :
البرنامج المطلوب يكون بالشكل التالى :
هذه العبارات هى اختلاف مفيد لعبارة while . الشكل العام لعبارة do – while يكون كما يلى
- الكود:
do
{
statements;
} while(expression);
هنا ، يتم تنفيذ العبارات statements طالما أن التعبير expression يكون true . التعبير expression عادة يحتوى على عبارات منطقية وعبارات علاقات .
فى المثال التالى ، يتم إنهاء الحلقة بعد التكرار 10 مرات
- الكود:
i = 0;
do
{
statement;
i++;
} while(I < 10);
لاحظ ، مرة أخرى ، أن الشرط الذى يحافظ على الحلقة يتم تغيره داخل الحلقة ، بحيث يتم إنهاء الحلقة بعد العدد المطلوب من التكرارات .
هناك اختلاف بين عبارة while وعبارة do – while . العبارات statements داخل حلقة while قد لا يتم تنفيذها أبدا إذا كان الشرط false . على الجانب الآخر ، العبارات statements داخل حلقة do – while يتم تنفيذها "مرة واحدة" على على الأقل ، وذلك لأنه يتم اختبار الشرط عند نهاية الحلقة .
الأمثلة التالية توضح كيفية بناء حلقة do – while واستخدامها فى البرامج :
مثال 1 :
اكتب برنامج للإعداد الابتدائى لمصفوفة أعداد صحيحة integer تسمى MyArray ، بأحاد “1s” . افترض أن المصفوفة بها 100 عنصر .
الحل : البرنامج المطلوب يكون كما يلى :
- الكود:
void main()
{
unsigned char i;
int MyArray[100];
i = 0;
do
{
MyArray[i] = 1;
i++;
} while(i < 100);
}
مثال 2 :
اكتب كود حلقة باستخدام عبارة do – while لنسخ سلسلة string تسمى “B” إلى سلسلة أخرى تسمى “A” .
الحل :
تذكر أن السلسلة هى مصفوفة أحرف تنتهى بحرف NULL(\0) . حلقة do – while أدناه سوف تنسخ محتويات السلسلة B إلى السلسلة A ، بما فى ذلك حرف الانتهاء NULL .
لاحظ أنه يتم تزايد “i” بعد أن يتم استخدام قيمتها كمرجع للسلسلة B .
- الكود:
i = 0;
do
{
A[i] = B[i];
} while(B[i++] != ‘\0’);
عند استخدام عبارة do – while ، من المهم التأكد من أن الشرظ الذى يحافظ على الحلقة يتم تغيره داخل الحلقة ، وإلا يتم تشكيل حلقة لانهائية . فيما يلى البرنامج أعلاه مكتوب بخطأ والذى يؤدى إلى عدم إنتهاء الحلقة مطلقا . البرنامج يتكرر فى الإعداد الابتدائى لعناصر المصفوفة بالآحاد :
- الكود:
void main()
{
unsigned char i;
int MyArray[100];
i = 0;
do
{
MyArray[i] = 1;
} while(I < 100);
}
• احيانا يكون من الضرورى إنشاء حلقات لانهائية . يمكن تحقيق ذلك بسهولة باستخدام عبارة do – while كما يلى :
- الكود:
do
{
statements;
} while(1);
مثال :
اكتب برنامج لضرب مصفوفتان أعداد صحيحة اسمهما X و Y كل منهما له 10 عناصر ، وخزن المجموع فى متغير نوع العدد الصحيح والمسمى Sum .
الحل :
البرنامج المطلوب يكون بالشكل التالى :
- الكود:
void main()
{
int X[10], Y[10], Sum;
unsigned char I = 0;
Sum = 0;
do
{
Sum = Sum + X[i]*Y[i];
i++;
} while(I < 10);
}
رد: ما هو الميكروكونترولر Microcontroller ؟
عبارة for :
عبارة for هى أكثر العبارات شيوعا لإنشاء الحلقات فى البرامج .
الشكل العام لهذه العبارة كما يلى :
• حيث التعبير الأول expression1 يحدد "القيمة الابتدائية" لعداد الحلقة ويتم تقييم هذا المتغير مرة واحدة فقط بمجرد إلى الحلقة .
• والتعبير الثانى Expression 2 هو "الشرط" الذى يحافظ على استمرار الحلقة . عذا التعبير يتم تقيمه (اخباره) كل تكرار ، للتحقق مما إذا كان ينبغى استمرار الحلقة من عدمه . التعبير الثانى Expression 2 عادة يكون علمل منطقى أو عامل علاقة .
• التعبير الثالث Expression 3 هو أيضا يتم تقييمه عند نهاية كل تكرار ، وهذا التعبير يغير القيمة التى يتم اختبارها من أجل إنهاء الحلقة . هذا التعبير عادة يكون تزايد قيمة عداد الحلقة .
فى حلقة for يشيع استخدام أكثر من عبارة . فى المثال التالى يتم تكرار الحلقة 10 مرات . القيمة الابتدائية لعداد الحلقة “i" هى “0” ، ويتم تزايده بواحد “1” عند كل تكرار ، وتستمر الحلقة طالما أن “i" يكون أصغر من “10” :
فيما يلى بعض الأمثلة على استخدام عبارة for :
مثال :
اكتب برنامج لحساب مربعات الأعداد من “1” إلى “49” وخزن النتيجة فى مصفوفة أعداد صحيحة باسم Mult .
الحل :
البرنامج المطلوب يكون كما يلى :
• يمكن بسهولة "تداخل" حلقات for كما هو موضح بالمثال القادم . فى هذا المثال جميع عناصر المصفوفة ثنائية الأبعاد MyArray يتم إعدادها بأصفار (على فرض أن عناصر المصفوفة 10 ) . فى هذا المثال ، يتم تكرار الحلقة "الداخلية" 10 مرات لكل قيمة من قيم “i" للحلقة الخارجية ، وهذا يعنى أن العدد الكلى للتكرارات يكون “100” .
يمكن حذف البارامترات (التعبيرات) فى حلقة for . هناك العديد من التغييرات لحلقة for استنادا على أى بارامتر يتم حذفه . إليك بعض الأمثلة :
• إنشاء حلقة لا نهائية :
• تحديد القيمة الابتدائية خارج الحلقة :
• لإنهاء الحلقة من داخلها :
عبارة for هى أكثر العبارات شيوعا لإنشاء الحلقات فى البرامج .
الشكل العام لهذه العبارة كما يلى :
- الكود:
for(expression1; expression2; expression3) statements;
• حيث التعبير الأول expression1 يحدد "القيمة الابتدائية" لعداد الحلقة ويتم تقييم هذا المتغير مرة واحدة فقط بمجرد إلى الحلقة .
• والتعبير الثانى Expression 2 هو "الشرط" الذى يحافظ على استمرار الحلقة . عذا التعبير يتم تقيمه (اخباره) كل تكرار ، للتحقق مما إذا كان ينبغى استمرار الحلقة من عدمه . التعبير الثانى Expression 2 عادة يكون علمل منطقى أو عامل علاقة .
• التعبير الثالث Expression 3 هو أيضا يتم تقييمه عند نهاية كل تكرار ، وهذا التعبير يغير القيمة التى يتم اختبارها من أجل إنهاء الحلقة . هذا التعبير عادة يكون تزايد قيمة عداد الحلقة .
فى حلقة for يشيع استخدام أكثر من عبارة . فى المثال التالى يتم تكرار الحلقة 10 مرات . القيمة الابتدائية لعداد الحلقة “i" هى “0” ، ويتم تزايده بواحد “1” عند كل تكرار ، وتستمر الحلقة طالما أن “i" يكون أصغر من “10” :
- الكود:
for(i = 0; i < 10; i++)
{
statements;
}
فيما يلى بعض الأمثلة على استخدام عبارة for :
مثال :
اكتب برنامج لحساب مربعات الأعداد من “1” إلى “49” وخزن النتيجة فى مصفوفة أعداد صحيحة باسم Mult .
الحل :
البرنامج المطلوب يكون كما يلى :
- الكود:
void main()
{
int Mult[50];
unsigned char i;
for(i = 1; i <= 49; i++)
{
Mult[i] = i*i;
}
}
• يمكن بسهولة "تداخل" حلقات for كما هو موضح بالمثال القادم . فى هذا المثال جميع عناصر المصفوفة ثنائية الأبعاد MyArray يتم إعدادها بأصفار (على فرض أن عناصر المصفوفة 10 ) . فى هذا المثال ، يتم تكرار الحلقة "الداخلية" 10 مرات لكل قيمة من قيم “i" للحلقة الخارجية ، وهذا يعنى أن العدد الكلى للتكرارات يكون “100” .
- الكود:
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
MyArray[i][j] = 0;
}
}
يمكن حذف البارامترات (التعبيرات) فى حلقة for . هناك العديد من التغييرات لحلقة for استنادا على أى بارامتر يتم حذفه . إليك بعض الأمثلة :
• إنشاء حلقة لا نهائية :
- الكود:
for(;;)
{
statements;
}
• تحديد القيمة الابتدائية خارج الحلقة :
- الكود:
i = 0;
for(; i < 10;)
{
statements;
i++;
}
• لإنهاء الحلقة من داخلها :
- الكود:
i = 0;
for(;; i++)
{
statements;
if(i >= 10) break;
}
رد: ما هو الميكروكونترولر Microcontroller ؟
الإنهاء المبكر للحلقة :
هناك حالات حيث قد نرغب فى إنهاء الحلقة مبكرا . يتم عمل ذلك باستخدام عبرة break . عندما يقابل البرنامج هذه العبارة ، فإنه "يجبر" على القفز الغير مشروظ إلى خارج الحلقة . يمكن استخدام عبارة break مع جميع عبارات التكرار .
فى المثال التالى ، يتم إنهاء الحلقة عندما يصبح المتغير p بالقيمة 10 كما يلى :
كيف تعمل عبارة break :
عبارة continue :
عبارة continue تتخطى بعض العبارات داخل الحلقة . تستخدم عبارة continue مع عبارة اتخاذ قرار مثل if…else .
الشكل العام لعبارة continue :
كيف تعمل عبارة continue :
عبارة goto :
يمكن استخدام عبارة goto لتغيير سير التحكم فى البرنامج . يمكن استخدام هذه العبارة إما فى حد ذاتها أو مع شرط .
الشكل العام لاستخدام هذه العبارة يكون كما يلى :
فى الشكل الأول ، يقفز البرنامج إلى العبارة التى تأتى بعد اسم العنوان المسمى Loop . "العنوان" label يمكن أن يكون أى اسم صالح لمتغير ويجب أن ينتعى بالنقطتين ( : ) .
فى الشكل الثانى ، يقفز البرنامج إلى "عنوان" محدد إذا كان الشرط true .
لا ينصح بالاستخدام المفرط لعبارة goto فى البرامج ، لأنها تتسبب فى برنامج غير منظم وصعب صيانته . يمكن كتابة برامج كبيرة ومعقدة دون استخدام عبارة goto . لعل التطبيق الأكثر فائدة لعبارة goto هو إنهاء البرنامج قبل الأوان .
هناك حالات حيث قد نرغب فى إنهاء الحلقة مبكرا . يتم عمل ذلك باستخدام عبرة break . عندما يقابل البرنامج هذه العبارة ، فإنه "يجبر" على القفز الغير مشروظ إلى خارج الحلقة . يمكن استخدام عبارة break مع جميع عبارات التكرار .
فى المثال التالى ، يتم إنهاء الحلقة عندما يصبح المتغير p بالقيمة 10 كما يلى :
- الكود:
p = 0;
while(p < 100)
{
statements;
p++;
if(p == 10) break;
}
كيف تعمل عبارة break :
عبارة continue :
عبارة continue تتخطى بعض العبارات داخل الحلقة . تستخدم عبارة continue مع عبارة اتخاذ قرار مثل if…else .
الشكل العام لعبارة continue :
- الكود:
Continue;
كيف تعمل عبارة continue :
عبارة goto :
يمكن استخدام عبارة goto لتغيير سير التحكم فى البرنامج . يمكن استخدام هذه العبارة إما فى حد ذاتها أو مع شرط .
الشكل العام لاستخدام هذه العبارة يكون كما يلى :
- الكود:
statements;
Loop:
statements;
goto Label;
or
statements;
Loop:
statements;
if(condition) goto Label;
فى الشكل الأول ، يقفز البرنامج إلى العبارة التى تأتى بعد اسم العنوان المسمى Loop . "العنوان" label يمكن أن يكون أى اسم صالح لمتغير ويجب أن ينتعى بالنقطتين ( : ) .
فى الشكل الثانى ، يقفز البرنامج إلى "عنوان" محدد إذا كان الشرط true .
لا ينصح بالاستخدام المفرط لعبارة goto فى البرامج ، لأنها تتسبب فى برنامج غير منظم وصعب صيانته . يمكن كتابة برامج كبيرة ومعقدة دون استخدام عبارة goto . لعل التطبيق الأكثر فائدة لعبارة goto هو إنهاء البرنامج قبل الأوان .
رد: ما هو الميكروكونترولر Microcontroller ؟
الدوال والميكروسى برو :
بشكل عام ، يكون من ممارسة البرمجة الجيدة ، كتابة البرنامج المعقد الكبير فى صورة مجموعة من الوحدات الأصغر ، حيث يمكن اختبار كل وحدة بشكل منفصل عن الكود الرئيسى . يمكن التفكير فى "الدالة" function على أنها كود برنامج مستقل بذاته قابل للاختبار ، تم إنشاؤه لأداء مهمة محددة . يتم إنشاء الدوال أيضا عندما يكون مطلوب تكرار خوارزمية (حل برمجى) معينة فى عدة أماكن مختلفة من البرنامج الرئيسى . على سبيل المثال ، قد تكون هناك حاجة لتحويل درجة الحرارة من فهرنهيت إلى مئوية فى عدة أماكن فى البرنامج . بدلا من تكرار الكود ، فإنه يكون أكثر كفاءة ويكون البرنامج أكثر قابلية للصيانة إذا تم كتابة كود تحويل درجة الحرارة فى شكل "دالة" . يمكن بعد ذلك استدعاء هذه الدالة كلما كان ذلك مطلوبا لإجراء التحويل المطلوب .
الشكل العام لإعلان الدالة :
عادة (وليس دائما) ما تقوم الدالة بإجراء عملية معينة وإرجاع (إعادة) return بيانات إلى البرنامج القائم بالاستدعاء . النوع type فى الدالة يشير إلى نوع البيانات التى ترجعها ، والاسم name هو اسم الدالة ، وينبغى الفصل بين البارامترات parameters (إن وجدت) بفواصل . العبارات الموجودة داخل الدالة (جسم الدالة) يجب أن تطوق بزوج من الأقواس المعكوفة {…} .
فيما يلى مثال لإعلان دالة ، والتى تقوم بحساب محيط الدائرة circumference ، بدلالة نصف قطرها ، وتعود إلى البرنامج القائم بالاستدعاء . هنا ، نصف قطر الدائرة radius يتم تمريره كوسيط argument للدالة .
لنفرض أننا نريد حساب محيط الدائرة التى نصف قطرها 2.5 cm ، وتخزين النتيجة فى متغير يسمى Circ ، يمكن استدعاء الدالة السابقة كما يلى :
إليك بعض الأمثلة :
مثال :
اكتب دالتين لحساب مساحة وحجم اسطوانة ، موضحا كيف تستخدم هذه الدوال فى البرنامج لحساب مساحة وحجم اسطوانة نصف قطرها 3.0 cm وارتفاعها 12.5 cm ، خزن المساحة فى المتغير c_area والحجم فى المتغير c_volume .
الحل :
البرنامج التالى يبين الدالتين . الدالة Cyl_Area لحساب مساحة الاسطوانة ، والدالة , Cyl_Volume لحساب حجم الاسطوانة .
البرنامج الرئيسى يستدعى هذه الدوال كما هو مبين أدناه . يستخدم نصف قطر وارتفاع الاسطوانة كبارامترات للدوال . يتم تخزين المساحة فى المتغير c_area والحجم فى المتغير c_volume .
النماذج المبدئية (الأولية) للدوال Function Prototypes :
إذا لم يتم تعريف الدالة قبل استخدامها في البرنامج الرئيسي، فإن المترجم يولد خطأ. وذلك لأن المترجم لا يعرف نوع البيانات التي ترجعها الدالة ونوع بارامتراتها . الطريقة الوحيدة لتجنب رسائل الخطأ هي إنشاء نموذج مبدئى للدالة وإعلانه في بداية البرنامج قبل استدعاء الدالة من قبل البرنامج الرئيسي. ويتكون النموذج المبدئى للدالة من نوع الدالة واسمها، يليهما أنواع بارامتراتها .
فيما يلي مثال لإعلان النموذج المبدئى :
اسم البارامترات اختيارى ، ويمكن تجنبه كما يلى :
البرنامج التالى يوضح كيف يمكن تعديل البرنامج المبين أعلاه لاستخدام النماذج المبدئية ، حيث يتم إعلان النماذج المبدئية للدالة قبل البرنامج الرئيسى ، ثم يتم إعلان الدالتين بعد البرنامج الرئيسى .
الدوال الخالية (الفارغة) void Functions :
الدالة الفارغة هى إحدى الحالات التى تظهر فيها الكلمة المخصوصة (المحجوزة) void كمحدد لنوع الدالة ، للإشارة إلى أن الدالة لا ترجع أى قيمة لبرنامج الاستدعاء . بالمثل ، الدالة التى بدون بارامترات يتم تحديدها باستخدام الكلمة المخصوصة void فى قائمة بارامتراتها . مثل هذه الدالة يتم استدعاؤها بدون بارامترات .
فيما يلى مثال على دالة فارغة void ، والتى ببساطة تحدد جميع أطراف خرج المنفذ PORTB بالحالة المرتفعة . هذه الدالة ليس لها بارامترات ولا تعيد أى بيانات :
تمرير البارامترات إلى الدوال :
من المهم إدراك أنه كلما تم استدعاء دالة ببارامترات ( ما عدا المصفوفة ، والتى سوف نتناولها فى الفقرة القادمة) ، يتم تمرير جميع البارامترات إلى الدالة بواسطة قيمة . وهذا يعنى أن قيم هذه البارامترات يتم نسخها إلى الدالة واستخدامها محليا بواسطة الدالة . لا يمكن تعديل قيم هذه البارامترات بواسطة الدالة .
فيما يلى مثال بسيط لتوضيح مفهوم "تمرير البارامترات بواسطة قيمة" :
فى هذا المثال قيمة بارامتر الدالة (a) كان “5” قبل استدعاء الدالة . داخل الدالة ، النسخة المحلية لهذا البارامتر يتم تزايده إلى “6” ، لكن قيمة هذا البارامتر تظل “5” فى البرنامج الرئيسى . عندما تعود الدالة يتم تخصيص القيمة “6” للمتغير “b” .
تمرير المصفوفات إلى الدوال :
فى بعض التطبيقات ، قد نرغب فى تمرير مصفوفات إلى دوال . يعد تمرير عنصر واحد من المصفوفة أمرا سهلا . كل ما علينا فعله هو فهرسة index العنصر الذى نرغب فى تمريره . كما هو موضح فى الفقرة السابقة ، يتم تمرير مثل هذا المتغير إلى الدالة كقيمة . على سبيل المثال ، العنصر الذى فهرسه (ترتيبه) “5” بالمصفوفة MyArray ، لتمريره إلى دالة تسمى Sum وتخزين قيمة العائد فى المتغير “a” ، ببساطة يمكن كتابة ما يلى :
تمرير المصفوفة بالكامل إلى دالة أكثر تعقيدا قليلا . فى هذه الحالة ، ببساطة نكتب اسم المصفوفة فى برنامج الاستدعاء . فى رأس الدالة ينبغى علينا أن نعلن مصفوفة من نفس النوع متبوعة بزوج من الأقواس الفارغة . من المهم أن ندرك أننا لا ننسخ المصفوفة بالكامل إلى الدالة ، ولكن ببساطة نمرر عنوان العنصر الأول من المصفوفة ، وهو أيضا يساوى اسم المصفوفة . ونظرا لأنه يتم تمرير العنوان إلى الدالة ، يقال أن عناصر الدالة تم تمريرها عن طريق المرجع . نتيجة لذلك ، يمكن تعديل عناصر المصفوفة الأصلية داخل الدالة . فيما يلى مثال لتوضيح العملية .
مثال :
اكتب برنامج لتحميل مصفوفة أعداد صحيحة تسمى “N” بالقيم من “1” إلى “10” . بعد ذلك استدعى دالة لحساب مجموع عناصر المصفوفة والعودة بالمجموع إلى برنامج الاستدعاء .
الحل :
البرنامج :
يتم تهيئة مصفوفة الأعداد الصحيحة N بالقيم من 1 إلى 10 فى البرنامج الرئيسى . بعد ذلك يتم استدعاء الدالة Sum ويتم تمرير المصفوفة إلى هذه الدالة . الدالة تحسب مجموع عناصر المصفوفة وتعيد المجموع إلى المتغير s فى البرنامج الرئيسى . لاحظ أن المصفوفة تسمى N فى الدالة الرئيسية ، لكنها تسمى A فى الدالة .
بشكل عام ، يكون من ممارسة البرمجة الجيدة ، كتابة البرنامج المعقد الكبير فى صورة مجموعة من الوحدات الأصغر ، حيث يمكن اختبار كل وحدة بشكل منفصل عن الكود الرئيسى . يمكن التفكير فى "الدالة" function على أنها كود برنامج مستقل بذاته قابل للاختبار ، تم إنشاؤه لأداء مهمة محددة . يتم إنشاء الدوال أيضا عندما يكون مطلوب تكرار خوارزمية (حل برمجى) معينة فى عدة أماكن مختلفة من البرنامج الرئيسى . على سبيل المثال ، قد تكون هناك حاجة لتحويل درجة الحرارة من فهرنهيت إلى مئوية فى عدة أماكن فى البرنامج . بدلا من تكرار الكود ، فإنه يكون أكثر كفاءة ويكون البرنامج أكثر قابلية للصيانة إذا تم كتابة كود تحويل درجة الحرارة فى شكل "دالة" . يمكن بعد ذلك استدعاء هذه الدالة كلما كان ذلك مطلوبا لإجراء التحويل المطلوب .
الشكل العام لإعلان الدالة :
- الكود:
type name(parameters)
{
body
}
عادة (وليس دائما) ما تقوم الدالة بإجراء عملية معينة وإرجاع (إعادة) return بيانات إلى البرنامج القائم بالاستدعاء . النوع type فى الدالة يشير إلى نوع البيانات التى ترجعها ، والاسم name هو اسم الدالة ، وينبغى الفصل بين البارامترات parameters (إن وجدت) بفواصل . العبارات الموجودة داخل الدالة (جسم الدالة) يجب أن تطوق بزوج من الأقواس المعكوفة {…} .
فيما يلى مثال لإعلان دالة ، والتى تقوم بحساب محيط الدائرة circumference ، بدلالة نصف قطرها ، وتعود إلى البرنامج القائم بالاستدعاء . هنا ، نصف قطر الدائرة radius يتم تمريره كوسيط argument للدالة .
- الكود:
float Circumference(float radius)
{
float c;
c = 2*PI*radius;
return c;
}
لنفرض أننا نريد حساب محيط الدائرة التى نصف قطرها 2.5 cm ، وتخزين النتيجة فى متغير يسمى Circ ، يمكن استدعاء الدالة السابقة كما يلى :
- الكود:
Circ = Circumference(2.5);
إليك بعض الأمثلة :
مثال :
اكتب دالتين لحساب مساحة وحجم اسطوانة ، موضحا كيف تستخدم هذه الدوال فى البرنامج لحساب مساحة وحجم اسطوانة نصف قطرها 3.0 cm وارتفاعها 12.5 cm ، خزن المساحة فى المتغير c_area والحجم فى المتغير c_volume .
الحل :
البرنامج التالى يبين الدالتين . الدالة Cyl_Area لحساب مساحة الاسطوانة ، والدالة , Cyl_Volume لحساب حجم الاسطوانة .
- الكود:
//
// This function calculate the area of a cylinder. The radius and height
// are passed as parameters to the function
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculate the volume of a cylinder. The radius and height
// are passed as parameters to the function
//
Float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
البرنامج الرئيسى يستدعى هذه الدوال كما هو مبين أدناه . يستخدم نصف قطر وارتفاع الاسطوانة كبارامترات للدوال . يتم تخزين المساحة فى المتغير c_area والحجم فى المتغير c_volume .
- الكود:
/*-----------------------------------------------------------------------------------------------
This program calculates the area and volume of a cylinder. The radius and height
of the cylinder are passed as parameters to two functions which calculate the
area and the volume.
In this example the radius and height are assumed to be 3.0cm and 12.5cm
respectively.
The area is stored in variable c_area, and the volume is stored in variable
c_volume.
------------------------------------------------------------------------------------------------*/
//
// This function calculates the area of a cylinder. The radius and height are passed
// as parameters to the function
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculates the volume of a cylinder. The radius and height are
// passed as parameters to the function
//
float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
//
// Main program
//
void main()
{
float r, h, c_area, c_volume;
r = 3.0; // The radius
h = 12.5; // The height
c_area = Cyl_Area(r, h); // Calculate the area
c_volume = Cyl_Volume(r, h); // Calculate the volume
}
النماذج المبدئية (الأولية) للدوال Function Prototypes :
إذا لم يتم تعريف الدالة قبل استخدامها في البرنامج الرئيسي، فإن المترجم يولد خطأ. وذلك لأن المترجم لا يعرف نوع البيانات التي ترجعها الدالة ونوع بارامتراتها . الطريقة الوحيدة لتجنب رسائل الخطأ هي إنشاء نموذج مبدئى للدالة وإعلانه في بداية البرنامج قبل استدعاء الدالة من قبل البرنامج الرئيسي. ويتكون النموذج المبدئى للدالة من نوع الدالة واسمها، يليهما أنواع بارامتراتها .
فيما يلي مثال لإعلان النموذج المبدئى :
- الكود:
float Circumference(float radius);
اسم البارامترات اختيارى ، ويمكن تجنبه كما يلى :
- الكود:
float Circumference(float);
البرنامج التالى يوضح كيف يمكن تعديل البرنامج المبين أعلاه لاستخدام النماذج المبدئية ، حيث يتم إعلان النماذج المبدئية للدالة قبل البرنامج الرئيسى ، ثم يتم إعلان الدالتين بعد البرنامج الرئيسى .
- الكود:
/*-----------------------------------------------------------------------------------------------
This program calculates the area and volume of a cylinder. The radius and height
of the cylinder are passed as parameters to two functions which calculate the
area and the volume.
In this example the radius and height are assumed to be 3.0cm and 12.5cm
respectively.
The area is stored in variable c_area, and the volume is stored in variable
c_volume.
------------------------------------------------------------------------------------------------*/
float Cyl_Area(float, float);
float Cyl_Volume(float, float);
//
// Main program
//
void main()
{
float r, h, c_area, c_volume;
r = 3.0; // The radius
h = 12.5; // The height
c_area = Cyl_Area(r, h); // Calculate the area
c_volume = Cyl_Volume(r, h); // Calculate the volume
}
//
// This function calculates the area of a cylinder
//
float Cyl_Area(float radius, float height)
{
float c;
c = 2*PI*radius*height;
return c;
}
//
// This function calculates the volume of a cylinder
//
float Cyl_Volume(float radius, float height)
{
float c;
c = PI*radius*radius*height;
return c;
}
الدوال الخالية (الفارغة) void Functions :
الدالة الفارغة هى إحدى الحالات التى تظهر فيها الكلمة المخصوصة (المحجوزة) void كمحدد لنوع الدالة ، للإشارة إلى أن الدالة لا ترجع أى قيمة لبرنامج الاستدعاء . بالمثل ، الدالة التى بدون بارامترات يتم تحديدها باستخدام الكلمة المخصوصة void فى قائمة بارامتراتها . مثل هذه الدالة يتم استدعاؤها بدون بارامترات .
فيما يلى مثال على دالة فارغة void ، والتى ببساطة تحدد جميع أطراف خرج المنفذ PORTB بالحالة المرتفعة . هذه الدالة ليس لها بارامترات ولا تعيد أى بيانات :
- الكود:
void SET_LED(void)
{
PORTB = 0xFF;
}
تمرير البارامترات إلى الدوال :
من المهم إدراك أنه كلما تم استدعاء دالة ببارامترات ( ما عدا المصفوفة ، والتى سوف نتناولها فى الفقرة القادمة) ، يتم تمرير جميع البارامترات إلى الدالة بواسطة قيمة . وهذا يعنى أن قيم هذه البارامترات يتم نسخها إلى الدالة واستخدامها محليا بواسطة الدالة . لا يمكن تعديل قيم هذه البارامترات بواسطة الدالة .
فيما يلى مثال بسيط لتوضيح مفهوم "تمرير البارامترات بواسطة قيمة" :
- الكود:
float Inc(float x)
{
x++;
return x;
}
//
// Main program
//
void main()
{
float a, b;
a = 5.0; // a = 5.0
b = Inc(a); // a = 5.0, b = 6.0
}
فى هذا المثال قيمة بارامتر الدالة (a) كان “5” قبل استدعاء الدالة . داخل الدالة ، النسخة المحلية لهذا البارامتر يتم تزايده إلى “6” ، لكن قيمة هذا البارامتر تظل “5” فى البرنامج الرئيسى . عندما تعود الدالة يتم تخصيص القيمة “6” للمتغير “b” .
تمرير المصفوفات إلى الدوال :
فى بعض التطبيقات ، قد نرغب فى تمرير مصفوفات إلى دوال . يعد تمرير عنصر واحد من المصفوفة أمرا سهلا . كل ما علينا فعله هو فهرسة index العنصر الذى نرغب فى تمريره . كما هو موضح فى الفقرة السابقة ، يتم تمرير مثل هذا المتغير إلى الدالة كقيمة . على سبيل المثال ، العنصر الذى فهرسه (ترتيبه) “5” بالمصفوفة MyArray ، لتمريره إلى دالة تسمى Sum وتخزين قيمة العائد فى المتغير “a” ، ببساطة يمكن كتابة ما يلى :
- الكود:
a = Sum(MyArray[5]);
تمرير المصفوفة بالكامل إلى دالة أكثر تعقيدا قليلا . فى هذه الحالة ، ببساطة نكتب اسم المصفوفة فى برنامج الاستدعاء . فى رأس الدالة ينبغى علينا أن نعلن مصفوفة من نفس النوع متبوعة بزوج من الأقواس الفارغة . من المهم أن ندرك أننا لا ننسخ المصفوفة بالكامل إلى الدالة ، ولكن ببساطة نمرر عنوان العنصر الأول من المصفوفة ، وهو أيضا يساوى اسم المصفوفة . ونظرا لأنه يتم تمرير العنوان إلى الدالة ، يقال أن عناصر الدالة تم تمريرها عن طريق المرجع . نتيجة لذلك ، يمكن تعديل عناصر المصفوفة الأصلية داخل الدالة . فيما يلى مثال لتوضيح العملية .
مثال :
اكتب برنامج لتحميل مصفوفة أعداد صحيحة تسمى “N” بالقيم من “1” إلى “10” . بعد ذلك استدعى دالة لحساب مجموع عناصر المصفوفة والعودة بالمجموع إلى برنامج الاستدعاء .
الحل :
البرنامج :
- الكود:
/*-----------------------------------------------------------------------------------------------
This program demonstrates how an array can be passed to a function. Here, array N is initialized with numbers 1 to 10. Then, function Sum is called to calculate the sum of the array elements. The sum is then returned to the main program and stored in variable s
------------------------------------------------------------------------------------------------*/
//
// This function calculates the sum of the elements of an array
//
int Sum(int A[ ])
{
char i;
int Total = 0;
for(i = 0; i < 10; i++) Total = Total + A[i];
return Total;
}
//
// Main program
//
void main()
{
int s, N[10];
char i;
for(i = 0; i < 10; i++) N[i] = i + 1; // Initialize array N
s = Sum(N); // Calculate the sum of elements
}
يتم تهيئة مصفوفة الأعداد الصحيحة N بالقيم من 1 إلى 10 فى البرنامج الرئيسى . بعد ذلك يتم استدعاء الدالة Sum ويتم تمرير المصفوفة إلى هذه الدالة . الدالة تحسب مجموع عناصر المصفوفة وتعيد المجموع إلى المتغير s فى البرنامج الرئيسى . لاحظ أن المصفوفة تسمى N فى الدالة الرئيسية ، لكنها تسمى A فى الدالة .
رد: ما هو الميكروكونترولر Microcontroller ؟
التوصيل الأساسى للميكروكونترولر BASIC CONNECTION
لكى يتمكن الميكروكونترولر من العمل الصحيح يجب توفير الآتى :
• مصدر للقدرة Power Supply .
• إشارة "الإعادة" أو "التصفير" Reset .
• إشارة نبضات الساعة Clock .
الشكل العلوى يبين أحد الدوائر البسيطة وهى ليست هكذا دائما لكنها كافية فى الوقت الحاضر .
1- مصدر القدرة POWER SUPPLY
على الرغم من أن الميكروكونترولر PIC16F887 يمكنه العمل عند جهود قدرة مختلفة إلا أن مصدر القدرة بالجهد 5V DC هو الأكثر ملائمة.
تستخدم الدائرة المنظم الموجب ذو الثلاثة أطراف LM7805 وهو يوفر إستقرار فى الجهد عالى الكفاءة كما يوفر تيار كافى ليمكن الميكروكونترولر والإلكترونيات المحيطة به من العمل العادى ( كافى هنا تعنى 1 أمبير).
2- إشارة الإعادة RESET SIGNAL
لكى يتمكن الميكروكونترولر من العمل الصحيح يجب تطبيق المنطق (1) (VCC) على طرف الإعادة reset المفتاح الضاغط الموصل بين طرف الإعادة MCLR والأرضى GND ليس ضرورى . ومع ذلك ، هو تقريبا دائما يستخدم لتمكين الميكروكونترولر من الرجوع بأمان إلى ظروف التشغيل العادية إذا ما سارت الأمور بشكل خاطئ .
عند الضغط على هذا المفتاح يتم توصيل الجهد 0V إلى الطرف MCLR فيقوم الميكروكونترولر بعمل إعادة reset ويبدأ البرنامج التنفيذ من البداية .
تستخدم مقاومة 10 كيلوأوم للسماح بتوصيل الجهد 0V للطرف MCLR عن طريق الضغط على المفتاح بدون حدوث دائرة قصر بين الجهد الموجب والأرضى .
3- إشارة نبضات الساعة CLOCK SIGNAL
بناء على العناصر المستخدمة بالإضافة إلى الترددات يمكن تشغيل المذبذب في أربعة أنماط مختلفة :
• كريستال بقدرة منخفضة : LP
• كريستال أو دائرة رنين : XT
• كريستال أو دائرة رنين بسرعة عالية : HS
• دائرة مكثف ومقاومة RC
لماذا هذه الأوضاع في غاية الأهمية؟
نظرا لحقيقة أنه يكاد يكون من المستحيل جعل مذبذب مستقرة وفى نفس الوقت يعمل فى مدى واسع من التردد يجب أن يعرف الميكروكونترولر الكريستال المتصل به حتى يتمكن من ضبط عمل الالكترونيات الداخلية له.
هذا هو السبب في أن جميع البرامج المستخدمة فى تحميل الشريحة تحتوي على خيار لاختيار نمط المذبذب.
أ- كريستال الكوارتز Quartz Crystal
عنداستخدام كريستال الكوارتز لتحقيق استقرار التردد فإن المذبذب الداخلى يعمل على تردد دقيق والذى لا يتأثر بالتغيرات في درجة الحرارة وجهد مصدر القدرة .عادة يكتب هذا التردد على جسم الكريستال .
يجب أيضا توصيل المكثفات C1 و C2 ت كما هو مبين بالشكل التالى .
سعة تلك المكثفات ليست ذات أهمية كبيرة. ولذلك فإن القيم الواردة في الجدول أدناه ينبغي أن تعتبر كتوصية، وليس كقاعدة صارمة.
ب- دائرة الرنين السيراميكى Ceramic Resonator
دائرة الرنين أرخص ولكنها تشبه الكريستال فى الوظيفة وفى طريقة العمل ولهذا نجد مخطط توصيلها مع الميكروكونترولر متماثل .مع ذلك فإن قيم المكثفات تختلف قليلا نتيجة لاختلاف الخصائص الكهربائية كما فى الجدول المرفق .
عادة توصل دائرة الرنين عندما لا يكون من الضرورى الحصول على تردد متناهى فى الدقة .
ت- المذبذب RC
عندما لا يكون تردد التشغيل ذات أهمية عندئذ لا تكون هناك حاجة لمكونات غالية إضافية للتثبيت . بدلا من ذلك يكتفى باستخدام دائرة RC بسيطة كما هو مبين بالشكل .
وحيث اننا سوف نستخدم مدخل المذبذب المحلى فقط فإن نبضات الساعة بتردد Fosc /4 سوف تظهر على الطرف OSC2 .هذا التردد يمثل تردد تشغيل الميكروكونترولر أى سرعة تنفيذ التعليمة .
ث- المذبذب الخارجى External Oscillator
عندما يكون المطلوب عمل تزامن فى عمل عدد من الميكروكونترولر أو إذا لأى سبب كان من غير الممكن استخدام أى من الطرق السابقة فيمكن توليد إشارة ساعة بمذبذب خارجى كما فى الشكل التالى .
لكى يتمكن الميكروكونترولر من العمل الصحيح يجب توفير الآتى :
• مصدر للقدرة Power Supply .
• إشارة "الإعادة" أو "التصفير" Reset .
• إشارة نبضات الساعة Clock .
الشكل العلوى يبين أحد الدوائر البسيطة وهى ليست هكذا دائما لكنها كافية فى الوقت الحاضر .
1- مصدر القدرة POWER SUPPLY
على الرغم من أن الميكروكونترولر PIC16F887 يمكنه العمل عند جهود قدرة مختلفة إلا أن مصدر القدرة بالجهد 5V DC هو الأكثر ملائمة.
تستخدم الدائرة المنظم الموجب ذو الثلاثة أطراف LM7805 وهو يوفر إستقرار فى الجهد عالى الكفاءة كما يوفر تيار كافى ليمكن الميكروكونترولر والإلكترونيات المحيطة به من العمل العادى ( كافى هنا تعنى 1 أمبير).
2- إشارة الإعادة RESET SIGNAL
لكى يتمكن الميكروكونترولر من العمل الصحيح يجب تطبيق المنطق (1) (VCC) على طرف الإعادة reset المفتاح الضاغط الموصل بين طرف الإعادة MCLR والأرضى GND ليس ضرورى . ومع ذلك ، هو تقريبا دائما يستخدم لتمكين الميكروكونترولر من الرجوع بأمان إلى ظروف التشغيل العادية إذا ما سارت الأمور بشكل خاطئ .
عند الضغط على هذا المفتاح يتم توصيل الجهد 0V إلى الطرف MCLR فيقوم الميكروكونترولر بعمل إعادة reset ويبدأ البرنامج التنفيذ من البداية .
تستخدم مقاومة 10 كيلوأوم للسماح بتوصيل الجهد 0V للطرف MCLR عن طريق الضغط على المفتاح بدون حدوث دائرة قصر بين الجهد الموجب والأرضى .
3- إشارة نبضات الساعة CLOCK SIGNAL
بناء على العناصر المستخدمة بالإضافة إلى الترددات يمكن تشغيل المذبذب في أربعة أنماط مختلفة :
• كريستال بقدرة منخفضة : LP
• كريستال أو دائرة رنين : XT
• كريستال أو دائرة رنين بسرعة عالية : HS
• دائرة مكثف ومقاومة RC
لماذا هذه الأوضاع في غاية الأهمية؟
نظرا لحقيقة أنه يكاد يكون من المستحيل جعل مذبذب مستقرة وفى نفس الوقت يعمل فى مدى واسع من التردد يجب أن يعرف الميكروكونترولر الكريستال المتصل به حتى يتمكن من ضبط عمل الالكترونيات الداخلية له.
هذا هو السبب في أن جميع البرامج المستخدمة فى تحميل الشريحة تحتوي على خيار لاختيار نمط المذبذب.
أ- كريستال الكوارتز Quartz Crystal
عنداستخدام كريستال الكوارتز لتحقيق استقرار التردد فإن المذبذب الداخلى يعمل على تردد دقيق والذى لا يتأثر بالتغيرات في درجة الحرارة وجهد مصدر القدرة .عادة يكتب هذا التردد على جسم الكريستال .
يجب أيضا توصيل المكثفات C1 و C2 ت كما هو مبين بالشكل التالى .
سعة تلك المكثفات ليست ذات أهمية كبيرة. ولذلك فإن القيم الواردة في الجدول أدناه ينبغي أن تعتبر كتوصية، وليس كقاعدة صارمة.
ب- دائرة الرنين السيراميكى Ceramic Resonator
دائرة الرنين أرخص ولكنها تشبه الكريستال فى الوظيفة وفى طريقة العمل ولهذا نجد مخطط توصيلها مع الميكروكونترولر متماثل .مع ذلك فإن قيم المكثفات تختلف قليلا نتيجة لاختلاف الخصائص الكهربائية كما فى الجدول المرفق .
عادة توصل دائرة الرنين عندما لا يكون من الضرورى الحصول على تردد متناهى فى الدقة .
ت- المذبذب RC
عندما لا يكون تردد التشغيل ذات أهمية عندئذ لا تكون هناك حاجة لمكونات غالية إضافية للتثبيت . بدلا من ذلك يكتفى باستخدام دائرة RC بسيطة كما هو مبين بالشكل .
وحيث اننا سوف نستخدم مدخل المذبذب المحلى فقط فإن نبضات الساعة بتردد Fosc /4 سوف تظهر على الطرف OSC2 .هذا التردد يمثل تردد تشغيل الميكروكونترولر أى سرعة تنفيذ التعليمة .
ث- المذبذب الخارجى External Oscillator
عندما يكون المطلوب عمل تزامن فى عمل عدد من الميكروكونترولر أو إذا لأى سبب كان من غير الممكن استخدام أى من الطرق السابقة فيمكن توليد إشارة ساعة بمذبذب خارجى كما فى الشكل التالى .
رد: ما هو الميكروكونترولر Microcontroller ؟
الميكروكونترولر PIC16F877A :
الميكروكونترولر PIC16F877A هو واحد من الميكروكونترولر PIC الأكثر انتشارا (شعبية) ، ومن السهل أن معرفة السبب . لأنه يأتى فى شكل دائرة متكاملة 40 طرف نوع DIP (فى صفين) ويمتلك العديد من الأجهزة الطرفية الداخلية peripherals . العيب الوحيد الذى يمكن أن يؤخذ علية هو أنه لا يمتلك ساعة clock داخلية ، مثل كثير من الميكروكونترولر PIC .
الميكروكونترولر PIC16F877A هو متحكم قوى قادر على القيام بالكثير من المهام لأنه يحتوى على ذاكرة برنامج كبيرة بما فيها الكفاية بحجم 8 كيلو كلمة 8k words ، وذاكرة RAM بحجم 368 Bytes ، وذاكرة EEPROM بحجم 256 Bytes وهذا يكفى للقيام بالعديد من المشاريع المختلفة .
السمات الأساسية :
أولا : وحدة معالجة مركزية CPU عالية الأداء ، بناء من نوع RISC ( كمبيوتر بمجموعة تعليمات مخفضة) :
• فقط تعلم 35 تعليمة كلمة واحدة .
• كل التعليمات يستغرق تنفيذها "دورة تعليمة" واحدة باستثناء تفرعات البرنامج ، التى يستغرق تنفيذها 2 دورة تعليمة .
• سرعة (تردد) التشغيل : دخل الساعة 0-20MHz ، و"دورة التعليمة" 0-200 ns .
• ذاكرة البرنامج الفلاش بحجم 8K ، وذاكرة البيانات RAM بحجم 368 بايت ، وذاكرة البيانات نوع EEPROM بحجم 256 بايت .
• ترتيب الأطراف متوافق مع الميكروكونترولر PIC16FXXX ذات 40 طرف .
ثانيا : خصائص الأجهزة الطرفية Peripheral المدمجة داخل الميكروكونترولر :
• المؤقت Timer0 : مؤقت / عداد 8-bit مع "مقياس سابق" prescaler (قاسم تردد).
• المؤقت Timer1 : مؤقت / عداد 16-bit مع مقياس سابق ، يمكن أن يتزايد خلال "النوم" sleep عن طريق الساعة/الكريستال الخارجية .
• المؤقت Timer2 : مؤقت / عداد 8-bit مع مقياس سابق ومقياس لاحق .
• 2 وحدة (موديول) CCP ، (Capture, Compare, PWM) .
• وحدة اتصال تسلسلى متزامن بنظام SPI (نظام قائد Master) ، وبنظام I2C (نظام قائد/منقاد أو تابع Master/Slave ) .
• وحدة اتصال تسلسلى ، ارسال واستقبال متزامن / غير متزامن عام USART .
• منفذ تابع متوازى PSP .
• دائرة كشف "هبوط أو انحسارالجهد" Brown-out من أجل الإعادة عند هبوط الجهد BOR .
ثالثا : الخصائص التناظرية Analog :
• محول من تناظرى لرقمى ADC بدقة تحويل 10-bit ، يغمل مع أى من ثمانى قنوات .
• الإعادة عند "هبوط الجهد" BOR .
• وحدة (موديول) مقارن تناظرى مع :
- 2 مقارن تناظرى .
- وحدة جهد مرجعى VREF قابلة للبرمجة ، مدمجة على الشريحة .
- دخل قابل للبرمجة لاختيار الدخل من مداخل الجهاز ، واختيار جهد المرجع .
- مخارج المقارن يمكن الوصول إليها خارجيا .
رابعا : الخصائص الخاصة للميكروكونترولر :
• ذاكرة برنامج فلاش محسنة ، 100,000 دورة مسح / كتابة .
• ذاكرة بيانات EEPROM ، 1,000,000 دورة مسح / كتابة .
• ذاكرة البيانات EEPROM تحتفظ بالبيانات لمدة تزيد عن 40 عام .
• قابل للبرمجة الذاتية تحت سيطرة البرمجيات .
• قلبل للبرمجة وهو بالدائرة ICSP من خلال طرفين .
• مؤقت حراسة WDT مع مذبذب RC خاص به من أجل الغمل الفعال ,
• حماية الكود ، قابل للبرمجة .
• وضع النوم Sleep ، لتوفير القدرة .
• خيارات المذبذب ، قابلة للاختيار .
• التصحيح فى الدائرة ICD من خلال طرفين .
خامسا : تقنية CMOS :
• تقتية ذاكرات فلاش و EEPROM ، منخفضة القدرة ، سرعة عالية .
• مدى جهد تشغيل واسع من 2.0V إلى 5.5V .
• مدى درجات حرارة تجارى وصناعى .
• استهلاك قدرة منخفض .
مخطط أطراف الميكروكونترولر PIC16F877A :
معظم أطراف الميكروكونترولر PIC16F877A متعددة الوظائف كما هو واضح من الشكل العلوى .
توظيف الأطراف بهذه الطريقة مفيد جدا لأنه يجعل الميكروكونترولر كحزمة أكثر إحكاما دون التأثير على عملها . لا يمكن استخدام هذه الوظائف المتعددة للطرف في وقت واحد، ولكن يمكن تغييرها في أي وقت خلال العمل .
• الأطراف VDD و VSS هى أطراف الإمداد بالقدرة الكهربية . للميكروكونترولر PIC16F877A يكون
VDD = 5V و VSS = 0V .
• الأطراف 13(OSC1) و 14(OSC2) هى أطراف توصيل المذبذب (الساعة) والتى سوف يوفر نبضات الساعة clock اللازمة من أجل عمل الميكروكونترولر .
• الطرف 1(MCLR) هو طرف "الإعادة" Reset للميكروكونترولر ، وهو يكون فعال فى الحالة المنخفضة . يجب توصيل هذا الطرف بالجهد المرتفع VDD من أجل العمل العادى للميكروكونترولر .
• فى الميكروكونترولر PIC ، تقسم أطراف الدخل / الخرج IO (Input Output) فى شكل منافذ مختلفة Ports ، وهى هنا ، PORTA,PORTB,PORTC,PORTD,PORTE . كل منفذ يكون مرتبط بسجلين ، السجل TRIS والسجل PORT ، على سبيل المثال TRISA,PORTA و TRISB,PORTB وهكذا .
السجل PORT والسجل TRIS :
السجل PORT و السجل TRIS هى سجلات تتعامل كع عمليات الدخل / الخرج فى الميكروكونترولر PIC . السجل TRIS يحدد وظيفة (اتجاه) طرف الدخل / الخرج . وجود المنطق “1” على بت من بتات السجل TRIS يجعل الطرف المناظر للمنفذ PORT "دخل" Input ، فى حين وجود المنطق “0” على بت من بتات السجل TRIS يجعل الطرف المناظر للمنفذ PORT "خرج" Output .
السجل PORT يمكن أن يستخدم فى "قراءة" أطراف الدخل أو "كتابة" حالات أطراف الخرج . لطرف الخرج ، المنطق “1” فى بت من بتات السجل PORT يجعل الطرف المناظر فى الحالة المرتفعة HIGH(VDD) ، فى حين أن المنطق “0” فى بت من بتات السجل PORT يجعل الطرف المناظر فى الحالة المنخفضة LOW(VSS) .
قراءة السجل PORT ، تقرأ مستوى الجهد الفعلى على أطراف الدخل / الخرج . إذا كان مستوى الجهد بالقرب من المستوى المرتفع HIGH(VDD) ، فإن بت السجل PORT المناظرة سوف تكون بالمنطق “1” ، وإذا كان مستوى الجهد بالقرب من المستوى المنخفض LOW(VSS) ، فإن بت السجل PORT المناظرة سوف تكون بالمنطق “0” .
الميكروكونترولر PIC16F877A هو واحد من الميكروكونترولر PIC الأكثر انتشارا (شعبية) ، ومن السهل أن معرفة السبب . لأنه يأتى فى شكل دائرة متكاملة 40 طرف نوع DIP (فى صفين) ويمتلك العديد من الأجهزة الطرفية الداخلية peripherals . العيب الوحيد الذى يمكن أن يؤخذ علية هو أنه لا يمتلك ساعة clock داخلية ، مثل كثير من الميكروكونترولر PIC .
الميكروكونترولر PIC16F877A هو متحكم قوى قادر على القيام بالكثير من المهام لأنه يحتوى على ذاكرة برنامج كبيرة بما فيها الكفاية بحجم 8 كيلو كلمة 8k words ، وذاكرة RAM بحجم 368 Bytes ، وذاكرة EEPROM بحجم 256 Bytes وهذا يكفى للقيام بالعديد من المشاريع المختلفة .
السمات الأساسية :
أولا : وحدة معالجة مركزية CPU عالية الأداء ، بناء من نوع RISC ( كمبيوتر بمجموعة تعليمات مخفضة) :
• فقط تعلم 35 تعليمة كلمة واحدة .
• كل التعليمات يستغرق تنفيذها "دورة تعليمة" واحدة باستثناء تفرعات البرنامج ، التى يستغرق تنفيذها 2 دورة تعليمة .
• سرعة (تردد) التشغيل : دخل الساعة 0-20MHz ، و"دورة التعليمة" 0-200 ns .
• ذاكرة البرنامج الفلاش بحجم 8K ، وذاكرة البيانات RAM بحجم 368 بايت ، وذاكرة البيانات نوع EEPROM بحجم 256 بايت .
• ترتيب الأطراف متوافق مع الميكروكونترولر PIC16FXXX ذات 40 طرف .
ثانيا : خصائص الأجهزة الطرفية Peripheral المدمجة داخل الميكروكونترولر :
• المؤقت Timer0 : مؤقت / عداد 8-bit مع "مقياس سابق" prescaler (قاسم تردد).
• المؤقت Timer1 : مؤقت / عداد 16-bit مع مقياس سابق ، يمكن أن يتزايد خلال "النوم" sleep عن طريق الساعة/الكريستال الخارجية .
• المؤقت Timer2 : مؤقت / عداد 8-bit مع مقياس سابق ومقياس لاحق .
• 2 وحدة (موديول) CCP ، (Capture, Compare, PWM) .
• وحدة اتصال تسلسلى متزامن بنظام SPI (نظام قائد Master) ، وبنظام I2C (نظام قائد/منقاد أو تابع Master/Slave ) .
• وحدة اتصال تسلسلى ، ارسال واستقبال متزامن / غير متزامن عام USART .
• منفذ تابع متوازى PSP .
• دائرة كشف "هبوط أو انحسارالجهد" Brown-out من أجل الإعادة عند هبوط الجهد BOR .
ثالثا : الخصائص التناظرية Analog :
• محول من تناظرى لرقمى ADC بدقة تحويل 10-bit ، يغمل مع أى من ثمانى قنوات .
• الإعادة عند "هبوط الجهد" BOR .
• وحدة (موديول) مقارن تناظرى مع :
- 2 مقارن تناظرى .
- وحدة جهد مرجعى VREF قابلة للبرمجة ، مدمجة على الشريحة .
- دخل قابل للبرمجة لاختيار الدخل من مداخل الجهاز ، واختيار جهد المرجع .
- مخارج المقارن يمكن الوصول إليها خارجيا .
رابعا : الخصائص الخاصة للميكروكونترولر :
• ذاكرة برنامج فلاش محسنة ، 100,000 دورة مسح / كتابة .
• ذاكرة بيانات EEPROM ، 1,000,000 دورة مسح / كتابة .
• ذاكرة البيانات EEPROM تحتفظ بالبيانات لمدة تزيد عن 40 عام .
• قابل للبرمجة الذاتية تحت سيطرة البرمجيات .
• قلبل للبرمجة وهو بالدائرة ICSP من خلال طرفين .
• مؤقت حراسة WDT مع مذبذب RC خاص به من أجل الغمل الفعال ,
• حماية الكود ، قابل للبرمجة .
• وضع النوم Sleep ، لتوفير القدرة .
• خيارات المذبذب ، قابلة للاختيار .
• التصحيح فى الدائرة ICD من خلال طرفين .
خامسا : تقنية CMOS :
• تقتية ذاكرات فلاش و EEPROM ، منخفضة القدرة ، سرعة عالية .
• مدى جهد تشغيل واسع من 2.0V إلى 5.5V .
• مدى درجات حرارة تجارى وصناعى .
• استهلاك قدرة منخفض .
مخطط أطراف الميكروكونترولر PIC16F877A :
معظم أطراف الميكروكونترولر PIC16F877A متعددة الوظائف كما هو واضح من الشكل العلوى .
توظيف الأطراف بهذه الطريقة مفيد جدا لأنه يجعل الميكروكونترولر كحزمة أكثر إحكاما دون التأثير على عملها . لا يمكن استخدام هذه الوظائف المتعددة للطرف في وقت واحد، ولكن يمكن تغييرها في أي وقت خلال العمل .
• الأطراف VDD و VSS هى أطراف الإمداد بالقدرة الكهربية . للميكروكونترولر PIC16F877A يكون
VDD = 5V و VSS = 0V .
• الأطراف 13(OSC1) و 14(OSC2) هى أطراف توصيل المذبذب (الساعة) والتى سوف يوفر نبضات الساعة clock اللازمة من أجل عمل الميكروكونترولر .
• الطرف 1(MCLR) هو طرف "الإعادة" Reset للميكروكونترولر ، وهو يكون فعال فى الحالة المنخفضة . يجب توصيل هذا الطرف بالجهد المرتفع VDD من أجل العمل العادى للميكروكونترولر .
• فى الميكروكونترولر PIC ، تقسم أطراف الدخل / الخرج IO (Input Output) فى شكل منافذ مختلفة Ports ، وهى هنا ، PORTA,PORTB,PORTC,PORTD,PORTE . كل منفذ يكون مرتبط بسجلين ، السجل TRIS والسجل PORT ، على سبيل المثال TRISA,PORTA و TRISB,PORTB وهكذا .
السجل PORT والسجل TRIS :
السجل PORT و السجل TRIS هى سجلات تتعامل كع عمليات الدخل / الخرج فى الميكروكونترولر PIC . السجل TRIS يحدد وظيفة (اتجاه) طرف الدخل / الخرج . وجود المنطق “1” على بت من بتات السجل TRIS يجعل الطرف المناظر للمنفذ PORT "دخل" Input ، فى حين وجود المنطق “0” على بت من بتات السجل TRIS يجعل الطرف المناظر للمنفذ PORT "خرج" Output .
السجل PORT يمكن أن يستخدم فى "قراءة" أطراف الدخل أو "كتابة" حالات أطراف الخرج . لطرف الخرج ، المنطق “1” فى بت من بتات السجل PORT يجعل الطرف المناظر فى الحالة المرتفعة HIGH(VDD) ، فى حين أن المنطق “0” فى بت من بتات السجل PORT يجعل الطرف المناظر فى الحالة المنخفضة LOW(VSS) .
قراءة السجل PORT ، تقرأ مستوى الجهد الفعلى على أطراف الدخل / الخرج . إذا كان مستوى الجهد بالقرب من المستوى المرتفع HIGH(VDD) ، فإن بت السجل PORT المناظرة سوف تكون بالمنطق “1” ، وإذا كان مستوى الجهد بالقرب من المستوى المنخفض LOW(VSS) ، فإن بت السجل PORT المناظرة سوف تكون بالمنطق “0” .
رد: ما هو الميكروكونترولر Microcontroller ؟
ربط الليد والسفن سيجمنت بالميكروكونترولر :
الليدات المشعة للضوء LEDs :
الليد هو مصدر ضوئى صغير من مادة شبه موصلة ، يستخدم أساسا لبيان حالة الدوائر الإلكترونية ، على سبيل المثال ، بيان وصول القدرة الكهربيىة إلى الدائرة . الشكل التالى يبين الليد ، رمز الدائرة الكهربية يشبه الدايود . الليد له طرفين (رجلين) ، الطرف الأطول هو "الأنود" والطرف الأقصر هو "الكاثود" . أيضا يتم التعرف على الكاثود عن طريق الجانب المسطح من الجسم . شدة الضوء المشع بواسطة الليد تعتمد على كمية التيار الأمامى المار خلال الليد . على سبيل المثال ، الليد الأحمر يكون له شدة إضاءة مناسبة عند مرور تيار قيمته 10 ملى أمبير .
معظم الليدات يكون لها هبوط جهد بقيمة 2V ، بينما الليد الأزرق والأبيض يمكن أن يصل جهدة إلى 4V . عامة ، تيار التشغيل يكون فى حدود 10 ملى أمبير ، يوجد ليدات تعمل على تيار منخفض .
الشكل التالى يبين توصيل الليد بطرف منفذ خرج الميكروكونترولر .
على فرض أن جهد خرج طرف المنفذ يكون 5V عندما يكون طرف المنفذ فى الحالة "المرتفعة" ، وعلى فرض أن الليد يعمل بتيار قيمته 10 ملى أمبير ، وأن هبوط الجهد عليه 2V ، يمكننا بسهولة حساب قيمة مقاومة الحد من التيار كما يلى :
المقاومة الأقرب عمليا هى 330 أوم . من المهم ملاحظة أن طرف الدخل / الخرج للميكروكونترولر يمكن أن يعطى تيار حتى 25 ملى أمبير ، ومن ثم فإن الليدات يمكن تشغيلها بتيار أكبر عند الرغبة ، بغرض الحصول على شدة إضاءة أكثر .
الليدات المشعة للضوء LEDs :
الليد هو مصدر ضوئى صغير من مادة شبه موصلة ، يستخدم أساسا لبيان حالة الدوائر الإلكترونية ، على سبيل المثال ، بيان وصول القدرة الكهربيىة إلى الدائرة . الشكل التالى يبين الليد ، رمز الدائرة الكهربية يشبه الدايود . الليد له طرفين (رجلين) ، الطرف الأطول هو "الأنود" والطرف الأقصر هو "الكاثود" . أيضا يتم التعرف على الكاثود عن طريق الجانب المسطح من الجسم . شدة الضوء المشع بواسطة الليد تعتمد على كمية التيار الأمامى المار خلال الليد . على سبيل المثال ، الليد الأحمر يكون له شدة إضاءة مناسبة عند مرور تيار قيمته 10 ملى أمبير .
معظم الليدات يكون لها هبوط جهد بقيمة 2V ، بينما الليد الأزرق والأبيض يمكن أن يصل جهدة إلى 4V . عامة ، تيار التشغيل يكون فى حدود 10 ملى أمبير ، يوجد ليدات تعمل على تيار منخفض .
الشكل التالى يبين توصيل الليد بطرف منفذ خرج الميكروكونترولر .
على فرض أن جهد خرج طرف المنفذ يكون 5V عندما يكون طرف المنفذ فى الحالة "المرتفعة" ، وعلى فرض أن الليد يعمل بتيار قيمته 10 ملى أمبير ، وأن هبوط الجهد عليه 2V ، يمكننا بسهولة حساب قيمة مقاومة الحد من التيار كما يلى :
المقاومة الأقرب عمليا هى 330 أوم . من المهم ملاحظة أن طرف الدخل / الخرج للميكروكونترولر يمكن أن يعطى تيار حتى 25 ملى أمبير ، ومن ثم فإن الليدات يمكن تشغيلها بتيار أكبر عند الرغبة ، بغرض الحصول على شدة إضاءة أكثر .
رد: ما هو الميكروكونترولر Microcontroller ؟
وحدات العرض (شاشات) السفن سيجمنت 7-segment displays :
وحدات العرض السفن سيجمنت كانت أقدم شاشات إلكترونية من نوع الليد تستخدم لعرض الأرقام . تستخدم هذه الأجهزة عادة فى الساعات الرقمية ، والعدادات (المبينات) الإلكترونية ، وأجهزة العد الإلكترونية ، وغيرها من المعدات المستخدمة لغرض البيانات الرقمية فقط .
تتكون وحدة العرض السفن سيجمنت من 7 عناصر (شرائح)مشعة للضوء مرتبة فى حاوية مستطيلة ، وبتوصيل ON وفصل OFF الشرائح المناسبة يمكننا الحصول على الأرقام من “0” إلى “9” .
الشكل التالى يبين وحدة عرض سفن سيجمنت . اختياريا ، تتوفر نقطة عشرية لعرض كسور الأعداد الغير صحيحة . يشار إلى شرائح وحدة الغرض بالحروف من “a” إلى “g” .
وحدات العرض السفن سيجمنت متوفرة فى شكلين : "الأنود المشترك" و "الكاثود المشترك" . الشكل التالى يبين توصيلات نوع الأنود المشترك ، أطراف الأنود لكل الشرائح يتم توصيلها معا لتشكيل طرف الأنود المشترك ، وعادة يتم توصيل هذا الطرف إلى مصدر القدرة . يتم توصيل ON الشرائح كل على حده عن طريق توصيل طرف كاثود الشريحة المطلوبة بالأرضى .
وبالمثل ، الشكل التالى يبين توصيلات نوع الكاثود المشترك . هنا ، يتم توصيل جميع كاثودات الشرائح معا لتشكيل طرف الكاثود المشترك ، وعادة ما يتم توصيل هذا الطرف بالأرضى . يتم توصيل ON الشرائح كل على حدة عن طريق تطبيق الجهد الموجب إلى طرف أنود الشريحة المطلوبة .
عرض الأرقام :
الشكل المبين أدناه يبين التوصيل بين الميكروكونترولر ووحدة العرض السفن سيجمنت . كما هو الحال مع الليدات القياسية ، من المطلوب استخدام مقاومات للحد من التيار فى كل شريحة . عادة تستخدم مجموعة (حزمة) المقاومات لسهولة البناء وخفض التكلفة وتوفير المساحة . تتكون هذه الحزمة من 8 أو 10 مقاومات من نفس القيمة وتكون فى شكل خط واحد .
الشكل التالى يبين كيفية عرض الأرقام من “0” إلى “9” بواسطة وحدة عرض سفن سيجمنت . لاحظ أنه يمكن أيضا عرض بعض الرموز والأحرف .
إن أسهل طريقة لعرض رقم على وحدة عرض سفن سيجمنت تكون أولا إنشاء جدول يوضح الأرقام والشرائح المناظرة التى تكون ON أو OFF لعرض الرقم المطلوب . ثم بعد ذلك ، يمكن تحديد نموذج البتات ( أو المكافىء السداسى عشرى) المطلوب لعرض رقم معين ، ويمكن عرض الرقم المطلوب عن طريق إرسال هذا النموذج إلى الجهاز .
الجدول التالى يبين تشفير وحدة العرض السفن سيجمنت ، وفيه الأرقام ، وحالات الشرائح المناظرة ، والأرقام السداسية عشر المطلوبة لإرسالها إلى المنفذ حيث توصل وحدة العرض بغرض عرض رقم معين .
فى بناء هذا الجدول ، يفترض أن البت الثامنة بصفر لأنها لا تستخدم فى العرض . على سبيل المثال ، لعرض الرقم “5” ، ينبغى علينا إرسال الغدد السداسى عشرى “0x6D” إلى المنفذ المتصل بوحدة العرض .
وحدات الغرض السفن سيجمنت المتعددة :
وحدة العرض السفن سيجمنت المفردة يمكن أن تعرض فقط الأرقام من “0” إلى “9” . فى كثير من التطبيقات ، يتم دمج وحدات العرض معا لإنشاء شاشة عرض أكبر . وحدتى عرض خانتين 2-digit يمكنها عرض الأرقام بين 0 و 99 ، وثلاثة وحدات 3-digit تعرض الأرقام من 0 إلى 999 ، وأربعة وحدات 4-digit يمكنها عرض الأرقام من 0 إلى 9999 وهكذا .
الشكل أداه يبين وحدة عرض مكونة من وحدتين لعرض رقمين 2-digit . عادة يتم فى كل مرة اختيار تشغيل رقم (خانة) من الأرقام(الخانات) المتعددة وتسمى طريقة multiplexing . على سبيل المثال ، بدون نظام الاختيار ، شاشة برقمين (وحدتين) سوف تتطلب 14 طرف ، وشاشة بثلاثة أرقام سوف تتطلب 21 طرف ، وهكذا . مع استخدام الاختيار من متعدد ، الشاشة رقمين سوف تتطلب 9 أطراف ، والشاشة بثلاث أرقام سوف تتطلب 10 أطراف ، وهكذا . ميزة أخرى لنظام الانتخاب من متعدد ، هى تخفيض القدرة المستهلكة بشكل ملحوظ .
فى تطبيقات الانتخاب من متعدد ، جميع الشرائح يتم تشغيلها على التوازى فى نفس الوقت ، ولكن يتم تمكين الطرف المشترك فقط ( الأنود أو الكاثود ) للرقم المطلوب . يتم تمكين وعدم تمكين الأرقام (الوحدات) بسرعة لدرجة أنها تعطى الانطباع للعين بأن كلا من وحدتى العرض تكون موصلة ON فى نفس الوقت . على سبيل المثال ، افرض أننا نرغب فى عرض الرقم “25” على شاشة بوحدتين ،من نوع المهبط المشترك . تكون الخطوات كما يلى :
1- أرسال البيانات لعرض “2” على كلا من الوحدتين .
2- مكن Enable الوحدة اليسرى MSB ( خانة المئات) فقط عن طريق توصيل طرف الكاثود المشترك لها بالأرضى .
3- الانتظار لفترة قصيرة .
4- إرسال البيانات لعرض “5” على كلا من الوحدتين .
5- مكن Enable الوحدة اليمنى LSB (خانة الآحاد) فقط عن طريق توصيل طرف الكاثود المشترك لها بالأرضى .
6- الانتظار لفترة قصيرة .
7- العودة إلى الخطوة “1” .
الطرف المشترك لكل وحدة عادة يتم التحكم فيه باستخدام ترانزستور كمفتاح . الشكل التالى يبين شاشة بوحدتى عرض رقمين متصلة بالميكروكونترولر وتستخدم ترانزستورات NPN للتحكم فى الوحدات . لاحظ أن تحديد قاعدة الترانزستور بالمنطق المرتفع سوف يوصل ON الترانزستور وبالتالى سوف يمكن طرف الكاثود المشترك المتصل به .
وحدات العرض السفن سيجمنت كانت أقدم شاشات إلكترونية من نوع الليد تستخدم لعرض الأرقام . تستخدم هذه الأجهزة عادة فى الساعات الرقمية ، والعدادات (المبينات) الإلكترونية ، وأجهزة العد الإلكترونية ، وغيرها من المعدات المستخدمة لغرض البيانات الرقمية فقط .
تتكون وحدة العرض السفن سيجمنت من 7 عناصر (شرائح)مشعة للضوء مرتبة فى حاوية مستطيلة ، وبتوصيل ON وفصل OFF الشرائح المناسبة يمكننا الحصول على الأرقام من “0” إلى “9” .
الشكل التالى يبين وحدة عرض سفن سيجمنت . اختياريا ، تتوفر نقطة عشرية لعرض كسور الأعداد الغير صحيحة . يشار إلى شرائح وحدة الغرض بالحروف من “a” إلى “g” .
وحدات العرض السفن سيجمنت متوفرة فى شكلين : "الأنود المشترك" و "الكاثود المشترك" . الشكل التالى يبين توصيلات نوع الأنود المشترك ، أطراف الأنود لكل الشرائح يتم توصيلها معا لتشكيل طرف الأنود المشترك ، وعادة يتم توصيل هذا الطرف إلى مصدر القدرة . يتم توصيل ON الشرائح كل على حده عن طريق توصيل طرف كاثود الشريحة المطلوبة بالأرضى .
وبالمثل ، الشكل التالى يبين توصيلات نوع الكاثود المشترك . هنا ، يتم توصيل جميع كاثودات الشرائح معا لتشكيل طرف الكاثود المشترك ، وعادة ما يتم توصيل هذا الطرف بالأرضى . يتم توصيل ON الشرائح كل على حدة عن طريق تطبيق الجهد الموجب إلى طرف أنود الشريحة المطلوبة .
عرض الأرقام :
الشكل المبين أدناه يبين التوصيل بين الميكروكونترولر ووحدة العرض السفن سيجمنت . كما هو الحال مع الليدات القياسية ، من المطلوب استخدام مقاومات للحد من التيار فى كل شريحة . عادة تستخدم مجموعة (حزمة) المقاومات لسهولة البناء وخفض التكلفة وتوفير المساحة . تتكون هذه الحزمة من 8 أو 10 مقاومات من نفس القيمة وتكون فى شكل خط واحد .
الشكل التالى يبين كيفية عرض الأرقام من “0” إلى “9” بواسطة وحدة عرض سفن سيجمنت . لاحظ أنه يمكن أيضا عرض بعض الرموز والأحرف .
إن أسهل طريقة لعرض رقم على وحدة عرض سفن سيجمنت تكون أولا إنشاء جدول يوضح الأرقام والشرائح المناظرة التى تكون ON أو OFF لعرض الرقم المطلوب . ثم بعد ذلك ، يمكن تحديد نموذج البتات ( أو المكافىء السداسى عشرى) المطلوب لعرض رقم معين ، ويمكن عرض الرقم المطلوب عن طريق إرسال هذا النموذج إلى الجهاز .
الجدول التالى يبين تشفير وحدة العرض السفن سيجمنت ، وفيه الأرقام ، وحالات الشرائح المناظرة ، والأرقام السداسية عشر المطلوبة لإرسالها إلى المنفذ حيث توصل وحدة العرض بغرض عرض رقم معين .
فى بناء هذا الجدول ، يفترض أن البت الثامنة بصفر لأنها لا تستخدم فى العرض . على سبيل المثال ، لعرض الرقم “5” ، ينبغى علينا إرسال الغدد السداسى عشرى “0x6D” إلى المنفذ المتصل بوحدة العرض .
وحدات الغرض السفن سيجمنت المتعددة :
وحدة العرض السفن سيجمنت المفردة يمكن أن تعرض فقط الأرقام من “0” إلى “9” . فى كثير من التطبيقات ، يتم دمج وحدات العرض معا لإنشاء شاشة عرض أكبر . وحدتى عرض خانتين 2-digit يمكنها عرض الأرقام بين 0 و 99 ، وثلاثة وحدات 3-digit تعرض الأرقام من 0 إلى 999 ، وأربعة وحدات 4-digit يمكنها عرض الأرقام من 0 إلى 9999 وهكذا .
الشكل أداه يبين وحدة عرض مكونة من وحدتين لعرض رقمين 2-digit . عادة يتم فى كل مرة اختيار تشغيل رقم (خانة) من الأرقام(الخانات) المتعددة وتسمى طريقة multiplexing . على سبيل المثال ، بدون نظام الاختيار ، شاشة برقمين (وحدتين) سوف تتطلب 14 طرف ، وشاشة بثلاثة أرقام سوف تتطلب 21 طرف ، وهكذا . مع استخدام الاختيار من متعدد ، الشاشة رقمين سوف تتطلب 9 أطراف ، والشاشة بثلاث أرقام سوف تتطلب 10 أطراف ، وهكذا . ميزة أخرى لنظام الانتخاب من متعدد ، هى تخفيض القدرة المستهلكة بشكل ملحوظ .
فى تطبيقات الانتخاب من متعدد ، جميع الشرائح يتم تشغيلها على التوازى فى نفس الوقت ، ولكن يتم تمكين الطرف المشترك فقط ( الأنود أو الكاثود ) للرقم المطلوب . يتم تمكين وعدم تمكين الأرقام (الوحدات) بسرعة لدرجة أنها تعطى الانطباع للعين بأن كلا من وحدتى العرض تكون موصلة ON فى نفس الوقت . على سبيل المثال ، افرض أننا نرغب فى عرض الرقم “25” على شاشة بوحدتين ،من نوع المهبط المشترك . تكون الخطوات كما يلى :
1- أرسال البيانات لعرض “2” على كلا من الوحدتين .
2- مكن Enable الوحدة اليسرى MSB ( خانة المئات) فقط عن طريق توصيل طرف الكاثود المشترك لها بالأرضى .
3- الانتظار لفترة قصيرة .
4- إرسال البيانات لعرض “5” على كلا من الوحدتين .
5- مكن Enable الوحدة اليمنى LSB (خانة الآحاد) فقط عن طريق توصيل طرف الكاثود المشترك لها بالأرضى .
6- الانتظار لفترة قصيرة .
7- العودة إلى الخطوة “1” .
الطرف المشترك لكل وحدة عادة يتم التحكم فيه باستخدام ترانزستور كمفتاح . الشكل التالى يبين شاشة بوحدتى عرض رقمين متصلة بالميكروكونترولر وتستخدم ترانزستورات NPN للتحكم فى الوحدات . لاحظ أن تحديد قاعدة الترانزستور بالمنطق المرتفع سوف يوصل ON الترانزستور وبالتالى سوف يمكن طرف الكاثود المشترك المتصل به .
صفحة 1 من اصل 5 • 1, 2, 3, 4, 5
مواضيع مماثلة
» برمجة الميكروكونترولر CHAPTER 2 - Programming Microcontroller
» دوائر ربط (توصيل) الميكروكونترولر MICROCONTROLLER INTERFACING CIRCUITS
» مدخلك الشخصى إلى الميكروكونترولر Your Personal Introductory Course :The PIC Microcontroller
» مراجعة برمجة الميكروكونترولر PIC من خلال مشاريع الميكروكونترولر PIC16F877A مع الدايودات المشعة للضوء والمترجم ميكروسى برو :
» 2.1 أنظمة الميكروكونترولر :
» دوائر ربط (توصيل) الميكروكونترولر MICROCONTROLLER INTERFACING CIRCUITS
» مدخلك الشخصى إلى الميكروكونترولر Your Personal Introductory Course :The PIC Microcontroller
» مراجعة برمجة الميكروكونترولر PIC من خلال مشاريع الميكروكونترولر PIC16F877A مع الدايودات المشعة للضوء والمترجم ميكروسى برو :
» 2.1 أنظمة الميكروكونترولر :
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 5
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى