منتديات الالكترونيات العصرية  
yoursite.com page title .

استرجاع كلمة المرور طلب كود تفعيل العضوية تفعيل العضوية
العودة   منتديات الالكترونيات العصرية > منتدى الحاكمات الدقيقة Microcontroller > منتدى المتحكمات ميكرو بلغة الاسمبلي

  #11  
قديم 06-12-2018, 11:16 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي أول برامجنا

أول برامجنا:
عائلةC51 - أتميل

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

نستخدم فيه AT89c51 متصلة كما بالصورة.
سنلاحظ هنا أن الليدات متصله على منفذ صفر PORT0 من خلال مقاومات متصلة بالموجب. السبب أن منافذ هذه العائلة لا تمد بتيار رغم أن الداتاشيت تقول أنها تستطيع ذلك لكن أيضا عندما تسحب منها تيار تحد فورا من تيار الخرج. باختصار لا تصدر تيار يضئ ليد أو يتحكم فى ترانزستور . لكنه يقبل تيار حتى 20 مللى أمبير.
توصل المفاتيح كما بالرسم. أعلم أن البعض سيعترض لكن كل أوجه الإعراض ليست لها ضرورة الآن.
فى صفحة البرنامج ستجد العديد من الأسطر كتبها لك البرنامج و كلها تبدأ بالفاصلة المنقوطة ";” و السطر بكاملة باللون الأخضر. هذا لأن هذه الفاصلة جعلت السطر بكاملة "تعليق" أى غير وارد فى البرنامج ولكنه للشرح أو التنسيق.
ثم يلى ذلك تعريف أن هذا هو الملف ألرئيسى و يمكنك حذفه.

كود:
كود:
; ============================================= ; Main.asm file generated by New Project wizard ; ; Created: Thu May 24 2018 ; Processor: 80C51 ; Compiler: ASEM-51 (Proteus) ;==============================================
ثم يلى ذلك تعليمه للمترجم بالنسق المستخدم وهو NOMOD51 و نلاحظ أنه مسبوق بعلامة الدولار $، هذه ألتعليمه تخص المترجم أى ستختلف باختلاف المترجم المستخدم و سيضعها آليا عند بدء مشروع جديد وهى فى بروتس تعنى لا تستخدم النسق الافتراضى لهذه العائلة و لذا يجب أن تتبعها بالخطوة التالية و تختار رقم الميكرو و تردد الكريستال الخ.
و يليه تعليمه للمترجم بالميكرو المستخدم وهو 8051 و هو ملف يلحق بالبرنامج به تعريفات لكل المسجلات و المنافذ و محتويات الميكرو الداخلية. بدونه لن تستطيع أن تكتب أمرا واحدا . أيضا مسبوق بعلامة $ و فى مترجم غيره قد تكون علامة # و اسم الملف 8051.MCU و كل مترجم سيضع اسم الملف الصحيح له.

كود:
$NOMOD51 $INCLUDE (8051.MCU)
ما يلى قسمين واحد للتعريفات ثم المتغيرات و متجهات إعادة التشغيل و خلافة و سيأتى شرحها لاحقا إن شاء الله
يمكنك حذف التالى أيضا ، سنبقى فقط على السطرين السابقين فقط.
كود:
;================================== ; DEFINITIONS ;================================== ;================================== ; VARIABLES ;================================== ;================================== ; RESET and INTERRUPT VECTORS ;==================================
و الآن سنصل لتعليق ; Reset Vector و لتعليمه هى

org 0000h
هذه اختصار Origin بمعنى نقطة أصل أو نقطة بدء لتقول للمترجم "أريد الكود التالى فى هذا العنوان"
وهى احتياطا لو تريد برنامج متقدم سيكون لها جدوى أما فى هذا البرنامج البسيط سيكون الكود فعلا فى خانة صفر ولا حاجة لتكرارها و يمكن حذفها.
حتى الآن كل ما سبق هو تعليمات للمترجم ولا ينتج عنها أى كود ولو حاولت أن تعكس المسار لتحصل على التعليمات من الكود، فلن تحصل مما سبق على أى كود ليكتب لك بدلا عنه هذه الأسطر.
أول أمر هو JMP start أى اقفز حيث العنوان Start
لكى تضع عنوان تذهب إليه وقتما شئت يجب أن يكون من كلمة واحدة قد تحتوى _ لزيادة الإيضاح و أن تبدأ بحرف وليس رقم و ألا تكون من كلمات الكود المستخدمة و أن تكون أول ما فى السطر أو قبلها مسافات بيضاء و أن تنتهى بالنقطتين ":” مثلا
كود:
LCD_TEST: عنوان جيد أو Delay25u:
ألتعليمه JMP بمعنى اقفز بدون قيد أو شرط للعنوان المذكور وهو هنا start
كما ذكرنا البرنامج سيبدأ دوما من خانة صفر و بدون استخدام باقى مكونات المتحكم فلا حاجة لها ويمكن حذفها
jmp Start
ثم الشرح ألذى يقول قطاع الكود و أيضا تعليمه مشابهة لتحديد مكان كتابة باقى البرنامج org 0100h و تعنى العنوان 100 بالنظام الستة عشرى لوجود الحرف h أما لو b سيكون ثنائى ولو بدون سيكون العشرى المعتاد
كود:
كود:
;==========================
; CODE SEGMENT
;==========================

   ;   org   0100h
Start:	
      ; Write your code here
يمكن حذف كل ما سبق ما عدا سطرى التعريف المذكورين و سطر العنوان Start
أى لدينا ثلاثة أسطر فقط وهنا نبدأ أول البرنامج الفاعل
وهذا موضوعنا القادم بإذن الله.
الصور المرفقة
نوع الملف: jpg Prog01c51.jpg‏ (14.5 كيلوبايت, المشاهدات 21)
رد مع اقتباس
  #12  
قديم 06-13-2018, 10:08 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي أول برامجنا ج2

ابتكر أحدهم فى شركة إنتيل استخدام كلمة Move وهى تعنى حرك أو انقل لكى تعنى انسخ ولا أدرى لماذا بينما استخدم نظيره فى موتورولا كلمة Load وهى بمعنى "حمًّل" أو "ضع شيء فى" ، وهى أقرب للمنطق لكن هكذا سارت الأمور و تبنت Mov كل من إنتيل و لاحقا أتميل و أيضا ميكرو تشيب
الاسم Mov هو مختصر ودوما بدون حرف e و يليها المنقول إليه أو الهدف ثم فاصلة "," ثم المنقول منه أو المصدر و لا قيود على من سيكون المصدر و من سيكون الهدف ، محتوى خانة ذاكرة أو عنوان الخانة أو مسجل و بهذا. لو كان المصدر حرفيا بمعنى رقم ما تريد نسخه أو وضعه فى مسجل ما نضع قبله علامة شباك "#” و بدون هذه العلامة سواء فى المصدر أو الهدف فهو عنوان لخانة ذاكرة و ما سيتأثر هو محتواها

السطر الأول سيكون
Mov P0 , #255
Mov p3 , #255
وهذا يعنى ضع فى المنفذ P0 القيمة 255 لوجود علامة "#” ثم السطر الثانى سيعنى ضع فى المنفذ P3 القيمة 255 لوجود "#” أيضا. هذا يعنى جعل كل أطراف هذين المنفذين عليهما +5 فولت و يمكن استخدامهم كمداخل أيضا.
ماذا لو لم نضع الشباك؟ أى هكذا MOV P3 , 255 سيترجمها المترجم انك تريد محتوى خانة الذاكرة رقم 255 حسبما يتصادف محتواه.
كود:
Loop:	
     jb	p3.0 ,  SW2test
     mov	P0 , #11111110b
