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

   

الصورة الرمزية ahmad_s_f
ahmad_s_f
:: المهندس/ أحمد سمير فايد ::
تاريخ التسجيل: Jun 2006
الدولة: سائح في ارض الله
المشاركات: 632
نشاط [ ahmad_s_f ]
قوة السمعة:
قديم 16-02-2009, 11:25 AM المشاركة 17   
افتراضي



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

اعلانات

الصورة الرمزية ahmad_s_f
ahmad_s_f
:: المهندس/ أحمد سمير فايد ::
تاريخ التسجيل: Jun 2006
الدولة: سائح في ارض الله
المشاركات: 632
نشاط [ ahmad_s_f ]
قوة السمعة:
قديم 16-02-2009, 12:21 PM المشاركة 18   
افتراضي


الرجاء وضع ملف المحاكاه الخاص بالجزء الثاني ... وفقك الله
فقد لاحظت عند تجربتي على الملف الخاص بالمحاكاه (أول ملف) بعد تعديل وصلات السفن سيجمنت .. لاحظت أن العداد يعمل بشكل تنازلي سليم وعند الضغط على السويتش الواصل بـ RB0 مرة واحدة يحدث مقاطعة INTERRUPT وبعد ذلك يمكن الضغط على السويتش الذي يزيد من قيمة العداد .. والسويتش الذي ينقص من قيمة العداد ولكن بعد ذلك لا يكمل البك العد التنازلي تلقائيا حتى بعد الضغط مرة أخرى على السويتش الواصل بـ B0 فهل هذا ما تريده ؟؟...أعتقد لا (طبعا ممكن أن نستمر بالضغط على السويتش الذي ينقص وسينقص تلقائيا كل ثانية تقريبا ..)
لذلك ربما تكون عدلت أنت هذه المشكلة بطريقة ما أو استخدمت طريقة توصيل مختلفة ... لذلك إذا كان هناك طريقة توصيل مختلفة وجربتها على التجربة الثانية أرجو ارسالها أو أخذ صورة لها ...

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

==================================
وفقنا الله جميعا لما يحب ويرضى ورزقنا وإياكم العلم النافع

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

m_mansour2005
:: مهندس متواجد ::
تاريخ التسجيل: Feb 2009
المشاركات: 80
نشاط [ m_mansour2005 ]
قوة السمعة:
قديم 16-02-2009, 02:42 PM المشاركة 19   
افتراضي


بسم الله الرحمن الرحيم
الملف كامل فى الرابط....

ثانيا توضيح دالة الانتربت:
التطبيق على pic16f876 حيث استخدم RB0 Interrupt
الدخول إلى الإنتربت يتم عن طريق الضغط على RB0 وعند الدخول إلى الإنتربت هناك احتمالات ثلاثة
1- الضغط على RA0 لزيادة العداد .
كود:
if(porta.f0)
 {     porta.f2=1;
      if(ones!=9) {porta.f3=1; ones++;}

       else
       {
          if (tens==9) {tens=0xff;}
            ones=0; tens++;
       }
       show();
 }
كود:
else
       {
          if (tens==9) {tens=0xff;}
            ones=0; tens++;
       }
       show();
ELSE : يعنى ONES=9 فلو كان ال TENS كمان ب 9 يعنى 99 على السفن سجمنت فهيكون الضغط على SWITCH الزيادة يحول ال99 ل00

كود:
tens=0xff;
بالنسبة لهذا الأمر تقدر تقول انه -1
لأن الريجيستر بعد مبيكون11111111 لما تزود واحد بيبقى صفر.

2-الضغط على RA1 لإنقاص العداد .
3- الضغط على RB0 مرة ثانية لحفظ الأرقام الحالية بعد الزيادة أوالنقصان أو كلاهما معا داخل ال EEPROM. (لاحظ هذه الخطوة لم اكملها بعد نتيجة لبعض المشاكل كما ذكرت)

إنشاء الله يكون اللى أنا عاوز أقوله قدرت انى اعبر عنه وأنا هكمل بقيت البرنامج انشاء الله . ومنتظر اراءك


الصورة الرمزية ahmad_s_f
ahmad_s_f
:: المهندس/ أحمد سمير فايد ::
تاريخ التسجيل: Jun 2006
الدولة: سائح في ارض الله
المشاركات: 632
نشاط [ ahmad_s_f ]
قوة السمعة:
قديم 16-02-2009, 03:19 PM المشاركة 20   
افتراضي


لماذا استخدمت جملة while بهذا الشكل
كود:
while(portb.f0){}
أرجو شرح الأمر ........وبالنسبة لباقي الأوامر انتظرني فلدي حل آخر (كود آخر) ربما يكون أفضل (وربما كودك أفضل) ولكن دع لي القليل من الوقت لأكتبه لك ...

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

