بسم الله الرحمن الرحيم
انا هشرحلك الدالتين دول لانهم مرتطبتين مع بعض
كود:
unsigned char get_sony_byte(char nbits){
char n;
unsigned char ir_byte;
unsigned int temp_ir;
ir_byte = 0; // initialise
for(n=0 ; n<nbits ; n++){
temp_ir = get_space(); // expect ~510uS
temp_ir = get_mark();
ir_byte >>= 1; // 650uS = 0, 1.2uS = 1
if ((temp_ir > 1000)&&(temp_ir < 1300)) {
ir_byte += 0x80;
}
}
ir_byte >>= 8-nbits;
return ir_byte;
}
void sony_read(){
unsigned int temp_ir;
ir_result[0] = 0; // return 0, 0 if glitch
ir_result[1] = 0; // return 0, 0 if glitch
while(ir_in); // wait for IR to go low
temp_ir = get_mark();
if((temp_ir>2000)&&(temp_ir<3000)) { // expect 2.4mS mark
ir_result[0] = get_sony_byte(7); // 7 bit command
ir_result[1] = get_sony_byte(5); // 5 bit address
Delay_ms(10); // wait for repeat messages to clear
}
}
نبدء من الداله
كود:
unsigned int temp_ir;
اولا
عرفت متغير بقيمة 1 بايت اى 8 بت لاستخدامة فى جلب النتائج
ثم
كود:
ir_result[0] = 0;
ir_result[1] = 0;
قمت بعمل تصفير للمتغيرين دول والى هيتحفظ فيهم قيم الاوامر سواء كومند او ادريس
ثم
اخبرته اذا كان الجهد 5 فولت على مدخل المستقبل ((اى لا يوجد ارسال))
لا تفعل اى شىء وانتظر واذا اتت نبضات سوف يتغير حال المدخل من 5 فولت الى صفر وعندها يبدء فى تنفيذ الاوامر الاخرى
وهى
كود:
temp_ir = get_mark();
اجعل قيمة المتغير temp_ir تساوى قيمة الداله get_mark()
والتى تحسب عرض النبضة
ثم يعود ليختبرها
كود:
if((temp_ir>2000)&&(temp_ir<3000))
اذا كانت قيمة المتغير لا تنحصر بين 2000 ميكرو ثانية و 3000 ميكرو ثانية
لا تفعل شىء واعد تكرار البرنامج من جديد
اما اذا كانت تنحصر بين 2000 ميكرو ثانية و 3000 ميكرو ثانية وهو عرض النبضة لريموت سونى
نفذ الاوامر التى بداخل جملة IF
واول هذه الاوامر هو
كود:
ir_result[0] = get_sony_byte(7);
اجعل قيمة المتغير
تساوى الناتج من حسابات الداله
وسوف تعرف فائدة الرقم 7 فى شرح الدالة
نذهب الان الى الداله لاجراء الحسابات ثم العودة بالنتائج
كود:
unsigned char get_sony_byte(char nbits)
هنا قلت له عرف الداله ثم اجعل قيمة المتغير nbits الذى بداخل القوسيين
يساوى نفس القيمة المكتوبة داخل قوسيين الداله الى هو فى الحالة دى 7
ودة فائدة كتابة الرقم 7
ولكن اية فائدتة الفعلية هذا داخل الشرح
ثم
كود:
char n;
unsigned char ir_byte;
unsigned int temp_ir;
عرفت هذه المتغيرات لاستخدامها فى الحسابات
ثم
جعل قيمة المتغير ir_byte تساوى صفر لاستخدامة فى الحسابات
ثم
كود:
for(n=0 ; n<nbits ; n++){
اعمل حلقة تكرار بعدد المتغير nbits
وهنا فائدتة الفعلية
انت تعلم ان بروتوكول سونى يرسل 7 اوامر كومن وبعد ذلك 5 ادريس
ولهذا نحتاج ان نكرر عملية قراءة البيانات 7 مرات وهى عدد بتات الاوامر
ثم
كود:
temp_ir = get_space();
وهو امر معرفة قمية الفواصل بين النبضات
وهى ليست هامة ولكن يجب حسابها حتى لا يحدث خطا
ثم
كود:
temp_ir = get_mark();
وهى لجعل قيمة المتغير temp_ir يساوى قيمة الداله get_mark()
وهى داله حساب عرض النبضة
ثم
اى قم بعمل ازاحة بقيمة 1 بت للمتغير والازاحة هى هكذا
00100000 فاذا اخبرنا البك بعمل ازاحة له تكون هكذا 00010000
اى انتقل الرقم 1 الى البت المجاور لة
ثم
كود:
if ((temp_ir > 1000)&&(temp_ir < 1300))
اختبر قيمة المتغير اذا كان تنحصر بين 1000 ميكرو ثانية و 1300 ميكرو ثانية
اى ان قيمة البت تساوى 1 نفذ الاوامر
قم باضافة 1 فى هذا البت
ثم عد مرة اخرى للتكرار
اما اذا كان قيمة المتغير لا تنحصر بين 1000 ميكرو ثانية و 1300 ميكرو ثانية
اى البت يساوى 0
لا تفعل شىء وعد من جديد
وهنا لنا وقفة بسيطة
كما قلت لك البرنامج قام فى البدء بعمل ازاحة ولتكن مثلا هكذا
10000000 وبعد الازاحة اصبحت هكذا
01000000
فاذا كان البت المستقبل يساوى واحد سوف يقوم الامر
باضافة واحد فى اول بت اى هكذا 11000000
واذا كان البت يساوى 0 فلن يفعل شىء وهو بذلك اصلا اضافة 0 كما ترى فى الاعلى
ويكرر الاوامر هذه 7 مرات
وعند الانتهاء
يجد هذا الامر
كود:
ir_byte >>= 8-nbits;
وفائدتة هى
ببساطة كما تعلم ان ان المتغير بقيمة بايت اى 8 بت
وهنا الاوامر 7 فقط
اذا اذا كانت الاوامر تساوى 1 بالديسمال
فيجب انت تكون هكذا 00000001
ولكن نحن قمنا بعمل 7 ازاحات فقط فسيصبح هكذا
00000010
اذا نحتاج لامر لكى يقوم بجعل قيمة المتغير صحيحة
وهذه فائدة هذا الامر
انهى يطرح قيمة ال nbits والذى قيمتة 7 من عدد البتات داخل البايت وهى 8
والناتج يقوم بعمل ازاحة به
والناتج هنا 1 اذا سوف يقوم بعمل ازاحة بمقدار 1 بت
اذا سوف يصبح الناتج هكذا
00000001
ثم يعود الى الداله sony_read()
ويجعل قيمة المتغير ir_result[0] تساوى هذه القيمة
وينزل الى الامر الذى يلية وهو
كود:
ir_result[1] = get_sony_byte(5);
فيعود ليكرر نفس الكلام ولكن هذه المرة قيمة
nbits
تساوى 5
اذا سوف يكون التكرار 5 مرات وهذه المرة هو عدد بتات الادريس
وعند النهاية سوف يجد الامر
كود:
ir_byte >>= 8-nbits;
وكما تعلم بعد عمل ازحة 5 مرات
مثلا اذا كانت قيمة بتات الادرس بالديسمال تساوى 1
اى يجب ان تكون هكذا
00000001 ولكن الازاحة كانت 5 مرات فقط يعنى هيصبح هكذا 00001000
ونحتاج لتعديل القيمة
وهذا فائدتة الامر
سوف يطرح قيمة المتغير nbits من قيمة البايت وهنا يكون الناتج 3
فيقوم بعمل ازاحة 3 مرات فيصبح الناتج هكذا 00000001 وهذا صحيح
ويعود ليختبر الاوامرة بقى اذا كنت دوست على الرقم واحد ينفذ الاوامر وهكذا