SW2Test:     
     jb	P3.1 , SW3Test
     mov	P0 , #11111100b
SW3Test:
     jb	p3.2 , start
     mov	P0 , #11111000b
      jmp start
;===========================
      END

الآن انسخ السطور السابقة فى مترجم بروتس وهذا شرح كل منها.
Loop:
عنوان و لدينا أيضا عنوانين آخرين هما SW2Test و SW3Test وهى ذات فائدة فى تحديد مسار البرنامج
يليه الأمر JB وهو اختصار Jump if Bit set و يعنى اقفز لو البت =1 وهو يليه اسم هذه البت ثم فاصلة ثم إزاحة عدد الخطوات التى يجب الانتقال إليها. هذه الخطوات هى فى بايت واحدة لذا ستكون بإجمالي 255 خانة بين للأمام 128 خطوة و للخلف 127 خطوة.
سيكون من الصعب عليك حساب عدد الخطوات فستحتاج لمعرفه كم خطوة لكل تعليمه الخ لذا نستخدم عنوان و نترك المهمة الصعبة للمترجم.
إذن السطر التالى يعنى
لو البت "المنفذ3 الطرف صفر" =1 اقفز حيث العنوان SW2test وهذا يعنى أنني اختبرت المفتاح SW1 فإن لم يفعل سينتقل للعنوان "اختبار المفتاح2” وهذا من فوائد العنوان أن يكون معبرا عن هدف هذه الخطوة لتذكيرك ماذا أنت ذاهب لتفعل
أما لو كان مضغوطا على المفتاح1 سيجعل الطرف = صفر و من ثم لن ينتقل و سينفذ ألتعليمه
mov P0 , #11111110b
أى سيضع صفرا على الطرف المتصل بالليد الأول ليضئ وهنا كان ممكن أن نكتب MOV P0 , 254 لكن قد تتساءل لاحقا ماذا تعنى 254 ووضعها بالصورة الثنائية أوضح لك أن كل الأطراف آحاد ماعدا الأول بصفر ، ثم نكرر عند العنوان SW2Test حيث نجد نفس ألتعليمه إلا أن البت أصبحت P3.1 أى المنفذ 3 الطرف رقم 1 و القفز للعنوان SW3Test
إن لم ينتقل أو يقفز سينفذ الأمر
mov P0 , #11111100b
و به تضيء ألليد الأول و الثانى.
و بعد العنوان الأخير سنجد الاختبار الأخير للبت الثالثة إلا أن القفز للبداية فإن لم يقفز سيضيء الليدات الثلاث ثم يقفز للبداية لتكرار الاختبارات مرة أخرى بالأمر Jmp لتحديد متى يتم الضغط على أى الأزرار.
و فى الحقيقة أمر JMP ليست من الأوامر رغم أن كل المترجمات تتبناها و الأمر الصحيح هو
AJMP أو LJMP و الفرق بينهم بايت واحدة فالأول AJMP من2 بايت و يعمل على 2 ك من حيث كتبت بينما الثانى LJMP من 3 بايت و يغطى المدى كاملا وهو ما تترجم إليه كلمة Jmp عادة.
قبل أن نترك الموضوع تعلمنا الأمر JB و هناك الأمر عكسه وهو JNB أظن توقعت Jump if Not Bit set يعنى سيختبر البت و الانتقال سيكون لو = صفرا بدلا من لو =1
آخر سطر وهو END لا معنى له و كثير من المترجمات استغنت عنه ولكنه مستبقى لأسباب تاريخية فقط.
قديما عندما كانت البرامج تدخل للحاسب بالبطاقات المثقبة لم يكن هناك وسيلة لتعلم الحاسب أن هذا آخر كارت برنامج وهذا تمام الكود عكس الآن حيث يقوم نظام التشغيل بهذه المهمة و يحدد لك أول و آخر الملف . لذا كان لابد أن يكون آخر كارت عليه هذا الكود END و إلا سيحصل على رسالة أن الملف غير كامل. أما الآن فسيقول لك لم أجد كلمة END، حسنا وماذا لو وجدتها؟؟ أليست آخر كلمة فى الملف؟ ولو انتهى الملف أليس هذا كاف من نظام التشغيل أن يخبرك بتمام الملف؟؟
الآن جرب محاكاة البرنامج و ستجده يعمل و الليدات تضئ و تطفئ طالما الزر مضغوطا عليه.
لكن هناك ملاحظات تتطلب التعديل، حاول أن تكتشفها و تعدلها قبل موضوعنا القادم بإذن الله.
رد مع اقتباس
  #13  
قديم 06-14-2018, 10:25 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي المشكلة و اصلاحها

لعلك لاحظت أن المحاكاة كشفت أن الليدات الثلاث تطفئ ثم تضيء مرة أخرى وهذا فى برنامجنا لا شيئ لكن فى الواقع لو هذا فى آله و تقوم بذبذبة جزء منها بهذا المعدل قد تتلفها، إذن ما العيب و كيف نصلحه؟؟
العيب أنك فى كل مرة تقفز إلى Start لتعيد الدورة و فيها تطفئ الكل بدلا من أن تعدل فقط حسب المطلوب لذا نضع عنوان آخر هو Loop وهو فيه الدورة التكرارية
كود:
 Start: 
      Mov	P0 , #255
      Mov	p3 , #255
Loop:	
      jb		p3.0 ,  SW2test
      mov	P0 , #11111110b
      sjmp	Loop
SW2Test:     
     jb		P3.1 , SW3Test
     mov		P0 , #11111100b
     sjmp	LOOP
SW3Test:
      jb		p3.2 , start
      mov	P0 , #11111000b
      jmp 	Loop
;===========================
      END
هنا سنقدم تعليمه جديدة وهى sjmp اختصار Short Jump وهى للانتقال فى مدى +128 و -127 خطوة و بهذا توفر بايت فى كل تعليمه من حجم البرنامج بالمقارنة بتلك JMP و التى تنتقل لأى مكان ولكنها تحتاج لخانة أخرى لتكملة العنوان 2 بايت.
الآن بعد الاختبار الأول إن لم يتم الانتقال و أضأنا ألليد سنعود لأول الاختبار مباشرة فلا جدوى من تكملة الاختبارات، بل على العكس عندما نختبر الأخير لا دلالة لدينا عن حالة الأول مثلا و من ثم الأفضل إضافة ألتعليمه sjmp loop لنعيد الاختبارات من الأول لنحدد أى الأزرار مضغوط.
نفس الأمر فى نهاية الاختبار الثانى حيث لو لم ينتقل نتيجة لأول اختبار سيختبر الثانى فينفذ أو ينتقل
إن نفذ فسيعود لبدء الاختبارات مرة أخرى
إن لم ينتقل سيذهب للثالث و الآن وصولة للثالث هو حكم بأن الأول و الثانى لم يضغط على أى منهما لكن عدد الخطوات للانتفال قد تغير. من فوائد العنوان انه عندما يتحرك صعودا أو هبوطا ستحسب الخطوات آليا ولو زادت عن المسموح سيعطى المترجم رسالة خطا لمعالجة الموقف.
الآن وباختبار الثالث إن كان غير مضغوط فيجب إطفاء الكل بالانتقال للعنوان start و إن كان مضغوط سنضيء الكل بتنفيذ الأمرMov P0 , #11111000b ثم نقفز لتكرار الاختبارات دون إطفاء.

