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

أدوات الموضوع

أشرف الخطيب
:: مهندس متواجد ::
تاريخ التسجيل: Mar 2009
الدولة: مصــــــــــــــــــــــــــــــر
المشاركات: 195
نشاط [ أشرف الخطيب ]
قوة السمعة:0
قديم 21-06-2009, 06:07 PM المشاركة 65   
افتراضي



أخى الحبيب فادى ..... ماشاء الله عليك .. دائما عندك الجديد والمفيد

ربنا يجزيك كل خير ...

اعلانات

Eagle69
:: مهندس متواجد ::
تاريخ التسجيل: May 2009
المشاركات: 114
نشاط [ Eagle69 ]
قوة السمعة:0
قديم 21-06-2009, 07:57 PM المشاركة 66   
افتراضي


بارك الله فيك يا اخ فاديوجزاك الله خيرا
وفي ميزان جسناتك

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

geniusse01
:: عضو ذهبي ::
تاريخ التسجيل: Apr 2008
الدولة: Jordan - Amman
المشاركات: 1,139
نشاط [ geniusse01 ]
قوة السمعة:106
قديم 27-06-2009, 05:39 PM المشاركة 67   
افتراضي مقاطعة التايمر زيرو كمؤقت زمني


السلام عليكم

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

عمل التايمر كمؤقت زمني :

ان عمل التايمر زيرو بشكل اساسي يعتمد ايضا على السجل OPTION_REG وهو يختلف بشكل بسيط عن عمل التايمر كعداد وتوضيح ذلك في الصورة التالية(هي نفس الصورة السابقة عند عمل التايمر كعداد) :



وان ما يهمنا هو البتات التالية:

بيت رقم 5 : وهو البيت الذي يحدد مصدر الاشارة هل هو خارجي ( ياخذ العد فقط من خلال RA4 اي من خلال البين رقم 4 في البورت A فقط ) ويتم هذا بوضع 1 في هذا البيت .. ام مصدرها داخلي (من الكريستالة الموصولة مع البيك ) ويتم هذا بوضع القيمة صفر في هذا البيت .

بيت رقم 3 : وهو البيت الذي يحدد هل مجال القسمة الموجود سيكون للتايمر زيرو او لمؤقت كلب الحراسة (WDT) كما يسمى . وبما اننا سنسنخدم التايمر زيرو كعداد فنحدد مجال القسمة للتايمر زيرو بوضع القيمة صفر في هذا البيت؟ اما في حال اردنا ان يكون مجال القسمة للتايمر زيرو (1:1) اي كل اشارة دخل يعدها التايمر ب 1 فانه نقوم باعطاء مجال القسمة لمؤقت كلب الحراسة وذلك يتم بوضع القيمة 1 في هذا البت.

البتات من 2 – 0 : وهي البتات المسؤولة عن مجال القسمة للنبضات القادمة الى تايمر زيرو ويتم استخدام الجدول الموجود في الصورة السابقة لمعرفة المجال الذي نريد استخدامه حسب المتطلبات لما نريد.كما نرى فالجدول يتكون من 3 اعمدة .نحن يهمنا العمود الايسر والاوسط ؟ اما الايمن فيخص WDT ولا يهمنا معرفته.

نلاحظ ان البيت رقم 4 لا يستخدم هنا على عكس العداد ، حيث ان المؤقت الزمني لا يهم فيه تحديد اتجاه اشارة الساعة وانما يتكفل البيك بذلك لذلك هذا البيت لا يهم ما نضع فيه من قيمة لانها لن توثر.

طبعا مجال القسمة هنا يعمل نفس عمله السابق بحدث انه عند تحديد مجال قسمة معين فان التايمر يزداد بمقدار 1 مع كل قيمة واحد للمجال اي :

