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

   

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



1-9-3 المصفوفات متعددة الأبعاد Multidimensional Arrays :
لغة السى تدعم المصفوفات متعددة الأبعادا . عندما يتم إعلان مصفوفة متعددة الأبعاد , يجب أن نفكر فى أنها "كمصفوفة لمصفوفات " . يمكن بناء المصفوفات متعددة الأبعاد ليكون لها بعدين أو ثلاثة أو أربعة أو أكثر .
فيما يلى الشكل النموذجى لإعلان مصفوفة ذات بعدين :

كود:
int two_d[5][10] ;
فى الذاكرة يتم تخزين عناصر المصفوفة فى شكل صفوف متتابعة كما يلى :

كود:
two_d[0][0] , two_d[0][1] , two_d[0][2] , …. two_d[0][9] , two_d[1][0] , two_d[1][1] , two_d[1][2] , …. two_d[1][9] , two_d[2][0] , two_d[2][1] , two_d[2][2] , …. two_d[2][9] , two_d[3][0] , two_d[3][1] , two_d[3][2] , …. two_d[3][9] , two_d[4][0] , two_d[4][1] , two_d[4][2] , …. two_d[4][9] ,

عندما يتم تهيئة مصفوفة ذات بعدين تكون بنفس الشكل , تتابع الصفوف:

كود:
int matrix[3][4] = { 0,1,2,3, 4,5,6,7, 8,9,10,11 } ;
المصفوفات متعددة الأبعاد تكون مفيدة فى عمليات مثل حساب المصفوفات , والمرشحات , وجداول البحث .
لنفترض أن لدينا لوحة مفاتيح تليفون والتى تولد بيان بصفوف وأعمدة , أو "شفرة – مسح" , حينما يتم الضغط على مفتاح . يمكن استخدام مصفوفة ذات بعدين كجدول بحث kook–up-table لتحويل شفرة المسح لحروف أسكى ASCII الفعلية للمفتاح . سوف نفترض فى هذا المثال أن روتين الدالة getkeycode( ) يمسح المفاتيح ويحدد قيم الصف والعامود لبيان موقع المفتاح المضغوط . كود إجراء عملية التحويل قد يكون بالشكل التالى :

كود:
#include <16F877.h> //register definition file for #fuses HS,NOWDT //a Microchip PIC16F877 #use delay(clock=10000000 //setup the RS232 port for standard output #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stream=RS232,bits=8) #include <stdio> #define TRUE 1 #define FALSE 0 char getkeycode(char *row , char *col); // the getkeycode routine gets the key press and // returns TRUE if a key is pressed , FALSE if not /* look up table for ASCII values */ const char keys[4][3] = { '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '*' , '0' , '#' } ; void main(void} { char row , col ; char I ; while(1) // while forever… { i = getkeycode( &row , &col); // TRUE , if there was a key pressed // and row and col contain whitch key if( i == TRUE) // only print the key value that is preassed putchar( keys[row][col] ) ; } }


شكل آخر ,أكثر شيوعا, للمصفوفة ثنائية الأبعاد هو السلاسل النصية strings . المثال التالى يعلن عن مصفوفة سلاسل نصية مهيئة بأيام الإسبوع :
كود:
char day_of_week[7][10] = { "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Ttursday" , "Friday" , "Saturday" } ;

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

كود:
prtntf("%s" , day_of_the_week[3][0] ) ; // prints Wednesday
اسم السلسلة النصية يعتبر عنوان أول حرف لهذه السلسة النصية . فقط ذكر أول بعد يشير بكفاءة لكامل السلسلة النصية مثل البعد الثانى . لذلك , يمكن الوصول لنفس السلسلة النصية بداخل المصفوفة كما يلى :
كود:
prtntf("%s" , day_of_the_week[3] ) ; // prints Wednesday
1-9-4 المؤشرات إلى الدوال :

اعلانات

اميرسمير
:: مهندس ::
تاريخ التسجيل: Nov 2011
المشاركات: 22
نشاط [ اميرسمير ]
قوة السمعة:
قديم 25-02-2013, 01:50 AM المشاركة 50   
افتراضي


بعثك الله مع النبيين والصديقين والشهداء والصالحين

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

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


