你这个通讯方式和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;
}
}
|