專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

幾種比較流行和成熟的紅外解碼程序做一下研究和總結(jié)2

作者:山西長治IT男   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年12月14日   【字體:

 本文接上篇繼續(xù)分析《幾種比較流行和成熟的紅外解碼程序做一下分析和總結(jié)1》:http://www.torrancerestoration.com/mcu/3320.html

      下面說一說第二種過濾重復(fù)碼的方法,(這個(gè)方法是老板告訴我的,呵呵,不解釋)廢話不多說,直接上程序:
/*-----------------------------------------------------------------------------------------
                  定時(shí)器0中斷處理
-----------------------------------------------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
       irtime++; //用于計(jì)數(shù)2個(gè)下降沿之間的時(shí)間,256us進(jìn)一次定時(shí)器中斷
         if(irtime>=1000)//irtime>=1000說明按鍵已經(jīng)松天有1000*256=256ms了,故可以使能紅外接收功能
         {
                  ir_flag=0;//使能紅外接收功能
         }
}
/*-----------------------------------------------------------------------------------------
                  外部中斷0中斷處理
-----------------------------------------------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)
{
       static unsigned char  i;            //接收紅外信號處理
       static bit startflag;                //是否開始處理標(biāo)志位
if(irtime<=54&&irtime>=50)//接收到引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms
{
         i=0;
}
if(ir_flag==1)
{
         irtime=0;                             //清零計(jì)數(shù)器
         return;
}
if(ir_flag==0)
{
                   irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1
             irtime=0;//清零irtime變量(老板習(xí)慣叫做寄存器)
             i++;//數(shù)組下標(biāo)自增1
               if(i==33)
                {
                         irok=1;//接收完33個(gè)紅外數(shù)據(jù)
                            i=0;//數(shù)組下標(biāo)清零
                            ir_flag=1;//失能紅外接收功能
                   }
         }
}
       
下面研究第二種紅外解碼的程序,這個(gè)程序沒有用到任何中斷,非常有意思啊,直接上源碼.不解釋.
/*----------------------------------------------------------------------------------------------------
                               紅外解碼處理函數(shù)
----------------------------------------------------------------------------------------------------*/
void ir(void)
{
         if(ir_check_flag==1)
         {
                   ir_check_flag=0;
 
                   if(PB.0==1)
                   {
                            if(irisH_bit==0)
                            {
                                     irisH_bit= 1;
                                     //這里可以添加上升沿到時(shí)時(shí),做相應(yīng)的處理
                            }
                   }
                   else
                   {
                            if(irisH_bit==1)
                            {
                                     irisH_bit= 0;
                                     if(irtime<=110&&irtime>=102)             //引導(dǎo)碼TC9012的頭碼,9ms+4.5ms
                                     {
                                               ramaddr1= irdata;
                                               num= 0;
                                               ir_en_flag=0;
                                     }
                                     if(ir_en_flag==1)
                                     {
                                               irtime=0;                  //如果是重復(fù)碼就將irtime清零,然后退出函數(shù)
                                               return;
                                     }
                                     if(ir_en_flag==0)
                                     {
                                               *ramaddr1= irtime;
                                               ramaddr1++;
                                               irtime= 0;
                                               num++;
                                               if(num==33)
                               {
                                   irok=1;          //32個(gè)數(shù)據(jù)全部存儲(chǔ)完畢,一幀數(shù)據(jù)接收完畢
                                                        num=0;
                                                        ramaddr1= irdata;
                                                        ir_en_flag=1;
                               }
                                     }
                            }
                   }
                   irtime++;
         }
         else
         {
                   return;
         }
}
         分析一下這個(gè)程序的算法,其思路類似于原來中斷函數(shù)的方法,也是記錄兩個(gè)下降沿之間的時(shí)間,并將其存入33個(gè)元素的一個(gè)數(shù)組中,數(shù)組的第一個(gè)位置存入的是那個(gè)淫蕩的引導(dǎo)碼,后面的32個(gè)位置存入的是32個(gè)紅外編碼.這個(gè)算法關(guān)鍵的一點(diǎn)就是那個(gè)irisH_bit位變量的作用.那個(gè)位變量是用來記錄邊沿的,無論是下降沿還是上升沿都能記錄,這個(gè)記錄的作用就是只能使相關(guān)的處理只在相應(yīng)的上升沿還是下降沿作用一次.這個(gè)函數(shù)每128us掃描一次.每128us計(jì)數(shù)器irtime增加一次.先來分析程序運(yùn)行時(shí)的情況,當(dāng)沒有下降沿的時(shí)候,一直是高電平一直執(zhí)行if(PB.0==1)下面的語句irtime一直做疊加的操作.當(dāng)加到最大值時(shí)又變?yōu)?做新一輪的疊加操作.這個(gè)是沒有意義的,等到第一個(gè)下降沿到來的時(shí)候進(jìn)入else語句由于是第一個(gè)下降沿那個(gè)這個(gè)irtime就是隨機(jī)的了,這時(shí)ir_en_flag=0,因?yàn)槭浅跏蓟瘯r(shí)的值,下面分兩種情況來說明這時(shí)的情況,如果這個(gè)irtime的時(shí)間剛好在引導(dǎo)碼的區(qū)間,那么就會(huì)清零num,數(shù)組下標(biāo)清0然后進(jìn)入if(ir_en_flag==0)語句將這個(gè)值取入數(shù)組的第一個(gè)位置,然后下一個(gè)下降沿來到了,這時(shí)這個(gè)時(shí)間就是實(shí)實(shí)在在的引導(dǎo)碼的時(shí)間,同樣會(huì)進(jìn)入if(irtime<=110&&irtime>=102)那一個(gè)分支,這時(shí)將數(shù)組下標(biāo)清零,同時(shí)進(jìn)入下一條分支語句if(ir_en_flag==0),這時(shí)將先前存入數(shù)組的每一個(gè)元素覆蓋掉,那個(gè)也就不存在了,而后是32個(gè)紅外數(shù)據(jù)的存入,這里有一個(gè)值得注意的問題在第32個(gè)紅外數(shù)據(jù)接收完成之后,會(huì)有一個(gè)下降沿,這個(gè)是不屬于那32個(gè)數(shù)據(jù)的電平.是多出來的一個(gè)下降沿,當(dāng)這33個(gè)數(shù)據(jù)接收完成的時(shí)候,會(huì)關(guān)斷數(shù)據(jù)的存儲(chǔ),只有下一次再接收到引導(dǎo)碼才會(huì)再次開啟數(shù)據(jù)的存儲(chǔ)功能,這樣做可以有效的把后面的重復(fù)碼干掉,這個(gè)程序的關(guān)鍵仍然是那個(gè)引導(dǎo)碼的時(shí)間只有這個(gè)時(shí)間足夠準(zhǔn)確,足夠狹窄才能和那個(gè)重復(fù)碼區(qū)別開來.
         下面提供另一個(gè)過濾重復(fù)碼的方法,直接上源代碼,不解釋.