======================================
ملحوظة إملائية بسيطة (خارج موضوعنا) :: يجب أن نكتب "إن شاء الله " بهذا الشكل ولا نكتبها إنشاء لأن إنشاء تعني خلق أو تكوين ..

======================================
رزقنا الله وإياكم العلم النافع ووفقنا جميعا لما يحب ويرضى

والسلام عليكم ورحمة الله وبركاته


m_mansour2005
:: مهندس متواجد ::
تاريخ التسجيل: Feb 2009
المشاركات: 80
نشاط [ m_mansour2005 ]
قوة السمعة:
قديم 16-02-2009, 03:36 PM المشاركة 21   
افتراضي


بسم الله الرحمن الرحيم
بالنسبة للملحوظة الإملائية إن شاء الله اخد بالى منها بعد كده.

كود:
 while(portb.f0){}
لأن الأوامر بتتنفذ بسرعة فانت لو طولت الضغط على السويتش ولو لمدة بسيطة ممكن ينفذ الكود اللى هيكون موجود فى جملة if ال التالية والتى لم انهها بعد3
كود:
else if (portb.f0)
 {

 }
فيه اضافات نسيت احذفها من البرنامج وهى انا بس كنت بجرب بيهم حاجات
كود:
porta.f2=1;
و
porta.f3=1;


الصورة الرمزية ahmad_s_f
ahmad_s_f
:: المهندس/ أحمد سمير فايد ::
تاريخ التسجيل: Jun 2006
الدولة: سائح في ارض الله
المشاركات: 632
نشاط [ ahmad_s_f ]
قوة السمعة:
قديم 16-02-2009, 03:58 PM المشاركة 22   
افتراضي


لاحظت في ملف المحاكاه الذي أرسلته أن السويتش الذي يزود قيمة العداد لا يعمل ولكن بالنسبة للكود السابق الذي لم يكن فيه EEPROM الذي كتبته أنت جربته على برنامج المحاكاه وكان يعمل جيدا .. ( لقد فوجئت أنك استخدمت EEPROM وهي المرحلة الثالثة مع أننا لم ننتهي من المرحلة الثانية) لذلك سيكون الكود الذي سأكتبه لك على المرحلة الثانية وليس الثالثة (أي بدون EEPROM ) إن شاء الله تعالى


m_mansour2005
:: مهندس متواجد ::
تاريخ التسجيل: Feb 2009
المشاركات: 80
نشاط [ m_mansour2005 ]
قوة السمعة:
قديم 16-02-2009, 04:27 PM المشاركة 23   
افتراضي


بسم الله الرحمن الرحيم
البرنامج الذى انا قمت بارساله كتابة وليس الملف صحيح ويعمل.ولكن
هذا الملف المرفق ليس به البرنامج فقط وانما به بعض التعديلات تجهيزا للمرحلة الثالثة وهى كالإتى
كود:
else if (portb.f0)
 {
       while (portb.f0) {}

       EEprom_write(0x00,ones);
       delay_ms(20);
       EEprom_write(0x00,tens);
       delay_ms(20);
       return;
 }
وهذه هى المشكلة التى تحدثت عنها باستمرار حيث ان البرنامج يعمل جيدا بدون الكود السابق ولكن عند اضافة هذا الكود يتوقف زر الزيادة عن العمل.

وايضا فى ملف المحاكاة تاكد من ان سويتش الزيادة ليس مضغوط..

انا اعتذر ولكنى لم اتذكر اننى قمت بالتعديل على البرنامج وقمت برفعه لك بمجرد طلبك

*********
نسيت ان اسأل هل توجد اعدادات للبروتس من اجل الكتبة فى ال eeprom حيث انه يدخل فى دالة ال write ولا يخرج على ما اعتقد...
هذا ليس خروجا عن الموضوع ولكن من اجل تجهيز المرحلة التالية........


التعديل الأخير تم بواسطة : m_mansour2005 بتاريخ 16-02-2009 الساعة 04:36 PM

الصورة الرمزية ahmad_s_f
ahmad_s_f
:: المهندس/ أحمد سمير فايد ::
تاريخ التسجيل: Jun 2006
الدولة: سائح في ارض الله
المشاركات: 632
نشاط [ ahmad_s_f ]
قوة السمعة:
قديم 17-02-2009, 02:15 AM المشاركة 24   
افتراضي الحمد لله ... يرزق من يشاء بغير حساب


بسم الله الرحمن الرحيم