جرب المحاكاة الآن
لو حاولت تنفيذ هذا عمليا على بوردة تجميع فلن يعمل لعدم توصيل كثير من الأطراف الهامة و التى لا يعيرها ألمحاكي اهتماما، ولكى تنفذها يجب أن تكون الدائرة هكذا.


ألمرة القادمة بإذن الله سنكرر نفس البرنامج مع بيك.
الصور المرفقة
نوع الملف: jpg Prog01c51a.jpg‏ (21.7 كيلوبايت, المشاهدات 20)
رد مع اقتباس
  #14  
قديم 06-15-2018, 11:08 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي الدائرة باستخدام ميكروتشيب pic16f877a

ميكروتشيب PIC16F877A
الآن سننفذ ذات الدائرة على بروتس باستخدام PIC16c877A متحكم و معه ذات المكونات و الدائرة كما بالرسم.
سنلاحظ اختلاف فى توصيل الليدات و السبب أن منافذ ألبيك قادرة على الإمداد بالتيار عكس أتميل التى تقبل فقط.

نلاحظ أيضا أننا لن نتعامل حاليا مع منفذي A,E لارتباطهما بالمحول تماثلى رقمى و يجب تهيئتهما للتعامل كمنفذ رقمى فقط.
يمكننا استخدام ألباقى وسنختار المنفذ D .

المنفذ B يحتوي مقاومات جذب للأعلى Pull-up وهى خاصية ضرورية لأن المنفذ عندما يهيأ كدخول ستكون له معاوقة دخول عالية و من ثم الجهد عليه غير محدد و عند قراءته كطرف رقمى قد يقرأ 1 ثم يقرأ صفر بلا انتظام ولكنها توضع للأطراف الثمانية معا أو تحذف معا ولا ينصح باستخدامها لو البعض دخول و الباقى خروج و هذا يعالج بوضع المقاومات هذه خارجيا وهى R4,R5,R6 و عادة ما تكون 10 ك أوم , ولذا لم يعد مهما استخدام المنفذ B كدخول أو خروج و سنختار كما هو بالرسم.
بمراجعة صفحة الكود سنجد كما سبق كثير من الأسطر لا حاجة لها الآن سوى سطر
كود:
#include p16f877a.inc ; Include register definition file
وهو لتعريف المترجم أسماء مكونات المتحكم ثم يلى ذلك تعريف بدء البرنامج بتحديد البدء RESET ثم الانتقال لأول البرنامج بالأمر GOTO START وأخيرا إلغاء طرف البرمجة فى البوردة PGM
RST code 0x0
goto Start
PGM code
بعد ذلك نبدأ بتهيئة المنفذ B كخروج و المنفذ D كدخول و هذا بتنفيذ الأمر TRISB=0 و يكتب هكذا
كود:
 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

حيث CLRF تعنى Clear أو إلغاء محتوى المسجل المشار إليه بالحرف f وهو هنا STATUS وهذا لاختيار المجموعة صفر حيث لا يمكن للبيك أن يتعامل مع الذاكرة ككل و يقسمها لمجموعات كل منها تسمى بانك أو مجموعة أو BANK و نختار Bank0 لجعل المخارج أصفار بالأمرين CLRF PORTB ثم CLRF PORTD بعد ذلك نختار بانك رقم 1 بالأمر BSF STATUS, RP0 لتهيئة المنافذ بعد ذلك بالأمر CLRF TRISB لجعل المنفذ B مخارج.

لتهيئه المنفذ D كدخول نحتاج لأمر مشابه للسابق أى TRISD=255 و المشكلة أنك لا تملك أمر مماثل لأتميل حيث تكتب ما تشاء حيث تشاء كيف تشاء لكن يمكنك فقط كتابه ما تشاء فى المسجل W ثم تنسخه حيث تشاء بعد ذلك، ولهذا تحتاج لأمرين هما
MOVLW 255
MOVWF TRISD
حيث الأول Move Literal W أو اكتب حرفيا فى المسجل W و القيمة المطلوب كتابتها هى 255 أى 11111111 ثنائى ثم نسخها للمسجل TRISD بالأمر التالى MOVWF أو انقل محتوى W للمسجل F و المسمى هنا TRISD و أخيرا الأمر
CLRF STATUS ; Bank0
لنعود للبانك صفر مرة أخرى لنكتب فى المنافذ. نبدأ البرنامج بالعنوان
كود:
Loop:  
      BTFSC      PORTD , 0
      GOTO	 Sw1
      MOVLW      1
      MOVWF      PORTB
      GOTO       Loop
هذا حيث سيتكرر البرنامج دوما و سنختبر المفاتيح بالأمر

BTFSS f, b Bit Test f, Skip if Set
و هى تعنى اختبر البت f و لو =1 لا تنفذ الأمر التالى مباشرة و عكسها
BTFSC f, b Bit Test f, Skip if Clear
و هى تعنى اختبر البت f و لو =0 لا تنفذ الأمر التالى مباشرة وهذا الأمر التالى طبعا يجب أن يكون أمر انتقال لمكان ما
GOTO xxx
وهكذا يصبح اختبر المنفذ PORTD الطرف صفر فإن كان =1 انتقل لعنوان Sw1 و إلا فالزر مضغوط ولذا نكتب 1 فى المسجل W ثم ننسخه للمنفذ B و نعود للعنوان Loop لنكرر الاختبار. أما لو انتقلنا إلى Sw1 سنجد
كود:
Sw1:
      BTFSC      PORTD , 1
      GOTO       Sw2
      MOVLW      3
      MOVWF      PORTB
      GOTO       Loop
اختبار مماثل لكن للمنفذ PORTD الطرف 1 بدلا من صفر و الانتقال إلى Sw2 أو إنارة 2 ليد بدلا من الأول فقط ثم العودة لأول الدورة Loop
كود:
Sw2:
      BTFSC      PORTD, 2
      GOTO       SW3
      MOVLW      7
	MOVWF      PORTB
	GOTO       Loop
فى عنوان Sw2 سنجد اختبار مماثل لكن للمنفذ PORTD الطرف 2 بدلا من صفر أو 1 و الانتقال إلى Sw3 أو إنارة 3 ليد بدلا من الأول فقط ثم العودة لأول الدورة Loop
كود:
SW3:     
     CLRF	PORTB 
     GOTO Loop
;===========
      END
و أخيرا فى عنوان SW3 سنطفئ الكل لنعود للأول Loop مرة أخرى و كما ذكرنا أن واقعيا هذه الدائرة لا تعمل و يجب أن تصبح هكذا

