单片机红外遥控器解码例程源码新说
外部中断开启上升和下降沿同时触发。这样的话,我们在两次触发后,计算出高或低的点评时间看是否准确,就可以了。
可以采用状态机也就是状态变换的思路来解码。引导码和用户码,分成两部分来解。高电平和低电平分成两部分来解码。
又因为位1和位0之间区别在于 高电平的时间不同,也就是 位0 _|—|位1
_|——|两者的
低电平的时间都是一样的,而后边的高电平长的为1短的为0,有这个特点就特别好解决了。可参考之前的文章,http://www.xiaovdiy.cn/?post=138
源代码奉上
if(EXTI_GetITStatus(EXTI_Line12)!= RESET)
{
if(RDATA()==0)//说明是下降沿到来
{
TIM_Cmd(TIM4, ENABLE);
if(lead_flg==0)//说明是第一次接收引导码
{
TIM_SetCounter(TIM4,0);//TIM4->CNT=0;(1)
lead_flg=1;
}
else if(lead_flg==2)
{
ir_cnt= TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
lead_flg=3;
if((ir_cnt<70)||(ir_cnt>90))//测试表明为79或80
{
lead_flg=0; //超出范围退出
return 0;
}
}
else if(lead_flg==3)//获得高电平时间
{
ir_cnt= TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
//接收3个字节24位码
high_cnt++;//加到24位每8次为1个字节
if(high_cnt<=8)
{
user_code[0]>>=1;
}
if(high_cnt<=16)
{
user_code[1]>>=1;
}
if(high_cnt<=24)
{
user_code[2]>>=1;
}
if((ir_cnt>35)&&(ir_cnt<45))//我们认为是bit 1
{
if(high_cnt<=8)
{
user_code[0]|=0x80;
}
if(high_cnt<=16)
{
user_code[1]|=0x80;
}
if(high_cnt<=24)
{
user_code[2]|=0x80;}
}
if(high_cnt>24)//说明接受完毕
{
lead_flg = 0;
high_cnt = 0;
REM_FLG = 1;//采集完毕 清除标志位
TIM_Cmd( TIM4,DISABLE);
}
}
}
else if(RDATA()!=0)//说明是第一次接收引导码的高电平
{
if(lead_flg==0)
{
return 0;
}
else if(lead_flg==1)//我们只接受一次低电平即可 2
{
ir_cnt= TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
lead_flg=2;
if((ir_cnt<70)||(ir_cnt>90))
{
lead_flg=0;//不是我们要的 退出
return 0;
}
}
else if(lead_flg==3)//非引导码进入中断上升沿触发的
{
ir_cnt= TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
if((ir_cnt<8)||(ir_cnt>20))//测试数据为ir_cnt =9 10稳定值
{
lead_flg=0;
return 0;//不是我们要的退出
}
}
}
}
评论