بعثك الله مع النبيين والصديقين والشهداء والصالحين
أخى الكريم الفاضل شكرا جزيلا لك

بارك الله فيك

اللهم آمين آمين آمين لى ولك وللجميع إن شا الله

مع تمنياتى بدوام التوفيق


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 25-02-2013, 09:43 PM المشاركة 52   
افتراضي



1-10 الهياكل Structures والاتحادات Unions :
تستخدم الهياكل والاتحادات لجمع المتغيرات تحت عنوان أو اسم واحد . ولأن كلمة "كائن" "object" فى البرمجة بلغة السى عامة تشير إلى مجموعة أو ارتباط لأعضاء فى بيانات , فإن الهياكل والاتحادات هى العناصر الأساسية فى "البرمجة الموجهة بالكائنات" object-oriented programming . البرمجة الموجه بالكائنات تشير إلى الطريقة التى يتعامل بها البرنامج مع البيانات على أساس العلاقات . يمكن النظر إلى الهيكل أو الاتحاد باعتباره "كائن" . أعضاء الهيكل أو الاتحاد هى خواص (متغيرات) الكائن . بعد ذلك يوفر اسم الكائن وسيلة للتعرف ارتباط الخواص بالكائن طوال البرنامج .

1-10-1 الهياكل Structures :
الهيكل هو إسلوب لإنشاء كائن بيانات مفرد من متغير واحد أو أكثر . تسمى المتغيرات بداخل الهيكل "أعضاء" members . هذا الإسلوب يسمح بتجميع الأعضاء للإشارة إليها باسم مفرد . على خلاف المصفوفة , المتغيرات المضمومة بداخل الهيكل لا تحتاج أن تكون من نفس النوع .
صيغة إعلان الهيكل كما يلى :

كود:
struct structure_tag_name { type member_1; type member_2; ………………. type member_x; } ; OR struct structure_tag_name { type member_1; type member_2; ………………. type member_x; } structure_var_name;

بمجرد تعريف قالب templateالهيكل , فإن المسمى structure_tag_name يساعد كواصف مشترك ويمكن استخدامه لإعلان الهياكل من هذا النوع طوال البرنامج .
فيما يلى إعلان للهيكلين var1 و var2 ومصفوفة من الهياكل var3 :

كود:
struct structure_tag_name var1 , var2 , var3[5] ;

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

كود:
structure_var_name.member_1 structure_var_name.member_x

مثل المصفوفات , يمكن تهيئة الهياكل عن طريق إتباع اسم الهيكل بقائمة التهيئة بين قوسين كما يلى :