من الواضح أن كم التعليمات أكثر بكثير مما استخدم مع السابق C51 وهذا راجع لقله الأوامر المتاحة فضلا عن كثير من التعليمات لا تستنتجها وحدك لبدء التهيئة و التشغيل.
لذا فألبيك يفضل دوما برمجته باستخدام اللغات العالية مثل البيزك أو C. فهذا البرنامج البسيط تطلب العديد من التعليمات ولو كان البرنامج أكثر تطورا ربما أصبح من الصعب تنفيذه بالأسيمبلى بألبيك .
يجب أن نتذكر هنا أننا باستخدام لغة ما غير الأسيمبلى قد تضيف كثير من التعليمات التى كان من الممكن اختصارها بالأسيمبلى.، لكن هناك أمر لا يسهل التغاضي عنه وهو استخدام مكتبات الأرقام العشرية و أنا شخصيا لو احتاج لعدد ثابت من الأرقام العشرية استخدم الحساب بدلا من المكتبات الجاهزة لاستهلاكها لذاكرة البرنامج فمثلا لو احتاج لرقمين صحيحين و كسرين عشريين أعتبر الحسابات ستكون على رقم أعلاه 9999 صحيح و استخدم له 2 بايت (حتى 65000) أو بالإشارة +/-32000 ثم فى عرض الرقم أضيق علامة عشرية بين الثانى و الثالث.
من المثال السابق نستخلص منهجا لما سيلى وهو أننا يمكننا مناقشة الأسيمبلى لمنتجات أتميل C51 فقط بينما AVR , ميكروتشيب سنكتفي باللغات العالية وذلك لكون الأسماء قد تغيرت و أيضا ذاكرة البرنامج زادت حتى سهل استخدام الحساب بالأرقام العشرية و من ثم اقتصرت البرمجة بالأسيمبلى على السرعة أولا و تقليل الحجم إن اضطر الأمر .

المرة القادمة إن شاء الله سنحاول كتابة هذا البرنامج باللغات العالية
الصور المرفقة
نوع الملف: jpg Proj01PIC16.jpg‏ (25.2 كيلوبايت, المشاهدات 19)
نوع الملف: jpg Proj01aPIC16.jpg‏ (29.5 كيلوبايت, المشاهدات 33)
رد مع اقتباس
  #15  
قديم 06-16-2018, 10:47 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي تمهيد للغات العالية

تمهيد للغات العالية:
التعريفات:
قبل أن نتناول اللغات العالية يجب أن نتعرض لما تركناه فى الشرح السابق و هو يخص البرمجة بشكل عام سواء بالأسيمبلى أو أى من اللغات العالية وهى الأجزاء الثلاث التالية
كود:
;==================================
; DEFINITIONS
;==================================
هذا الجزء يسمى التعريفات و كما سبق الذكر فهذه الأسطر هى تعليقات لتذكرك فقط أين يفضل أن تملأ هذه البيانات، لذا يمكنك بعد حذفه أن تكتب ما تريد أو تتركه للتنسيق فقط.
أغلب المترجمات تفترض أنك تضع هذا فى أول البرنامج دوما لأنه سيحتاج هذه المعلومات لاحقا و القلة فقط تدعم الإعلان لاحقا فهى ستحتاج لمسح الملف كاملا مرة لتحديد كل التعريفات ثم تبدأ فى التحليل .
لنعد للبرنامج السهل الأول سنجد
كود:
Start: 
      Mov	P0 , #255
      Mov	p3 , #255
Loop:	
      jb		p3.0 ,  SW2test
      mov	P0 , #11111110b
      sjmp	Loop
SW2Test:     
     jb		P3.1 , SW3Test
     mov		P0 , #11111100b
     sjmp	LOOP
SW3Test:
      jb		p3.2 , start
      mov	P0 , #11111000b
      jmp 	Loop
بالتأكيد أنك نسيت ما قلنا و الآن تتساءل ما هو أو فيم يستخدم P0 و ما هو P3 و ستضطر للعودة للدوائر لتكتشف أن P0 الخاص بالليدات و P3 الخاص بالأزرار لذا لو هناك وسيلة تسهل هذا الأمر؟!!
أجل هذا القسم هو لهذا الغرض فيمكنك مثلا كتابة
كود:
Switches	EQU P0
LEDs		EQU P3
SW1		EQU P0.0
SW2		EQU P0.1
SW3		EQU P0.2
كلمة EQU اختصار Equal وهى شائعة فى مترجمات الأسيمبلى و فى البيزك باسكوم تستخدم كلمة Alias وهى تعنى اسم مرادف ، وفى ميكروإلكترونيكا تستخدم Symbol وهى ليست قياسية فى لغة البيزك أما C فتستخدم كلمة at أو #define
Switches Alias P0
هكذا تعطى اسم للمنفذ ككل و اسم لكل طرف إن شئت، بل لو عرفت المنفذ أولا يمكنك استخدام اسمه لاحقا للتسهيل أكثر هكذا
SW1 EQU Switches.0
فى ميكروإلكترونيكا
Symbol Sw1 = Switches
فى لغةC نجد تعليمه للمترجم هى
كود:
 #define My_Name System_Name
فكلمة define تعنى عرف و هذه الجملة تقول استخدم My_Name بدلا من System_Name هكذا
كود:
 #define Switches PORT0
هذه الطريقة سهلت التذكر كثيرا ففى أى وقت تراجع البرنامج ستعلم ماذا – أين
هناك نقطة أخرى بالغة الأهمية أيضا، فماذا لو بعد الانتهاء من البرنامج و بدأت فى رسم البوردة وجدت تعارض فى المسارات ووجدت أنه من الأفضل استخدام منفذ آخر أو طرف آخر. من الأفضل أن تتحمل الخطأ فلو حاولت مراجعة البرنامج كاملا لتغير هذا الطرف بالتأكيد ستنسى و تعانى الأمرين حتى تجعله يعمل مرة أخرى.
باستخدام هذه المسميات سيكفى أن تغير التعريف فى أول البرنامج وهو سطر واحد فقط ليعمل البرنامج كما يجب على الوضع الجديد بالأطراف الجديدة. أليست هذه نعمة؟!
الآن الخبر الجيد أن هذه المسميات تكون للمترجم فقط ولا ينتج عنها أى كود لذا لا تبخل فى جعل الاسم مناسبا لا هو قصير جدا ويصعب تذكره مثل X,C فلن تذكر لاحقا X يعنى ماذا ولاC أيضا، ، ولا تجعل الاسم طويلا فيصعب عليك كتابته كل مرة داخل البرنامج مثل Liquid_Crystal_Data_Port و يكفى مثلا LCD_Data
أيضا هذه الطريقة لا تشترط على ماذا تطبق فيمكنك تطبيقها على ثوابت مثل NoOfLoops=25 أو حتى على معادلة أو كود مثلا
كود:
 PressTime Alias delay (25)
فما سيفعله المترجم هو ببساطة كما لو أنه استخدم خاصية "استبدل" Replace من القائمة " تحرير" EDIT و بدل النصوص كلها قبل أن يبدأ الترجمة .
بلغة ميكرو سى نستخدم الصورة التالية ولاحظ أن ميكروإلكترونيكا هى الشركة الوحيدة التى تستخدم تعريفين bit , sbit , فى كل منتجاتها وتنصح باستخدام sbit دوما.
كود:
sbit SW1 at RC5_bit;

