قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 09-10-2011, 11:49 AM المشاركة 17   
افتراضي



الأمر do-while
يستخدم هذا الأمر فى عمل بناء تكرار وهو يشبه أمر while فيما عدا أن اختبار (تقييم) الشرط يتم فى نهاية الحلقة ( بدلا من بدايتها كما هو حال أمر while ).

الشكل العام :
do command while (condition);

or

do
{
command1;
command 2;
} While (test condition);






فى بناء do-while يتم إجراء الاختبار فقط عند نهاية الحلقة . وذلك يؤدى إلى أن التعليماد الموجودة بداخل حلقة do-while يتم تنفيذها مرة واحدة على الأقل . إذا تحقق الشرط تتكرر الحلقة وإذا لم يتحقق يتم الخروج من الحلقة .

مثال :
void main () {
int a = 0;
// تعريف متغير نوع عدد صحيح وتخصيص الصفر له

do
{
//
المدخل
a ++; //
تنفيذ تزايد المتغير بواحد
PORTB = ~ PORTB; // تنفيذ عكس حالة أطراف المنفذ
}
while (a> 100); //
اختبار الشرط والنتيجة خروج من الحلقة لعدم تحقق الشرط
}





أمر break وأمر continue

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 09-10-2011, 11:51 AM المشاركة 18   
افتراضي


أمر break وأمر continue

أمر Break
تستخدم عبارة break فى الإيقاف الفورى (القطع) لأى حلقة . أثناء تنفيذ الحلقة أن وجد هذا الأمر يتم الخروج الفورى منها .

مثال :





void main () {
int a = 0;

do
{
a ++; //
تنفيذ تزايد المتغير بواحد

break; // إيقاف تنفيذ الحلقة فورا والخروج منها
PORTB = ~ PORTB; // عدم تنفيذ عكس حالة أطراف المنفذ
}
while (a <100);

}





عبارة break صالحة للاستخدام مع كل من : do-while و while و for و case .

الأمر Continue
يقوم الأمر continue بإعادة بدء restarts اختبار شرط الحلقة مرة ثانية . فى كل مرة يوجد فى الحلقة الأمر continue لا يتم تنفيذ الأوامر التى تليها .
مثال :
void main () {
int a = 0;

do
{
a ++;
continues; //
العودة إلى بداية الحلقة

PORTD = ~ PORTD;

}
while (a <100);

}





فى هذا المثال : سوف , لن يتم تنفيذ الأوامر الموجودة أسفل الأمر continue لأنه فى كل مرة نصل فيها إلى تنفيذ الأمر continue يتم توجيه البرنامج تلقائيا إلى رأس الحلقة غير معتمدا على أى حالة للمتغيرات .
عبارة continueصالحة للاستخدام مع كل من : do-while و while و for و case .

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 11-10-2011, 11:58 AM المشاركة 19   
افتراضي


التعامل مع المفاتيح ولوحة المفاتيح فى الميكروسى
لا غنى عن المفاتيح فى معظم المشاريع لأنها تسمح لك بإدخال بيانات إلى الميكروكونترولر كما فى الشكل التالى .






تستخدم مقاومات داخل الميكروكونترولر تسمى "مقاومات الجذب لأعلى " pull-up وهى تضمن "وجود مستوى منطقى مرتفع عند طرف مدخل الميكروكونترولر عندما يكون المفتاح مفتوح" . عند الضغط على المفتاح تتحول الحالة المنطقية لطرف الدخل إلى الحالة المنخفضة لتوصيله بالأرضى كما فى الشكل السابق .
على الرغم من أن الميكروكونترولر PIC به مقاومات جذب لأعلى داخلية بالمنفذ PORTB إلا أنه يمكن أيضا استخدام مقاومات جذب لأعلى خارجية .
عندما نقوم بإنشاء مشروع به مفتاح متصل بالميكروكونترولر يجب أن نأخذ الحذر من آلية تأثير منع الارتدادات (الوثبات) debouncing عند الضغط على المفتاح .