على فرض اننا اخترنا مجال معين وليكن(1:16) فان هذا يعني انه كل 16 اشارة خارجية فان التايمر زيرو سيزداد بمقدار واحد . يعني اول 16 سيصبح واحد وثاني 16 سيصبح 2 وثالث 16 سيصبح 3 وهكذا .وبالتالي لمعرفة عدد الاشارات الخارجية فاننا نقوم بضرب القيمة في التايمر زيرو بقيمة المجال للحصول على القيمة بشكل تقريبي.

الان عند بتفعيل المقاطعة للتايمر زيرو من سجل المقاطعات INTCON (بالاضافة الى تفعيل علم المقاطعة العام وتصفير اعلام المقاطعة) وعند وضع الاعدادت المناسبة في المسجل OPTION_REG فانه ستحدث المقاطعة ايضا عندما تتغير قيمة العد في التايمر زيرو من 255 الى صفر .

الان في حال اردنا ان نعد باستخدام التايمر زيرو وبدون استخدام مجال قسمة فنضع القيمة 1 في البت رقم 3 من هذا المسجل (اي جعلنا مجال القسمة تابع لمؤقت الحراسة ،وبما انه لا يوجد سوى مجال قسمة واحدة اعطيناه لمؤقت الحراسة فان التايمر زيرو يعد بدون اي مجال قسمة اي (1:1) ).

ان استخدام المجال (1:1) يسمح بالحساب الدقيق لعدد النبضات الداخلة ،اما استخدام مجال تقسيم معين مثلا (1:4) فان هذا يعني انه كل اربع نبضات فان التايمر يعد بمقدار 1، وبالتالي اذا كان عدد النبضات الداخلة عن طرق الطرف RA4 مثلا 4 او 5 او 6 او 7 فان القيمة الموجودة في التايمر زيرو هي 1 وبالتالي ينتج لدينا نسبة خطا حسب المجال فهنا لدنيا نسبة خطا 3 نبضات (5 \6\7) ولهذا يتم استخدام نسبة التقسيم والطفحان معاً للحصول على اقرب قيمة ممكنة من القيمة المطلوبة للزمن (هناك حل اخر سنطرحه في الاسئلة في هذا الدرس) ، وبما ان مجال التقسيم مع مجال التايمر زيرو لا يكفي للحصول على زمن كبير نسبيا (مثلا لا يمكن ان يصل الى ثانية واحدة بالنسبة للزمن ) فانه يتم استخدام متغير (وليكن Y ) بحيث انه عند حدوث طفحان للموقت يزداد التايمر زيرو بمقدار واحد .

ملاحظة مهمة : ان تردد الكريستالة عندما يدخل الى البيك يتم تقسيمه على 4 دائما ، وبعد القسمة على 4 تصل اشارة الكريستالة الى مجال القسمة ثم الى التايمر . لهذا قبل البدء في اي حسابات نقوم بقسمة تردد الكريستالة على 4 وبعدها نحسب اعتمادا على الرقم الناتج .ولكن ما معني تردد الكريستالة ؟؟؟
ان التردد هو عدد تكرار الاشارة خلال ثانية واحدة .فعندما نقول ان تردد اشارة ما هو 50 هيرتز فهذا يعني ان الاشارة نفسها تتكرر 50 مرة كل ثانية واحدة . ويمكن تشبيهها بالصف الدراسي فعدد الطلاب اليوم هو نفس عدد الطلاب غدا وهكذا طوال الفصل الدراسي(طبعا دون ان يغيب احد الطلاب ويخرب العلاقة هههههههههه) وبالتالي يتم الحصول على نفس عدد النبضات في كل ثانية ولا تتغير..

(يتبع ) ...


التعديل الأخير تم بواسطة : geniusse01 بتاريخ 27-06-2009 الساعة 05:44 PM

geniusse01
:: عضو ذهبي ::
تاريخ التسجيل: Apr 2008
الدولة: Jordan - Amman
المشاركات: 1,139
نشاط [ geniusse01 ]
قوة السمعة:106
قديم 27-06-2009, 05:47 PM المشاركة 68   
افتراضي تكملة1: مقاطعة التايمر زيرو كمؤقت زمني