char  Switches at PORT0 ;
لا تسألنى لماذا يجب أن ينتهى السطر بالفاصلة المنقوطة ";” فلم أجد إجابة شافية حتى الآن
البعض يقول تحديد نهاية السطر، حسنا هذا كان ضروريا وقت ما كنا نقرأ من الكروت المثقوبة لنحدد بها أى ";” نهاية السطر أما الآن فهناك فى الويندوز 2 بايت فى نهاية كل سطر هما CR,LF وهما كود 10 و كود 13 أما فى أبل أو يونكس / لينيكس و ملفات الأردوينو فهى إما الأولى أو الثانية فقط حيث CR اختصار Carriage Return أى رجوع العربة (الحاملة للورقة) أى الرجوع لأول السطر و LF اختصار Line Feed أى تحرك لسطر جديد ... أى أن هناك نهاية سطر مزدوجة فى كل سطر ولا حجة لهذا العذر و لكن لها ميزة عظيمة فى إرباك المبرمج خاصة أنها أحيانا لو وضعت تسبب إرباك المترجم ولا يعطى رسالة خطأ حتى ، فقط يعطيك برنامج كما تخيله هو ، ولو نسيتها فكثيرا ما يكتشفها لكن ليست دوما.
السطر الأول يعنى المفتاح SW1 عند الطرف رقم 5 من المنفذ C من المسجل PORT
السطر الثانى يعنى تخصيص اسم Switches للمنفذ0
الثوابت:
نفس مفهوم الأسماء يمكن امتداده للقيم الثابتة رغم عدم ظهورها فى المثال السابق إلا أنك قد تحتاج للتعامل مع 25 مدخلا و تحتاج دورة فيها 25 للقراءة ثم أخرى ربما للحساب و ثالثة للمقارنة ورابعة للعرض على الشاشة الخ فستجد نفسك فى عديد من الدورات كلها 25 مرة
و مثال آخر أنك تحتاج تكرار أمر ما عدة مرات لتحصل على نتيجة ثابته أو تتأكد من ثبات القيمة فعادة ما نضع رقم
لكن بنفس القياس لو احتجت لتغيير الدورات فى المثال الأول بالنقصان أو الزيادة سيكون ذلك كابوسا لكن لو استخدمت التعريف السابق فى إعطاء اسم للرقم فكل ما عليك هو تعديله فى أول البرنامج مرة واحدة
كل مترجم له طريقته فى هذا فالبعض يستخدم طريقة EQU السابقة أو Alias أو يجعلها واضحة باستخدام اللفظ "ثابت" أو Constant و اختصارا Const هكذا
Const Loops = 25
Const repeat = 50
نفس الخبر الجيد السابق ينطبق هنا فهذه الثوابت لا تأخذ من ذاكرة المتحكم لأنها لا تحفظ فى البرنامج و يقوم المترجم باستبدال كل كلمة Loops بالعدد 25 و هكذا و فى النهاية يقوم بالترجمة باستخدام الأعداد و ليس الأسماء و سنوضح الفروق بالأمثلة على لغتى البيزك و السي..
لكن هل من الممكن أن نعدل هذه القيمة بحسب الحاجة؟ هذا يسمى "المتغيرات" لكن لتنوعها سنجعلها المرة القادمة بإذن الله
رد مع اقتباس
  #16  
قديم 06-17-2018, 09:46 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي المتغيرات

المتغيرات
نأتى الآن للجزء التالى من التعليقات التى سبق حذفها وهى باسم المتغيرات

كود:
;================================== ; VARIABLES ;==================================
لكونها تتغير بحسب الحاجة إذن يجب أن نعلم مسبقا أو نحدد لها حجم ما مناسب لأننا سنضطر لوضعها فى الذاكرة و من ثم ستأخذ قدر من المتاح، وقد تقول لا بأس فالمتحكم به عدة الآف من الخانات، للأسف يجب أن أذكر هنا أنها من حجم الذاكرة العشوائية وليست ذاكرة البرنامج وهى فى أتميل AT89x51 قدرها 128 خانة فقط و ألباقى AT89x52 فما فوق قدرها 256 خانة وفى AVR تصل 1 ك و أكثر و تصل 368 خانة فى PIC16 أو اقل فى بعض الأرقام. يمكنك أن تخصص لكل متغير من بايت واحدة إلى 4 بايت ولا تزيد عن ذلك إلا فى حالة النصوص.
كن حذرا هنا فما لم تكن تتعامل مع الأسيمبلى فكل تخصيص لمتغير أنه بت واحدة ، سيحجز المترجم مقابلها بايت كاملة !!.
يجب أن تعلن صراحة عن المتغيرات التى ستستخدمها و إلا ستلقى رسالة خطأ و يتوقف عن الترجمة.
فى الأسيمبلى تستخدم كلمه EQU السابقة أيضا، ستقول كيف؟ سأقول كما سبق أن ذكرنا هى تعنى هذا يساوى أو يستبدل بذلك فلو تصف خانة ذاكرة إذن هى متغير لأن محتواها يأخذ أى قيمة من صفر إلى 255 و أذكر أننا قلنا فى ألتعليمه Mov P0 , #255 ` ذكرنا أن "#” تضع 255 على المنفذ لكن لو حذفناها سيأخذ محتوى الذاكرة 255 حسبما كان هذا و يضعه على المنفذ ، بهذا لو كتبت ألتعليمه
Days EQU 50
فهذا يعرف المترجم أن عليه استبدال كلمة Days بالقيمة 50 فى الأمرين التاليين
Mov P0 , #Days
Mov P0 , Days
ومن ثم فى السطر الأول سيضع حرفيا على المنفذ صفر قيمة 50 أما فى السطر الثانى سيأخذ محتوى خانة الذاكرة رقم 50 و يضعها على المنفذ. لو تريد تخصيص Word وهى من 2 بايت سيخصص المترجم المكان الأول الذى أشرت إليه فى الأمر و التالى له آليا. لا يوجد فى الأسيمبلى أكبر من 2 بايت إلا بتخليقك أنت لما تحتاج أو تستخدم مكتبة خارجية.

فى لغة البيزك تستخدم كلمة Dim و هى اختصار Dimension بمعنى "يصنع وفقا لأبعاد محددة" وهى بلغة الحرفيين كلمة "يواصف" أى يعطيه المواصفات و أكثر المترجمات تسمح بتسمية عدد من المتغيرات المتساوية الحجم مثلا
Dim Loop , Cycle , X , T as byte
وهى هنا تقول أصنع متغيرات واحد باسم Loop وآخر باسم Cycle وآخر باسم X وآخر باسم T كل منها بايت واحدة و لتسمى آخر بحجم 2 بايت يجب أن تعلن من جديد باستخدام Dim
فى لغة C تضع النوع أولا هكذا
كود:
Byte Loop , Cycle , X , T ;
أنواع المتغيرات و أحجامها :
أصغر متغير هو البت الواحدة وفى عائلة C51 يوجد منها 2 بت للمستخدم و للأسف لا يوجد مثلها فى أى من المتحكمات الأخرى.
داخل كل متحكم يوجد ما يسمى مسجل حالة البرنامج أو Program Status Word و اختصارا PSW وهذا اسمه أى لو تريد الكتابة فيه أو القراءة منه تستخدم الاسم PSW.1 مثلا لقراءة البت رقم 1

الصورة لعائلة C51 حيث نجد فيها 2 بت للمستخدم الأولى باللون الأصفر و اسمها F0 أى يمكنك أن تستخدم هذا الاسم مباشرة هكذا
JB F0, Next_Action
أو تعيد تسميتها بالتعريفات السابق شرحها و الثانية باللون البرتقالى وهى بلا اسم لذا يمكنك استخدام PSW.1 أو تعريفها بأي اسم مناسب . باقى الخانات سيلى شرحها لاحتوائه على كثير من الأمور الهامة.
لو اخترت أى بت أخرى سيخصص المترجم بايت كاملة لها.
لو ستستخدم مترجمات ميكرو الكترونيكا تذكر أنها تسمى sbit

