صفحة 3 من 4 الأولىالأولى 1 2 3 4 الأخيرةالأخيرة
النتائج 21 إلى 30 من 37

الموضوع: الميكرو كونترولر انواعه و برمجته و استخداماته

  1. #21
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي برنامج غسالة صغيرة

    دورات في الهندسة الكهربائية

    روابط الدورات - اضغط على صورة الدورة للاشتراك

     

    محطات التحويل الكهربائية

     

     

    image119

    دورة محركات و مولدات التيار المستمر

     

     

    image120

    دورة المحولات الكهربائية

     

     

    image121

    أساسيات أنظمة الخلايا الشمسية

     

     

    image122

    حسابات الأنظمة الشمسية المتصلة بالشبكة

     

     

    image123

    أساسيات كهرباء المنازل

     

     

    image124

    محطات الديزل وانظمة UPS

     

     

    image125

    توليد و انتاج الكهرباء

     

     

    image126

    تعريف بتخصص الهندسة الكهربائية

     

     

    image127

    تسويق نفسك للوظيفة والعمل الحر

     

     

    image128
    برنامج غسالة صغيرة :

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

    غسالة باستخدام C51 و لغة الأسيمبلى:

    من الخبرة السابقة وجدنا أن عند تطبيق التيار يحدث إعادة بدء تشغيل RESET ومن ثم كل المنافذ تصبح آحاد أى +5 فولت وكثير من المصممون يفضلون أسلوب أن واحد يعنى تشغيل و صفر يعنى إيقاف لأنه منطقى و يبدأ البرنامج بأمر جعل المنفذ =صفر و يفاجأ أنه عند التشغيل تفعل كل الريلايات معا ثم تفصل مما يسبب لحظة بدء تشغيل خاطئه فى البدء.
    هذه قد تكون مكروهة ولكنها أحيانا تكون خطيرة و تسبب مشاكل.
    قد تسأل نفسك أليس أول أمر هو التصفير؟ وهل فى ميكرو ثانية تستجيب الريلايات؟ هذا غير منطقى!!
    الواقع أنك لم تحسب كم من الوقت يمر قبل أن ينفذ هذا الأمر، ارجع للداتاشيت ستجد أن المذبذب أولا يحتاج بضع مللى ثانية ليقوم و يستقر و الميكرو يحتاج لبضع نبضات حتى يستجيب للريسيت أو إعادة التشغيل و أخيرا يبدأ فى تنفيذ الأمر.
    لذا الأفضل أن تعتمد حالة البدء كأساس و عندما تريد تغييرها افعل ذلك فى الوقت المناسب.
    من هنا سنجعل كافة المخارج كما هى = 1 و تعنى فصل الريلايات و عندما نريد تفعيل أى منها نستخدم صفر.
    أسهل طريقة و أقلها كلفة أن نستخدم ريلاى 5 فولت وهو متوافرو معه ترانزستور س م س أو PNP ومقاومة و دايود كالآتى

    ببساطة عندما تكون مقاومة القاعدة R8 متصله ب +5 فولت سيكون جهد القاعدة Base مساو للباعثEmitter ولا يمر تيار و عندما يكون طرف المقاومة = صفر سيمر تيار القاعدة Base و من ثم يفتح الترانزستور و يفعل الريلاى. الدايود D8 طبعا لإلغاء تأثير الملف عند الغلق.
    هذه الدائرة سنكررها 5 مرات لتشغيل الموتور و تسريع الموتور عند العصر و فتح المياه و فتح مصرف المياه و تشغيل السخان
    دوائر الليدات لبيان الدورة و الحرارة سبق نقاشها فى البرنامج الأول وهى هنا امتداد له و أيضا توصيل المفاتيح Switches هو امتداد لما سبق فيما عدا طرفى Start/Stop أو بدء التشغيل و طرف Emergency. طرف بدء التشغيل لبدء التشغيل بالخيارات المطروحة ولكن لن يوقف الغسالة فى المنتصف. هذا لا ينفى حدوث مشاكل تستوجب توقف الدورة لذا بالضغط على زر Start أو البدء مع زر الطوارئ Emergency تفرض إيقاف الغسالة و ذلك لتجنب إيقاف الغسالة بالخطأ عند الضغط العفوى على الزر.
    هذا تم بحيلة بسيطة وهى إدخال إشارة الطوارئ على طرف المقاطعة الخارجية INT0

    نحتاج لمنطق يقول لو صفر مع صفر يكون الخرج صفر ولو أى تركيبة أخرى يكون الخرج =1

    هذا يتطلب بوابة "أو" OR-Gate كما بالرسم المتكاملة 4071 فعند الضغط على أى من المفتاحين سيكون على الطرف الآخر واحد و يبقى الخرج واحد حتى يتم الضغط على كلاهما فيصبح الخرج صفر وهذا يسبب مقاطعة المتحكم ومن ثم إيقافه لكونه على طرف INT0 .
    أعلم أن من سيفحص البرنامج لاحقا سيقول أن الطرف المتصل بالمنفذ3.0 و المسمى Emergency لم يستخدم، نعم و لكن إما تستبدل البوابة و تستخدم 7432 أو توصل طرف 4071 بمقاومة للموجب ولو نحتاج لهذا الطرف للتحكم فى أى شيء آخر يمكننا فعل ذلك - بهذه الطريقة نوفر مقاومة تعليق Pullup .
    الآن دورة الغسالة تحتاج حتى 24 دقيقة فكيف نحصل عليها؟
    البعض يلجأ فى اللغات العالية لأوامر تسبب عدم استجابة المتحكم لأى شيء آخر وهذا يلغى فائدته لذا استخدام عداد و نقوم بتغييره له مضاره ومثال على ذلك
    كود:
    MOV R0,#250 DJNZ R0,$
    وهذه تعنى ضع فى المسجل R0 القيمة 250 (لاحظ وجود شباك هنا)
    ثم الأمر DJNZ هو اختصار Decrement and Jump if Not Zero ثم المسجل R0 و علامة الدولار ، علامة الدولار هذه اختصار لكلمة "هنا" فكأنك استبدلت العنوانين التاليين بها
    Here: DJNZ R0,Here
    فيما عدا أنك فى كل مرة تستخدم هذه الدورة ستحتاج لأسم جديد لها أما "$” فلا
    و الحادث أنك تضع 250 فى المسجل ثم تنقص 1 فإن لم يكن صفرا تعود لذات الأمر أى تنقص منه 1 أى باختصار تظل تنقص 1 حتى يصبح محتواه صفرا لن تنفذ الانتقال مرة أخرى و تخرج منها أى لف حول نفسه 250 مرة كل مرة تستهلك 24 نبضة من الكريستال – زمن قليل جدا
    وكان من الممكن استخدام الأمر
    MOV 10,#250
    DJNZ 10,$
    وهو يعنى ضع فى خانة الذاكرة 10 (لاحظ عدم وجود شباك هنا) القيمة 250 (لاحظ وجود شباك هنا) … فقط ستستهلك خانة ذاكرة اكثر لأن العنوان يحتاج بايت بينما المسجل جزء من الأمر.
    لذا سنحتاج عديد من هذه الدوائر و يا حبذا لو متداخلة لكن بصعوبة نصل لثانية لذا نلجأ لحيلة المقاطعة أيضا

    نأخذ عينة من أحد طرفى المحول 9 فولت متردد (النقطة 1) و من خلال الدايود D7 نأخذ أنصاف الموجة الموجبة فقط ثم نمررها على ترانزستور كمكبر يحولها لموجة مربعة و نضعها على طرف المقاطعة INT1 باسم Clock إذن كل مقاطعة بعد 20 مللى ثانية و كل 50 مقاطعة بثانية كاملة.
    إذن مزيد من شرح المقاطعة المرة القادمة إن شاء الله
    الصور المرفقة الصور المرفقة
    • نوع الملف: png PNP relay drv.png‏ (1.6 كيلوبايت, 119 مشاهدات)
    • نوع الملف: png WashC51 Emergency.png‏ (2.0 كيلوبايت, 123 مشاهدات)
    • نوع الملف: png WashC51 50 Hz.png‏ (2.9 كيلوبايت, 129 مشاهدات)

  2. #22
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي المقاطعة فى عائلة c51

    المقاطعة فى C51

    سبق أن شرحنا عناوين المقاطعة و ما يحدث. عند المقاطعة و هنا لنبرمج المقاطعة يجب أن نعود لجدول الوظائف الخاصة فنجد فى خانة 0A8h حيث نجد مسجل باسم IE اختصار Interrupt Enable أى إتاحة المقاطعة و آخر فى 08Bh باسم IP اختصار Interrupt Priority أى أولوية المقاطعة.
    الأول IE يحدد أى من المصادر متاح و الأول على اليسار بت 7 إتاحة الكل

    لو EA أو إتاحة الكل = صفر (حالة البدء) لن يتاح أى من المقاطعات الأخرى لذا يجب أن يكون =1 لتتاح أى من الباقيات.
    بعد ذلك نجد البت 4 للتسلسلى و البت رقم 3 لتايمر 1 و البت رقم 2 للخارجى رقم 1 و البت رقم 1 لتايمر صفر و البت رقم صفر للخارجى رقم صفر
    يجب أن تكون أى منهم = 1 لكى تفعل المقاطعة المناظرة له و إلا فعكس الميكرو تشيب لن تسبب أى مقاطعة.
    ما يسبب المقاطعة الفعلية هى بت أخرى فى كل موديول مثلا موديول التايمر به بت للمقاطعة لن تستجيب ما لم EA = 1 و أيضا بت التايمر الخاصة بها = 1 فى هذا المسجل IE و سنعرض لذلك لاحقا.
    عندما تحدث مقاطعة فستستجيب الدائرة آليا كما شرحنا سابقا ولكن قبل الانتقال للعنوان تجعل EA =صفر فلا يستجيب لأى مقاطعة أخرى. لذلك يجب أن ينتهى برنامج المقاطعة بأمر خاص هو RETI وتعنى العودة من المقاطعة وهى تخبر الدائرة أن المقاطعة تمت خدمتها و من ثم آليا تعيد EA=1 مرة أخرى.
    قد يكون البرنامج طويلا و تحتاج لمراقبة أشياء أخرى و تحتاج المقاطعة أثناء المقاطعة، الحل بسيط
    SETB EA
    CLR EA
    الأمر الأول يجعل البت المشار إليها (وهى هنا نصا EA ) بواحد و التالى يجعلها = صفر لو أحتاج الأمر أن تنفذ شيء ما دون مقاطعة و طبعا يمكنك الإشارة لأى بت حتى فى منفذ ما بأى من الأمرين السابقين مثلا SETB P0.3 أو لو اسمها معروف مثل CLR C أو المراكم A أيضا CLR A كلها متاحة و تسهل العمل.
    ماذا يحدث لو حدث 2 مقاطعة أو أكثر فى آن؟ حسنا الدائرة تتولى فحص البيتات بالترتيب وهذا يعطيها أولوية ترتيب كما يلى
    IE0 الخارجى صفر ثم TF0 تايمر صفر ثم IE1 الخارجى واحد ثم TF1 تايمر واحد ثم التسلسلى بشقيه إرسال أو استقبال و أخيرا تايمر 2
    الآن ماذا يحدث لو أردت تغيير هذه الأولوية كأن تعطى الأولوية للتسلسلى مثلا أو اكثر من مصدر؟
    حسنا المسجل الآخر IP اختصار Interrupt Priority أى أولوية المقاطعة. لهذا الغرض حيث تجد الخمسة مصادر من بت صفر إلى بت 4

    كلها تكون = صفر فى البدء و أى بت تغيرها =1 تضع المقاطعة المناظرة بأولوية أعلى.
    الآن لو نقلت أى مقاطعة لأولوية أعلى سيستجاب لها أولا قبل أى من الأخريات. لو نقلت أكثر من واحدة فذات ترتيب الفحص السابق سيسرى بين الأعلى أولوية فقط ثم بعد ذلك ما بقى فى الأقل أولوية. ولو حدث مقاطعة لأقل أولوية لن يقاطعها سوى شيء من الأعلى أولوية.
    لا أدرى لماذا ألغيت الأولوية فى عائلة AVR.

    الآن بالعودة لدائرة الطوارئ لإيقاف الغسالة نجد أنها متصلة بالمقاطعة الخارجية صفر IE0 ذات الأولوية الأعلى

    لتفعيلها نحتاج لتنفيذ الأمرين
    SETB EA
    SETB EX0
    أو تنفيذ الأمر
    MOV IE,#10000001b

    الآن نريد أن نفعل المقاطعة الأخرى للمؤقت صفر و المتصل بالنبضات Clock لتحسب الزمن وهذا موضوعنا القادم بإذن الله
    الصور المرفقة الصور المرفقة

  3. #23
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي حساب الزمن بالمقاطعة

    حساب الزمن بالمقاطعة

    الدائرة السابق شرحها لتوليد موجة مربعة من 50 هرتز توفر لنا نبضة أو مقاطعة 50 مرة فى الثانية أى 60*50=3000 مرة فى الدقيقة، إذن بتوفير عداد يعد 3000 سيعطى خرج كل دقيقة و من ثم نعد 20 دقيقة لزمن الغسيل، لكن لو أردت إضافة شاشة رقمية تبين الوقت لن يكون لديك وسيلة لعد الثوانى ، لذا سنعد الثوانى و منها الدقائق.
    فى الوحدة AT89C51 يوجد مؤقت صفر و مؤقت 1 و بدء من AT89C52 و باقى المتحكمات أضيف لها مؤقت ثالث اسمه T2 وهو 16 بت ذاتى التحميل و صمم خصيصا لتسهيل التعامل مع المنفذ التسلسلى لذا لا حاجة لاستخدامه هنا.
    المؤقت 1. أيضا 16 بت ولذا لا حاجة أيضا لاستخدامه هنا . جدير بالذكر أن كل المسجلات و المؤقتات ذات 16 بت تكون من خانتين و تجد هذا صراحة فى جدول الوظائف الخاصة Special Function Register SFR و هذا يمكنك من استخدام أمرين لتحميل النصف العلوى و الثانى لتحميل النصف السفلى أو تستخدم أمر واحد بتحميل المسجل أو المؤقت دفعة واحدة لكنها مهمة المترجم أن يحول هذا الأمر المقبول بأغلب المترجمات للأمرين السابقين.
    أما مؤقت صفر فيتكون من نصفين TH0 و TL0 حيث H=High, L=Low و يمكننا أن نشغله بهما معا كمؤقت 16 بت أو مؤقت 8 بت ذاتى التحميل حيث نضع ذات القيمة فى كلا النصفين و عند تشغيله يرتفع من القيمة الموضوعة و حتى 255 أى 0FFh و عندها يعطى مقاطعة و يعود للقيمة المحفوظة فى النصف الآخر ليكرر الدورة ما لم يتدخل المبرمج لتغيير القيمة المحفوظة فى TH0 .
    ملحوظة : فى هذه العائلة المؤقتات/عدادات تعد صاعدا فقط...، أيضا عند تهيئتها كعداد تأخذ من طرف خارجى بذات الاسم و عند تهيئتها كمؤت ستأخذ من النظام الداخلى أى تردد الكريستال مقسوما على 12 أى عدد الدورات.
    هكذا بوضع 255-50 = 205 فى كلا النصفين فإن TL0 سيتصاعد حتى 255 (بعد 50 نبضة) ثم يحدث مقاطعة و ينسخ 205 من TH0 ليكمل دورة جديدة .
    خرج دائرة توليد 50 هرتز المشروحة المرة الماضية تدخل على طرف المؤقت "تايمر صفر" و لذا يجب أن نهيئه لهذا العمل. فى SPR نجد خانتين أحداهما يسمى TMOD وهى تايمر مود أى نسق التشغيل وهذا محتواها

    نلاحظ أن نصفه الأيمن 4 بت (باللون الأصفر) تخص تايمر صفر و الأخريات للتايمر 1
    البت اليسرى تسمى Gate وهى لتمكن التحكم فى التايمر من خارج المتحكم
    البت التالية تسمي C/T وهى تجعل المسجل يعمل تايمر أو مؤقت. لو 1 يكون عداد و يعد النبضات على الطرف المناظر T0 أو T1
    بعد ذلك 2 بت يحددان وظيفة العداد/مؤقت
    لو صفر صفر كما بالجدول سيعمل 13 بت منها خمسة مقسم سابق Prescaler
    لو واحد صفر يكون 16 بت
    لو صفر واحد يكون 8 بت ذاتى التحميل كما شرحنا وهو النسق ألذى سنتبناه
    لو 11 سيتوقف تايمر 1 ولو فى النصف الأيمن ، تايمر صفر كل قسم منفصل حيث TL0 يعمل 8 بت بينما
    TL1 هو 8 بت أيضا لكن يخضع لنبضات تحكم T1
    لذلك سنضع فيه 00000010 لكى يعمل تحميل ذاتى

    بعد ذلك نجد خانة أخرى اسمها TCON أى تحكم فى التايمر

    و نجد أن كل 2 بت متجاورة توفر وظائف مختلفة لكن لذات التايمر فمثلا باللون الأصفر نجد
    TF1 اختصار Timer1 over Flow وهذه البت هى فعلا مسببة المقاطعة
    و دوائر المتحكم تقيمها عندما ينتقل محتوى المسجل Timer1 من الحد الأقصى للصفر فتسبب مقاطعة و عندما ينتقل البرنامج لتنفيذ برنامج المقاطعة (أى خدمة المقاطعة) يعيدها صفرا (عكس ما يحدث فى ميكرو تشيب إذ يجب أن تفعلها بنفسك وهو أحد أسباب مشقة برمجته بالأسيمبلى هنا وفى باقى البيتات فى هذا المسجل) .
    الثانية TR1 وهى اختصار Timer Run أى تايمر واحد تشغيل/إيقاف عندما يقيمها (=1) البرنامج يعمل المؤقت و عندما يلغيها = صفر يتوقف
    باللون البرتقالى TF0 بت المقاطعة للتايمر صفر وكما سبق =1 عند ألمقاطعة و عند خدمة المقاطعة ستعود آليا لصفر و TR0 تشغيل و إيقافه و بتهيئته كعداد سيأخذ من الطرف T0 (وهو فى دائرتنا نوصلها بمولد 50 هرتز) .
    باللون الأخضر مقاطعة خارجية رقم 1 أى IE1 وهى Interrupt External التى تسبب المقاطعة نتيجة نزول الطرف الخارجى INT1 منفذ 3 طرف 3 و البت التالية IT1 وهى Interrupt Trigger تغير استجابة المتحكم للتغيير على الطرف INT1 منفذ 3 طرف 3 ،من قدح بالمستوى Level Trigger أى تستجيب للمستوى = صفر إلى قدح بالحافة Edge Trigger أى حافة هابطة من+ 5 فولت للصفر.
    لو هذه البت = صفر ستستجيب المقاطعة للمستوى = صفر و من ثم لو تمت الاستجابة له و لم يعود للمستوى 1 قبل العودة من المقاطعة ، فإن الميكرو سيجدها ما زالت صفر و من ثم بالخطأ يظنها مقاطعة جديدة، أما لو كانت 1 فهذا يعنى أن الاستجابة تحدث نتيجة الانتقال من واحد للصفر و لن تتكرر مرة أخرى حتى تعود الحالة للواحد مرة أخرى ثم تنتقل للصفر و كثيرا ما يكون هذا أسلم .
    و أخيرا باللون الأزرق ذات الخاصيتين لكن للطرف INT0 و بهذا نحتاج لوضع IT0=1 بالأمر
    SETB IT0

    وهكذا اكتملت الدائرة و أصبحت كما يلى

    برجاء ملاحظة أن هذا للتعليم ولكن واقعيا يجب إضافة مكثف من 0.01uF إلى 0.1uF على طرفى كل مفتاح لتجنب الارتداد و الاهتزاز Bouncing و ضمان عدم تكرار النبضة كما أن كل طراز له حساسات مختلفة عن ما اقترحته هنا و أيضا الدورات ستختلف لذا يمكنك تعديل أى برنامج حسب الواقع.
    الآن نبدأ بالبرمجة بالأسيمبلى و حتى ذلك الحين نفكر كيف نهيكله ، مثلا يقرأ المفاتيح حتى يقرأ Start ثم يبدأ ملئ المياه حتى يقفل المفتاح ثم يبدأ التسخين حتى الحساس المعنى ثم تدور 5 أو 12 أو 20 دقيقة غسيل ثم صرف حتى الحساس ثم ملئ مرة أخرى للشطف ثم دوران دقيقتين ثم صرف ثم ملئ و شطف دقيقتين أخرتين ثم دورة العصر خمسة دقائق ثم التوقف

    حسنا هذا المرة القادمة إن شاء الله
    الصور المرفقة الصور المرفقة
    • نوع الملف: png TMOD-C51.png‏ (6.7 كيلوبايت, 130 مشاهدات)
    • نوع الملف: png TCON-C51.png‏ (6.1 كيلوبايت, 140 مشاهدات)
    • نوع الملف: png WashC51.png‏ (16.7 كيلوبايت, 168 مشاهدات)

  4. #24
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي برنامج الغسالة بالأسيمبلى

    كتابة البرنامج بالأسيمبلى:

    البداية و التعريفات والمقاطعة:

    حسنا البرنامج التالى أثناء فحصه ستجد أنك تستطيع تطويره و تحسين وظائفه، لم لا ؟ فقط هذا تعليمى لتوضيح كيف نبرمج ولماذا نفعل ذلك و أيها الأفضل. ، ولو أرنا الأفضلية سنحتاج وقت أطول بكثير فضلا عن تحديد الطراز لكل نوع حساس ، أبسط الأمثلة نستخدم حساسين للحرارة المتوسطة و العالية و يمكنك أن تستخدم حساس متغير لضبط الحرارة كما تشاء.
    الآن سنبدأ بمشروع جديد أو برنامج جديد حسب المترجم ألذى تستخدمه و نختار فى البداية أمر تعريف الميكرو و سنختار متحكم AT89C52 أو بديل.
    نبدأ بالتعريفات و سنعرف أولا المنافذ الأربعة و نستخدم هذه التعريفات لتعريف الأطراف مما يجعل المسميات أقرب للفهم و التذكر
    كود:
    $NOMOD51 $INCLUDE (80C52.MCU) ;===================================== ; DEFINITIONS ;===================================== LEDs Equ P0 Relays equ P1 Switches equ P2 Controls Equ P3 FullLED Equ LEDs.0 HalfLED Equ LEDS.1 SmallLED Equ LEDs.2 HOTLED Equ LEDs.3 MildLED Equ LEDs.4 ColdLED Equ LEDs.5 WaterOn Equ Relays.0 DrainOn Equ Relays.1 HeaterOn Equ Relays.2 MotorOn Equ Relays.3 Run_Nspin Equ Relays.4 WaterFull Equ Relays.5 WaterEmpty Equ Relays.6 DoorOpen Equ Relays.7 MidTemp Equ Switches.0 HiTemp Equ Switches.1 Cold Equ Switches.2 Mild Equ Switches.3 Hot Equ Switches.4 Small Equ Switches.5 Half Equ Switches.6 Full Equ Switches.7 RUN Equ Controls.1 ;===================================== ; VARIABLES ;===================================== Seconds Equ R7 Minutes Equ R6 JobPending Equ F0 ;===================================== ; RESET and INTERRUPT VECTORS ;===================================== org 0000h ; Reset Vector sjmp Start org 0003h ; Adress of INT0 (IE0)Emergency sjmp Start ; Reset All Parameters and Ports org 000Bh ; Adress of Interrupt Timer 0 (TF0) DJNZ Seconds,Tfinish MOV seconds,#59 Djnz Minutes,Tfinish CLR Jobpending CLR TR0 ; Stop counter Tfinish: RETI
    بعد التعريفات يأتى دور المتغيرات و نعرف أنها إما تكون اسم لخانة فى الذاكرة أو لو أمكن يكون مسجل لكونه أسرع. نذكر أن فى أتميل مجموعة مسجلات منها ثمانية يسهل التعامل معهم ولبعضهم ميزات إضافية وهى تعرف باسم R0:R7 لذلك سنعرف أحدهما باسم الدقائق و آخر باسم الثوانى هما R7,R6 و نحتاج لعلم Flag يشير أن الزمن لم ينتهى بعد.
    أعلم أنك ستقول سينتهى عندما كل من R7,R6 أو بمسمياتهم Minuted,Seconds يساويان صفر
    أجل لكن لتعلم ذلك يجب أن تختبرهما على التوالى كل مرة تريد فيها التحقق من انتهاء الزمن وهذا ما يسمى برمجة غير احترافية لإضاعتهما كود و زمن و أنت أصلا لا تحتاج لذلك
    لا تنسى أن كل مقاطعة وظيفتها أن تنقص الثوانى و تنقص الدقائق حتى تتساوى بالصفر أى أنك بالفعل حسبت هذا الأمر وما عليك سوى حفظ النتيجة ، هنا نستخدم البت F0 السابق شرحها فى PSW و المسماة User Flag فتجعلها =1 ثم تبدأ العد و عند تمامه اجعلها = صفر و بالتالى كل ما عليك أن تختبرها فقط بتعليمه صغيرة و بسيطة لتعلم إن كان الزمن قد تم أم لا.


    بعد ذلك يأتى البدء و المقاطعة، سنجد فى خانة صفر حيث الريسيت قفزة لعنوان Start حيث بدء البرنامج الفعلى
    يليها فى العنوان 3 حيث عنوان مقاطعة الطرف الخارجى INT0 وهى الطوارئ و هنا يجب الإيقاف و العودة حيث بدأنا لذلك نستخدم القفز إلى Start أيضا كما لو أننى أطفأت الوحدة ثم أعدت تشغيلها مرة أخرى
    و أخيرا فى عنوان B وهو =12 حيث مقاطعة العداد ألذى يستقبل 50 هرتز من الخارج و بعد 50 عد أى كل ثانية سيحدث مقاطعة. هنا سننقص الثوانى 1 فإن بقى ثوانى نعود من المقاطعة و إلا لو أصبحت صفرا ننقص الدقائق 1 فإن لم تكن صفرا نعيد الثوانى إلى 59 و نبدأ الدورة من جديد أى نعود من المقاطعة وهكذا حتى تنتهى الدقائق وتصبح صفرا نوقف العداد و نعلن انتهاء الزمن بتصفير العلم Jobpending و نخرج من المقاطعة.
    لاحظ هنا أن آخر دقيقة لم نعدها لذا عند البدء مثلا بخمس دقائق نضع 5 دقائق و 59 ثانية.
    المرة القادمة إن شاء الله نكمل باقى البرنامج .

  5. #25
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي تجهيز الغسالة و اعداد الخيارات

    تجهيز الغسالة :

    بعد أن مهدنا للمقاطعة و البدء الخ نبدأ البرنامج طبقا للهيكلة السابقة فمثلا نقول بعد اختيار الكمية و الحرارة، لو الباب مغلق نبدأ ملئ الخزان و عند تمامه نشغل السخان طبقا للحرارة
    ما بين عنوان البدء و عنوان الدورة "التكرارى" نجد ما يسمى التمهيد أوHouse Keeping أو حرفيا ترتيب المنزل
    السطر الأول إتاحة كل المقاطعات و مقاطعة T0 ومقاطعة الخارجى INT0
    الثانى و الثالث تحميل كل من نصفى المسجل T0 بالقيمة المطلوبة و الرابع تهيئه T0 كعداد ذاتى التحميل بعدها جعل المقاطعة الخارجية قدح بالحافة Edge Trigger ثم تغيير مؤشر الرصة بعيدا ثم وضع المنافذ الأربع فى حال البداية رغم أنها كذلك إلا أن هنا ضرورة لحالة الطوارئ فهى لن تعيد المنافذ لحال البدء لذا تفرض بالبرنامج تحسبا.
    لو حدث طارئ و ضغطت على زر الطوارئ ستجبر المتحكم على البدء من جديد و سينهى التهيئة و الوصول هنا و ينتقل عبره لدورة تشغيل الموتور قبل أن تتمكن من رفع إصبعك من على زر البدء لذا وجب الانتظار هنا حتى ترفع يدك عنه لذا نختبر لو البت Run = 0 سنظل فى دوره وذلك بالأمر JNB اختصار Jump if Not Bit set ثم اسم البت Run و العنوان المقصود الذهاب إليه و علامة الدولار هى رمز مختصر لكلمة "هنا" بدلا من و ضع عنوان أول السطر و كتابته مرة أخرى فى الأمر هكذا
    Here: JNB Run,Here
    هكذا سنظل ندور هنا طالما زرار RUN=0 ثم بعده نختبر الخيارات

    كود:
    ;===================================== ; CODE SEGMENT ;===================================== Start: MOV IE,#10000011b ; Enable T0 & INT0 external MOV TH0,#205 ; Auto reload MOV TL0,#205 MOV TMOD,#00000110b ; T0 8bit counter auto reload MOV TCON,#1 ; Clear All interrupts, SETB IT0 Edge triggered MOV SP,#70 ; Move stack away MOV LEDs,#11011011b ; Reset All PORTS! select Small cold cycle MOV Relays,#255 MOV Switches,#255 MOV Controls,#255 JNB RUN,$ ; Run button release JB Full,TstHalf Loop: ORL LEDs,#00000111b CLR FullLED TstHalf: JB Half,TSTSmall ORL LEDs,#00000111b CLR HalfLED TSTSmall: JB Small,TstHot ORL LEDs,#00000111b CLR SmallLED TstHot: JB Hot,TstMild ORL LEDs,#00111000b CLR HotLED TstMild: JB Mild,TstCold ORL LEDs,#00111000b CLR MildLED TstCold: JB Cold,TstStart ORL LEDs,#00111000b CLR ColdLED TstStart:

    بعد ذلك نجد العنوان Loop التكرارى
    الخيار الافتراضى هنا Small Cold بعد ذلك نفحص أى الأزرار تضغط فإن لم يكن Full ننتقل للتالى و إلا نضيء ألليد الخاص بالكمية Full بجعل طرفه = صفر ولو أردنا السرعة نضع أمر انتقال sjmp TstHot حتى لا نضيع وقت فى اختبار الحالتين التاليتين و للكود الأقل نكتفى بما لدينا
    أود هنا أن أوضح أساسا من أساسيات البرمجة وهى السرعة مقابل الكود، من المنطقى أن يكون الكود الأكثر أبطا فى التنفيذ لكن غالبا ما يكون الكود الأطول أسرع فى التنفيذ وهذا مثال على ذلك فإضافة أوامر انتقال يضيف كود ليختصر تنفيذ ما لا يجدى تنفيذه.
    بعد ذلك نختبر Half و ننتقل لو لم يضغط لاختبار Small و إلا نضيء HalfLED ، ولكى نضئ واحد يجب أن نطفئ أى ليد آخر قد يكون مضاء و لكنا لا نعلم ما هو ، لذا نطفئ الكل بأمر
    ORL LEDs,#00000111b
    حيث ORL اختصار OR Logic وهى تنفيذ وظيفة OR أى وظيفة "أو" على مستوى البت. تسمى Logic لأن هناك فى بعض المترجمات للغات العالية تستخدم دوال على مستوى المتغير تسمى Boolean OR حيث يعتبر أى رقم هو موجود أو = منطق واحد أو حقيقى أو TRUE و الصفر فقط هو منطق صفر أو False أو غير موجود وهو يعطى نتائج مختلفة فمثلا على مستوى البايت سيكون متمم complement أى رقم هو صفر و متمم الصفر هو FF أو 255 و مترجمات C51 لا تدعمه .
    تنفيذ الأمر السابق يفرض 111 فى البيتات الثلاث الأقل فيطفئ الليدات الثلاث معا ثم أمر CLR لإضاءة ما نريد
    بعد ذلك نكرر العمل مع البتات الثلاث الأخريات لاختيار الحرارة ساخن أو دافئ أو بارد مع ملاحظة أن أمر ORL الآن مع البيتات الثلاث .
    المرة القادمة إن شاء الله نختبر هل نبدأ أم نكرر ما سبق

  6. #26
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي التشغيل و الإيقاف

    التشغيل و الإيقاف:

    بالكود السابق اعدنا تحديد الدورة المطلوبة و بقى أن ندير الموتور . سنختبر زر البدء فإن لم يكن مضغوط نعود للدورة مرة أخرى فقد يقوم المشغل بتعديل فى الدورة. و إن كان مضغوط فنختبر هل الباب مفتوح؟ إن كان مفتوح ننتظر غلقه و بعدها نفتح صنبور المياه WaterON ثم ننتظر ملئ الوعاء من حساس WaterFull ثم غلق الصنبور ثم بعد ذلك يختبر البعض هل دور ساخن نفتح السخان و ننتظر حساس الحرارة العالية و إلا هل متوسط الحرارة فنشغل السخان و ننتظر حساس الحرارة المتوسطة وإلا نختبر هل البارد مختار فلا نفعل شيئا وهذا هو المنطقى.
    لكن بقليل من التفكير نعكس الترتيب لنوفر بعض الخطوات ، نختبر هل دورة بارد المختارة؟ ننتقل مباشرة لتحديد الزمن و إلا نفتح السخان
    HeaterON فهو مطلوب فى الحالتين ثم نختبر هل ليد متوسط الحرارة MildLED غير مضاء سننتظر حساس الحرارة العالية ثم ننتقل لتحديد الزمن و إلا ننتظر الحرارة المتوسطة و الانتقال هنا حتمى بتتابع الأحداث ولا نحتاج أمر انتقال.
    هيه لماذا لم تختبر إن كانت الحرارة العالية مختارة؟
    ببساطة هم ثلاث خيارات ، الأول و الثانى لم يختار أى منهما، ماذا تتوقع؟ كان لازما لو عدم اختيار أى منهم واردا فنطلق انذار بأن الإختيار خاطئ.
    كود:
    TstStart: JB run,Loop ; Wait Run Press JB DoorOpen,$ ; Wait Door to close CLR WaterOn ; Fill with water JB WaterFull,$ ; Wait full Tank SETB WaterON ; Close water Valve JNB ColdLED,SetCycle ; Cold cycle No Heat needed CLR HeaterON ; Turn Heater ON JNB MildLED,HOTTemp JB HiTemp,$ ; wait Hot sensor SJMP SetCycle HOTTemp: JB MidTemp,$ ; wait Warm sensor SetCycle: ; Now Start Washing SETB HeaterON ; Turn off heater JNB FullLED,HalfCycle MOV Minutes,#20 SJMP RunMotor HalfCycle: JNB HalfLED,SmallCycle MOV Minutes,#8 SJMP RunMotor SmallCycle: MOV Minutes,#5 RunMotor:

    الآن انتقلنا لتحديد الزمن، فنغلق السخان و من الجيد أن نغلقه هنا فالبعض يكرر أمر الإغلاق فى الحالات الثلاث السابقة وهو تكرار مستهلك للذاكرة لا داعى له
    .
    نختبر Full فإن كانت مختارة نضع فى الدقائق 20 دقيقة و ننتقل لتشغيل الموتور و إلا نختبر Half
    هيه، ذكرت أنك تحتاج تضع 59 فى الثوانى!! أجل ذاكرة جيدة لكنك لم تقرأ السطر قبل السابق! و لم تتعلم الدرس!
    نختبر Half و فإن كانت مختارة نضع فى الدقائق 8 دقائق و ننتقل لتشغيل الموتور و كما سبق و قلنا هو الاحتمال الأخير الباقى أن نضع 5 دقائق و الانتقال هنا أيضا حتمى بتتابع الأحداث.
    المرة القادمة إن شاء الله سنتحدث عن تشغيل الموتور فى دورة الغسيل ثم دورتين للشطف و ثالثة للعصير و التوقف بانتظار تحديد دورة أخرى أو تكرار هذه الدورة

  7. #27
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي دورات الغسيل و الشطف و العصر ثم الإيقاف

    دورات الغسيل و الشطف و العصر ثم الإيقاف:

    لم نضع سابقا قيمة 59 للثوانى ، حسنا أول ما نفعله هو وضعها فهى مكررة للكل ثم نقيم العلم أى البت JobPending والتى هى دليل انتهاء الزمن و المقاطعة سترجعها للصفر عند انتهاء الزمن ثم نبدأ الموتور و نشغل العداد الداخلى T0 و ننتظر انتهاء الوقت ثم نوقف الموتور. ثم نفتح الصرف و ننتظر حساس المياه لنعلم خلو الخزان ثم نغلق الصمام ثم نفتح الماء للشطف و ننتظر حساس الملئ و نغلق الصمام ثم نضع 5 دقائق لدورة الشطف و نبدأ كما سبق ثم نوقف الموتور
    كود:
    RunMotor: MOV Seconds,#59 SETB JobPending CLR MotorOn SETB TR0 ; Start Timer/Counter JB JobPending,$ ; Wait to Finish SETB MotorON ; stop motor CLR DrainON ; Open Drain JB WaterEmpty,$ ;Wait Drain Setb DrainON ; Close Drain CLR WaterON ; Fill again JB WaterFull,$ SETB WaterON ; Close Water MOV Minutes,#5 ; 1St Rinze MOV Seconds,#59 SETB JobPending CLR MotorOn ; Start Rinze SETB TR0 ; Start Timer JB JobPending,$ ; Wait to Finish Setb MotorOn ; Stop Rinze CLR DrainON ; Open Drain second cycle JB WaterEmpty,$ ;Wait Drain Setb DrainON ; Close Drain CLR WaterON ; Fill again JB WaterFull,$ SETB WaterON ; Close Water MOV Minutes,#5 ; 2nd Rinze MOV Seconds,#59 SETB JobPending SETB TR0 ; Start Timer/Counter CLR MotorOn ; Start Rinze SETB TR0 ; Start Timer JB JobPending,$ ; Wait to Finish Setb MotorOn ; Stop Rinze CLR DrainON ; Open Drain second cycle JB WaterEmpty,$ ;Wait Drain MOV Minutes,#3 ; SPIN MOV Seconds,#59 SETB JobPending CLR MotorOn ; Start Rinze CLR Run_Nspin ; SPIN SETB TR0 ; Start Timer/Counter JB JobPending,$ ; Wait to Finish SETB Run_NSpi' SETB MotorON ; Stop Motor' Setb DrainON ; Close DRAIN' ;; MOV Relays,#255 ; ALL OFF, INITIAL Sta ;MOV Controls,#255 jmp Loop ;==================================== END


    ثم نصرف المياه و نكرر الشطف مرة ثانية ثم نتوقف وبعد الصرف نضع
    3 دقائق لدورة العصر و نبدأ كما سبق مع تفعيل طرف RUN_NSPIN للسرعة العالية ثم نتوقف.
    الآن قبل أن نعود للدورة نحتاج للتأكد من أن الموتور مغلق و العودة للسرعة العادية و الصرف مغلق بالثلاث أوامر المذكورة ولكنها موضوعة بصورة تعليق لأن استخدام أمرين فقط كما هو مبين كافى لإعادة الوضع كاملا للتوقف.


    أيضا هنا استخدمنا أزرار وليدات وهو أمر جيد لكثير من التطبيقات لكنه فى إدخال الأرقام متعب قليلا لذا بعد انتهاء شرح اللغات أفكر فى برنامج ميكروويف منزلى لتناول لوحة الأرقام Key Pad مع الشاشات السباعية و تغير وظيفة طرف حسب الظروف ثم برنامج لشيء آخر لتناول محول تماثلى رقمى و ألشاشة LCD هذا لو لم تشير رغباتكم لاتجاه آخر.


    قبل أن نبدأ فى إعادة البرنامج بالبيزك ثم بلغة C أود شرح بعض النقاط العملية فى التنفيذ وهو موضوعنا القادم بإذن الله

  8. #28
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي اعتبارات عملية فى تنفيذ مثل هذه ألبوردات

    اعتبارات عملية فى تنفيذ مثل هذه ألبوردات:

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

    رجاء للفحص و الدراسة وليس التطبيق حاول تصفح مرسل إذاعة FM ، ستجد كم المشاكل حول أنه لم يعمل كثيرة رغم أننى نفذت أكثر من واحد – المشكلة فقط "أنه كان متاحا لى راسم ذبذبات يرسم و يحسب هذا التردد" و من ثم علمت كم هو بعيد عن التردد المطلوب.
    الآن ماذا يهمك و أنت تدرس متحكم؟ رجاء راجع حجم الملف المستخدم ستجده ثلاث إلى 5 لفات على قلم رصاص رفيع أى طول السلك لا يزيد عن10 سم. كم هو طول خطوط التغذية لديك؟؟
    تغليظ المسارات يقلل من الأثر لكنه ليس بالقدر المطلوب، وفى هذا المجال

    التوصيل على اليسار أكثر أمنا و أقل تأثيرا عن التوصيل على اليمين وهذا يعنى أن مسارات تغذية الريلايات من المنبع تكون منفصلة تماما عن باقى المكونات الإلكترونية ولا تجعل الرجوع مشتركا إلا فى نقطة البدء
    أيضا وضع مكثف بجوار كل ريلاى أو فى مدخل تغذيتهم سيجعل نبضات الريلاى مأخوذة منه ولا تعبره لباقى الدوائر
    لو تستخدم وسائل خارجية مثل الموتورات و السولينويدات أى صمامات المياه الكهربية فكلها قد تعمل من220 متردد و الريلاى سيتحكم فيها. حسنا ضوضاء هذه المعدات ستشكل مشكلة أيضا لذا عادة ما تفصل مساراتها عن مسارات وحدة التغذية.
    استخدام وحدات تغذية مثبتة الجهد و تقطيعية تقلل كثيرا من أثر هذه الضوضاء لأنها تعتمد التقطيع ثم التخلص من أثره. و استخدام مرشح دخول للبوردة يقلل كثيرا من أثر هذه التداخلات.
    استخدام مرشح تغذية يفيد جدا فى التخلص من أثر هذه التداخلات Line Filter و ممكن أن يكون على البوردة لو تغذى من مصدر متردد سواء 220 أو 12 فولت أو يكون قبل محول الدخول.

    أيضا يجب الاهتمام جيدا بتغذية المتحكم ذاته حتى لا تدخل له نبضات من طرفى التغذية. كما أن الكثير لا يعبأ بطرف MCLR أو RESET فإما تلغيه و تهيء الطرف كمدخل / مخرج وتعتمد على الريسيت الذاتى مع انخفاض الفولت و تضع على طرفى التغذية مكثفات كافية أو تجعله طرف بدء تشغيل و توصله بالمقاومة و المكثف المناسبين
    أيضا لا تنسى أن وضعك مكثف 100 ميكروفاراد لا يغنى عن واحد 0.1 ميكرو على ألتوازى معه و الأفضل أن يكون قرص سيراميك لأن لف طبقات المكثف يخلق ملف داخلى يعوق الاستجابة للترددات العالية.

    قبل البدء قى تحويل البرنامج باللغات العالية سنبدأ فى المرة القادمة فهم ما هى اللغات العالية وهو موضوعنا القادم إن شاء الله
    الصور المرفقة الصور المرفقة
    • نوع الملف: png LineFilter.png‏ (1.6 كيلوبايت, 112 مشاهدات)
    • نوع الملف: png PCB Wireing.png‏ (1.7 كيلوبايت, 111 مشاهدات)

  9. #29
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي هيكل اللغات العالية و تكونها

    هيكل اللغات العالية و مم تتكون:

    اللغات العالية تشترك فى مجموعة من الصفات مع اختلافات فى نص كتابتها و قد تتعجب أنها تتكون من 10 أوامر فقط تنقسم لثلاثة أقسام هى الشروط Conditions و الدورات Iteration ثم القفز أو الانتقال Jump
    قبل دراسة تفاصيلها ندرس الهيكل العام لأى برنامج
    الهيكل العام:

    تبدأ بالتسميات حيث تعطى لأى مكون اسم مريح من واقع الدائرة لتذكرك ما دور كل اسم سواء كان منفذ كامل أو طرف من منفذ أو مكون داخلى كمسجل أو علم Flag أو قيمة ثابتة أو متغيرة الخ. التسميات لا تأخذ أى ذاكرة لأنها تنتهى عند بدء الترجمة حيث يستبدل المترجم كل اسم بما يساويه سواء أكان مكون أو حتى معادلة رياضيه (كثير من المترجمات تسمح بهذا وليست الكل) . هذه التسميات تكون بالتعليمه Alias أو Symbol حسب المترجم باسكوم أو ميكروإلكترونيكا و يفضل غالبا و يحتم أحيانا كثيرة أن يكون فى أول البرنامج لحاجة المترجم لها لترجمة باقى الأسطر .
    يلى ذلك التعريفات حيث تعرف المتغيرات و الثوابت اسم كل منها و حجمه (كم بايت) وهل هو موجب فقط أم موجب و سالب كما سبق الشرح و هل هى رقم عشرى Float
    يلى ذلك تعريف ألدوال و الوظائف حيث يمكن تعريفها وكتابة الكود اللازم لها أو نكتفى بالتعريف فقط و نضع الكود لها لاحقا.
    فى اللغات العالية يتكون البرنامج من مجموعة من الوظائف و قد تحتاج ألدوال أيضا و الوظيفة هى ببساطة مجموعة أوامر متتابعة تؤدى مهمة معينه. مثلا اكتب على الشاشة كذا الخ ولا ناتج لها سوى العمل المطلوب. أما ألدوال فهى مشابهة إلا أنها تعطى نتيجة مثلا جيب الزاوية فهى دالة أعطيها 30 تعطينى نصف لأن جا 30 = 0.5
    هذه الأسماء عامة أى تشمل البرنامج كاملا بكافة أقسامه. أغلب المترجمات تسمح بالتعريف داخل الدالة أو الوظيفة و يكون ظهور هذه القيمة داخل الدالة فقط مثلا لو عرفت دالة باسم "Send" و عرفت داخلها قيمة "Count" فقيمة Count هذه لا تستطيع أى تعليمة فى البرنامج خارج
    "Send" أن تصل إليها و تتعامل معها

    تعريف الوظيفة:

    هى مجموعة تعليمات بين بداية و نهاية يحددان ما يخص هذه الوظيفة ففى البيزك نجد باسكوم تستخدم فى قسم التعريفات
    كود:
    Declare Sub InitLCD Declare Sub Testvar(b As Byte , I As Integer , W As Word )
    و الكلمة الأولى هى Declare وتعنى إشهار أو إعلان ثم كلمة Sub اختصار Subroutine للدلالة أنها لا تعطى نتيجة حسابية ثم يلى ذلك اسمها وهو InitLCD وهى تهيئه الشاشة LCD و يمكن أن تضيف () قوسين لتذكرك أنها لا تقبل بيانات أو بالصورة فى السطر التالى وهى باسم Testvar لاختبار متغيرات مثلا ثم تضع بين قوسين أسماء لهذه المتغيرات غير الأسماء التى سبق لك استخدامها فى التعريفات مع كلمة As و حجم أو نوع كل منها ولو أكثر من واحد تفصل بينهم بفاصلة)
    لاحقا فى البرنامج و حيث تريد لهذه الوظيفة أن توضع فى الذاكرة بين باقى البرنامج تكتب ما يلى
    كود:
    Sub InitLCD . . End Sub Sub Testvar(b As Byte , I As Integer , W As Word ) . . . End Sub
    هذه الطريقة تتيح لك أن تقسم الذاكرة حسب ما تريد و تضع كل وظيفة أو دالة بالضبط حيت ترى ، أما طريقة ميكروإلكترونيكا فيجب أن تعلنها و تضعها قبل استخدامها هكذا
    كود:
    SUB PROCEDURE DoThisThing () . . . End Sub
    البداية هى كلمة Sub اختصار Subroutine ثم كلمة PROCEDURE للدلالة أنها لا تعطى نتيجة حسابية (لا معنى لتكرار الأمر هنا ولكنها ليست قياسية فى أى نظام بيزك) ثم يلى ذلك اسمها وهو ما عبرت عنه بكلمة DoThisThing ثم قوسين () لتبيان أننا لا نحتاج أى شيء لهذه الوظيفة أما لو مثل وظيفة الكتابة على الشاشة مثلا تكون
    كود:
    SUB PROCEDURE WriteLCD (Line2Print as string) .كود . . End Sub
    فتضع بين القوسين Line2Print as string وهى Line2Print مجرد اسم ليذكرك لاحقا ماذا تحتاج لأن تضع بدلا منه ثم as string تعريف أنها نص
    و لكى تستخدم أى منهم نتبع الصيغة البسيطة كأى تعليمه أخرى مثلا
    كود:
    InitLCD Testvar(5 , 20 , 1245 ) DoThisThing WriteLCD (“ Hello World “)
    تعريف الدالة


    أما الدالة فتكون بطريقة باسكوم
    Declare Function Myfunction(byval I As Integer , S As String) As Integer

    و نغير كلمة Sub بكلمة Function للدلاله على أنها وظيفة تعيد نتيجة إما رقم أو نصوص أو ما تحدد لها
    لاحقا وحيث تريد أن تضعها تكتب الكود لها هكذا
    كود:
    Function Myfunction(byval I As Integer , S As String) As Integer . .كود .كود MyFunction = 2*I/y End Function
    السطر MyFunction = ….. هو نتيجة هذه الدالة التى سترد بها وهى تقابل مثلا فى الدالة الشهيرة لجيب تمام الزوايا القيمة 0.5 لدالة جا30 ولا يشترط أن تكون آخر سطر بل يمكنك أن تجعلها مشروطة مثلا لو Length بكذا MyFunction = 1 ولو بكذا MyFunction = 2 الخ أى يمكم أن تتكرر بحسب الشروط.

    و تطلبها كما تطلب أى دالة عادية فستحتاج مثلا أن تعرف بعض المتغيرات منها CurrentVal مثلا و تريد أن تضع فيه جا 30 ستكتب ببساطة
    كود:
    CurrentVal = Sin(30) CurrentVal = Myfunction(5,”Day”)
    والسطر التالى لو ستطلب ألداله Myfunction بدلا منها


    أما بطريقة ميكروإلكترونيكا فيمكن تعريفها مسبقا بكتابة
    sub function First(dim a as word, dim b as word) as word forward

    البداية هى كلمة Sub اختصار Subroutine ثم كلمة function للدلالة على أنها تعيد نتيجة ثم يلى ذلك اسمها وهو ما عبرت عنه بكلمة First ثم قوسين () بينهما الأسماء و أحجامها و بعد ذلك كلمتى as word لتفيد أنها ستعيد قيمة بحجم Word و أخيرا كلمة forward للدلالة على أن الكود سيأتى لاحقا
    لاحقا تضع الكود كما يلى

    كود:
    SUB function First(dim a as word, dim b as word) as word .كود .كود .Result = 5*a/b End Sub
    و القيمة التى تعاد هى Result=... و نفس الشروط السابقة و طلبها كما فى المثال السابق أيضا.
    ذكرنا سابقا أن التعريفات ذات مدى عام أو شامل تغطى كل الوظائف و ألدوال أى يمكن لأى منها أن تقرأ هذه التعريفات أو تغيرها بصرف النظر عن كونها دالة أو وظيفة لكن لو فى داخل أى دالة أو وظيفة أعلنت متغير جديد سيكون مجاله محليا فقط أى بداخل الدالة أو الوظيفة ولا يمكن التعامل معه خارجها.
    لاحظ أن كل البرنامج مجموعة من الوظائف لذا على الأقل سيحتوى على وظيفة واحدة فقط و تسمى Main ولا تعلن بأى من الوظائف السابقة Declare , SUB و لذلك تنتهى بكلمة END فقط بدون أى إضافات .


    فى لغة C نجد الأمر مختلف قليلا فلا يوجد وظيفة أو دالة ولكن كلها subroutine فإن أعاد شيئا فهو دالة وإلا فيكون وظيفة و الإعلان عنها كما يلى
    كود:
    int max(int x, int y) { return (x>=y) ? x : y; }
    أول كلمة int تعنى أن العائد من حجم Integer ، إذن هى دالة و ليست وظيفة و اسمها max و بين القوسين القيمتين المطلوب المفاضلة بينهما و حجم كل منهما ثم القوس المعوج الشهير
    القيمة التى سترد بها هى بعد return و طبعا نفس الشروط السابقة و هى هنا تقول ما بين القوسين x أكبر من أو تساوى y . أما بعدها نجد ؟ وهذه تعنى "هل ما بين القوسين صحيح؟ لو نعم صحيح أعد أو قيمة تالية وهى هنا X و إن لم تكن أعد القيمة التى تليها أى Y . عبقرية لكن حاول أن تتذكرها عندما تحتجها أو تستنتجها ما لم أكن ذكرتها لك ولو خطأ ما فى النص حاول اكتشافه ، شخصيا أفضل كثيرا الصيغة
    IF X>=Y THEN RESULT=X ELSE RESULT =Y
    بسيطة و مفهومة بلا شرح و منطقية. و أخيرا القوس المعوج الغالق .
    هواه هذه اللغة يعيبون على لغة البيزك كلمة مثل End Sub , End Function.
    حسنا كل الأوامر العشرة و كل وظيفة تنتهى بذات القوس “{” و المترجم يربطه بأقرب واحد مفتوح “}” ونادرا ما تكون دالة أو وظيفة لا تحتوى عدد من الأوامر المتداخلة
    فعندما ترى { لا تعلم أى شيء يخص هذا القوس و تبذل جهدا كبيرا لتتبع الأقواس عبر الصفحات
    أما لو وجدت END IF فقد علمت أنك أغلقت دورة IF ولم تغلق غيرها ولن تذهب END IF لأقرب شيء مفتوح مثل دورة For لأنه لا يخصها، لذلك أستطيع أن اركز اهتمامى على البرمجة و منطقها عوضا عن فوازير الأقواس التى لا تربح جوائز - معذرة هذا رأيى المتواضع و لكل رأى يسعد به
    أخيرا لاحظنا كلمة ByVal ولم نقل عنها شيئا، هى اختصار By Value و مقابلها ByRef أى By Reference. لو لدينا متغير ما مثل Angle و لديك وظيفة باسم ChK_A فيها ستختبر قيمة Angle و بناء عليها تفعل خيار من خيارات كثيرة قد تحتاج لتعليمه مثل If sin(Angle) =.5 Then فماذا سيفعل المترجم؟؟
    سابقا هو خصص مثلا الخانة 10 من الذاكرة لحفظ قيمة Angle و فى هذه اللحظة Angle=45 و الآن تطلب منه استخدام دالة من داخل دالتك ChK_A لحساب جيب الزاوية، إذن هل سيرسل للدالة قيمة 10 حيث تقبع قيمة Angle أم يرسل المحتوى 45؟ و ما الفرق !! كلاهما واحد!!
    كلا الفرق شاسع فلو أرسل القيمة By_Val فالتغيير داخل الدالة سيكون على القيمة 45 فقط أما لو أرسلتها By_ref فالتغيير سيكون على محتوى الخانة. وهذا هو الوضع الافتراضى أن أن أى تغيير داخل الدالة سيطال المتغير الأصلى.
    مهلا سبق أن قلت أن الدالة لا تعيد شيئا وهنا تقول أنها تغير من قيمة المتغيرات أى أنها تعيد شيئا!! أجل وهذه ميزة يمكنك استخدامها و تسمى الأثر الجانبى أو الغير مباشر Side Effect


    المرة القادمة إن شاء الله نتكلم عن الأوامر أو الأكواد التى تستخدم لبناء البرنامج

  10. #30
    مشرف قسم تقنية الالكترونيات
    تاريخ التسجيل
    Jun 2008
    الدولة
    القاهرة - مصر
    المشاركات
    3,181

    افتراضي الأكواد العشرة

    الأكواد العشرة

    تنقسم الأكواد العشر لثلاث مجموعات هى الشروط و الدورات و الانتقال
    الشروط:

    الأمر IF

    الأول هو ما سبق شرحه IF و نعيد شرحه هنا أولا بالأسيمبلى كان فى صورة JB أو JNB وهما القفز لو بت =1 أو = صفر ولكن عموما تحتاج مقارنة رقمين لذا نستخدم معها الأمر CJNE وهو اختصار Compare and Jump if Not Equal وهى تقارن بين المراكم A و قيمة مباشرة أو محتوى ذاكرة مع المراكم أو محتوى مسجل مع المراكم أو باعتبار مسجل من R0,R1 حامل عنوان فيقارن المراكم بالذاكرة التى يشير إليها هذا المسجل أو مسجل مع قيمة مباشرة مثلا سنقارن محتوى المسجل R7 بالقيمة المباشرة 60 هيكسا و ننتقل لو مختلفين إلى Not_Eq. ما يحدث حقا هو طرح القيمة 60 هيكسا من محتوى R7 و بالتالى لو 60 أكبر ستسبب Carry =1 و إلا سيكون Carry = Zero و يمكن التحقق بالأمر JC أى قفز لو Carry =1
    كود:
    CJNE R7, # 60H, NOT_EQ ; . . . . . . . . ;R7 = 60H. Code if equal sjmp Finish NOT_EQ: JC REQ_LOW ; IF R7 < 60H. Some Code for R7 > 60H. ; . . . . . . . . ;R7 > 60H. sjmp Finish REQ_LOW: code for R7 < 60H. Finish:

    لو تريد أن تقارن شيء آخر ستضع قيمة فى R7 و الثانية فى الأمر المباشر و هكذا أى ستحتاج لأوامر MOV لتعديل القيم
    نفس الشيء بالبيزك و مثال للمقارنة على التساوى فقط فى التالى أو يمكنك التعديل بلا يساوى أو اكبر من أو أصغر من أو ما تشاء من شروط متعدة




    كود:
    If Sw1 = 1 then Goto SW2test Else LEDs = 254 End If كما يمكنك أن تجعلها متداخلة Nested أى أكثر من أمر داخل بعض هكذا If PORT1 = 1 then ; Level 1 Goto SW2test Else IF PORT2 = 1 THEN ; Level 2 LEDs = 254 ELSE ; Level 2 LEDs= 255 Else ; Level 1 LEDs=255 End If


    لاحظ هنا نقطة مهمة IF الأولى استفسرت عن شيء ما وهو PORT1 بينما Else IF التالية استفسرت عن شيء آخر تماما وهو PORT2 وهذه قيمة هذا الأمر ولو عدنا للغة الأسيمبلى سنجد أن هذا الأمر سيضع PORT1 أولا فى المراكم A ثم يقارنها بالقيمة 1 و بعد ذلك يضع القيمة PORT2 فى المراكم ليقارنها بالقيمة 1 وفى كل مرة نستخدم أمر MOV قبل الاختبار
    نقطة هامة أخرى، أين تضع End If يعتمد على المترجم فالمترجم باسكوم يعتمد Elseif و يعتبرها امتداد للأولى (وهذا من سمات لغة البيزك المرئى الأصلية للحاسبات) و من ثم تفاضل بين عديد من الخيارات و متى تحقق أحدها خرجت من الدورة ولذا تحتاج End if واحدة فقط فى آخرها و يمكنك وضع IF أخرى متداخلة حيث تشاء لتتمكن من فحص خيارات أخرى متى شئت و هذا يصعب فى ميكروإلكترونيكا فمثلا


    كود:
    If a = b then '…...1 Led0 = 1 elseif c=d then '…....2 Led1=1 elseif porta = 5 then '…......3 if a= 8 then Print Porta = 5 and a=8 elseif g=7 then Motor1 = 1 else Motor 1 =0 end if else if Portc =0 '….....4 Led3=1 else ' ….....5 Led4 = 0 end if

    سنلاحظ هنا أن الشروط 1،2،3،4،5 تبادلية فإن تحقق 1 ينفذ الأمر Led0 = 1 ثم تخرج و إلا يفحص 2 و هكذا، بهذا فالشروط باللون الأحمر لن تفحص إلا لو لم تتحقق الشروط السابقة أولا ثم تحقق الشرط porta = 5 و عندها نتحقق كما لو ان كل أمر من الأحمر تعنى لو porta = 5 مع a= 8 و قد تكتب هكذا
    (a= 8) AND (porta = 5)
    إلا أننا وفرنا تنفيذ أمر AND فى كل تساؤل.
    ميكروإلكترونيكا لا تعتمد elseif و تعتمد بدلا عنه else if بمسافة تفصل بينهما فتعتبر if التالية جديدة و تتطلب End If خاصة نفس فكرة أقواس السى وهذا يجعل الأمور معقدة و مربكة .
    مما سبق أيضا نستنتج أن ترتيب الأوامر يعطى أولوية الاختبار فقد يسبب تساؤل عن أمر ما أقل أهمية فى عدم فحص أمر آخر أكثر أهمية .


    و لنكتبه بلغة C


    كود:
    if (PORT1=1) { goto SW2test ; } else if (PORT2) { LEDs = 254 ; } else { LEDs=255; }

    الآن علمنا أن هناك MOV زائدة فى كل أمر حتى لو كان المتغير لم يتغير لكن تريد مقارنته بعدة قيم ولا داعى لنقله كل مرة للمراكم A لنقارنه ، فهذا سيوفر خانة ذاكرة فى كل اختبار و يزيد سرعة الاستجابة ، لذا كان الأمر الثانى.

    الأمر Select case أو switch

    وهو الثانى ، فكما رأينا الحاجة أم الاختراع فقد وضع هذا الأمر لمقارنة قيمة واحدة مقابل عدد كبير من الاحتمالات، لذا فهذا الأمر بالأسيمبلى سيكون ذات التعليمات السابقة و ستكرر الأمر CJNE عدة مرات كل مرة بقيمة اختبار أخرى و لكن لن تستخدم JC إلا لو احتجت لها و ستضع القيمة التى تختبرها مرة واحدة فقط فى المراكم وهى فى المثال التالى قيمة reg و بعد ذلك تكرر CJNE حسب ما تريد، أى ستوفر أمر MOV مع كل مقارنة.
    و فى البيزك / باسكوم


    كود:
    select case reg case 0 opmode = 0 case 1,2,6 opmode = 1 case 5 TO 7 opmode = 2 Case > 9 : Print “Too High” Case else : PRINT “NOT Valid” end select

    السطر الأول نجد هو المتغير تحت الاختبار و من ثم يوضع أول الأمر فى المراكم ثم يقارن عدة مرات بعد ذلك. قد يكون أى متغير مثل PORT0 أو أى شيء تسميه أو حتى معادلة يجب حلها أولا مثل select case x*y/z
    المهم أنها رقم صحيح (قيد بسبب الميكرو لكن فى الحاسبات الشخصية تكون أى شيء) أو قد يكون نصا أو حرف.
    هذا المترجم يسمح بكلمة TO لتحديد مدى من إلى كما يسمح بتعدد القيم 1,2,6 و بالعلاقات النسبية أكبر من أو أصغر من أو اكبر من و يساوى أو أصغر من و يساوى
    لاحظ أن لو تطابق المتغير مع أول شرط ستنفذ الأوامر المرتبطة به بكاملها (واحد أو أكثر) ثم يخرج آليا من الشرط ولا تختبر باقى الحالات. لو لم يتطابق فسيقارن التالى وهكذا

    ميكروإلكترونيكا تستخدم الصيغة ذاتها مع تعديل طفيف


    كود:
    select case reg case 0 opmode = 0 case 1,2,3,4 opmode = 1 case 5,6,7 opmode = 2 end select

    وهو أنها لم تتبنى كلمة TO باعتبار أن القيم المتعددة قد تغنى لكن لن تكون مثلا مثل من 100 إلى 200 و لم تتبنى المقارنات > < >= <= أيضا.


    بلغة السى نجدها


    كود:
    switch (phase) { case 0: Lo(); break; case 1: Mid(); break; case 2: Hi(); break; default: Message("Invalid state!"); }

    حيث phase هى المتغير تحت المقارنة ثم تلى القيمة الأولى وهى صفر فينفذ الأمر لو متطابق ولا ينفذه لو غير مطابق و فى كلتا الحالتين سينتقل لاختبار القيمة التالية،(لماذا؟؟) لذا وجب وضع الأمر break حتى يخرج من الدورة عند تحقق الشرط !!!
    لاحظ أيضا أنك لا تستطيع استخدام مدى من .. إلى .. ولا أكثر من قيمة 1,2,3,4 ولا نسب أكبر و أصغر الخ. رقم و فقط و بسبب ذلك قد تضطر لاستخدام أمر IF بدلا منها !!!!! أو تفضل البيزك مثلى
    المرة القادمة إن شاء الله ندرس الدورات

صفحة 3 من 4 الأولىالأولى 1 2 3 4 الأخيرةالأخيرة

المفضلات

ضوابط المشاركة

  • لا تستطيع إضافة مواضيع جديدة
  • لا تستطيع الرد على المواضيع
  • لا تستطيع إرفاق ملفات
  • لا تستطيع تعديل مشاركاتك
  •  

https://fahraf1.com/

https://electricstuffs.com

http://www.tkne.net/vb/announcement.php?f=2