أخي العزيز m_mansour2005 :
الكود الذي كتبته أنت الخاص بالجزء الثاني والذي هو
كود:
unsigned char B[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; unsigned char ones,tens; void show() { portb=B[tens]; portc=B[ones]; delay_ms(1000); } void interrupt() { while(portb.f0){} // debounce begin: if(porta.f0) { porta.f2=1; if(ones!=9) {porta.f3=1; ones++;} else { if (tens==9) {tens=0xff;} ones=0; tens++; } show(); } else if (porta.f1) { if(ones!=0) {ones--;} else { if(tens==0){tens=10;} ones=9; tens--; } show(); } else if (portb.f0) { } else {goto begin;} } void main() { intcon.f7=1; intcon.INTE=1; //rb0 interrupt adcon1=0x06; trisa=0x03; // porta 0,1 as switches trisb=0x01; trisc=0; start: tens=1; ones=5; test: show(); if(tens==0 && ones==0) {goto start;} if(ones==0) {tens--; ones=9 ;goto test;} ones--; goto test;
كود جيد ... ولكن ستكون وظيفته هي كما أخبرتني
التطبيق على pic16f876 حيث استخدم RB0 Interrupt
الدخول إلى الإنتربت يتم عن طريق الضغط على RB0 وعند الدخول إلى الإنتربت هناك احتمالات ثلاثة
1- الضغط على RA0 لزيادة العداد .
2-الضغط على RA1 لإنقاص العداد .
3- الضغط على RB0 مرة ثانية لحفظ الأرقام الحالية بعد الزيادة أوالنقصان أو كلاهما معا داخل ال EEPROM. (لاحظ هذه الخطوة لم اكملها بعد نتيجة لبعض المشاكل كما ذكرت)
وإليك الكود الذي كتبته والذي يؤدي نفس الوظيفة السابقة لكن مع تعديل طريقة كتابة الكود ...

حيث أنني في هذا الكود جعلت هناك أربعة دوال وهم :-

1- الدالة الخاصة بالانتربت
2- الدالة الخاصة بالعرض على السفن سيجمنت show
3- الدالة الخاصة بزيادة العدد ( تزيد واحد ) increment
4- الدالة الخاصة بتنقيص العدد (تنقص واحد) decrement

هذا طبعا بالإضافة للدالة الرئيسية للبرنامج ...
لماذا استخدمت هذه الدوال؟؟ لتسهيل العمل والتعديل وكذلك لزيادة التنسيق ولسرعة الفهم ..
فمثلا عند الضغط على السويتش الواصل بـ a0 سوف يزيد واحد وذلك عن طريق استدعاء الدالة التي تزيد من القيمة الحالية بمقدار واحد كما في الكود التالي
كود:
if(porta.f0==1){while(porta.f0==1){}increment();show();}
ستلاحظ استخدامي للأمر while وذلك حتى لا يزيد البرنامج من القيمة إلا بعد رفع اليد من على السويتش ( المفتاح ) حيث يزيد من القيمة مرة واحدة فقط.
ستلاحظ أن هذه الطريقة (التي كتبت بها الكود) سهلة الفهم جدا ... فالكود السابق يعني لو ضغطت على السويتش انتظر حتى ارفع يدي من عليه ثم زود واحد عن طريق استخدام الدالة Increment وبعد ذلك اعرض القيمة الجديدة على السفن سيجمنت عن طريق استخدام الدالة show .
وبنفس الطريقة سنكتب الكود الخاص بالسويتش الثاني ولكن مع استخدام الدالة decrement والتي تنقص واحد
كود:
if(porta.f1){while(porta.f1){}decrement();show();}
وأيضا في الدالة الرئيسية نستخدم الدالة decrement حتى لا أطيل في شرح هذه النقطة إليك الآن الكود الخاص بالجزء الثاني والذي يؤدي نفس الوظيفة التي ذكرتها أنت .

كود:
unsigned char B[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; unsigned char ones,tens; void show() { portb=B[tens]; portc=B[ones]; } void increment(){if(ones==9 && tens==9) {tens=0;ones=0;show();} else if (ones==9){ones=0; tens++; show();} else ones++; } void decrement(){if(tens==0 && ones==0) {tens=1;ones=5;show;} else if(ones==0) {tens--; ones=9 ;show;} else ones--; } void interrupt() { if(porta.f0){while(porta.f0){}increment();} if(porta.f1){while(porta.f1){}decrement();} show(); } void main() { intcon.f7=1;intcon.INTE=1;adcon1=0x06;trisa=0x03;trisb=0x01; trisc=0; // initaliztion tens=1; ones=5; start: show(); delay_ms(1000); decrement(); goto start; }
وستلاحظ أنني عدلت في الدالة show عن المرة السابقة فلم أضع الأمر الذي ينتظر.
والميزة الأكبر في الكود السابق أن دالة الانتربت ستجدها صغيرة جداً وليست طويلة بالإضافة أنها سهلة الفهم ...

وكما قلت لك سابقاً أنت حر في رأيك فقد ترى أن برنامجك أفضل وقد ترى أن برنامجي أفضل أو تخلط بينهم ...

من مزايا الكود السابق أنك لو أردت أن تجعل هذا العداد عداد تصاعدي بدلا من تنازلي كل ما عليك فعله هو تغيير أمر واحد في الدالة الرئيسية فتغير الأمر الذي يستدعي الدالة decrement وتجعل بدلا منها decrement كما يلي
كود:
start: show(); delay_ms(1000); increment(); goto start;
والآن أريد أن أسألك سؤال قبل الإنتقال للمرحلة الثالثة وهو :
لماذا تريد استخدام eeprom ... هل لغرض تعليمي فقط أم لإنجاز هذا المشروع ؟.. إذا كان الهدف هو إنجاز هذا المشروع فلدي حلول تجعلك لا تستخدم eeprom ولا تستخدم الانتربت أيضا لو أردت ؟؟

إذا كانت وظيفة الـ eeprom هي أنها تسجل آخر قيمة (في دالة الانتربت) وبعد الرجوع من الانتربت تقرأ القيمة الموجودة في eeprom لتكمل العد .. فإذا كانت هذه فقط هي الوظيفة المطلوبة فلا داعي لاستخدام eeprom (إلا إذا كان ذلك لغرض تعليمي أو تجريبي ) ...

المهم ... لقد كتبت كود آخر يقوم بما يلي :
1- عداد تنازلي أوتوماتيكي .
2- عند الضغط على السويتش الواصل بـ rb0 مرة واحدة يتوقف العداد وينتظر البك مدة معينة حوالي خمسة وعشرين ثانية خلال هذه المدة يسمح لك بالضغط على سويتش واصل بـ a0 ليزيد القيمة أو a1 لينقص القيمة .
3- عند الضغط مرة أخرى على السويتش الواصل بـ rb0 سيكمل البرنامج العد من القيمة التي عدلناها (آخر قيمة)
وهذا الكود لا يستخدم eeprom وهو يشبه الكود السابق ولكن مع تعديل معين وفكرة غريبة من نوعها (ألهمني الله إياها) ستجدها في الكود .

وإليك الآن هذا الكود

كود:
unsigned char B[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; unsigned char ones,tens; void show() { portb=B[tens]; portc=B[ones]; } void increment(){if (ones==9 && tens==9) {tens=0;ones=0;show();} else if (ones==9){ones=0; tens++; show();} else ones++; } void decrement(){if(tens==0 && ones==0) {tens=1;ones=5;show;} else if(ones==0) {tens--; ones=9 ;show;} else ones--;} void interrupt() { char x; while(portb.f0==1){} for(x=0;x<255;x++){ if(porta.f0){while(porta.f0){}increment();show();} else if(porta.f1){while(porta.f1){}decrement();show();} else {while(portb.f0){delay_ms(1000);x=254;}} delay_ms(100); } INTCON.INTF=0; } void main() { intcon.f7=1;intcon.INTE=1;adcon1=0x06;trisa=0x03;trisb=0x01; trisc=0; // initaliztion tens=1; ones=5; test: show(); delay_ms(1000); decrement(); goto test; }
الآن للخروج من الانتربت والعودة إلى الدالة الرئيسية سنستخدم الأمر التالي
كود:
INTCON.INTF=0;
ارجع للداتا شيت (جزء الانتربت) إذا لم تكن تعرف الأمر السابق جيدا.

والآن هناك جملة for تقوم بتكرار عملية الاختبار(اختبار السويتشات) عدد معين من المرات وفي كل مرة ينتظر البك 100 ملي ثانية ( ليكون هذا الزمن للتأخير ) حتى لا تنفذ جملة for بسرعة رهيبة .. ولكن المشكلة كيف أخرج من جملة for لأنني أحتاج لذلك ..

فعند الضغط على السويتش b0 مرة أخرى لابد من الخروج من الانتربت أي لابد من الخروج من جملة for
وللخروج من جملة for استخدمت فكرة أعتقد أنها جميلة ألهمني الله بها وهي أن أجعل قيمة المتغير x وهو المسؤول عن عملية التكرار أجعله يساوي 254 وبالتالي لن يتحقق الشرط اللازم لعملية التكرار

x<255

أي سأخرج من جملة for وبالتالي ينفذ البك الأمر الذي يلي جملة for وهو المسؤول عن الخروج من الانتربت .

أرجو أن تكون فهمت هذه الفكرة ..

وأرجو أن تكون استفدت من هذه الأكواد التي كتبتها وأسأل الله أن يوفقنا جميعا لما يحب ويرضى وأن يجعل عملنا خالصا لوجه الكريم وأن يرزقنا وإياكم العلم النافع ويبارك لنا فيه ..

والسلام عليكم ورحمة الله وبركاته .


التعديل الأخير تم بواسطة : ahmad_s_f بتاريخ 17-02-2009 الساعة 02:53 AM


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