الوحدة الثانية من المتغيرات هى البايت وهى 8 بت وهى تعبر عن حرف من كلمة أى حرف هجائى أو عدد من صفر وحتى 255.
بعض المترجمات خاصة فى اللغات العالية مثل ميكرو الكترونيكا تسمى الحرف Chr اختصار Character و تسمى أيضا Short اختصار Short-Integer و من كل تضع بلا إشارة UN-signed Character أو بالإشارة signed Character و تصبح أعلى بت فيها رقم 7 تمثل إشارة الرقم. لو صفر يكون العدد موجبا و لو 1 يصير سالبا و بهذا تعبر عن +127 إلى -128 فقط بدلا من صفر إلى 255 أيضا
Signed short int أو Un-signed short int لنفس المدى
أما مترجم BASCOM فيستخدم Byte من صفر إلى 255
الصور المرفقة
نوع الملف: png psw-51.png‏ (1.5 كيلوبايت, المشاهدات 16)

التعديل الأخير تم بواسطة ماجد عباس محمد ; 06-17-2018 الساعة 11:04 AM
رد مع اقتباس
  #17  
قديم 06-18-2018, 10:20 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي المقاطعة و البدء

الثالث هو 2 بايت أى 16 بن و يسمى فى ميكرو الكترونيكا Int اختصار Integer و منهsigned Integer
من -32768 إلى +32767 ومنه Un-signed Integer من صفر و حتى 65535
أما مترجم BASCOM فيستخدم Integer من -32768 إلى +32767 و Word من صفر و حتى 65535 وهذه من التعبيرات المستخدمة فى الميكرو بروسيسور وقبلها عند أول تطبيقات الحاسبات

الرابع من 4 بايت و يسمى فى ميكرو الكترونيكا Long وهو من -2147483648 إلى +2147483647 و أيضا Un-signed Long وهو من صفر إلى 4294967295
أما مترجم BASCOM فيستخدم Long وهو من -2147483648 إلى +2147483647 و أضاف لنسخة AVR الكلمة DWORD وهو من صفر إلى 4294967295

الخامس الأرقام العشرية و يسمى فى ميكرو الكترونيكا Float أو Double أو Long Double و كلهم ذات الشيء من 4 بايت للمدى من 1.5x10^–45 إلى 3.4x10^38
أما مترجم BASCOM فيستخدم Single من 4 بايت أو 32 بت للمدى من 1.5x10^–45 إلى 3.4x10^38 و أضاف لنسخة AVR الكلمة Double من 8 بايت أو 64 بت للمدى 5.0x10^–324 إلى 1.7x10^308

وسادسا النصوص وهى حتى 254 حرف باسم String

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

المقاطعة و البدء:
الكل له مكان محدد للبدء حيث يجب أن تضع أين يبدأ برنامجك وهى خانة صفر فى أول الذاكرة، لذا قد تكون بداية برنامجك فعلا أو انتقال لحيث تضع برنامجك فى الذاكرة.
أما فى المقاطعة فكما ذكرنا سابقا أن أتميل لها عنوان خاص بكل مقاطعة بينما ميكروتشيب لها عنوان واحد فقط تضع فيه عنوان برنامج معالجة المقاطعة تكون فى خانة 4 حيث تضع عنوان معالجة المقاطعة تتعرف من أين أتت ثم تقوم بالمطلوب أما فى أتميل ستجد لكل مقاطعة خانة حيث تضع عنوان معالجة المقاطعة الخاصة بهذا المصدر مما يوفر عليك تحديد مصدرها.
كود:
;==================================
; RESET and INTERRUPT VECTORS
;==================================
فى أتميل نجد فى C51 ما يلى و فى AVR أضيف لها أكثر من ذلك

كود:
; Interrupt vectors:     
 (0000H):		;  Reset system

الرقم بين قوسين هو بديل للتعليمه السابق شرحها Org (0000) H أوتعنى ضع الكود التالى فى هذا العنوان وهو صفر و حرف H يعنى أنه هيكسا ولو لم يذكر سيترجم عشرى. لو لم تستخدم أى من المقاطعات التالية فيمكنك وضع أول كود برنامجك هنا (فى خانة الصفر) لكن لو ستستخدم أى من المقاطعات التالية يستحسن وضع أمر انتقال لبداية البرنامج مثل Ljmp Start غنى عن التعريف أن Start هو عنوان لاحق فى البرنامج
أول مقاطعة من الطرف الخارجى INT0 بعد 3 خانات من الريسيت وهى كافية لأمر القفز لكن كل عنوان مقاطعة بعد ذلك يبعد 8 خانات عن السابق له ، لذلك لو ما تحتاجه لخدمة المقاطعة يمكن أن تكفيه 8 خانات مثل قراءة منفذ تسلسلى أو إعادة تحميل عداد الخ ،يمكنك الاكتفاء بهذه الخانات و إلا ستحتاج لأمر القفز لعنوان آخر.

كود:
(0003h) :		; Adress of INT0 (IE0)
	Ljmp Int0Code
 (000Bh):		; Adress of Interrupt Timer 0 (TF0)
	Ljmp T0Code
 (0013H)		; External 1 (IE1)
	Ljmp Ext1Code
 (001BH)		; Timer 1  (TF1)
	Ljmp T1Code
 (0023h):  		; Serial Interrupt
	Ljmp SiCode
 (002Bh):		; Timer2 (TF2 or EXF2)
	;Timer2 code if used......     يمكنك وضع كود تايمر2 هنا مباشرة ولا حاجة لأمر انتقال إلا للضرورة
.
.
Start:
.
.
T0Code:
.
.
Int0Code:
.
.
SiCode:
.
.
T1Code:
لاحظ أنك تمتلك الحرية فى ترتيب العناوين التى تنتقل إليها كيف شئت كما أن عنوان البدء Start يمكن أن تكون أيضا فى أى ترتيب
عندما تحدث مقاطعة يحفظ المتحكم عنوان الخطوة التالية فى الرصة Stack ثم ينتقل للعنوان المذكور و ينفذ ما به و إن وجد به أمر قفز للعنوان الخاص بهذا الطالب للخدمة و هناك ، أنت تعلم ما ستستخدم من مسجلات ، لذا لو تريد فى برنامج المقاطعة استخدام أى من المسجلات فمن الحكمة أن تحفظها أيضا خاصة مسجل حالة البرنامج PSW لأنه يحتوى مؤشرات ناتج الحسابات و تحفظ هذه المسجلات فى الذاكرة لكن الأسلم و الأسرع بأمر "دفع فى الرصة" Push و عكسه استرداد من الرصة POP فهو يحفظ الترتيب خاصة مع المسجلات 16 بت

كود:
	Push	direct	; direct is any register or memory
	POP	direct	    ;	''	''
و سبب أن هذا الأمر أفضل أنك تحفظ أى مسجل دون أن تهتم كثيرا أين فمؤشر الرصة يتولى ذلك عنك، كل ما تحتاجه أن تسترد عكس ما تدفع فإن دفعت مثلا A ثم B ثم المسجل R4 تسترد R4 أولا ثم B ثم A. المزيد عن المقاطعة فى التطبيق التالى للتوضيح بالمثال.
فى ميكرو تشيب الأمر أكثر تعقيدا لأن لديك مكان واحد تنتقل إليه و هناك عليك أن تبحث أى المصادر سبب هذه المقاطعة و مما يزيد الأمور سوءاً أن البت الخاصة بالمقاطعة ستكون 1 بصرف النظر عن أن هذه المقاطعة متاحة أصلا أم لا ولا أن المقاطعة كلها أصلا متاحة أم لا لذلك من الأفضل تركها للغات العالية حيث تولد الكود اللازم للتحقق.

