بسم الله الرحمن الرحيم
(( حل المشكلة ))
أخي الحبيب .. المشكلة بسيطة إن شاء الله
ولكنها تحتاج إلى فهم جزئية معينة في الميكروكنترولر وفي طريقة عمل الميكروسي .
ولتجرب ما أقوله لك لتتأكد ولترى بنفسك .
قم بإنشاء مشروع جديد باستخدام pic16f877a يحتوي على الكود التالي .
كود:
char ahmad_samir[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
};
void main()
{
}
هذا المشروع استخدمنا فيه مصفوفة مكونة من 90 عنصر . وعند القيام بالترجمة لن تحدث أي مشاكل .
والآن قم بإضافة ستة عناصر للمصفوفة وقم بالترجمة
كود:
char ahmad_samir[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6
};
void main()
{
}
أيضا لن تلاحظ أي مشكلة إطلاقا .. الآن أصبحت عدد العناصر 96 عنصر وإذا قمت بإضافة عنصر واحد فقط يقول لك لا توجد ذاكرة تكفي , فتستغرب وتقول كيف مع أنه عندما كان هناك 96 عنصر كان يقول باقي نسبة كبيرة من الرام .
الإجابة ببساطة ذاكرة الرام في الميكروكنترولر مقسمة في عدة أماكن وليست مجموعة من الريجسترات مخزنة متتالية وراء بعضها .
افتح معي الداتا شيت الخاصة بالبك 16f877a الصفحة رقم 19
http://ww1.microchip.com/downloads/e...doc/39582b.pdf
ستجد أربعة أعمدة (جداول) كل جدول مكتوب تحته BANK0 أو BANK1 .. وهكذا
ستجد أن المتغيرات أو الريجسترات التي يمكننا استخدامها كمتغيرات أو عناصر في مصفوفة ... إلخ مقسمة إلى أربعة أجزاء . كل جزء موجود في بنك معين
Bank0 و Bank1 و bank2 و Bank3
هذه المتغيرات اسمها في الداتاشيت general purpose register وتختصر أحيانا بـ GPR
ستجد أنه يوجد 96 عنصر أو متغير في bank0 وتجد 80 عنصر فيbank1 وستجد في بنك 2 و 3 ستة وتسعين عنصر 96 (ستجدهم مقسمين إلى 16 و 80) .
وفي لغة مايكروسي عندما تقوم بتعريف مصفوفة فإنه يضعها لك في بنك يحتوي على 96 عنصر فقط وبالتالي لو قمت بالزيادة عن هذه القيمة وجعلت عدد العناصر 97 لا يستطيع الميكروسي أن يتدارك مشكلة أن البنك انتهت العناصر المتاحة فيه وبالتالي يظهر لك رسالة ويقول أنه لا يوجد ذاكرة كافية وتجده يكتب لك اسم المصفوفة بجوار هذه الرسالة . مع أنه يوجد ذاكرة ويوجد الكثير . لكن البنك امتلأ .
دعنا نفهم الموضوع أكثر ونقوم ببعض التجارب ولكن يجب أن تعرف هذه المعلومة:
يمكنك أن تخزن المصفوفة في مكان محدد من الذاكرة باستخدام الأمر absolute
هذا الأمر يجعل الميكرو يخزن المتغيرات الخاصة بالمصفوفة ابتداءا من العنوان الذي تذكره له .
انظر لبنك واحد في الداتاشيت ستجد أننا يمكننا أن نبدأ في تخزين المتغيرات ابتداءا من العنوان رقم A0 وستجد أنه يمكننا تخزين 80 عنصر بكتابة الكود التالي
كود:
char ahmad_samir[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
}absolute 0xA0;
void main()
{
}
الكود السابق جعلنا نخزن 80 عنصر في الرام RAM ابتداءا من عنوان معين وهو A0 .
والآن لو أضفنا عنصر آخر للمصفوفة السابقة (ستصبح 81 عنصر) ستظهر رسالة خطأ لأن بنك واحد bank1 يحتوي على 80 عنصر فقط .
هل تعلم ماذا سيحدث لو كتبنا نفس الكود السابق (80 عنصر وليس 81)ولكن جعلنا العنوان هو A1 وليس A0 .
سيظهر رسالة خطأ أيضا مع أنه يوجد 80 عنصر في هذا البنك ولكن هم عبارة عن 79 عنصر ابتداءا من العنوا A1 بالإضافة للعنصر الثمانون صاحب العنوان A0 . إذن إذا كتبنا هذا العنوان يمكننا تخزين 79 عنصر في نفس المصفوفة فقط .
وبالمثل لو جعلنا العنوان A2 يمكننا تخزين 78 عنصر فقط .
-- للأسف هكذا تعمل اللغة --
إذن الحل أخي حتى لا أطيل عليك أن تقوم بتقسيم العناصر التي تريد تخزينها في الرام إلى أربعة مصفوفات كل مصفوفة تضعها في بنك معين .
وبهذا يمكنك تخزين 96 عنصر في المصفوفة الأولى والتي تبدأ من العنوان 0X20
يمكنك تخزين 80 عنصر في المصفوفة الأولى والتي تبدأ من العنوان 0XA0
يمكنك تخزين 96 عنصر في المصفوفة الأولى والتي تبدأ من العنوان 0X110
يمكنك تخزين 96 عنصر في المصفوفة الأولى والتي تبدأ من العنوان 0X190
وإليك المثال التالي الذي سيجعلك تستغل 100% من الرام الخاصة بالبك
كود:
//this example show how to use 100% of RAM BY
// make many matrixes each matrix on specefic Bank
// Bank0 has 96 General purpose Register
// Bank1 has 80 GPR
// Bank2 has 96 GPR
// Bank3 has 96 GPR
//
// Written By Eng. Ahmad Samir Fayed
// ahmad_s_f*hotmail.com
/*
لكي تسطيع استخدام الحد الأقصى من
الرام الخاصة بالميكروكنترولر لن تستطيع
فعل ذلك باستخدام مصفوفةواحدة وملأها
بالحد الأقصى من العناصر بل يجب تخزين
هذه العناصر في عدة مصفوفات
كل مصفوفة تخزنها في بنك معين
فمثلابنك صفر حتوي على 96عنصر
إذن يمكنك تخزين 96 عنصر في مصفوفة وتجعل
الميكروكنترولر يخزنهافي عنوان محدد
باستخدام الأمر
absolute
هذاالمثال تم عمله باستخدام الميكروكنترولر
pic16f877a
وبالطبع كل ميكروكنترولر يختلف عن الآخر
العناوين وعدد العناصر المتاحة أي مساحة الرام
إذااستفدت لا تنسانامن دعواتك بالعلم النافع
والصلاح والهدايةوالرزق
أخوكم / أحمدسمير فايد
وأي سؤال راسلني على ايميلي
ahmad_s_f*hotmail.com
*/
// 96 item in Bank0 store data from adress 0x20
char a1[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6
}absolute 0x20;
// 80 item in Bank1 store data from adress 0xA0
char a2[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
}absolute 0xA0;
// 96 item in Bank2 store data from adress 0x110
char a3[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6
}absolute 0x110;
// 96 item in Bank3 store data from adress 0x190
char a4[]={
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6
}absolute 0x190;
void main()
{
}
-------------------------------
تحذير : بالنسبة للمصفوفة الأولى المخزنة ابتداءا من العنوان 20 لا تجعلها أكثر من 96 عنصر مع أنك لو فعلت ذلك لن يعطيك خطأ ERROR ولكن سيفعل مصيبة كبيرة وهو أنه سيخزن بيانات داخل الريجسترات الخاصة التي تؤدي إلى تغير وظيفة الميكروكنترولر . فمن المعلوم أن هناك ريجسترات عامة ( وهي المتغيرات العادية التي نستخدمها ) وريجسترات خاصة لو وضعنا فيها قيمة معينة تجعل الميكرو ينفذ شيء معين مثل TRISA و PORTB و ... إلخ
------------------------------
أريد أن أقول أن التركيب الداخلي للذاكرة في pic18f452 يختلف كثيرا عن pic16f877 لذا يمكنك عمل مصفوفات بحجم أكبر .
لا تنسانا من دعواتك ..
رزقنا الله وإياكم العلم النافع والعمل الصالح وقبل ذلك حبه ورضاه .
-----------------------
بالنسبة للأخ حيدر .. أعتقد أخي أنك قمت باستخدام الروم وليس الرام باستخدام الأمر const قبل تعريف المصفوفة حتى تستطيع تخزين مصفوفة كبيرة كهذا .
التعديل الأخير تم بواسطة : ahmad_s_f بتاريخ 23-07-2010 الساعة 08:50 PM
السبب: لإضافة تعليق على مشاركة الأخ حيدر
|