منع الارتدادات debouncing
تأثير المرونة الميكانيكية عند الضغط على المفتاح تسمى "إرتدادات أو وثبات" "Bouncing" والتى تتسبب فى قراءات خاطئة (مزيفة) للمفتاح نتيجة الانعكاسات التى تسبب قراءة المفتاح أكثر من مرة . روتين منع الارتدادات ليس أكثر من فاصل زمنى صغير بين لحظة تحرير المفتاح وإعادة قراءة المفتاح . هذا المدى الزمنى يسمح بانتهاء هذه الظاهرة بشكل طبيعى , ومن ثم تجنب القراءات الزائفة . هذا الفاصل الزمنى حوالى 25 ملى ثانية .
يمكن للميكروسى التعامل مع المفتاح "بدالة المفتاح" البسيطة كما يلى .

دالة المفتاح Button function

صيغة الدالة :

Button (& port, pin, debounce time, active_state);



حيث :
& port: المنفذ المتصل به المفتاح .
pin : الطرف المتصل به المفتاح وقيمته من 0 إلى 7 .
debounce time : زمن منع الارتدادات بالملى ثانية .
active_state : الحالة الفعالة .


مثال :

Button (& PORTB, 1, 10, 0);







المفتاح المطلوب قراءة حالته متصل بالمنفذ PORTB بالطرف رقم 1 وهو RB0 وزمن التأخير لمنع الارتدادات هو 10 ملى ثانية والحالة الفعالة (عند الضغط عليه) هى الحالة المنخفضة (الصفر) .

عائد دالة المفتاح :
العائد يكون بالقيمة صفر false عند عدم التفعيل أى عند عدم الضغط على المفتاح.
العائد يكون بالقيمة واحد true عند التفعيل أى عند الضغط على المفتاح .
دالة المفتاح تهىء المنفذ تلقائيا كمدخل .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 11-10-2011, 12:00 PM المشاركة 20   
افتراضي


البرنامج الأول :
كما فى الشكل : ميكروكونترولر PIC متصل بمفتاح ضغط push-button وليد LED .






الغرض :
فى كل مرة يتم فيها الضغط على المفتاح الضاغظ وتحريره تتغير الحالة المنطقية لليد بين التوصيل on والفصل off مع تحديد زمن التأخير لمنع الارتدادات بقيمة 20 ملى ثانية .



void main ()
{
trisd.f0 = 0; //إعداد الطرف كمخرج
trisb.f0 = 1; // إعداد الطرف كمدخل
do {
if (Button (& PORTB, 0, 20, 0)) //إذا تم الضغط على المفتاح(العائد بواحد) يتم تنفيذ الأوامر التالية
{
delay_ms (200); //التأخير 200 ملى ثانية
portd.f0= ~ pord.f0; // عكس حالة الليد
}
} While (1);
}







فى البرنامج السابق:
  • تم إعداد الطرف RB0 كمخرج trisd.f0 = 0; لاتصاله بالليد .
  • وإنشاء حلقة do-while غير منتهية حتى يعمل الميكروكونترولر بصفة مستمرة .
  • برمجة دالة المفتاح كما فى الشكل التالى :




شرح الجزء التالى من البرنامج :

if (Button (& PORTB, 0, 20, 0)) //إذا تم الضغط على المفتاح(العائد بواحد) يتم تنفيذ الأوامر التالية
{
delay_ms (200); //التأخير 200 ملى ثانية
portd.f0= ~ pord.f0; // عكس حالة الليد
}






عند الضغط على المفتاح S1 يتم تنفيذ دالة المفتاح وتعود (العائد) return بالقيمة "واحد 1 " true بينما فى حالة عدم الضغط على المفتاح يكون عائده هو الصفر 0 = false .
أى أنه عند الضغط على المفتاح يكون عائد دالة المفتاح true وبالتالى يكون نتيجة شرط if هو true ويتم تنفيذ تعليمات جملة if الموجودة بين القوسين .
البرنامج السابق به مشكلة , لأنه عندما " لا نحرر الضغط من على المفتاح " تكون نتيجة شرط if بالقيمة true دائما وسوف يستمر تنفيذ التعليمات فى الحلقة الغير منتهية مرارا وتكرارا وتكون النتيجة توصيل on وفصل off الليد باستمرار أثناء الضغط على المفتاح .

