الان ننتقل الى القسم العملي:
سؤال 1 : قم بعمل عداد يعد من 0-9 ويزداد العد كل ثانية واحدة . النتيجة تظهر على سيفن سيجمنت موصولة الى البورت C .استخدم كريستالة 4 ميجا .
الان الدارة المستخدمة في الملف المرفق :
الجواب :
بما اننا نستخدم كريستالة 4 ميجا فان التردد الذي يعمل عليه البيك هو ربع هذا التردد اي 1 ميجا هيرتز . هذا يعني انه خلال ثانية واحدة فان التايمر يجب ان يعد الى المليون (هل تذكر السؤال الثالث في عمل التايمر كعداد وهو العد الى مليون هنا ياتي دوره ) .
الان باختيار اكبر مجال قسمة وهو 256 وبما ان التايمر زيرو هو سجل 8 بيت ويستطيع العد من 0-255 اي مجاله هو ايضا 256 فان اكبر قيمة يعدها التايمر هي 256*256=65536 وهي اقل من مليون بكثير لذلك نستخدم مجال القسمة لنحصل على المتغير Y حيث ان المتغير يساوي (في هذه الحالة عند تردد 1 ميجا) :
القانون بشكل عام لحساب Yفي حال ان لدينا تكرار معين للنبضات وليكن F ومجال القسمة هو ( 1 : DS ) :
(Y= F / (256*DS
طبعا يتم حساب قيمة Y بعد معرفة التردد المستخدم للكريستالة وقيمة المجال المستخدم . عندها يتم اخد القيمة الصحيحة الاقل والقيمة الصحيحة الاكبر من القيمة المحسوبة ونعوض في القانون السابق نفسه لنعرف اي قيمة اقرب للتردد اي:
F= 256*DS*Y
واقرب قيمة محسوبة من التردد تكون هي افضل قيمة ويتم اختيارها في البرنامج خصوصا اننا يهمنا الدقة والبعد عن الاخطاء . يتم حساب المتغير Y لجميع المجالات الموجودة واختيار افضل قيمة موجودة منها.
ملاحظة مفيدة : عندما تريد اختيار مجال معين فالافضل الا تختار مجال صغير ( لان البعض قد يكتب برنامج مقاطعة طويل نسبيا وبالتالي في خلال حدوث طفحان ثاني يكون البرنامج مازال ينفذ المقاطعة الاولي وبالتالي يحدث خطا) اما ان كان برنامج المقاطعة صغير جدا فيمكن استخدام المجال الصغير .
لقد قمت في السؤال رقم 3 في العداد باستخدام المجال (1:64) والمجال (1:256) اما هنا فلأني اعتمد فقط عملية اختبار المتغير Y ثم تعديل القيمة على البورت C وهي تعليمات بسيطة فساختار هنا مجال (1:2) واكتب البرنامج.
الان نحسب قيمة المتغير Y من العلاقة :
( Y= F / (256*DS
حيث ان عدد النبضات هو F=1000000 هيرتز و DS=2 :
(Y=1000000/(256*2
Y=1953,125
الان نحسب القيمة الناتجة عن المجال والمتغير في حال القيمة الصحية الاقل وهي (1953) :
1953*2*256=999936
الان نحسب القيمة الناتجة عن المجال والمتغير في حال القيمة الصحية الاقل وهي (1954) :
1954*2*256=1000448
بمقارنة القيمتين مع المليون نجد ان القيمة الاولى هي الاقرب وتختلف عن القيمة الحقيقة فقط ب (0,000064( ثانية وبالتالي نختار القيمة الاولى ونكتب البرنامج .
ان فكرة البرنامج كالتالي: حيث نقوم بعمل الاعدادت البورتات وسجلات المقاطعة لكل شي ونقوم باظهار القيمة على البورت C . ان البرنامج ينتقل الى المقاطعة (اي يحدث طفحان في هذه الحالة كل 256*2=512 اشارة خارجية ) ويجب ان يحدث 1953 مرة طفحان لنستطيع العد تقريبا الى ثانية .اذن في المقاطعة سيقوم البرنامج بزيادة المتغير Y كل مرة يدخل فيها المقاطعة .ومن ثم يختبر هذ ا المتغير هل وصل الى 1953 ؟؟؟ فان كانت النتيجة لا فان الزمن لم يصل ثانية بعد ويقوم البرنامج بتصفير علم المقاطعة للتايمر ويعود للبرنامج الرئيسي . اما في حال وصل المتغير الى 1953 فمعناه ان الزمن اصبح ثانية وعندها فقط يزيد القيمة على البورت C بمقدار واحد ويعطي المتغير Y القيمة صفر حتى يبدأ توقيت ثانية من جديد والاختبار للمتغير من جديد وهكذا...هذا باختصار عمل البرنامج والان بالبرنامج كالتالي:
كود:
int y;
void interrupt()
{
y++;
if(y>=1953) { portc++;
if (portc>9) portc=0;
y=0;
}
intcon.f2=0;
}
void main()
{
trisc=0;
portc=0;
tmr0=0;
intcon=0b10100000;
option_reg=0b10000000;
while(1)
{
portc;
}
}
سؤال 2: الان قم بعمل فلاشر على البورت B بحيث يبدا العد من على البورت B من الصفر الى 255 ، ويتم زيادة العدد على البورت B كل نصف ثانية . الكريستالة المستخدمة هي بتردد 32768 هيرتز .
الدارة المستخدمة في الملف المرفق :
الجواب
الان كما قلنا فان التردد الداخل للبيك يقسم على 4 وهكذا ينتج ( 8192) اي كل 8192 هيرتز ينتج لدينا ثانية واحدة .
الان بما اننا نريد ان يحصل العد للفلاشر كل نصف ثانية . وبالتالي فانه خلال ثانية فانه يدخل المقاطعة مرتين اي Y=2 وهكذا من العلاقة نحسب المجال الذي يجب استخدامه حيث F=8192 ، Y=2 :
(DS=F/(256*Y
DS=8192/(256*2)=16
الان بما انه لدينا كل المعلومان ما ينقصنا الا كتابة البرنامج حيث انه كل نصف ثانية فان البيك سيدخل المقاطعة وعندها في المقاطعة نزيد قيمة البورت B حتى يصل الى 255 وهكذا.
وبالتالي البرنامج سيكون كالتالي :
كود:
int y;
void interrupt()
{
y++;
if(y>=2) y=0;
portb++;
intcon.f2=0;
}
void main()
{
trisb=0;
portb=0;
tmr0=0;
intcon=0b10100000;
option_reg=0b10000011;
while(1)
{
portb;
}
}
(يتبع)...