الآن بعد أن عرفنا التعريفات و الثوابت و المتغيرات يمكننا أن نعيد صياغة برنامجنا السابق باللغات العالية، بالبيزك مرة و C مرة وهذا موضوعنا القادم بإذن الله.
رد مع اقتباس
  #18  
قديم 06-19-2018, 11:06 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي اللغات العالية

اللغات العالية :
ربما نسينا برنامجنا السابق لذا ها هو مجددا و بعد إضافة المسميات

كود:
Switches	EQU P0
LEDs		EQU P3
SW1		EQU P3.0
SW2		EQU P0.1
SW3		EQU P0.2

Start:
      Mov	Switches , #255
      Mov	LEDs , #255
Loop:	
      jb		SW1 ,  SW2test
      mov	LEDs , #11111110b		;  = 254
      sjmp	Loop
SW2Test:     
     jb		SW2 , SW3Test
     mov		LEDs , #11111100b		; = 252
     sjmp	LOOP
SW3Test:
      jb		SW3 , start
      mov	LEDs , #11111000b		; = 248
      jmp 	Loop

و أظن أنه أصبح مفهوما بصورة أوضح. هل يمكننا وضعه فى كلمات لشرح خطواته؟
نعطى منفذ الليدات اسم LEDs ونعطى السويتشات اسم Switches و السويتش الأول اسم SW1 وهكذا
ضع على منفذ السويتشات 255 و على منفذ الليدات 255
العنوان دورة:
لو المفتاح Sw1 =1 عندها انتقل للعنوان SW2test
و إلا ضع على الليدات 254 ثم عد للدورة
العنوان SW2test:
لو المفتاح Sw2 =1 عندها انتقل للعنوان SW3test
و إلا ضع على الليدات 252 ثم عد للدورة
العنوان SW3test:
لو المفتاح Sw3 =1 عندها انتقل للعنوان start
و إلا ضع على الليدات 248 ثم عد للدورة

هل نترجمه للإنجليزية؟؟
لو = IF ، و إلا = Else و عندها = Then و إعطاء اسم هى Dimension لآنها تعنى اسم و حجم معا أو حيز أو صنع شيء طبقا لمواصفة محددة أما استخدام اسم بديل فهو Alias . كثير من المترجمات تفضل البدء بكلمة Main بمعنى أساسى ، لا بأس فهى تعرفك أنت أين يبدأ البرنامج و دوما ما تحتاج عنوان فى بداية البرنامج لتكراره.

كود:
Main:
Switches = 255
LEDs = 255
Loop:
If Sw1 = 1  then
	Goto SW2test
Else
	LEDs = 254
	Goto loop
End If

حيثما تريد كتابة أكثر من تعليمه فى أى من الجزأين فإما تكتب كل منهما فى سطر مستقل كما سبق أو تفصل بينهما بالحرف ": “ كما فى المثال التالى أو ربما المترجم يتبنى حرف آخر، فلنستخدمه إذن.
طبعا هنا ستقول أن كلمة "عندها أو Then “ زائدة لكن ستجد ضرورتها لو كتبتها فى سطر واحد هكذا
If Sw1 = 1 then Goto SW2test Else LEDs = 254 : Goto loop
فهى تفصل بين كود الشرط و ألذى قد يكون معادلة طويلة و بين الأوامر الواجب تنفيذها عند تحقق الشرط كما Else تفصل بين كود التحقق و كود عدم التحقق – كل كلمة لها مكانها و ضرورتها و مفهومة إن نسيت بمقدورك أن تستنتجها و تركز فى البرنامج بدلا من التركيز على ما لا جدوى منه من أقواس و فواصل منقوطة وهل الفاصلة قبل القوس أم بعده..
وفى نمط السطر الواحد سنستغنى عن حد الختام وهو End If لأنها تفصل بين كود Else و باقى البرنامج.
هكذا يمكننا أن نكتب باقى البرنامج بالسطر الواحد هكذا

كود:
SW2test:
If Sw2 = 1  then  Goto SW3test  Else  	LEDs = 252  : Goto loop  
SW3test:
If Sw3 = 1  then  Goto Start  Else  LEDs = 248 : Goto loop

طبعا لو عكسنا المنطق سنوفر قفزة من الاثنتين (الأولى) بحكم أنها للمكان التالى مباشرة فيمكننا القول

كود:
If Sw1 = 0  then  LEDs = 254  : Goto loop 
If Sw2 = 0 then  LEDs = 252  : Goto loop  
If Sw3 = 0  then  LEDs = 248  : Goto loop  
Goto Main

لاحظ أن البرنامج الأفضل هو ألذى يقوم بمهام أكثر بكود أقل فى زمن أسرع.

و لنكتبه بلغة C أولا يجب أن تلتزم بالأحرف المكتوبة بمعنى لو كتبت Loop ثم لاحقا goto loop سيعترض أن العنوان غير موجود. هذا من بقايا نشأة اللغة فالفرق بين الحرف الكبير و الصغير هو البت رقم 5 فمثلا
حرف A = 0100 0001 بينما حرف a=0110 0001 وهكذا فى باقى الأحرف و لتوحيد المقاس يلزم تنفيذ أمر على كل الحروف مثل OR x,#0010 0000 لجعل الحروف صغيرة أو AND x,1101 1111 لجعلها كبيرة وهذا كان رفاهية و إسراف عندما كانت ذاكرة الحاسبات تحسب بالبايت و تشترى بالبت و حتى لاحقا عندما حسبت بالكيلو بايت. أيضا كل الأوامر تكتب بالأحرف الصغيرة ولو كتبت أى حرف كبير لن يتعرف عليها المترجم. هذا قد يوقعك فى مشكلة لو أخطأت فى حجم حرف فى اسم متغير فى برنامج من عدة صفحات حسب المترجم المستخدم.
سنجد أن البداية بالتعريفات كما سبق الشرح ثم بكلمة Void وهى تعنى "خلاء" أو فراغ أو مساحة و كلمة main ضرورية للبدء ثم قوسين لتحديد أنك لا تضع بينهما أى بيانات مطلوب معالجتها ثم القوس المعوج ألذى يحدد البداية و مثله للنهاية

