新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)紅外遙控器解碼例程源碼新說(shuō)

        單片機(jī)紅外遙控器解碼例程源碼新說(shuō)

        作者: 時(shí)間:2016-11-27 來(lái)源:網(wǎng)絡(luò) 收藏
        這是第三次更改這個(gè)紅外遙控解碼的例程了。之前的第一版是直接用51單片機(jī)的外部中斷然后在里邊加延時(shí)采集高低電平的長(zhǎng)短來(lái)判斷引導(dǎo)碼和位1位0的,這個(gè)當(dāng)初不知是從哪看的,這種方式太誤導(dǎo)人了,如果想用這種思路移植到stm32上,還是趁早打住吧,stm32這種高級(jí)處理器難道只用來(lái)紅外遙控解碼嗎?不,肯定會(huì)有更高級(jí)的任務(wù)去等待他處理,外部中斷加延時(shí)可以提高遙控的響應(yīng)速度,但實(shí)際上這種方式很占資源,當(dāng)cpu在處理其他緊急任務(wù)的時(shí)候,突然來(lái)個(gè)按鍵,打斷進(jìn)程,并且一置占用進(jìn)程,經(jīng)測(cè)試過(guò),遙控一個(gè)鍵碼有50-90ms,這對(duì)單片機(jī)來(lái)說(shuō)可是不小的時(shí)間啊。所以,可以結(jié)合外部中斷+定時(shí)器兩種方式來(lái)解碼。
        外部中斷開(kāi)啟上升和下降沿同時(shí)觸發(fā)。這樣的話,我們?cè)趦纱斡|發(fā)后,計(jì)算出高或低的點(diǎn)評(píng)時(shí)間看是否準(zhǔn)確,就可以了。
        可以采用狀態(tài)機(jī)也就是狀態(tài)變換的思路來(lái)解碼。引導(dǎo)碼和用戶碼,分成兩部分來(lái)解。高電平和低電平分成兩部分來(lái)解碼。
        又因?yàn)槲?和位0之間區(qū)別在于 高電平的時(shí)間不同,也就是 位0 _|—|位1
        _|——|兩者的
        低電平的時(shí)間都是一樣的,而后邊的高電平長(zhǎng)的為1短的為0,有這個(gè)特點(diǎn)就特別好解決了。可參考之前的文章,http://www.xiaovdiy.cn/?post=138
        源代碼奉上
        if(EXTI_GetITStatus(EXTI_Line12)!= RESET)
        {
        if(RDATA()==0)//說(shuō)明是下降沿到來(lái)
        {

        TIM_Cmd(TIM4, ENABLE);
        if(lead_flg==0)//說(shuō)明是第一次接收引導(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))//測(cè)試表明為79或80
        {
        lead_flg=0; //超出范圍退出
        return 0;

        }
        }
        else if(lead_flg==3)//獲得高電平時(shí)間
        {
        ir_cnt= TIM_GetCounter(TIM4);
        TIM_SetCounter(TIM4,0);
        //接收3個(gè)字節(jié)24位碼
        high_cnt++;//加到24位每8次為1個(gè)字節(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))//我們認(rèn)為是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)//說(shuō)明接受完畢
        {
        lead_flg = 0;
        high_cnt = 0;
        REM_FLG = 1;//采集完畢 清除標(biāo)志位

        TIM_Cmd( TIM4,DISABLE);
        }


        }

        }
        else if(RDATA()!=0)//說(shuō)明是第一次接收引導(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)碼進(jìn)入中斷上升沿觸發(fā)的
        {
        ir_cnt= TIM_GetCounter(TIM4);
        TIM_SetCounter(TIM4,0);

        if((ir_cnt<8)||(ir_cnt>20))//測(cè)試數(shù)據(jù)為ir_cnt =9 10穩(wěn)定值
        {
        lead_flg=0;
        return 0;//不是我們要的退出

        }


        }
        }

        }


        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 商都县| 承德县| 息烽县| 桃园市| 右玉县| 合作市| 兴山县| 元氏县| 泰安市| 岳普湖县| 册亨县| 兴和县| 嘉定区| 曲阜市| 岑溪市| 谢通门县| 伊金霍洛旗| 通海县| 梁河县| 西畴县| 石渠县| 新化县| 南部县| 陆良县| 台州市| 大城县| 石棉县| 菏泽市| 阿拉善左旗| 福贡县| 稷山县| 安多县| 娄烦县| 始兴县| 奎屯市| 五河县| 宣威市| 塔城市| 马边| 大厂| 日照市|