الان ننتقل الى القسم العملي:

سؤال 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;
}
}
(يتبع)...


التعديل الأخير تم بواسطة : geniusse01 بتاريخ 27-06-2009 الساعة 05:53 PM

geniusse01
:: عضو ذهبي ::
تاريخ التسجيل: Apr 2008
الدولة: Jordan - Amman
المشاركات: 1,139
نشاط [ geniusse01 ]
قوة السمعة:106
قديم 27-06-2009, 05:56 PM المشاركة 69   
افتراضي تكملة2: مقاطعة التايمر زيرو كمؤقت زمني


سؤال 3 : اكتب برنامج باستخدام المقاطعة يقوم بتشغيل موتور ماء (موصول مع الطرف RB0) عند الضغط على مفتاح (موصل مع الطرف RC0) ويطفىء تلقائيا بعد ساعة واحد بالضبط. استخدم كريستالة بتردد 32768 هيرتز لذلك.


الدارة المستخدمة في الملف المرفق:





(معلومات اضافية ) :

كما لاحظنا فان هناك خطا حتى لو كان بسيط عند استخدام كريستالة 1 ميجا لحساب ثانية واحدة ويتم التغلب عليها كالتالي :

الان الحل الثاني للحصول على زمن ثانية واحدة بالضبط دون وجود اي كسور هو استخدام كريستالة بتردد 32768 هيرتز .

الان كما قلنا فان التردد الداخل للبيك يقسم على 4 وهكذا ينتج ( 8192) اي كل 8192 هيرتز ينتج لدينا ثانية واحدة .

نحسب قيمة المتغير Y من العلاقة السابقة وباختيار مجال قسمة (1:32) يكون :
Y=8192/(256*32)=1
بما ان المتغير يساوي 1 ، فان المقاطعة تحدث كل ثانية واحد ة بالضبط ، ولا داعي لاستخدام متغير ، وهكذا نتغلب على مشكلة الخطا في الحسابات ونحصل على زمن ثانية واحدة بدون اي خطأ .

نهاية المعلومات الاضافية.

من المعلومات السابقة نجد ان التردد الذي سنتعامل معه هو 8192 هيرتز ونسبة التقسيم (1:32) وهكذا تحدث مقاطعة كل ثانية واحد بالضبط.

الان نريد برنامج فقط عن الضغط على المفتاح RC0 يقوم بتشغيل الليد على الخرج RB0 ويحسب ساعة كاملة وبعدها يطفىء الخرج وينتظر المفتاح ان يضغط من جديد.

البرنامج كالتالي :
كود:
char time=0,start=0;
void interrupt()
{
start=1;
time++;
if(time>=3600)
{  intcon=0;
time=0,start=0;
portb.f0=0;}

intcon.f2=0;
}
void main()
{
trisb.f0=0;
trisc.f0=1;
portb.f0=0;

while(1)
{
if(!portc.f0)
    {
        if(start!=0) goto end;
         tmr0=0;
         intcon=0b10100000;
         option_reg=0b10000100;
         end :
         portb.f0=1; }
}
}

ملاحظة : ملفات المشروع موجود على الرابط التالي لمن اراد تجربة المشروع وان يرى كيفية عمله وعمل المقاطعة ولاي استفسار ..الرابط التالي للاسئلة هو :

جواب السؤال الاول:

http://arabsh.com/9uedfmv0zywu.html

جواب السؤال الثاني:

http://arabsh.com/03zbtjb3ghsh.html

جواب السؤال الثالث:

http://arabsh.com/ktagy7yw63fu.html

ومع السؤال الثالث انتهى شرح المقاطعات الثلاث وهي :
1) مقاطعة الطرف RB0.
2) 2)مقاطعة الاطراف RB4\RB5\RB6\RB7
3) مقاطعة التايمر واستخدامه كعداد خارجي او مؤقت زمني .

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