كود:
void main() 
{
TRISA  = 0xFF;              //          PORTA is input   
TRISC  = 0;                     //       PORTC is output   
Loop:
if (Sw1=1) {
	Goto SW2test ;
		}
else {
	LEDs = 254 ; 
	Goto loop ;
}
الشرط يجب أن تضعه بين قوسين (لماذا ؟ لا تسألنى فلم يجيبنى أحد ولا أرى سببا غير ما شرحت سابقا) لو أردت أن تضع بعد ذلك أكثر من سطر فيجب أن تبدأ بالقوس المعوج } و تنتهى بآخر { و كل سطر منتهى بالمقدسة ";" من غير ليه و الصورة المختصرة تصبح

كود:
SW2test:
if (Sw1 = 0 ) 
	{ LEDs = 254  ;
	 Goto loop ;
}
if (Sw2 = 0) {
	 LEDs = 252  ;
	 Goto loop  ; }
if (Sw3 = 0)  {
  	LEDs = 248 ;
	 Goto loop  ;
Goto Start  ;
}
هكذا حولنا البرنامج الصغير إلى كافة اللغات المعنية. هل نطوره؟ حسنا المرة القادمة إن شاء الله نبدأ فى معرفة المزيد من تفاصيل المعالج و المزيد من الأوامر لنصنع كارت تحكم فى غسالة كهربية مثلا ثم فرن ميكرو ويف .
أيضا التعليمات بالبيزك و السى أعطت ذات الكود أى لا توجد لغة أقرب للمكونات من الأخرى.
رد مع اقتباس
  #19  
قديم 06-20-2018, 10:08 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي صورة أخرى من ألتعليمه if

صورة أخرى من ألتعليمه IF
بعض الشركات تحبط استخدام الأمر GOTO و تفضل عدم استخدامه و مثال لذلك تقترح الصورة المتداخلة من الأمر IF وتسمى Nested IF وهى أنك بعد الجزء ELSE تضع الشرط التالى مباشرة وهى قد تبدو منطقية و أسهل فهما و لنجرب ذلك فى المثال السابق حيث كان البرنامج بعد التعريفات

كود:
Start:
Switches = 255
LEDs = 255
Loop:
If Sw1 = 0  then  LEDs = 254  : Goto loop 

If Sw2 = 0 then  LEDs = 252  : Goto loop  

If Sw3 = 0  then  LEDs = 248  : Goto loop  
Goto Start

باستخدام الطريقة المتداخلة تصبح

كود:
Start:
Switches = 255
LEDs = 255
Loop:
If Sw1 = 0  then 
     LEDs = 254   
Else   If Sw2 = 0 then
	 LEDs = 252 
          Else   If Sw3 = 0  then
                      LEDs = 248 
                   Else
                      LEDs = 255       ; السطر الأخير
End IF
Goto Start
حسنا تخلصنا من معظم GOTO ماعدا الأخيرة فقط وهذه لها أمر آخر يمكن استخدامه لكن لو الذاكرة محدودة فمن الأفضل استخدام الأسلوب الأول ، لماذا؟
سينشئ المترجم آليا أمر انتقال لنهاية الدورة حيث تكتب END IF أو تضع القوس المعوج فى لغة C وهذا سيضيف المقابل للسطر الأخير أمر وضع 255 على المنفذ و انتقال لأخر الدورة بدلا من Start

و قبل أن نطور برنامجنا السابق و نتعمق أكثر نرى كيف نطبق هذا باستخدام النوعين الآخرين وهذا موضوعنا القادم بإذن الله
رد مع اقتباس
  #20  
قديم 06-21-2018, 10:09 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي البرنامج بالمتحكمات الآخرى

البرنامج باستخدام AVR
باستخدام الأسيمبلى سنحاج لتعديل البرنامج كله فقد تغير الأمر MOV ليصبح LDI اختصار LOAD Immediate أى تضع قيمة ما مباشرة فى مسجل و LDS لنسخ ذاكرة إلى مسجل و عكسها STS Store Data to space فضلا عن باقى التعليمات أيضا كما أن المنافذ هنا قد تغيرت و أصبح لكل منفذ 3 مسجلات واحد للخرج و يسمى PORTx و الثانى للاتجاه دخول/خروج و يسمى DDRx و الثالث لحالة الطرف و يسمى PINx كما سبق الشرح ، لذا سيكون أصعب بقليل كتابة هذا البرنامج لكنه ممكن ، و نظرا لكبر الذاكرة المتاحة و الرغبة فى التعامل مع الأرقام العشرية سيكون من الأفضل الاكتفاء باللغات العالية
كما علمنا سابقا أن منافذ AVR أصبحت تعطى تيار أو تقبل تيار مشابه لمنافذ ألبيك و عكس C51 لذا يمكن أن نتبنى الأسلوبين أى المطابق للسابق

أو مشابه للبيك هكذا مع مراعاة تغيير أوامر إضاءة ألليد من صفر إلى 1 وأذكر هذا تمهيدا للتعامل مع الريلايات لاحقا


أيضا لم أوصل طرف RESET لأنه يمكن الاستغناء عنه باختيار خاصية Brown out detect مع فولت 2.7 فعندما يهبط جهد التغذية لهذه القيمة يحدث ريست داخلى آليا ولا حاجة للتوصيل الخارجى لكن إن شئت فليكن، أيضا لم أوصل الكريستال لأنه يمكن استخدام المولد الداخلى 1 ميجا أو 2 أو 4 أو 8 ميجا و إن كان دقيق فى حدود 1% وهو فى نظرى كاف لكثير من التطبيقات ما عدا الوقت الدقيق ألذي يحتاج أكثر من هذه الدقة أو لو تستخدم التواصل التسلسلى.

باستخدام البيزك و مراعاة المسجلات الثلاث السابقة سيصبح البرنامج

كود:
$regfile = "m16def.dat"	 '  تحديد الميكرو
$Crystal=4000000		 '  تردد الكريستال
$hwstack=40			 '  تحديد المرصوصة
$swstack=16			 '  تحديد المرصوصة
$framesize=32			 '  ذاكرة كمسودة لبعض ألدوال
السطور الخمس السابقة تخص المترجم أساسا و تجدها مسبوقة بعلامة الدولار $ وهى فى باسكوم كما يلى
الأول تحديد ملف التعريف بالميكرو Atmega16A
الثانى تردد الكريستال وهو لا يهم إلا فى حساب الكود اللازم للمنفذ التسلسلى و حساب التأخير المطلوب فى بعض الوظائف
الثالث تخصيص مرصوصة الانتقال و المقاطعة الخ وتسمى Hardware أو مرصوصة المكونات
الرابع تخصيص مرصوصة تسمى Software أو مرصوصة البرامج وهى مطلوبة للمترجم لبعض العناوين
الخامس كمسودة لحسابات يحتاجها المترجم لبعض ألدوال كتنسيق النصوص الخ

كود:
Leds Alias PORTA : Leds_dcn Alias DDRA		 '  تسميه المنافذ و المفاتيح و مسجل الاتجاه
Switches Alias PORTD : Switch_dcn Alias DDRD
Sw1 Alias PIND.0 : Sw2 Alias PIND.1 : Sw3 Alias PIND.2
 '  تسميه المفاتيح لاحظ استخدام PIND بدلا من  PORTD  
Main:
     Leds_dcn = 0 : Switch_dcn = 255
Start:
Switches = 255
Leds = 255                                                  ' enable  Pullup
Loop:
If Sw1 = 0  then  LEDs = 254  : Goto loop 
If Sw2 = 0 then  LEDs = 252  : Goto loop  
If Sw3 = 0  then  LEDs = 248  : Goto loop  
Goto Start

نلاحظ أن البرنامج لم يختلف كثيرا لدرجة أننا لم نحتاج لإعادة رسم الدائرة فيمكننا أن نستخدم ذات الأطراف فقط نراعى أن أطراف التغذية و الكريستال و الريسيت قد تغيرت أرقامها.
المرة القادمة إن شاء الله نعيده بالبيك 16 و 18
الصور المرفقة
نوع الملف: jpg Prog01AVR01.jpg‏ (28.0 كيلوبايت, المشاهدات 16)
نوع الملف: jpg Prog01AVR02.jpg‏ (31.4 كيلوبايت, المشاهدات 16)
رد مع اقتباس
إضافة رد

مواقع النشر (المفضلة)

أدوات الموضوع
انواع عرض الموضوع

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

BB code is متاحة
كود [IMG] متاحة
كود HTML معطلة



الساعة الآن 09:11 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
الحقوق محفوظة لمنتديات الاليكترونيات العصرية

Security team

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77