|
第一篇文章到现在差不多一年了,但是很少更新,自己都觉得不好意思了。正好手头上面有一个关于类似红外解码的问题,感觉以前写的比较烂(也就是我博客里面的第一篇文章中的程序),这次重新写一次。这次只用到一个定时器和一个I/O口,并且使用的是状态机的方法。
需要注意的是①定时器分辨率需要在0.05ms的时候解码的响应速度才会块,当然你也可以将分辨率调得更高,但是需要注意的是分辨率不能够高得定时器中断里面的程序都运行不了,时间太短了,这样会导致定时不准。②在对高电平时间和低电平时间进行计数的时候为了防止干扰的影响,当计数大于一个数的时候复位到READY状态。
程序大概如下:
/**********************************************/
/*IR*/
#define T_IR P3_3
#define HIGH 1
#define LOW 0
#define NEC 1
#define KAIRUI 2
#define IRMODE KAIRUI
#if (IRMODE == NEC)
//需要在定时器为0.05ms时响应比较快
#define Max_IR_time 640 //32ms*20
#define HEAD_HIGH_TIME 180 //9ms*20 //跟输入波形是反的
#define HEAD_LOW_TIME 90 //4.5ms*20
#define ONE_HIGH_TIME 10 //0.56ms
#define ONE_LOW_TIME 34 //1.69ms
#define ZERO_HIGH_TIME 10 //0.565ms
#define ZERO_LOW_TIME 10 //0.56ms
#define HEAD_HIGH_TIME_REVISE 40
#define HEAD_LOW_TIME_REVISE 30
#define ONE_HIGH_TIME_REVISE 4
#define ONE_LOW_TIME_REVISE 10
#define ZERO_HIGH_TIME_REVISE 4
#define ZERO_LOW_TIME_REVISE 4
#elif (IRMODE == KAIRUI)
#define Max_IR_time 640 //32ms*20
#define HEAD_HIGH_TIME 320 //16ms*20 //跟输入波形是反的
#define HEAD_LOW_TIME 320 //16ms*20
#define ONE_HIGH_TIME 40 //2ms*20
#define ONE_LOW_TIME 40 //2ms*20
#define ZERO_HIGH_TIME 60 //3ms*20
#define ZERO_LOW_TIME 20 //1ms*20
//20%
#define HEAD_HIGH_TIME_REVISE 100//64
#define HEAD_LOW_TIME_REVISE 100//64
#define ONE_HIGH_TIME_REVISE 10//8
#define ONE_LOW_TIME_REVISE 10//8
#define ZERO_HIGH_TIME_REVISE 15//12
#define ZERO_LOW_TIME_REVISE 5//4
#endif
#define ONE 1
#define ZERO 2
#define None 0
#define HEAD_HIGH 4
#define HEAD_LOW 5
#define CODE_HIGH 6
#define CODE_LOW 7
/**********************************************/
void init_IR(void)
{
uint8 i;
tick.Low = 0;
tick.High = 0;
IR.Low_time = 0;
IR.High_time = 0;
for(i=0;i<SIZE_OF_IRCode;i++)
{
IR.coding_reg = 0;
}
IR.Sta = READY;
IR.type = None;
IR.Count = 0;
}
uint8 decode_IR(void)
{
uint8 the_bit = 0;
uint8 i;
uint8 ptr;
//对头码进行解码
if((IR.Sta == READY || IR.Sta == HEAD_HIGH) && T_IR == HIGH)//head high
{
if(tick.High < Max_IR_time)
{
tick.High ++;
IR.Sta = HEAD_HIGH;LED_OFF();
}
else
{
init_IR();
return 0;
}
}
if(IR.Sta == HEAD_HIGH && T_IR == LOW)//head low
{
IR.High_time = tick.High;
tick.High = 0;
//if(IR.High_time > (HEAD_HIGH_TIME - 40) && IR.High_time < (HEAD_HIGH_TIME + 40))
//{
IR.Sta = HEAD_LOW;
//}
}
if(IR.Sta == HEAD_LOW && T_IR == LOW)//head low
{
if(tick.Low < Max_IR_time)
{
tick.Low ++;
}
else
{
init_IR();
return 0;
}
}
if(IR.Sta == HEAD_LOW && T_IR == HIGH)//HEAD OVER
{
IR.Low_time = tick.Low;
tick.Low = 0;
if(IR.High_time > (HEAD_HIGH_TIME - 40) && IR.High_time < (HEAD_HIGH_TIME + 40) && IR.Low_time > (HEAD_LOW_TIME - 30) && IR.Low_time < (HEAD_LOW_TIME + 30))
{
IR.Sta = RECEIVE;
IR.type = 'D';
}
else
{
init_IR();
return 0;
}
}
//对数据进行解码
if((IR.Sta == RECEIVE || IR.Sta == CODE_HIGH) && T_IR == HIGH)
{
if(tick.High < Max_IR_time)
{
tick.High ++;
IR.Sta = CODE_HIGH;
}
else
{
init_IR();
return 0;
}
}
if(IR.Sta == CODE_HIGH && T_IR == LOW)//CODE low
{
IR.High_time = tick.High;
tick.High = 0;
IR.Sta = CODE_LOW;
}
if(IR.Sta == CODE_LOW && T_IR == LOW)//CODE low
{
if(tick.Low < Max_IR_time)
{
tick.Low ++;
}
else
{
init_IR();
return 0;
}
}
if(IR.Sta == CODE_LOW && T_IR == HIGH)//ONE CODE OVER
{
IR.Low_time = tick.Low;
tick.Low = 0;
//ZERO
if(IR.High_time > (ZERO_HIGH_TIME - 4) && IR.High_time < (ZERO_HIGH_TIME + 4) && IR.Low_time > (ZERO_LOW_TIME - 4) && IR.Low_time < (ZERO_LOW_TIME + 4))
{
IR.Sta = RECEIVE;
the_bit = ZERO;
}
//ONE
else if(IR.High_time > (ONE_HIGH_TIME - 4) && IR.High_time < (ONE_HIGH_TIME + 4) && IR.Low_time > (ONE_LOW_TIME - 10) && IR.Low_time < (ONE_LOW_TIME + 10))
{
IR.Sta = RECEIVE;
the_bit = ONE;
}
else
{
init_IR();
return 0;
}
}
if(the_bit)
{
IR.Count ++;
if(IR.Count <= (SIZE_OF_IRCode*8))
{
ptr = (IR.Count+7)/8-1;
IR.coding_reg[ptr] <<= 1;
if(the_bit == ZERO)
{
the_bit = None;
IR.coding_reg[ptr] &= Bin(11111110);
}
else if(the_bit == ONE)
{
the_bit = None;
IR.coding_reg[ptr] |= Bin(00000001);
}
if(IR.Count == (SIZE_OF_IRCode*8))
{
for(i=0;i<SIZE_OF_IRCode;i++)
{
IR.coding = IR.coding_reg;
}
init_IR();
IR.send = 1;
}
}
}
}