كود:
struct DATE { int month ; // declare a template for a int day ; // data structure int year ; } // declare a structure variable and initialize .. struct DATE date_of_birth = { 2, 21, 1961 } ;


والذى يعطى نفس نتيجة التخصيصات التالية :


كود:
date_of_birth.month = 2 ;
date_of_birth.day = 21 ;
date_of_birth.year = 1961 ;

يمكن تمرير هيكل إلى دالة كبارامتر بالإضافة إلى الإعادة من دالة . على سبيل المثال , الدالة :
كود:
struct PART new_location ( int x , int y ) { struct PART temp ; temp.part_name = "" ; // initialize the name to NULL temp.sku = 0 ; // and zero to sku number temp.bin.x = x ; // set the location to the passed x and y temp.bin.y = y ; return temp ; // and then returns the structure to the caller }

يجب أن يتم إرجاع الهيكل PART بالأعضاء bin.x و bin.y مخصصة إلى بارامترات تمرر إلى الدالة . الأعضاء sku و part_name يجب أيضا أن يتم مسحها قبل عودة الهيكل . عندئذ يمكن استخدام الدالة السابقة للتخصيص كما يلى :

كود:
widget = new_location ( 10 , 10 ) ;
سوف تكون النتيجة : مسح sku و part_name وتحديد قيمة كل من widget.bin.x و wedget.bin.y بالقيمة "10"



الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 25-02-2013, 09:46 PM المشاركة 53   
افتراضي


1-10-4 الاتحادات Unions :
يتم إعلان والوصول إلى الاتحاد بطريقة مماثلة ,إلى حد كبير, للهيكل . شكل إعلان الاتحاد كما يلى :
كود:
union union_tag_name { type member_1 ; type member_2 ; …………………. type member_x ; } ; OR union union_tag_name { type member_1 ; type member_2 ; …………………. type member_x ; } union_var_name ;

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

كود:
union SOME_TYPES { char character ; int integer ; long int long_one ; } my_space;


فى هذا المثال كمية الذاكرة المخصصة بالحيز my_space تكافىء لحجم النوع long int long_one ( 4 بايت) .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 25-02-2013, 09:48 PM المشاركة 54   
افتراضي



1-11 أنواع الذاكرة Memory Types
بناء المعالج الدقيق قد يتطلب حفظ المتغيرات والثوابت فى ذاكرة من نوع مختلف . البيانات التى سوف لا تتغير يجب حفظها فى نوع واحد من الذاكرة , فى حين أن البيانات التى سوف تتغير ( قراءة وكتابة) بشكل متكرر فى البرنامج , يجب أن تحفظ فى نوع آخر من الذاكرة . يمكن استخدام نوع ثالث من الذاكرة لحفظ البيانات المتغيرة والتى يجب الحفاظ عليها حتى عندما يتم إزالة القدرة من النظام .

1-11-1 الثوابت والمتغيرات :
صمم الميكروكونترولر PIC باستخدام بناء هارفارد Harvard , بمساحات منفصلة لذاكرة المعطيات (البيانات) (SRAM) , وذاكرة البرنامج (FLASH or EPROM) و الذاكرة EEPROM . الموقع الأفتراضى أو التلقائى للمتغيرات , فى حالة عدم تحديد نوع الذاكرة ,هو الذاكرة SRAM . الثوابت يمكن أن توضع فى ذاكرة FLASH ( حيز البرنامج) عن طريق استخدام الكلمة المحجوزة "const" .
لوضع المتغيرات فى الذاكرة EEPROM , تتوفر مكتبة بمجموعة من الدوال لتناول الإجراءات المعقدة المطلوبة للحصول على البيانات من أو إرسالها إلى هذه الذاكرة .
الإعلانات التالية تضع البيانات الطبيعية مباشرة فى ذاكرة البرنامج (FLASH) . قيم هذه البيانات جميعها ثابت ولا يمكن تغيرها بأى وسيلة عن طريق تنفيذ البرنامج .
كود:
cons long integer_constant = 1234 + 5 ;
cons char char_constant = 'a' ; 
const int32 long_int_constant1 = 99 L ;
const int32 long_int_constant2 = 0x10000000 ;
const int integer_array1[ ] = { 1 , 2 , 3 } ;
// The first two elements will be 1 and 2 , the rest will be 0 .
const int integer_array2[10] = { 1 , 2  } ;
const int multidim_array[2][3] = { 1, 2, 3 } , { 4, 5, 6 } ; 
const char string_constant1[ ] = "Tis is a string constant" ;
const struct {
                        long a ; 
                        char b[3] , c[3] ;
} sf = { 0x000a , { 0xb1 , 0xb2 , 0xb3 } , { 0xb1 , 0xb2 , 0xb3 } ; 
كود:

حيز ذاكرة EEPROM غير متطاير . يتم التخصيص والوصول إلى المتغيرات يدويا عن طريق المبرمج . المترجم CCS-PICC يوفر مكتبة للوصول إلى EEPROM بالدوال الآتية :
كود:
unsigned char read_eeprom ( unsigned char address ) ; void write_eeprom ( unsigned char address , unsigned char value ) ;

فى كل من الدالتين read_eeprom( ) و write_eeprom( ) , العنوان address هو قيمة من "0" إلى "255" , ويصف أى مواقع الذلكرة EEPROM يتم الوصول إليه . مدى العنوان يتغير مع المعالج المختار . على سبيل المثال PIC16F873 له 128 byte من الذاكرة EEPROM المدمجة . فى حين أن PIC16F877 له 256 byte . أيضا , البيانات التى تمرر إلى الدالة write_eeprom( ) , أو تعود من الدالة read_eeprom( ) تكون بعرض 8 bits . هذا يعنى أن الأعداد من الأنواع long integer وfloating-point تتطلب "جلب متعدد" بغرض الحصول على القيمة الكاملة , ويجب أخذ الحيطة من أن تلك القيم لا تتغير قبل أن يتم نقلها بكاملها إلى موقعها النهائى .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 25-02-2013, 09:50 PM المشاركة 55   
افتراضي


تعريف البت #bit وتعريف البايت #byte :
منافذ الدخل / الخرج والمحيطات تقع فى حيز سجلات الملفات . لذلك يتم استخدام تعليمات خاصة لكى تبين للمترجم الفرق بين مواقع ذاكرة المعطيات SRAM المستخدمة كمتغيرات والتى لتلك المستخدمة لمنفذ الدخل / الخرج أو المحيطات الأخرى بسجلات الملفات . الكلمات الخاصة #bit و #byte تبين للمترجم أن عناوين محددة وتعليمات وصول يتم استخدامها للوصول إلى سجلات الدخل / الخرج للميكروكونترولر PIC .
مثال :

كود:
// define port names and bit names #byte PORTD = 0x08 #bit PORTD0 = PORTD.0 #bit PORTD1 = PORTD.1 #bit PORTD2 = PORTD.2 #bit PORTD3 = PORTD.3 #bit PORTD4 = PORTD.4 #bit PORTD5 = PORTD.5 #bit PORTD6 = PORTD.6 #bit PORTD7 = PORTD.7 #byte PORTC = 0x07 #bit PORTC2 = PORTC.2 void main(void) { set_tris_d(0x00) ; // set all of port D to ouyput set_tris_c(0xFB) ; // set all port C bit 2 to output while(1) { PORTD++ ; //lights !! if(PORTD4) PORTC2 = 1 ; else PORTC2 = 0 ; } delay_ms(10) ; }



الوصول إلى مستوى البت لسجلات الدخل / الخرج يكون مسموح عن طريق استخدام اختيار لاحقة بعد اسم سجل الدخل / الخرج .
مثال :

كود:
#include <16F877.h> // register definition file for #fuses HS , NOWDT // a Microchip PIC16F877 #byte PORTA = 0x05 #byte DDRA = 0x85 #bit DDRA0 = DDRA.0 #bit DDRA1 = DDRA.1 #bit PORTA0 = PORTA.0 #bit PORTA1 = PORTA.1 void main(void) { DDRA0 = 0 ; // set bit 0 of port A as output DDRA1 = 1 ; // set bit 1 of port A as input PORTA0 = 1 ; // set bit 0 of port A to a 1 while(1) { if ( PORTA1 ) // test bit 1 input of port A PORTA0= 0 ; else PORTA0 = 1 ; }
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 25-02-2013, 09:52 PM المشاركة 56   
افتراضي


1-12 أساليب "الزمن – الحقيقى" Real – Time Metheods :
برمجة "الزمن الحقيقى" أحيانا تفقد بناؤها بسبب بعض أنواع المعالجة المعقدة والتى يمكن إجراؤها فقط بواسطة آلات كبيرة وبأنظمةعمل مثل "يونكس" Unix . مع ذلك فإن الأنظمة المدمجة يمكنها , فى كثير من الحالات , التنفيذ على أساس الزمن الحقيقى .
البرنامج البسيط قد يؤدى مساره مرارا وتكرارا . قد يكون قادرا على الاستجابة للتغير بالبيئة التى يعمل بها الأجهزة hardware , ولكنه سوف يفعل ذلك فى الزمن الخاص به شخصيا . يستخدم إصطلاح "الزمن الحقيقى" real – time للإشارة إلى أن مهمة البرنامج قادرة على إجراء كافة المهام بطريق منظمة بداخل توزيع معين للزمن . وقد يشير المصطلح أيضا إلى أن البرنامج له المقدرة "للاستجابة الفورية" للمؤثرات الخارجية ( دخل الأجهزة) .
الميكروكونترولر PIC , الغنى بمجموعة المحيطات , يمتلك القدرة ليس فقط للاستجابة لوحدات "المؤقتات" , ولكن علاوة على ذلك , "لتغيرات الدخل" . قدرة البرنامج للاستجابة لتغيرات هذا "العالم – الحقيقى"
real – world تسمى "مقاطعة" interrupt أو "المعالجة الاستثنائية" .

1-12-1 استخدام المقاطعات Using Interrupts :



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