البرنامج الثانى :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 11-10-2011, 12:02 PM المشاركة 21   
افتراضي


البرنامج الثانى :
لعلاج المشكلة فى البرنامج السابق , ننشأ برنامج جديد الغرض منه التحويل بين توصيل وفصل الليد (يمثل جهاز خارجى) عند كل "ضغط ثم تحرير" للمفتاح . أى عند الضغط على المفتاح ثم تحريره يتم عكس حالة الليد , إذا ظل الضغط على المفتاح تتغير حالة المفتاح مرة واحدة فقط . زمن منع تأثير الارتدادات 20 ملى ثانية .

البرنامج :

كود:
/* برنامج قراءة مفتاح دورة برمجة الميكروكونترولر بلغة السى الهدف : قراءة حالة المفتاح ومن ثم توصيل وفصل ليد تمثل جهاز خرج إعداد : Eng.F.Abdelaziz http://www.eeecb.com/vb/index.php */ # Define LED1 portd.f0 //استخدام الموجه لتخصيص (تعريف) اسم لطرف ليسهل التعامل معه int old_ state// تعريف متغير التحكم لحفظ حالة المفتاح القديمة void main () { trisd.f0 = 0; // إعداد الطرف المتصل بالليد كمخرج trisb.f0 = 1; // إعداد الطرف المتصل بالمفتاح كمدخل do { if (Button (& PORTB, 0, 20, 0)) old_ state=1; //إذا تم الضغط على المفتاح , ضع واحد فى متغير الحالة القديمة if (old_ state== 1 & & Button (& PORTB, 0, 20, 1)) { // التحقق من أن المفتاح قد تم تحريره وعندئذ يتم تنفيذ التالى LED1 = ~ LED1; //عكس حالة الليد old_ state= 0; // تصفير متغير التحكم لتجهيزه للضغطة التالية } } While (1); }



الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 11-10-2011, 12:03 PM المشاركة 22   
افتراضي


شرح تفاصيل البرنامج :
الجزء الأول : التعليق
/*
برنامج قراءة مفتاح
دورة برمجة الميكروكونترولر بلغة السى
الهدف : قراءة حالة المفتاح ومن ثم توصيل وفصل ليد تمثل جهاز خرج
إعداد :
Eng.F.Abdelaziz
http://www.eeecb.com/vb/index.php
*/








الجزء الثانى : التوجيه # Define

# Define LED1 portd.f0 //استخدام الموجه لتخصيص (تعريف) اسم لطرف ليسهل التعامل معه




هذا التوجيه يستخدم لتخصيص (تعريف) الاسم LED1 للطرف RD0 , من هذه النقطة فى البرنامج سوف نستخدم الاسم LED1 وسوف يتعرف عليه المترجم على أنه الطرف portd.f0 (RD0)فيقوم بتغيرة وإعادته إلى أصله الطبيعى كعنوان لذاكرة الكرف RD0 .
مثال :

# Define display1 portd.f0 // display1= portd.f0= RD0= LED1
# Define LED2 portd.f1 // LED2= portd.f1= RD1
void main () {
TRISD = 0; // إعداد جميع أطراف المنفذ كمخارج
display1 = 0;// LED1=off
LED2 = 1;//LED2=on
}



الجزء الثالث : تعريف و تعيين المتغيرات :

intold_ state// تعريف متغير التحكم لحفظ حالة المفتاح القديمة






نعرف متغير من النوع int بالاسم old_ state . مهمة هذا المتغير جعل الليد on/off فقط بضغطة واحدة من المفتاح , الاستمرار فى الضغط على المفتاح يتسبب فى الخروج من تعليمات if .

الجزء الرابع : الدالة الرئيسية :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 11-10-2011, 12:04 PM المشاركة 23   
افتراضي


الجزء الرابع : الدالة الرئيسية :