/*----------------------------------------------------------------------------------------------------
                                    紅外解碼處理函數(shù)
----------------------------------------------------------------------------------------------------*/
void ir(void)
{
         if(ir_check_flag==1)
         {
                   ir_check_flag=0;
                   if(PB.0==1)
                   {
                            if(irisH_bit==0)
                            {
                                     irisH_bit= 1;
                            }
                   }
                   else
                   {
                            if(irisH_bit==1)
                            {
                                     irisH_bit= 0;
                                     if(irtime<=110&&irtime>=102)   //引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms
                                     {
                                               ramaddr1= irdata;
                                               num= 0;
                                     }
                                     if(ir_en_flag==1)
                                     {
                                               irtime=0;           //如果是重復(fù)碼就將irtime清零,然后退出函數(shù)
                                               return;
                                     }
                                     if(ir_en_flag==0)
                                     {
                                               *ramaddr1= irtime;
                                               ramaddr1++;
                                               irtime= 0;
                                               num++;
                                               if(num==33)
                               {
                                   irok=1;          //32個(gè)數(shù)據(jù)全部存儲(chǔ)完畢,一幀數(shù)據(jù)接收完畢
                                                        num=0;
                                                        ramaddr1= irdata;
                                                        ir_en_flag=1;
                               }
                                     }
                            }
                   }
                   irtime++;
                   if(irtiem>=10000)              //如果長時(shí)間沒有按下?lián)u控的按鍵,就重新接收下一幀數(shù)據(jù)
                   {
                            ir_en_flag=0;
                   }
         }
         else
         {
                   return;
         }
}
         這個(gè)程序去除重復(fù)碼的方法就是老板告訴我的去除重復(fù)碼的方法.這里一幀新的數(shù)據(jù)的接收使能是松開按鍵的時(shí)間超過128ms,算法就是這樣的,不過和上面的那個(gè)程序相比這個(gè)程序沒有上面的那個(gè)好,第一個(gè)是這個(gè)時(shí)間如果設(shè)置的太短的話,過濾的作用,時(shí)間設(shè)置的太短,如果這個(gè)時(shí)間小于兩個(gè)重復(fù)之間的時(shí)間間隔那會(huì)就會(huì)再次使能中斷的接收,從而把原來的數(shù)據(jù)覆蓋掉,導(dǎo)致程序的出錯(cuò).如果這個(gè)時(shí)間設(shè)置的太長,那個(gè)一次按鍵按下去又得等待十年的時(shí)間才能再次開啟紅外的接收,是不是很坑爹。。!,即使這個(gè)時(shí)間設(shè)置的恰到好處,也還是有一個(gè)時(shí)間的延遲的,相比上面的那個(gè)沒有時(shí)間延遲的程序還是有一點(diǎn)瑕疵啊!所以說上面那個(gè)程序,也就是我編的那處程序才是最好的算法和程序.

關(guān)閉窗口

相關(guān)文章