單片機紅外遙控器解碼例程源碼新說
外部中斷開啟上升和下降沿同時觸發(fā)。這樣的話,我們在兩次觸發(fā)后,計算出高或低的點評時間看是否準確,就可以了。
可以采用狀態(tài)機也就是狀態(tài)變換的思路來解碼。引導(dǎo)碼和用戶碼,分成兩部分來解。高電平和低電平分成兩部分來解碼。
又因為位1和位0之間區(qū)別在于 高電平的時間不同,也就是 位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)//說明是第一次接收引導(dǎo)碼
{
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個字節(jié)24位碼
high_cnt++;//加到24位每8次為1個字節(jié)
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)//說明是第一次接收引導(dǎo)碼的高電平
{
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)//非引導(dǎo)碼進入中斷上升沿觸發(fā)的
{
ir_cnt= TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
if((ir_cnt<8)||(ir_cnt>20))//測試數(shù)據(jù)為ir_cnt =9 10穩(wěn)定值
{
lead_flg=0;
return 0;//不是我們要的退出
}
}
}
}
評論