ارجو من الله ان يرزقنا جميعا الاخلاص في العمل ويرزقنا خير الدنيا والاخر .. انه ولي ذلك والقادر عليه.. باسمك اللهم وبحمدك .
نشهد ان لا اله الا انت .. نستغفرك ونتوب اليك.

وآخر دعوانا ان الحمدلله رب العالمين .. وصلى الله على سيدنا محمد وعلى اله وصحبه وسلم.


الصورة الرمزية عطية حسن محمود
عطية حسن محمود
:: عضو ذهبي و مشرف سابق لورشة صيانة التلفزيون ::
تاريخ التسجيل: Aug 2005
المشاركات: 1,073
نشاط [ عطية حسن محمود ]
قوة السمعة:124
قديم 27-06-2009, 09:05 PM المشاركة 70   
افتراضي


تسلم ايديك اخى فادى
ملف الافوميتر كامل كما طلبته وبه الكثير من المقاطعات
ارجو دراسته وتصحيحه والكود تم نجميعه من عدة مواقع
http://filaty.com/f/906/32365/FADY.rar.html
جزاك الله خيرا


mizort1989
:: مهندس متواجد ::
تاريخ التسجيل: Mar 2009
المشاركات: 70
نشاط [ mizort1989 ]
قوة السمعة:0
قديم 09-08-2009, 03:01 PM المشاركة 71   
افتراضي


جزاكم الله خيرا علي الدرس الرائع


mizort1989
:: مهندس متواجد ::
تاريخ التسجيل: Mar 2009
المشاركات: 70
نشاط [ mizort1989 ]
قوة السمعة:0
قديم 11-08-2009, 10:39 AM المشاركة 72   
افتراضي


اشكرك مجددا اخي علي الموضوع الرائع

بعد القراءه المتأنيه للمشروع اريد ان اخد رأيك في مشكلتي

انا بعمل فك شفره لريموت سوني اللي بيستخدم sirc protocol

و ده شكل الإشاره الداخله للميكرو



و ديه مواصفات الواحد و الصفر و الوقت بين كل اشاره و الثانيه


كما تري ان الإشاره لو طولها 1.2 ms تبقي بتمثل 1

و لو طولها 0.6 ms تبقي بتمثل 0 و بين كل واحده و التانيه 0.6 ms

فأنا بعمل برنامج يقيس عرض الإشاره

المشكله دلوقتي

1- اشتغل بال RB0 و لا ب TMR0

علما بأني مش هبقي عارف عرض الإشاره اللي قادمه ممكن 1.2 ms او 0.6 ms

هنفرض اني هشتغل علي RB0 و الrising edge يعني من 0 الي 5 فولت

انا فكرت اعمل حاجه زي كده

كود:
int xx,c=0; char sig[13]; for(xx=0;xx<13;xx++) { val = !testBit(PORTB,0); while(val==1) { c++; delay_us(1); ` } switch(c) case 2400: sig[xx]='i'; goto n_sig; case 1200: sig[xx]='1'; goto n_sig; case 600: sig[xx]='0'; goto n_sig; default: goto no_sig; n_sig: delay_us(600); }
الval ده هيبقي متخزن فيه قيمه البورت في اللحظه ديه بواحد او بصفر

بس السؤال هل اعمل عداد c

و اعمل بعده delay هيكون دقيق كفايه

و لو فيه حل اخر بالTMR0 يا ريت تقوله

كمان حاجه

فيه ناس قالتلي ممكن تستعمل TMR1 بس انا مش فاهمه لسه فلو عندك عنه معلومات يبقي جزاكم الله خيرا

و شكرا مجداا


التعديل الأخير تم بواسطة : mizort1989 بتاريخ 11-08-2009 الساعة 10:42 AM
إضافة رد

العلامات المرجعية

«     الموضوع السابق       الموضوع التالي    »
أدوات الموضوع

الانتقال السريع إلى


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

Powered by vBulletin® Version 3.8.6, Copyright ©2000 - 2025