![]() |
#21
|
|||
|
|||
![]()
البرنامج باستخدام PIC16
الدائرة سبق رفعها لذا سنستدعيها للمرجعية و سنعيد كتابة البرنامج بالبيزك نلاحظ هنا تطبيق تعديل إضاءة ألليد من صفر إلى 1 وهو سيستخدم فى الريلايات لاحقا سواء مع ألبيك أو مع AVR سنلاحظ أيضا مع ميكروإلكترونيكا ستحتاج لتعريف اتجاه المنفذ نصا بالاسم و لن تستطيع استخدام اسم سبق تعريفه وهذا قصور فى هذا المترجم ثم تعين الاتجاه لاحقا عكس باسكوم سيقدم أمر Config للتهيئة أيضا هو لا يدعم Elseif لذا يجب تفصيلها كود:
program Proj01PIC16 ' Declarations section Dim Leds as byte at PORTB DIM Leds_DCN as byte at TRISB DIM Switches_DCN as byte at TRISD Dim SW1 as sbit at PORTD.0 Dim SW2 as sbit at PORTD.1 DIM SW3 as sbit at PORTd.2 main: If Sw1 = 0 then LEDs = 1 else If Sw2 = 0 then LEDs = 2 else If Sw3 = 0 then LEDs = 3 else Leds = 0 end if end if end if Goto Main end. رغم أن تركيب الأطراف كما هو ولم يتغير (عكس الانتقال من C51 للأحدث) إلا أن بعض الأطراف أضيفت لها وظائف جديدة و كعادة ميكروتشيب أحيانا تفترض الوظيفة الجديدة هى الأساس ، لذا لو أردت استخدام الطرف كمنفذ رقمى يجب أن تلغى الوظيفة الجديدة . استخدمنا سابقا المنفذين B,D و على وجه الخصوص B0,B1,B2 لليدات و الأطراف D0,D1,D2 للأزرار. فى الطراز الجديد نجد أن B0:B4 تعمل كأطراف تماثلية لذا يجب إعادة تهيئه المنفذ كرقمى و كدخول لذا سيكون من الأسهل استبدال الأطراف للأطراف B5,B6,B7 و ستصبح الدائرة هكذا الآن نجد التسمية ذات فائدة كبرى إذ بدلا من إعادة كتابة البرنامج كله نحتاج فقط لتصحيح التسمية فى أول البرنامج سواء استخدمنا البيزك أو C وهذه أيضا إحدى حسنات اللغات العالية وهى أن الكود أغلبه لا يحتاج تعديل . مزيد من خواص المتحكم فى المرة القادمة إن شاء الله |
#22
|
|||
|
|||
![]()
مسجل الوظائف الخاصة Special Function Register :
حسنا عرفنا أن هناك بعض المسجلات لتغيير خواص المنافذ Ports و أخرى لوظائف أخرى، أين هى و كيف تعمل؟ ببساطة هى ذاكرة داخل المعالج و من خواص أى ذاكرة أن يكون لها حجم محدد و غالبا مرتبط بنظام العد الثنائى ذلك تصنع بحجم ما أكبر من الحاجة الفعلية المستخدمة ، بعض هذه الخانات يوظف و البعض الآخر يرجئ استخدامه لطرز أحدث أو أكثر إمكانيات. وهذا يكون أوفر و أسرع فى التصنيع . تفاصيل كل مسجل ستجدها فى الداتاشيت ولذا سنعرض لواحد منها فقط من قبيل العلم بالشيء لكن ما يهمنا فعلا هو أسماء الخانات ووظيفة كل منها و هل تعدل على مستوى البت أم البايت كاملة ومحتواه عند البدء RESET هناك مثيل له فى البيك و آخر للأتميل AVR و لكل منها طريقتة للكتابه فيه. ستجد أن كل ما يحتويه المتحكم فى هذه الذاكرة مثل المنافذ P0,P1,P2,P3 و المراكم الأساسى A و الثانوى B و خانة حالة البرنامج PSW السابق ذكرها و عدد من المؤقتات وخانات تعديل خواصها و التحكم فيها و عداد البرنامج و عداد ألرصه و عداد آخر يسمى مؤشر البيانات Data Pointer اختصارا DP و مسجل المقاطعات و ستجد فى كل خانة اسم و رقم. الاسم هو ما يمكنك استخدامه لتكتب أو تقرأ من هذه الخانة مثلا P0 للمنفذ صفر و القيمة 11111111 هى عند البدء سيكون هكذا أى به هذه القيمة وعنوانه 80 هيكسا و بجواره مباشرة فى الخانة 81 هيكسا نجد مؤشر ألرصه SP أو Stack Pointer و الرقم 00000111 أى أنه يبدأ بالرقم 7 و طبعا يمكنك تغيير الرقم كما تشاء أما الأرقام المدونة XXX فهى تعنى غير متوقعة و يجب تخصيصها قبل قراءتها و خانه التواصل التسلسلى. نلاحظ هنا أن العمود الأول و الملون يمكنك معالجة كل بت على حدة أو الخانة كاملة بينما الباقى فيجب أن تتعامل بالبايت. مسجل حالة البرنامج Program Status Word -PSW سبق أن ذكرنا بعض المعلومات عنه لكن هنا سنتناوله بالتفصيل. هل الميكرو به فقط A,B لا غير؟ ماذا لو احتجت لأكثر من ذلك؟ تقدم لك هذه العائلة عدد كبير من المسجلات Registers و يمكنك أن تفعل بها أى شيء سوى أن تجعلها مراكم أى تأخذ مباشرة نتيجة العملية الجارية أولا لديك ثمانية مسجلات تسمى r0-r7 و طبعا تمتاز بأن أمر الحفظ فيها أو القراءة منها يستخدم بايت واحدة لأنها معروفة و تحتاج 3 بت فقط من البايت للإشارة إليه فمثلا MOV R2, #data ستضع قيمة data فى المسجل R2 مباشرة على المقابل من الأمر مثلا MOV 50, #data حيث تحتاج لبايت للأمر MOV مشيرا للذاكرة ثم بايت أخرى لتحدد العنوان 50 فى الذاكرة و البايت الثالثة قيمة data التى تريد حفظها. حسنا ! أين إذن هذه المسجلات الثمانية؟ لا تفاجأ – فهى يمكن أن تحتل أربع أماكن من الذاكرة العشوائية ، إما من صفر إلى 7 ، أو من 8 إلى F ، أو من 10 إلى 17 ، أو من 18 إلى 1F ما هذه الحيرة كلا يا صديقى هذه مصدر القوة كيف؟ لو أنك تحسب لبيانات قادمة من جزء فى ماكينة مثلا ، عادة أسرع وسائل الحفظ هى المسجلات الآن تود حساب شيء آخر ثم تعود لما أنت عليه الآن لابد من حفظ المسجلات فى مكان آمن ثم تحسب الأمر المستجد و تحفظ نتائجه أيضا فى مكان آمن آخر ثم تقرا ما كنت تحسب للجزء الأول – قصة طويلة مملة ، أليس كذلك؟ ما رأيك فى أن تستبدل هذا السيناريو بكلمة استخدم طقم 2 وعند العودة قل استخدم طقم 1؟ أليس أسهل و أبسط؟؟ و كيف يتم هذا؟ ببساطة نعود لمسجل PSW وهى اختصار Program Status Word أو خانة حالة البرنامج وهى تحتوى ثمانية خانات Flip Flop تعمل كل منها عمل الراية Flag إما 1 أو صفر حسب الحالة PSW.PNG لاحظ Bit3,Bit4 باسم Register Bank Select أو اختيار بنك المسجلات (البنك = المجموعة) لو = صفر تعنى المدى من صفر إلى 7 من الذاكرة العشوائية أى أول سبعة أماكن لو = Ol يكون المدى الثانى أو من 8 إلى F لو = lO يكون المدى الثالث أو من 1O إلى 17 لو = l l يكون المدى الرابع أى من 18 إلى 1F كل ما عليك عمله هو تغيير بت واحدة أو 2 بت فقط لتحصل على طقم جديد مع الحفاظ على القديم بلا تغيير للعودة إليه وماذا عن الباقى فى PSW حسنا رقم صفر أقصى اليمين هى Parity "تكافؤ" وتحدد إن كان المراكم A يحتوى عدد فردى أو زوجى من "1" رقم 1 هى للمستخدم كيف يشاء لتذكر هل حدث أمر ما أم لم يحدث. رقم 2 لو زاد العدد عن الحد و تتحكم بها وحدة الحساب والمنطق لتصحيح الناتج فى حال كان الرقم موجب و سالب(127 إلى -128 ) أم موجب فقط من 0 إلى 255 رقم 3،4 سبق الحديث عنهما رقم 5 للاستخدام العام مثل رقم 1 رقم 6 AC وهو لتصحيح جمع الأرقام بالنظام العشرى بدلا من النظام الثنائى فمثلا عند جمع 17 + 26 لا يوجد سوى الجمع الثنائى أى الناتج سيكون 3D و لكننا نريد جمع عشرى أى 17+26 =43 فماذا نفعل؟ عند جمع 7+6= 13 أى D سيوضع آليا واحد فى الراية AC دلالة أن المجموع تعدى 9 و باستخدام بعد الجمع مباشرة ألتعليمه DA A وهى اختصار Decimal Adjust ACCUMULATOR فتتولى بفحص هذه الراية و باقى الرايات مثل C تصحيح الرقم آليا من 3D إلى 43. وهذا مفيد فى التعامل مع كثير من الأرقام BCD و التى توجد فى بعض الحساسات أو تسهل التعامل مع الأرقام. يجب ألا ننسى أن الأرقام التى تجمع يجب أن تكون أصلا BCD و إلا سينتج خطأ الأخير رقم 7 Carry هو مثل السابق لكن لأى عملية جمع عندما يكون المجموع زائد عن 255 أو بعد تعليمه DA A لو الناتج أعلى من 99 طبعا غنى عن الذكر أن هذه الخانة يمكنك التعامل فيها على مستوى البت فتختبر هذه أو تفرض تلك أو تلغيها (تجعلها=1 أو صفر) فى هذا الرابط http://datasheets.chipdb.org/Intel/M...S/27238302.PDF نجد مرجع شامل كتبته شركة إنتل INTEL وهى مبتكرة هذا الميكرو و إن اشتهر أكثر بأنه من إنتاج ATMEL ومن مراجع ATMEL حقيقة وجدت صعوبات كثيرة فى لم شمل أجزاء الميكرو و فهم مكوناته من أكثر من مرجع معا ولكن فى هذا الملف نجد معظم البنود مرتبة و مشروحة. فى كل متحكم ستجد PSW أو مسجل حالة البرنامج مع اختلافات طفيفة فى المحتوى و استخدام اللغة العالية عادة يغنى عن تفاصيله و استخدامه . فى سلسلة AVR أصبح عدد المسجلات 32 مسجل منها 6 تعمل كثلاثة مسجلات كل منها 16 بت باسم X,Y,Z ولها خواص برمجية مميزة. فى عائلة ميكروتشيب فعددها محدود جدا مما يعقد استخدامها فيم يستخدم المتحكم و متى لا يكون مجديا؟ وهل ما زالت الطريقة التقليدية باستخدام الدوائر التماثلية تناسب تطبيقات أكثر من المتحكم؟ هذا موضوعنا القادم بإذن الله |
#23
|
|||
|
|||
![]()
استخدامات الميكروكونتروللر أو المتحكم
البعض يتخيل أن الميكرو أو المتحكم هو رائعة العلم و أنه أتى ليقول لعالم ألتماثلى وداعا لكن مهلا نحتاج لفهم بعض الحقائق عن هذه الأشياء ثم نحكم. أولا ما هى أقصى سرعة نتحدث عنها هنا؟ حسنا نلجأ للدائرة و سنجد كريستال هى الحاكم ألرئيسى و من الداتاشيت لهذه الأنواع نجد أن أعلى تردد استخدم هو 30 ميجا – طبعا الكثير منها 25 فقط أو 20 ميجا فقط. إذن لا تحلم بأسرع من 30 ميجا ماذا تعنى؟ أجل تعنى حدك الأقصى فلا تستطيع توليد تردد أو قياسه أو التحكم فى شيء بمعدل أسرع من ذلك. أيضا هناك نقطة هامة وهى كيف يعمل الميكرو من الداخل؟ لدينا ما يسمى Sequencer أو مرتب الأحداث أو موالى الأحداث أو سمه ما شئت وهو المسؤول عن تنفيذ الأحداث بتتالى محدد وهو 1- قراءة الكود من ذاكرة البرنامج 2- زد واحد على مسجل عنوان البرنامج 3-تحليل الكود و معرفة الخطوة التالية هل تنفيذ السابق كأمر مفرد (مثلا NOP لا تفعل شيئا أو INC A زد واحد لمحتوى المراكم أو CLR A ألغى محتويات المراكم الخ) أو هو حساب يتطلب أخذ قيمة تالية من الذاكرة 4- قراءة الكود التالى من الذاكرة كبيان 5- تنفيذ الأمر ثم البدء من جديد هذه الخطوات يأخذ وقتا وهذا الوقت يحسب بعدد نبضات الكريستال لهذا فعائلة C51 تحتاج 12 نبضة لتنفيذ دورة كاملة و التى قد تكفى تنفيذ أمر وحيد الخانات أو أمر مفرد كما سبق (مثلا NOP لا تفعل شيئا أو INC A زد واحد لمحتوى المراكم أو CLR A ألغى محتويات المراكم الخ) أو قد تحتاج 12 أخرى لغالبية الأوامر و التى تأخذ دورتين. إذن30 ميجا / 24 ستصبح1.25 مليون أمر فقط فى الثانية. لاحقا أنتجت الشركة وحدات تنفذ فى 6 دورات و حتى دورتين فقط لكن بكريستال لا تزيد عن 20 ميجا و من ثم أعلى سرعة هى 10 مليون أمر فى الثانية. بالنسبة لميكروتشيب فهى تحتاج 4 نبضات فى الدورة إذن 30 /4 تصبح 7.5 مليون أمر فى الثانية رائع ماذا نحتاج أكثر من ذلك؟ أجل أنت لست وحدك فى هذا العالم و تتحكم فيما حولك بالبرنامج أى المسألة ليست بسيطة كما نظن ولو عدنا للمثال السابق سنجد أننا لنتحكم فى بضع أمور بسيطة تطلب الأمر عدة خطوات و رغم أن البرنامج لا ينفذ كله فى كل مرة إلا أننا يجب أن نستوعب هنا خاصية من أهم خصائص البرمجة عن سرعة التنفيذ لاحظ أن دورة أو Cycle هى 12 نبضة من الكريستال، وهكذا نستهلك 2 دورة فى كل تعليمه أى 4 دورات تمهيد من Start إلى Loop و من ثم 6 دورة لو كان المفتاح الأول مضغوطا ثم نكرر و إلا سنضيف 6 للمفتاح الثانى و إلا 6 للمفتاح الثالث. أى كل دورة كاملة للبرنامج إما 6 أو 12 أو 18 دورة أى 72 نبضة من الكريستال أو 144 أو 216 دورة. وهذا زمن لا بأس به، و بالطرز الحديثة حيث تستخدم 2 نبضة من الكريستال لكل تعليمه ستستهلك 12 أو 24 أو 36 دورة من الكريستال كود:
Start: Mov Switches , #255 ; 2Byte, 2Cycle Mov LEDs , #255 ; 2Byte, 2Cycle Loop: jb SW1 , SW2test ; 3Byte, 2Cycle mov LEDs , #11111110b ; = 254 2Byte, 2Cycle sjmp Loop ; 2Byte, 2Cycle SW2Test: jb SW2 , SW3Test ; 3Byte, 2Cycle mov LEDs , #11111100b ; = 252 2Byte, 2Cycle sjmp LOOP ; 2Byte, 2Cycle SW3Test: jb SW3 , start ; 3Byte, 2Cycle mov LEDs , #11111000b ; = 248 2Byte, 2Cycle jmp Loop ; 2Byte, 2Cycle مع ميكروتشيب الأمر أسهل حيث الكل يأخذ 3 دورة و بايت واحدة فيكون البرنامج يحتاج 8 تعليمات حتى يصل إلى Loop أى 32 دورة للتمهيد ثم كود:
CLRF STATUS ; Bank0 CLRF PORTB ; Initialize PORTB by clearing output data latches CLRF PORTD ; Initialize PORTD by clearing output data latches BSF STATUS, RP0 ; Select Bank1 CLRF TRISB ; All OUTs MOVLW 255 MOVWF TRISD CLRF STATUS ; Bank0 كود:
Loop: BTFSC PORTD , 0 GOTO Sw1 MOVLW 1 MOVWF PORTB GOTO Loop Sw1: BTFSC PORTD , 1 GOTO Sw2 MOVLW 3 MOVWF PORTB GOTO Loop Sw2: BTFSC PORTD, 2 GOTO SW3 MOVLW 7 MOVWF PORTB GOTO Loop SW3: CLRF PORTB GOTO Loop وهذا يقودنا لمثال بسيط، تود أن تصنع دائرة مثبت فولت ، لديك طريقين إما تماثلى بالمتكاملات أو بمتحكم و الأخير يعطى إيهاما بأننا ننظمها بالحاسب الآلى حسنا سرعة المتكاملة الخطية تستجيب فى أقل من ميكرو ثانية طبقا للداتاشيت فكم تعليمه تنفذها فى هذا الوقت؟؟ يمكنك وضع ميكرو للوجاهة و تعرض التيار و الفولت الخ لكن دع التحكم للمتكاملة الخطية سواء أكانت تماثلية أو تقطيعية. الآن يمكننا أن نفكر فى تطوير برنامجنا السابق لنبدأ مثلا بغساله آلية ذات 6 برامج وهو موضوعنا القادم بإذن الله. |
#24
|
|||
|
|||
![]()
برنامج غسالة صغيرة :
الغسالة عادة ما يكون لها شاشة تكتب المراحل و مجموعة أزرار لتحديد برنامج من عشرات البرامج، لكن لكوننا لسنا خبراء فى الغسيل سنكتفى بما يلى: ثلاث أزرار لاختيار البرنامج خفيف – وسط – كامل يحدد الوقت من 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,$ ثم الأمر DJNZ هو اختصار Decrement and Jump if Not Zero ثم المسجل R0 و علامة الدولار ، علامة الدولار هذه اختصار لكلمة "هنا" فكأنك استبدلت العنوانين التاليين بها Here: DJNZ R0,Here فيما عدا أنك فى كل مرة تستخدم هذه الدورة ستحتاج لأسم جديد لها أما "$” فلا و الحادث أنك تضع 250 فى المسجل ثم تنقص 1 فإن لم يكن صفرا تعود لذات الأمر أى تنقص منه 1 أى باختصار تظل تنقص 1 حتى يصبح محتواه صفرا لن تنفذ الانتقال مرة أخرى و تخرج منها أى لف حول نفسه 250 مرة كل مرة تستهلك 24 نبضة من الكريستال – زمن قليل جدا وكان من الممكن استخدام الأمر كود:
MOV 10,#250 DJNZ 10,$ لذا سنحتاج عديد من هذه الدوائر و يا حبذا لو متداخلة لكن بصعوبة نصل لثانية لذا نلجأ لحيلة المقاطعة أيضا نأخذ عينة من أحد طرفى المحول 9 فولت متردد (النقطة 1) و من خلال الدايود D7 نأخذ أنصاف الموجة الموجبة فقط ثم نمررها على ترانزستور كمكبر يحولها لموجة مربعة و نضعها على طرف المقاطعة INT1 باسم Clock إذن كل مقاطعة بعد 20 مللى ثانية و كل 50 مقاطعة بثانية كاملة. إذن مزيد من شرح المقاطعة المرة القادمة إن شاء الله |
#25
|
|||
|
|||
![]()
المقاطعة فى 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 لتحسب الزمن وهذا موضوعنا القادم بإذن الله |
#26
|
|||
|
|||
![]()
حساب الزمن بالمقاطعة
الدائرة السابق شرحها لتوليد موجة مربعة من 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 بت منها 5 مقسم سابق 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 دقيقة غسيل ثم صرف حتى الحساس ثم ملئ مرة أخرى للشطف ثم دوران دقيقتين ثم صرف ثم ملئ و شطف دقيقتين أخرتين ثم دورة العصر خمسة دقائق ثم التوقف حسنا هذا المرة القادمة إن شاء الله |
#27
|
|||
|
|||
![]()
كتابة البرنامج بالأسيمبلى:
البداية و التعريفات والمقاطعة: حسنا البرنامج التالى أثناء فحصه ستجد أنك تستطيع تطويره و تحسين وظائفه، لم لا ؟ فقط هذا تعليمى لتوضيح كيف نبرمج ولماذا نفعل ذلك و أيها الأفضل. ، ولو أرنا الأفضلية سنحتاج وقت أطول بكثير فضلا عن تحديد الطراز لكل نوع حساس ، أبسط الأمثلة نستخدم حساسين للحرارة المتوسطة و العالية و يمكنك أن تستخدم حساس متغير لضبط الحرارة كما تشاء. الآن سنبدأ بمشروع جديد أو برنامج جديد حسب المترجم ألذى تستخدمه و نختار فى البداية أمر تعريف الميكرو و سنختار متحكم 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 أعلم أنك ستقول سينتهى عندما كل من R7,R6 أو بمسمياتهم Minuted,Seconds يساويان صفر أجل لكن لتعلم ذلك يجب أن تختبرهما على التوالى كل مرة تريد فيها التحقق من انتهاء الزمن وهذا ما يسمى برمجة غير احترافية لإضاعتهما كود و زمن و أنت أصلا لا تحتاج لذلك لا تنسى أن كل مقاطعة وظيفتها أن تنقص الثوانى و تنقص الدقائق حتى تتساوى بالصفر أى أنك بالفعل حسبت هذا الأمر وما عليك سوى حفظ النتيجة ، هنا نستخدم البت F0 السابق شرحها فى PSW و المسماة User Flag فتجعلها =1 ثم تبدأ العد و عند تمامه اجعلها = صفر و بالتالى كل ما عليك أن تختبرها فقط بتعليمه صغيرة و بسيطة لتعلم إن كان الزمن قد تم أم لا. بعد ذلك يأتى البدء و المقاطعة، سنجد فى خانة صفر حيث الريسيت قفزة لعنوان Start حيث بدء البرنامج الفعلى يليها فى العنوان 3 حيث عنوان مقاطعة الطرف الخارجى INT0 وهى الطوارئ و هنا يجب الإيقاف و العودة حيث بدأنا لذلك نستخدم القفز إلى Start أيضا كما لو أننى أطفأت الوحدة ثم أعدت تشغيلها مرة أخرى و أخيرا فى عنوان B وهو =12 حيث مقاطعة العداد ألذى يستقبل 50 هرتز من الخارج و بعد 50 عد أى كل ثانية سيحدث مقاطعة. هنا سننقص الثوانى 1 فإن بقى ثوانى نعود من المقاطعة و إلا لو أصبحت صفرا ننقص الدقائق 1 فإن لم تكن صفرا نعيد الثوانى إلى 59 و نبدأ الدورة من جديد أى نعود من المقاطعة وهكذا حتى تنتهى الدقائق وتصبح صفرا نوقف العداد و نعلن انتهاء الزمن بتصفير العلم Jobpending و نخرج من المقاطعة. لاحظ هنا أن آخر دقيقة لم تحول لثوانى و بالتالى لم تحسب لذا عند البدء مثلا بخمس دقائق نضع 5 دقائق و 59 ثانية. المرة القادمة إن شاء الله نكمل باقى البرنامج . |
#28
|
|||
|
|||
![]()
تجهيز الغسالة :
بعد أن مهدنا للمقاطعة و البدء الخ نبدأ البرنامج طبقا للهيكلة السابقة فمثلا نقول بعد أن نختار الكمية و الحرارة ، لو الباب مغلق نبدأ ملئ الخزان و عند تمامه نشغل السخان طبقا للحرارة ما بين عنوان البدء و عنوان الدورة "التكرارى" نجد ما يسمى التمهيد أوHouse Keeping أو حرفيا ترتيب المنزل السطر الأول إتاحة كل المقاطعات و مقاطعة T0 ومقاطعة الخارجى INT0 الثانى و الثالث تحميل كل من نصفى المسجل T0 بالقيمة المطلوبة و الرابع تهيئه T0 كعداد ذاتى التحميل بعدها جعل المقاطعة الخارجية قدح بالحافة Edge Trigger ثم تغيير مؤشر الرصة بعيدا ثم وضع المنافذ الأربع فى حال البداية رغم أنها كذلك إلا أن هنا ضرورة لحالة الطوارئ فهى لن تعيد المنافذ لحال البدء لذا تفرض بالبرنامج تحسبا. لو حدث طارئ و ضغطت على زر الطوارئ ستجبر المتحكم على البدء من جديد و سينهى التهيئة و الوصول هنا و ينتقل عبره لدورة تشغيل الموتور قبل أن تتمكن من رفع إصبعك من على زر البدء لذا وجب الانتظار هنا حتى ترفع يدك عنه لذا نختبر لو البت Run = 0 سنظل فى دوره وذلك بالأمر JNB اختصار Jump if Not Bit set ثم اسم البت Run و العنوان المقصود الذهاب إليه و علامة الدولار هى رمز مختصر لكلمة "هنا" بدلا من و ضع عنوان أول السطر و كتابته مرة أخرى فى الأمر هكذا Here: JNB Run,Here هكذا سنظل ندور هنا طالما زرار RUN=0 ثم بعده نختبر الخيارات كود:
الخيار الافتراضى هنا 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 الآن مع البيتات الثلاث . المرة القادمة إن شاء الله نختبر هل نبدأ أم نكرر ما سبق |
#29
|
|||
|
|||
![]()
التشغيل و الإيقاف:
بالكود السابق اعدنا تحديد الدورة المطلوبة و بقى أن ندير الموتور . سنختبر زر البدء فإن لم يكن مضغوط نعود للدورة مرة أخرى فقد يقوم المشغل بتعديل فى الدورة. و إن كان مضغوط فنختبر هل الباب مفتوح؟ إن كان مفتوح ننتظر غلقه و بعدها نفتح صنبور المياه 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 دقائق و الانتقال هنا أيضا حتمى بتتابع الأحداث. المرة القادمة إن شاء الله سنتحدث عن تشغيل الموتور فى دورة الغسيل ثم دورتين للشطف و ثالثة للعصير و التوقف بانتظار تحديد دورة أخرى أو تكرار هذه الدورة. التعديل الأخير تم بواسطة ماجد عباس محمد ; 06-30-2018 الساعة 09:53 AM |
#30
|
|||
|
|||
![]()
دورات الغسيل و الشطف و العصر ثم الإيقاف:
لم نضع سابقا قيمة 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 Rinse 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_NSpin ; SETB MotorON ; Stop Motor ; Setb DrainON ; Close DRAIN MOV Relays,#255 ; ALL OFF, INITIAL State MOV Controls,#255 jmp Loop ;==================================== END الآن قبل أن نعود للدورة نحتاج للتأكد من أن الموتور مغلق و العودة للسرعة العادية و الصرف مغلق بالثلاث أوامر المذكورة ولكنها موضوعة بصورة تعليق لأن استخدام أمرين فقط كما هو مبين كافى لإعادة الوضع كاملا للتوقف. أيضا هنا استخدمنا أزرار وليدات وهو أمر جيد لكثير من التطبيقات لكنه فى إدخال الأرقام متعب قليلا لذا بعد انتهاء شرح اللغات أفكر فى برنامج ميكروويف منزلى لتناول لوحة الأرقام Key Pad مع الشاشات السباعية و تغير وظيفة طرف حسب الظروف ثم برنامج لشيء آخر لتناول محول تماثلى رقمى و ألشاشة LCD هذا لو لم تشير رغباتكم لاتجاه آخر. قبل أن نبدأ فى إعادة البرنامج بالبيزك ثم بلغة C أود شرح بعض النقاط العملية فى التنفيذ وهو موضوعنا القادم بإذن الله |
![]() |
مواقع النشر (المفضلة) |
أدوات الموضوع | |
انواع عرض الموضوع | |
|
|