void main () {



الدالة الرئيسية main () هى أول ما ينفذ فى برنامج لغة السى . لاحظ أن الدالة الرئسية تلى "معرف نوعها" وهو void والذى يهدف إلى إبلاغ المترجم أن هذه الدالة "فارغة ليس لها عائد بيانات " .

الجزء الخامس : برمجة (إعداد – تهيئة) المنافذ كمداخل ومخارج :

trisd.f0 = 0; // إعداد الطرف المتصل بالليد كمخرج
trisb.f0 = 1; // إعداد الطرف المتصل بالمفتاح كمدخل






السجل TRIS وظيفته تحديد إتجاه أطراف المنفذ (قراءة أو كتابة) . فى هذا البرنامج لدينا مفتاح متصل بالطرف RB0 , لقراءة حالة هذا المفتاح يجب إعداد الطرف كمدخل . دالة المفتاح هى المسؤلة عن تحديد هذه السجلات نيابة عنا .
لدينا ليد متصل بالطرف RD0 , يجب "إرسال" مستوى منطقى إلى هذا الطرف لذلك يجب إعداده كطرف مخرج .

الجزء السادس : روتين الحلقة
تذكر أننا نحافظ على التنفيذ الدائم للبرنامج بواسطة الميكروكونترولر . فى هذا المثال نستخدم حلقة
do-while .

do {
if (Button (& PORTB, 0, 20, 0)) old_ state=1;
//إذا تم الضغط على المفتاح ضع واحد فى متغير الحالة القديمة
if (old_ state== 1 & & Button (& PORTB, 0, 20, 1)) {
// التحقق من أن المفتاح قد تم تحريره وعندئذ يتم تنفيذ التالى
LED1 = ~ LED1; //عكس حالة الليد
old_ state= 0; // تصفير متغير التحكم لتجهيزه للضغطة التالية
}
} While (1);








لاحظ أن نتيجة اختبار شرط الحلقة يكون دائما trueWhile (1)

روتين اتخاذ القرار ودالة المفتاح :
الأوامر التالية تهدف إلى قراءة حالة المفتاح S1 المتصل بالطرف RB0 بالميكروكونترولر PIC و توصيل وفصل الليد المتصل بالطرف RD0 .
الأمر الأول :

if (Button (& PORTB, 0, 20, 0)) old_ state=1;
//إذا تم الضغط على المفتاح ضع واحد فى متغير الحالة القديمة



الأمر old_ state=1ينفذ فقط عندما تكون نتيجة اختبار الشرط :
(Button (& PORTB, 0, 20, 0)) صواب true أى عندما عندما تكون نتيجة دالة المفتاح true وآخر بارامتر (الحالة الفعالة) يعنى أن نتيجة الدالة تكون صواب عند الضغط على المفتاح (حالة الدخل بصفر) .

الأمر الآخر :

if (old_ state== 1 & & Button (& PORTB, 0, 20, 1)) {
// التحقق من أن المفتاح قد تم تحريره وعندئذ يتم تنفيذ التالى




فى هذا السطر من البرنامج تجرى العملية المنطقية AND بين المتغير old_ state(عندما يكافىء الواحد أى بعد الضغط على المفتاح ) والعائد من دالة المفتاح Button والغرض منها هو التحقق من تحرير المفتاح . لاحظ أن آخر بارامتر فى هذه الدالة هو الواحد (فعال عند التحرير) أى أن نتيجة هذه الدالة تكون true عندما يكون المفتاح محرر . (قبلها دالة اختبار ضغط المفتاح) .
الأوامر التالية سوف يتم تنفيذها فقط عندما تكون نتيجة شرط if صواب true وهذا يستوجب أن يكون المتغير old_ state يساوى واحد وعائد دالة المفتاح بواحد أيضا أى يكون المفتاح غير مضغوط (محرر) .

عكس حالة الليد وتصفير resetحالة المتغير :

LED1 = ~ LED1; //عكس حالة الليد
old_ state= 0; // تصفير متغير التحكم لتجهيزه للضغطة التالية








قراءة 4 مفاتيح :


الصورة الرمزية احمد الربعي
احمد الربعي
:: مهندس متميز ::
تاريخ التسجيل: Jun 2011
المشاركات: 591
نشاط [ احمد الربعي ]
قوة السمعة:
قديم 11-10-2011, 04:26 PM المشاركة 24   
افتراضي


الله عليك يابشمهندس -- بصراحة الموضوع اكثر من رائع ومفيد جدا



الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 07:36 AM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)