你這個通訊方式和NEC紅外協議很類似,既然是單線單工,你的引導碼和數據應該是讀的同一個引腳,那么time1,time2是同一個引腳的電平持續時間,對嗎?要找到問題,我的思路是這樣的,僅供參考:
1 根據你的晶振精度,以及系統中有無其它優先級更高的中斷影響通訊時序,合理設計0、1bit的時序特征,提高容錯性,比方說3~10us低電平后接10~20us高電平代表0; 10~18us低電平厚街3~10us高電平代碼1;
2 由于時序要求比較高,發送端的延時最好用定時器來做
3 示波器測量輸出端時序,比方說你發送數據0x55,確認發送端的輸出時序和你的協議設計相符
4 接收端用定時器的輸入捕獲功能來測量電平時間
中斷服務程序
void Capture_ISR (void)
{
// 讀取timer寄存器時間time
if (!receive_flag)
{
receive(time);
}
}
void receive(uint16_t Capture_Time )
{
if(IR_State == 0)
{
IR_LDC_Ready = 0; // Clear LeaDer Code Ready
IR_State=1;
}
// Leader or Repeater code
else if(IR_State == 1)
{
// Leader code
if((Capture_Time >= IR_LDC_MIN) && (Capture_Time <= IR_LDC_MAX))
{
IR_LDC_Ready = 1; // Set LeaDer Code Ready
IR_State++;
}
else
{
IR_State = 1;
IR_LDC_Ready = 0; // Clear LeaDer Code Ready
}
}
// Data
else if((IR_State >= 2 && IR_State < 10) && (IR_LDC_Ready == 1))
{
IR_State++;
NewByte1 = NewByte1 >> 1;
if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
NewByte1 &= 0x7f;
else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
NewByte1 |= 0x80;
else
IR_State = 0;
}
else if((IR_State >= 10 && IR_State < 18) && (IR_LDC_Ready == 1))
{
IR_State++;
NewByte2 = NewByte2 >> 1;
if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
NewByte2 &= 0x7f;
else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
NewByte2 |= 0x80;
else
IR_State = 0;
}
else if((IR_State >= 18 && IR_State < 26) && (IR_LDC_Ready == 1))
{
IR_State++;
NewByte3= NewByte3>> 1;
if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
NewByte3&= 0x7f;
else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
NewByte3|= 0x80;
else
IR_State = 0;
}
else if((IR_State >= 26 && IR_State < 34) && (IR_LDC_Ready == 1))
{
IR_State++;
NewByte4= NewByte4>> 1;
if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
NewByte4&= 0x7f;
else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
NewByte4|= 0x80;
else
IR_State = 0;
}
else if((IR_State >= 34 && IR_State < 42) && (IR_LDC_Ready == 1))
{
IR_State++;
NewByte5= NewByte5>> 1;
if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
NewByte5&= 0x7f;
else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
NewByte5|= 0x80;
else
IR_State = 0;
}
if(IR_State == 42)
{
IR_LDC_Ready = 0; // Clear LeaDer Code Ready
received_flag= 1;
IR_State = 0;
}
}
|