تمام انا فهمت الفكرة لاكن الفكرة انو انا عاوز استقيل اشارة من الريموت
فا استخدمت برنامج ir protocal
لاكن معنديش فكرة عن البرنامج ازاى احسب زمن النبضات فى البرنامج ازاى
عشان وانا بعمل كود الاستقبال يكون مظبوط
؟
|
السلام عليكم
اخي كريم طريقه بسيطه بأذن الله وهي انك تلاحظ انه عندما يستقبل ريسيفر اشاره من ريموت يتحول من 1 الى 0 يعني (( من 5 فولت الى 0 فولت)) وهنا كلما تغير اشاره من 1 الى 0 يحدث انتربت في هذه حاله قم بتصفير تايمر 0 وعندما تأتي نبضه اخرى ايضا يحدث الانتربت وهنا قارن هل زمن (( يتم حسابه من تايمر 0)) يساوي زمن النبضه
طبعا هنا كلامي خاطئ لماذا لاني لايمكن ان يحدث مساواه للزمن وعليه اختار مجال فقول هل الزمن الي تم قياسه اكبر من قيمه فلانيه واصغر من قيمه فلانيه يعني القيمه المتوقعه فأذا كانت ضمن مجال الصحيح اذن هذه هي النبضه البدء ومن ثم انتقل الى حساب النبضات البقيه
لاحظ معي جيدا
هذا كود الارسال (( انا بحاول فقط وضحلك الفكره))
كود:
void IR_Send(char IR_Address, char IR_COmmand)
{
char ir_byte[4];
char bitnum;
char bytenum;
ir_byte[3] = ~IR_COmmand;
ir_byte[2] = IR_COmmand;
ir_byte[1] = ~IR_Address;
ir_byte[0] = IR_Address;
Delay_ms(100); // precaution to be certain of some dead time before message start
PWM1_Start(); // mark
led=1;
Delay_us(9000); // 9mS mark start bit
PWM1_Stop(); // space
led=0;
Delay_us(4500); // 4.5mS space ends start bit
for(bytenum = 0; bytenum < 4; bytenum++) // 4 bytes to send
{
for(bitnum = 0; bitnum < 8; bitnum++) // 8 bits LSB first
{
PWM1_Start(); // mark
led=1;
Delay_us(560); // 560uS mark for '0' or '1'
PWM1_Stop(); // space
led=0;
if(ir_byte[bytenum] & (1 << bitnum)) // test bit <bitnum>
{
Delay_us(1680); // 1.68mS space for a '1'
}
else{
Delay_us(560); // 560uS space for a '0'
}
}
}
PWM1_Start(); // mark
led=1;
Delay_us(560); // stop bit of '1'
PWM1_Stop(); // space
led=0;
Delay_us(1680); // stop bit of 1
Delay_ms(100); // precaution to be certain of some dead time after message ends
IR_led=0;//off IR_led because if PWM1_Stop() maybe IR_led=0 or IR_led=1 then must be sure off IR_led
}
تلاحظ عندي اربعه البايتات اريد ارسالها وطبعا هذا هو البرتوكول IR NEC protocol
لاحظ هذا الكود ويمثل اشاره البدء
كود:
PWM1_Start(); // mark
led=1;
Delay_us(9000); // 9mS mark start bit
PWM1_Stop();
ايضا بدءت باشاره 9 ملي ثانيه ثم توقف لمده 4.5 ms ثم بدء بارسال البيانات
كود:
for(bytenum = 0; bytenum < 4; bytenum++) // 4 bytes to send
{
for(bitnum = 0; bitnum < 8; bitnum++) // 8 bits LSB first
{
PWM1_Start(); // mark
led=1;
Delay_us(560); // 560uS mark for '0' or '1'
PWM1_Stop(); // space
led=0;
if(ir_byte[bytenum] & (1 << bitnum)) // test bit <bitnum>
{
Delay_us(1680); // 1.68mS space for a '1'
}
else{
Delay_us(560); // 560uS space for a '0'
}
}
}
تلاحظ انه تم تشغيل ليد الارسال لمده 560 مايكروثانيه اما زمن التوقف هنا اذا كان بت =1 فزمن التوقف هو 1680 مايكروثانيه وما بت=0 فزمن التوقف هو 560 مايكرو
بعد ذلك
ارسال النبضه النهايه
كود:
PWM1_Start(); // mark
led=1;
Delay_us(560); // stop bit of '1'
PWM1_Stop();
================================================
الان ناتي الى اشلون استقبل هذه البيانات
الجواب هو انا بحسب زمن وقارن هذا الزمن هل ضمن نسق الصحيح
بالطبع هو لازم بالبدايه احسب زمن النبضه البدء لانها هي نقطه البدايه
وهنا استخدمت تايمر 1 (( لكونه تايمر 16 بت ))
كود:
void InitTimer1(){
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0xFF;
TMR1L = 0x37;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
لاحظ معي
من كود داله الانتربت
كود:
case 0 : {
IR_Timer_Count = 0;
IR_Received_Flag=0xAA;
if (ir_in == 0)IR_State = 1; // we have got mark signal
break;
}
case 1 : { // we wait for 9ms mark signal
if (ir_in == 0) IR_Timer_Count ++; // increment timer counter
if (ir_in == 1) if ((IR_Timer_Count > 80) && (IR_Timer_Count < 110))// between 8ms and 11ms
{
IR_State = 2; // go to next state (wait for 4.5ms space)
IR_Timer_Count = 0; // reset timer counter
}
else{
IR_State = 0; // reset IR state because we did not got required 9ms mark
IR_Timer_Count = 0; // reset timer counter
IR_Received_Flag=0xAA;
}
break;
}
لاحظ وكما اخبرتك ان ريسفر لما يستلم اشاره يتحول من 1 الى 0 وعندما تختفي اشاره يعود الى 1
لذا تلاحظ انه تم اختبار هل if (ir_in == 0)IR_State = 1 وفي نفس الوقت تم تصفير عداد الزمن وهو IR_Timer_Count = 0;
و IR_State = 1 معناها انتقل الى case 1
كود:
case 1 : { // we wait for 9ms mark signal
if (ir_in == 0) IR_Timer_Count ++; // increment timer counter
if (ir_in == 1) if ((IR_Timer_Count > 80) && (IR_Timer_Count < 110))// between 8ms and 11ms
{
IR_State = 2; // go to next state (wait for 4.5ms space)
IR_Timer_Count = 0; // reset timer counter
}
else{
IR_State = 0; // reset IR state because we did not got required 9ms mark
IR_Timer_Count = 0; // reset timer counter
IR_Received_Flag=0xAA;
}
break;
}
تلاحظ انه اذا لايزال ir_in == 0 معناها اشاره لاتزال موجوده وتلاحظ ان عداد زمن بتزايد وعندما يتحول ir_in == 1 عندها اختبرت هل وقت IR_Timer_Count ضمن مجال لزمن النبضه البدء 9ms
كود:
if (ir_in == 1) if ((IR_Timer_Count > 80) && (IR_Timer_Count < 110))// between 8ms and 11ms
ملاحظه الانتربت يحدث كل 100 مايكروثانيه
فأذا كان شرط متحقق اذن اشاره هي فعلا اشاره البدء 9ms وهنا اخبرته
IR_State = 2 اي انتقل الى case 2 وفي نفس الوقت اخبرته بأن تجعل عداد زمن =0 اي IR_Timer_Count = 0 لماذا لكي استمر بفحص كل النبضات لحين وصولي الى النبضه النهائيه
للعلم زمن حسب الارسال 0 يعني زمن 560us و 1 يعني 1680us
ارجو اني وضحت لك الفكره