بسم الله الرحمن الرحيم
أخي العزيز 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;
}
الآن للخروج من الانتربت والعودة إلى الدالة الرئيسية سنستخدم الأمر التالي
ارجع للداتا شيت (جزء الانتربت) إذا لم تكن تعرف الأمر السابق جيدا.
والآن هناك جملة for تقوم بتكرار عملية الاختبار(اختبار السويتشات) عدد معين من المرات وفي كل مرة ينتظر البك 100 ملي ثانية ( ليكون هذا الزمن للتأخير ) حتى لا تنفذ جملة for بسرعة رهيبة .. ولكن المشكلة كيف أخرج من جملة for لأنني أحتاج لذلك ..
فعند الضغط على السويتش b0 مرة أخرى لابد من الخروج من الانتربت أي لابد من الخروج من جملة for
و
للخروج من جملة for استخدمت فكرة أعتقد أنها جميلة ألهمني الله بها وهي أن أجعل قيمة المتغير x وهو المسؤول عن عملية التكرار أجعله يساوي 254 وبالتالي لن يتحقق الشرط اللازم لعملية التكرار
x<255
أي سأخرج من جملة for وبالتالي ينفذ البك الأمر الذي يلي جملة for وهو المسؤول عن الخروج من الانتربت .
أرجو أن تكون فهمت هذه الفكرة ..
وأرجو أن تكون استفدت من هذه الأكواد التي كتبتها وأسأل الله أن يوفقنا جميعا لما يحب ويرضى وأن يجعل عملنا خالصا لوجه الكريم وأن يرزقنا وإياكم العلم النافع ويبارك لنا فيه ..
والسلام عليكم ورحمة الله وبركاته .