|
| قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots |
|
|
|
|||||
|
أول البرنامج بعد التهيئة السابقة وصلنا لأول البرنامج حيث العنوان التكرارىLoopAgain بعد ذلك الاختبار If Full = 0 Then أى لو زرار Full مضغوط إذن نفعل السابق وهو ORL ثم LEDs,#00000111b ، الوظيفة "أو" OR وهى بالأسيمبلى ORL وفى البيزك OR لأنه هنا لا يعتمد النوع الآخر Boolean من OR و تتحول الوظيفة لهذه الصيغة Leds = Leds Or &B00000111 أى أن اجعل LEDs تساوى = LEDs OR 00000111 و هنا الرمز &B ليعنى أن الرقم بالنظام ألثنائى Binary قبل أن نترك هذه الخطوة نعلم أن هناك أربعة وظائف هى OR,AND,NOT, EXOR وهى أو – مع – عاكس – أو المطلقة وهى كما هى هكذا لا تحتاج لتفكير ولا تذكر ولا تستخدم رموز أو إشارات – لغة انجليزية بسيطة و مفهومة كان من الممكن أن نكمل بطريقتين، الأولى كود:
البرنامج أصبح كود:
فى الأمر التالى استخدمنا فى الأسيمبلى الأمر JNB ColdLED,SetCycle ; Cold cycle No Heat needed لنختبر إذا زرار البارد قد اختير ننتقل و إلا نشغل السخان و تترجم If Coldled = 1 Then Reset Heateron ' No Cold then Heater On ثم نختبر إذا زرار الوسط قد اختير ننتقل لنرقب حساس الدافئ و إلا نرقب حساس الحار كود:
JNB MildLED,HOTTemp
jb HiTemp,$ ; wait mild sensor
sjmp SetCycle
HOTTemp:
jb MidTemp,$ ; wait HOT sensor
و تترجم هكذا
If Coldled = 1 Then ' not Cold then
Reset Heateron ' Heater on
If Mildled = 0 Then Bitwait Midtemp , Reset Else Bitwait Hitemp , Reset
Set Heateron ' Turn off heater
End If ' Now Start Washing
كود:
باقى الدورات موضوعنا القادم بإذن الله |
| اعلانات |
|
|||||
|
باقى الدورات ألان ندير الموتور الفترة الزمنية المحددة ، ولكى نعرف الزمن يجب أن نقيم JobPending أى نجعله = 1 و ندير الموتور و ننتظر JobPending أن يحدد نهاية المدة و كانت هكذا كود:
RunMotor: MOV Seconds,#59 SETB JobPending CLR MotorOn SETB TR0 ; Start Timer/Counter JB JobPending,$ ; Wait to Finish SETB MotorON ; stop motor كود:
Set Jobpending ' Timing flag
Reset Motoron ' Start Motor
Start Timer0 ' Start Timer/Counter
Bitwait Jobpending , Reset ' Wait to Finish
Set Motoron
كود:
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 Rinse MOV Seconds,#59 SETB JobPending CLR MotorOn ; Start Rinse SETB TR0 ; Start Timer JB JobPending,$ ; Wait to Finish Setb MotorOn ; Stop Rinse 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 Rinse MOV Seconds,#59 SETB JobPending SETB TR0 ; Start Timer/Counter CLR MotorOn ; Start Rinse SETB TR0 ; Start Timer JB JobPending,$ ; Wait to Finish Setb MotorOn ; Stop Rinse كود:
Mov Rinse,#2 RinseLoop: 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 Rinse MOV Seconds,#59 SETB JobPending CLR MotorOn ; Start Rinse SETB TR0 ; Start Timer JB JobPending,$ ; Wait to Finish Setb MotorOn ; Stop Rinse Djnz Rinse, RinseLoop ألان نترجم هذا بلغة البيزك نضيف فى التعريفات Dim Rinse As Byte , cntr as byte و هنا تترجم التعليمات هكذا . كود:
For cntr = 1 To Rinse
Reset Drainon ' Open Drain
Bitwait Waterempty , Reset ' Wait Drain
Set Drainon ' Close Drain
Reset Wateron ' Fill again
Bitwait Waterfull , Reset
Set Wateron ' Close Water
Runtime = 300 ' Rinse Time
Set Jobpending
Reset Motoron ' Start Rinse
Start Timer0 ' Start Timer
Bitwait Jobpending , Reset ' Wait to Finish
Set Motoron ' Stop Rinse
Next ' Loop Back
كود:
CLR DrainON ; Open Drain
JB WaterEmpty,$ ;Wait Drain
MOV Minutes,#3 ; SPIN
MOV Seconds,#59
SETB JobPending
CLR MotorOn ; Start Rinse
CLR Run_Nspin ; SPIN
SETB TR0 ; Start Timer/Counter
JB JobPending,$ ; Wait to Finish
MOV Relays,#255 ; ALL OFF, INITIAL State
MOV Controls,#255
jmp Loop
;====================================
END
وتترجم هكذا
Reset Drainon ' Open Drain second cycle
Bitwait Waterempty , Reset ' Wait Drain
Runtime = 180 ' SPIN
Set Jobpending
Reset Motoron ' Start Rinse
Reset Run_nspin ' SPIN
Start Timer0 ' Start Timer/Counter
Bitwait Jobpending , Reset ' Wait to Finish
Relays = 255 ' ALL OFF, INITIAL State
Controls = 255
Goto Loopِagain
|
| اعلانات اضافية ( قم بتسجيل الدخول لاخفائها ) | |
|
|
|
|||||
|
البرنامج بمترجم بيزك من ميكروإلكترونيكا ها هو البرنامج كاملا لمترجم باسكوم و سنعدل ما نحتاج فقط كود:
' DEFINITIONS
Leds Alias P0 : Relays Alias P1 : Switches Alias P2 : Controls Alias P3
Fullled Alias Leds.0 : Halfled Alias Leds.1 : Smallled Alias Leds.2
Hotled Alias Leds.3 : Mildled Alias Leds.4 : Coldled Alias Leds.5
Wateron Alias Relays.0 : Drainon Alias Relays.1 : Heateron Alias Relays.2
Motoron Alias Relays.3 : Run_nspin Alias Relays.4 : Waterfull Alias Relays.5
Waterempty Alias Relays.6 : Dooropen Alias Relays.7 : Midtemp Alias Switches.0
Hitemp Alias Switches.1 : Cold Alias Switches.2 : Mild Alias Switches.3
Hot Alias Switches.4 : Small Alias Switches.5 : Half Alias Switches.6
Full Alias Switches.7 : Run Alias Controls.1
' VARIABLES
Dim Runtime As Word
Jobpending Alias Psw.5
Dim Rinse As Byte , cntr as byte
Emergency:
Goto Begin
Counttime:
Decr Runtime
If Runtime = 0 Then
Reset Jobpending
Stop Timer0
End If
Return
نظرا لعدم قبوله أكثر من أمر لكل سطر فسنضطر إلى التعريف هكذا
program WM
' Declarations section
symbol FullLED = LEDs.0
symbol HalfLED = LEDS.1
symbol SmallLED = LEDs.2
symbol HOTLED = LEDs.3
symbol MildLED = LEDs.4
symbol ColdLED = LEDs.5
symbol WaterOn = Relays.0
symbol DrainOn = Relays.1
symbol HeaterOn = Relays.2
symbol MotorOn = Relays.3
symbol Run_Nspin = Relays.4
symbol WaterFull = Relays.5
symbol WaterEmpty = Relays.6
symbol DoorOpen = Relays.7
symbol MidTemp = Switches.0
symbol HiTemp = Switches.1
symbol Cold = Switches.2
symbol Mild = Switches.3
symbol Hot = Switches.4
symbol SmallLoad = Switches.5
symbol Half = Switches.6
symbol Full = Switches.7
symbol RUN = Controls.1
Dim Leds as byte at P0
dim Relays as byte at P1
Dim Switches as byte at P2
Dim Controls as byte at P3
Dim JobPending as sbit at PSW.F0
dim RunTime as word
dim Rinse as byte
dim cntr as byte
sub procedure INT0_Interrupt() org IVT_ADDR_EX0
asm
sjmp 0
end asm
end sub
sub procedure Timer0_Interrupt() org IVT_ADDR_ET0
Dec (RunTime)
If RunTime = 0 then
JobPending = 0
TR0_bit = 0 ' Stop Timer1
end if
end sub
السطر الأول اسم البرنامج ثم التعريفات كما سبق الشرح و لكن هذا المترجم يتطلب إعلان الاسم بكلمه DIM قبل استخدامه أى Symbol لا تجدى فى تعريف ما يلى كما فى باسكوم لذا سنعرف المنافذ كلها للمقاطعة يستخدم هذا المترجم تعريف مختلف sub procedure INT0_Interrupt() org IVT_ADDR_EX0 حيث Sub كلمة يستخدمها دوما كما فى فكر لغة C وهى زائدة كما بينا فى باسكوم فهو يتبعها بكلمة procedure أو كلمة Function وواحدة تغنى ثم اسم المقاطعة وهو هنا INT0_Interrupt() ثم كلمة org أو IV لتخبره أنها مقاطعة Interrupt Vector و أخيرا العنوان IVT_ADDR_EX0 فى المقاطعة الخاصة بالطوارئ كنا سنستخدم انتقال للبداية GOTO Begin لكنها لا تقبل رقم و تطلب عنوان "سبق تعريفه" لذا إما ننقل كل الكود لآخر البرنامج أو لنتحايل و نبقى على التتابع استخدمنا الأسيمبلى بالتعريف asm ثم القفز ثم end asm. المقاطعة الثانية نستخدم نفس الأوامر. يلى ذلك أوامر التهيئة ما بين Begin , LoopAgain كود:
Begin:
Config Timer0 = Counter , Mode = 2 , Gate = Exteral
Th0 = 205 ' Auto reload
Tl0 = 205
Tcon = 1
Enable Interrupts
Enable Int0
Leds = &B11011011 ' Reset All PORTS! select Small cold cycle
Relays = 255
Switches = 255
Controls = 255
Rinse = 2
On Int0 Emergency , Nosave
On Timer0 Counttime
الأسطر الحمراء لا يدعمها هذا المترجم ولذلك سنضطر لتهيئة التايمر يدويا كما سبق فى الأسيمبلى كما أن نتيح المقاطعة و نبدأ و نوقف العداد بالأمر النصى بدلا من Enable فتصبح كود:
IE=%10000011 ' Enable T0 & INT0 external
TH0 = 205 ' Auto reload
TL0 = 205 ' Start Value
TMOD = %00000110
TCON = 1 ' Clear All interrupts, Set INT0 Edge trigger
SP = 70 ' Move stack away
Leds = %11011011 ' Reset All PORTS! select Small cold cycle
Relays = 255
Switches = 255
Controls = 255
Rinse = 2
الآن أول أمر كان انتظار عودة زر RUN لحالة عدم الضغط و لكن الأسف الأمر Bitwait غير مدعوم ولا بديل له فالمكتبة تتيح أمر sub function Button(dim time_ms as byte, dim active_state as byte) as byte حيث يجب أن تعرف قبل استخدامه متغير باسم Button_PIN ثم تحدد الزمن و تحدد 1 أم صفر فتعيد لك 255 لو حدث أو صفر لو لم يحدث و من ملف المساعدة نجد أنها تختبر الطرف ثم بعد الزمن تعيد اختباره وهذا يحتاج لمكافئ بالأسيمبلى كبير لا حاجة له فضلا عن أننا يجب أن نعيد التعريف عند كل تغيير للطرف وهذا عبئ لا معنى له ، لذا سنستغل الكود ألعادى Do loop الشرط لو Full=0 سيتطلب الأمرين التاليين و نظرا لحدود المترجم سنحتاج سطرين منفصلين الأول كالسابق مع تغيير &B واستخدام الحرف % ثم السطر الثانى لا يدعم المترجم الأمر Reset و لكنه يوفر أمر SetBit(P0, 2) ' Set P0.2 و الأمر ClearBit(P0, 7) ' Clear P0.7 والمشكلة هنا أنهما لا يقبلا سوى الأمر الصريح كما بالمثالين السابقين أى لا نستطيع الاستفادة بالتسميات ولو أردنا التعديل لاحقا سنفحص كل سطر بحثا عنها لذا سنستخدم الأمر الصريح أيضا . أيضا يجب ملاحظة أن هذا المترجم لا يدعم الأمر Elseif لذا يجب أن نكتب Else و فى داخلها نضع If جديدة لها Else وهكذا و نضع End If بعدد If المستخدمة عكس باسكوم End If واحدة للدورة كلها مما يجعل باسكوم أكثر وضوحا. الكود يصبح كود:
do ' Wait Run =1 unpressed
loop until Run = 1 ' Run button release
Loopagain:
If Full = 0 Then
Leds = Leds Or %00000111
FullLED = 0
Else
if Half = 0 Then
Leds = Leds Or %00000111
Halfled = 0
Else
if SmallLoad = 0 Then
Leds = Leds Or %00000111
Smallled = 0
end if
end if
End If
If Hot = 0 Then
Leds = Leds Or %00111000
Hotled = 0
Else
if Mild = 0 Then
Leds = Leds Or %00111000
Mildled = 0
Else
if Cold = 0 Then
Leds = Leds Or %00111000
Coldled = 0
end if
end if
End If
If Run = 1 Then Goto LoopAgain ' Wait Run Press
كود:
do
loop until Run = 1 ' Run button release
do
If Full = 0 Then
Leds = Leds Or %00000111
FullLED = 0
Else
if Half = 0 Then
Leds = Leds Or %00000111
Halfled = 0
Else
if SmallLoad = 0 Then
Leds = Leds Or %00000111
Smallled = 0
end if
end if
End If
If Hot = 0 Then
Leds = Leds Or %00111000
Hotled = 0
Else
if Mild = 0 Then
Leds = Leds Or %00111000
Mildled = 0
Else
if Cold = 0 Then
Leds = Leds Or %00111000
Coldled = 0
end if
end if
End If
loop until RUN =0
بعد ذلك غلق الباب و تحديد الفترة الزمنية حسب الخيارات و هذا موضوعنا القادم بإذن الله |
|
|||||
|
تكملة البرنامج بعد ذلك غلق الباب و تحديد الفترة الزمنية حسب الخيارات و كانت كود:
كود:
While TRUE ثم تستبدل Goto Loopagain WEND و استبقيتهم للآخر حتى لا يبدو البرنامج معقد و به كثير من التنبؤات ولكن يمكن استبدال شيء بأخر المرة القادمة إن شاء الله سنستخدم ذات البرنامج بلغة C |
|
|||||
|
الغسالة باستخدام C51 و لغة C: للأسف لا يوجد مصدر آخر سهل سوى ميكروإلكترونيكا لذا لا مقارنة سوى بين اللغتين و أتميل لها أتميل استوديو لكنه كبير جدا و ثقيل على الحاسب و سنبدأ بالبيزك و نحوله إلى C سنبدأ بالتعريفات وكانت كود:
كود:
فى كود المقاطعة الثانى الخاص بالطوارئ أى المقاطعة الخارجية نجد ألتعليمه كود:
if ( --Runtime = 0 ){
وهى للمبتدئ تعنى ما يلى على خطوتين
Runtime = --Runtime
if (Runtime = 0) {
يلى ذلك جزء التعريفات و كما سبق مع ميكروإلكترونيكا سنحتاج تهيئة العدادات يدويا فالتعليمة Config غير مدعومة أى أن هذا الكود التالى سيصبح كما سيلى بعد التعديل كود:
فى البيزك عموما هى غير مدعومة لكن فى المترجمات الخاصة الوحدات المتقدمة مثل AVR فالكل يقول مدعومة ولا يذكر كيف، و الأفضل عملها يدويا كود:
|
|
|||||
|
الغسالة باستخدام AVR و لغة البيزك: سنضع الدائرة لكى نرى ما إن كنا نحتاج أى من التعديلات وهذه هى ![]() أولا سنحاول الحفاظ على الهيكل العام للدائرة و نستبدل المتحكم و أول ما نلاحظه أننا استخدمنا الترانزستورات NPN مع الريلايات 12 فولت لا لسبب سوى شيوع هذه الطريقة و خشيت أن أبقى على الطريقة القديمة مخافة الظن أن هذا ما يجب أن يكون بينما لك مطلق الحرية فى تبنى أى من الحلين ، و إثباتا لذلك سأبقيه مع الليدات. لهذا فكل ما نحتاجه هو تعديل أوامر التحكم فى الريلايات من Set إلى RESET و العكس بالعكس. و ستجد ذلك فى الكود مشروحا للتذكرة . ثانيا لم أوصل دائرة الريسيت و دائرة الكريستال لآن المتحكم يدعم الريسيت الداخلى و مذبذب م س داخلى و لك الحرية فى استخدامهما بدلا من المكونات الخارجية لتحقيق الوفر ، فقط من خيارات المبرمجة يجب أن تختار هذه الخيارات في مجموعة تسمى فيوزات من المبرمجة وليست فى البرنامج. وجب هنا إيضاح نقطة أن هناك أشياء تبرمج بالكود و أشياء تبرمج أثناء عملية البرمجة و من خلال المبرمجة ذاتها و تسمى فيوزات لآنها تبرمج مع الكود لكن فى كثير من الأحوال ستحتاج لمبرمجة توازى لإلغاء وضع هذه الفيوزات و تغييرها أما المبرمجة التوالى و التى تناسب البرمجة فى البوردة فيمكنها عادة أن تفعل هذه الفيوزات لكنها أحيانا تكون غير قادرة على إعادته هذه الفيوزات لأصلها باعتبار أنها خيارات المصمم ولا يجوز تغييرها بواسطة المستخدم. استخدام الفيوزات فى العائلتين لكن الفرق الوحيد أن وضع هذه الفيوزات فى ميكروتشيب تضبطه من المترجم وهو يتولى إنشاء ما يلزم لذلك أما فى أتميل فيجب اختيار الفيوزات من واجهة المبرمجة ذاتها و ليس من المترجم. و أخيرا المقاطعات حيث يجب توصيل التايمر الخارجى للطرف المناسب وهو هنا المنفذ B الطرف صفر و كان عليه أحد الريلايات WaterOn أى فتح صمام المياه للملو و سنضطر لتوصيله لمكان آخر و نختار مثلا PORTA.6 (أو اختار ما يناسبك) الآن سننقل كود بيزك باسكوم C51 إلى باسكوم AVR و نرى ما يحدث ، نفتح صفحة جديدة ثم من قائمة options نختار Compiler ثم Chip. يفتح لنا عدة خيارات تحدد منها نوع المتحكم و تردد الكريستال و بعض الأمور الأخرى مثل لو تستخدم شاشة LCD أو المنفذ التسلسلى الخ ثم اضغط على زر ADD TO CODE فسيضيف مجموعة التعليمات السابق الحديث عنها ثم ننسخ النص السابق. أسماء المنافذ تغيرت من صفر -1-2 الخ إلى أحرف لذا سنغيرها إلى PORTA,PORTB الخ. أيضا كما شرحنا عن وجود PINA لقراءة الطرف و أخيرا DDRA لتحديد اتجاه المنفذ A و مثله لباقى المنافذ مقاومة الانحياز لأعلى أو التعليق لأعلى PULLUP هنا عامة لكل طرف و ليست لمنفذ واحد كما فى ميكروتشيب و تصبح فاعلة بجعل الطرف (أو المنفذ) دخول ثم تكتب فيه 1 . لاحظ أنه كدخول تقرأ منه لا أن تكتب فيه لذا هذه الكتابة تذهب لمقاومة Pullup و متاحة لكل الأطراف فى كل المنافذ و كل طرف يتحكم فيه على حده بهذه الطريقة. لكن ماذا لو تحسبا لظرف ما يجب ألا تتاح هذه المقاومات؟ هل سنعدل كافة المنافذ أم ماذا؟ كلا فهناك بت واحدة اسمها PUD اختصار Pull Up Disable فى مسجل اسمه SFIOR وهى غالبا معروفة دون الحاجة لاسم المسجل. وهذه البت عادة = صفر و عند تغييرها إلى 1 توقف عمل كافة المقاومات فى كل المنافذ. عندما تضغط على زرار "صح" سيعترض على التعليمات الخاصة بالتايمر صفر فالقيم TH,TL,TCON لم تعد موجودة و تغيرت لتوسعة عمليات هذا المؤقت فقد شمل العد التصاعدى أو التنازلى و المقارنة بالصفر أو 255 أو قيمة أخرى فى مسجل آخر باسم OCR0 و هذه يمكن توجيهها لتوليد موجة بتعديل عرض PWM . بيزك باسكوم لا يدعم خاصية PWM لتايمر صفر ذو 8 بت لكنه يدعمها لتايمر 1 ذو 16 بت بصورة أشمل، لذا لو شئت فيمكنك استخدام مجموعة أوامر لتهيئه تايمر صفر لهذا الغرض . عموما فى هذا التطبيق سنحتاج فقط عد النبضات لذا يكفينا التنسيق الذاتى المدعم من المترجم. قد تكون النسخة المسجلة عدلت هذه السمة ولكنى لم اشتريها بعد. سنحذف الثلاث أسطر الخاصين بالتعليمات TH,TL,TCON و نستبدلها بالأمر TIMER0=205 وهكذا سيصبح البرنامج كود:
المرة القادمة إن شاء الله سنشرح الدائرة بالميكرو C |
|
|||||
|
الدائرة بلغة C كما فعلنا سننسخ البرنامج بلغة C لمتحكم c51 و نضعها فى ميكروإلكترونيكا مترجم AVR و نحاول الترجمة ، طبعا المشاكل و الاعتراضات أغلبها تعود لمترجمات ميكروإلكترونيكا عوضا عن اللغة فاختلافات C سبق تحديدها. سنجد اعتراضات أسماء المنافذ يلى ذلك اعتراضات تغيير التعريفات فقد كانت كود:
sbit Fullled at P0_0_bit ; و أصبحت sbit Fullled at PortA.b0 ; سيعترض أيضا على تعريف المقاطعة و لن تجد شرحا للمتوافر فى ملف المساعدة و لكنه فقط يقول لك تجد المتاح فى مساعد التحرير حيث تكتب IVT ثم تضغط CNTRL+Space تظهر لك نافذة تختار منها أنواع المقاطعة المتاحة لذلك سنختار مرة مقاطعة Timer0 و مرة المقاطعة الخارجية. أيضا أمر ajmp أصبح Jmp فقط من تغيرات لغة الأسيمبلى كما أن أسماء المسجلات للعدادات قد اختلفت لذا سنستبدل تعليماتها بالأمر TCNT0 = 205. الآن لم يعد لدينا Start timer, Stop Timer , Config Timer كما فى باسكوم لذا سنضطر لفهم المتحكم أكثر لكى نعيد تهيئته العداد تايمر صفر يعتمد على المسجل TCCR0 و ألذى يحتوى على 4 مجموعات لمهام عدة لذا قمت بتلوين كل مجموعة لتسهيل التتبع. أيضا تحت الخانة نجد W=Write أى كتابة فقط R=Read أى قراءة فقط R/W=Read Write قراءة و كتابة ثم تحتها نجد قيمة البدء إما 0 أو 1 أو X أى غير محددة ![]() البت رقم 7 و اسمها FOC0 اختصار Force Out Compare تجعل نتيجة المقارنة تحدث فورا و هى لا تعمل فى حال نظام PWM البت 6 و 3 باسم WGM00,WGM02 لاحظ عدم التجاور وهما بمعنى Waveform Generator Mode يحددان النسق ألذى يعمل به فلو 00 أى صفر يكون النسق العادى ولو ثنائى 01 أى = 1 يكون النسق تعديل عرض النبضة مع تصحيح الوجه PWM phase correct ولو 10 أى =2 تعمل بنظام CTC أى Clear Timer on Compare Match أى يصفر العدان عند تطابق العد، أما لو ثنائى 11 أى = 3 يكون النسق Fast PWM أى تعديل عرض النبضة السريع. البت رقم 4 و رقم 5 باسم COM00,COM01 أى Compare Output Match Mode فلو يساويان صفر تكون الأداء العادى للعداد أما الحالات الثلاث الباقية فلها وظائف تتغير بحسب ما إن كان WGM السابقة قد حددتPWM أو CTC أو Fast PWM الثلاثة بت CS00,CS01,CS02 تحدد مصدر القدح 000 تعنى بدون مصدر وبذلك يوقف المؤقت ، لو 001 أى = واحد تأخذ من النبضات الداخلية لوحدة I/O بدون تقسيم ، ولو 010 أى 2 تقسم على 8 ولو 011 أى ثلاثة تقسم على 64 ولو 100 أى 4 تقسم على 256 ولو 101 أى حمسة تقسم على 1024 ولو 110 أى سته تأخذ من الخارج أى الطرف T0 الحافة هابطة ولو 7 أى 111 يأخذ من الخارج ذات الطرف T0 الحافة الصاعدة. و بذلك نوقف التايمر بجعلها صفر المطلوب الآن أن نضع فيه صفر ليتوقف ثم نضع فيه 111 أى 7 ليعمل فى النسق العادى بحافة صاعدة أو 6 لحافة هابطة رجاء لا تسألنى لماذا أفضل باسكوم عن ميكروإلكترونيكا !!! المقاطعة : كان فى C51 عدد 8 خانات لكل مقاطعة تنفذ فيها شيئ ما أو تنتقل أما هنا فلكل واحد 2 بايت فقط ولا تسأل لماذا فقد أصبح لديك 21 مصدر للمقاطعات المختلفة منها مثلا لكل تايمر عدد من المقاطعات واحد عند بلوغ العد الأقصى وواحد عند تساوى العد العلوى وآخر للعد السفلى الخ لذا فليس أمامك سوى الانتقال ما لم تكن المصادر المجاورة غير مستخدمة أيضا كنتيجة لذلك لم يعد هناك مسجل واحد يكقى هذا العدد لذا تمت إضافة المقاطعة العامة فى مسجل الحالة Status register اختصارا SREG وهى البت رقم 7 ولها أمرين بالأسيمبلى هما SEI بمعنى Set Interrupts و الأمر CLI بمعنى Clear Interrupts وهى تعطل مع المقاطعة و فى نهاية كود الخدمة و بسبب تعليمه RETI تعود للإتاحة مرة أخرى – أو ما كانت عليه قبل المقاطعة ، كما يمكنك إتاحة المقاطعة داخل كود الخدمة بالأمر السابق لو شئت . هناك أيضا بت لكل من باقى المقاطعات ولكنها موزعة على مسجلات عدة مرتبطة بالوظيفة فستجد مع المؤقت إتاحة مقاطعته و هكذا. أعلم أنك تقول هذا أمر شاق ولا أستطيع مجادلتك فى هذا لكن هذا ما يجعل باسكوم أسهل باستخدام أمر Config ما لم تريد معرفة كافة التفاصيل و تتحكم به لأقصى حد و تتعمق فى الاحتراف فلا بأس يمكنك فعل ذلك باستخدام أى مترجم. بالنسبة للمقاطعة الخارجية نجد المسجل MCUCR أى MCU Control Register حيث MCU = Micro Control Unit يختص الجزء الأيمن منه بهذه المقاطعة و الأيسر فى وضع الكمون Sleep حيث عندما لا نحتاج نشاطه يدخل فى مرحلة كمون لتوفير الطاقة لحين حدوث مقاطعة أو ريست ، و له 7 أوضاع تحددها SM0,SM1,SM2 أما SE فهى عامة بمعنى تنفيذ الخيار أو تعطيله للتأكد من أن الدخول فى هذا النمط بأمر المبرمج فقط و الأنماط هى، لو صفر يكون نمط Idle و لو ثنائى 001 أى 1 نمط تقليل ضوضاء للمحول ألتماثلى رقمى ولو 010 أى 2 يكون نمط Power Down و لو 011 أى 3 نمط توفير الطاقة و لو 4 أو 5 فغير موظفه ولو 110 أى 6 يكون وضع Standby ,ولو 111 أى 7 يكون extended standby وكلها تفرق فى أى الوظائف متاحة و ما يمكنه إيقاظ المتحكم. ![]() الجزء الأيمن للمقاطعة الخارجية رقم 1 و البت3 و البت 2 باسم ISC11,ISC10 بمعنى Interrupt Sense يحددان كيفية الاستجابة فلو كانا صفر فالطرف INT1 يستجيب للمستوى صفر ولو كانا ثنائى 01 أى = 1 فيستجيب لأى تغيير و إن كانا ثنائى 10 أى = 2 فالاستجابة للحافة الهابطة و إن كانا ثنائى 11 أى 3 تكون للحافة الصاعدة البت صفر و البت 1 باسم ISC01,ISC00 يعنيان نفس السلوك لمدخل INT0 عرفنا كيف نهيئ تايمر صفر و الدخول INT0 بقى أن نفعل المقاطعات ![]() لدينا مسجل باسم General Interrupt Control Register أو مسجل التحكم العام فى المقاطعة و اختصارا GICR فيه البت 6 للمقاطعة INT0 و البت 7 للمقاطعة INT1 و البت 5 للمقاطعة INT2 و وضع 1 فى أى منها يفعل المقاطعة طبقا للضبط السابق. نلاحظ هنا أن المقاطعة ستحدث حتى لو كان الطرف خرج و ذلك إتاحة مقاطعة بالكود أى Software interrupt و لدينا المسجل TIMSK-Timer-Counter Interrupt Mask Register وهو يتيح المقاطعة ![]() فالبت صفر باسم TOIE0 تتيح المقاطعة OV أى عندما يصل العد إلى 255 ثم يقلب لصفر أما البت رقم 1 باسم OCIE0 فهى تتيح المقاطعة عندما يساوى العد تلك القيمة السابق حفظها فى مسجل باسم OCR0 أى Output Compare Register للتايمر صفر و بهذا يمكننا أن نستخدم الخاصية الأولى و نعيد العد مرة أخرى فى العداد كما كان أو نضع فى OCR0 قيمة ما و لتكن 50 و نعد صعودا حتى تحدث المقاطعة لتساوى العد فنصفر العداد مرة أخرى باقى المسجل لإتاحة مقاطعات مختلفة للتايمر 1 و التايمر 2 فى المتحكم المرة القادمة إن شاء الله نكمل البرنامج |
|
|||||
|
كود البرنامج مما سبق سنستبدل تشغيل تايمر صفر بالكود TCCR0=6 أو 7 حسب الخافة هابطة أم صاعدة (هنا لا فرق) و إيقافه TCCR0=0 لإتاحة المقاطعة الخارجية GICR.6=1 أو INT0 = 1 وللأسف ميكروإلكترونيكا لا يقبل INT0 = 1 لذا سنستخدم GICR.6=1 و للتهيئه MCUCR=2 للحافة الهابطة و لإتاحة تايمر صفر نستخدم TOIE0 = 1 فى المسجل TIMSK و ميكروإلكترونيكا لا يقبل اسم البت ولذا نستخدم TIMSK=1 اسم المسجل و بالصدفة لا نحتاج لتفعيل أى بت أخرى فيه. سيصبح الكود كود:
المرة القادمة إن شاء الله سنكررها بالميكروتشيب PIC16C877A و اللغتان أيضا |
|
جميع الحقوق محفوظة 2026
|

