久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

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

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

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年04月15日   【字體:

 

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

解碼程序一:

/*-----------------------------------------------------------------------------------------

                  定時(shí)器0中斷處理

-----------------------------------------------------------------------------------------*/

void tim0_isr (void) interrupt 1 using 1

{

 irtime++;  //用于計(jì)數(shù)2個(gè)下降沿之間的時(shí)間

}

/*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(startflag)                       

{

if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

 i=0;

}           

                      irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                      irtime=0;

                      i++;

                        if(i==33)

                        {

                                       irok=1;

                                          i=0;

                            }

}

           else

              {

                            irtime=0;

                            startflag=1;

              }

}

              先來分析一個(gè)這個(gè)程序,這個(gè)程序用了兩個(gè)中斷,一個(gè)定時(shí)器中斷,一個(gè)外斷中斷,程序的算法是讓定時(shí)器中斷不停的記數(shù),外部中斷在下降沒來臨的時(shí)候?qū)⑦@個(gè)記數(shù)值并將上一次記的數(shù)值存在一個(gè)數(shù)組中,不過這個(gè)程序有一個(gè)小Bug,就是那個(gè)startflag是沒有起到關(guān)鍵性的作用的啊?!其實(shí)編這個(gè)程序的程序員想的是用startflag,這個(gè)方法可以過濾過那一個(gè)引導(dǎo)碼,但是如果你足夠細(xì)心就會(huì)發(fā)現(xiàn)他沒有做startflag清0的操作,不過詭異的事情是即使這樣也沒有影響正常的解碼程序的運(yùn)行,其實(shí)只要你認(rèn)真分析一下就會(huì)發(fā)現(xiàn)有沒有startflag清0這一個(gè)判斷的條件其實(shí)沒有多大的意義,我的意思是有沒有這一條語句都不會(huì)影響正常的解碼,首先來分析原程序,也就是沒有startflag清0這一語句的情況,第一個(gè)引導(dǎo)碼來的時(shí)候,進(jìn)入else語句,將第一個(gè)引導(dǎo)碼過慮掉,進(jìn)入else語句的就是后面有用的解值了,第一次會(huì)執(zhí)行到if(irtime<54&&irtime>=50)這一條語句,因?yàn)橐龑?dǎo)碼的長(zhǎng)度剛好在這個(gè)范圍內(nèi),所以會(huì)執(zhí)行下會(huì)的一條i=0,也就是會(huì)把數(shù)組的下標(biāo)清0,然后會(huì)把相應(yīng)的32個(gè)紅外編碼存到數(shù)組中,注意這里的數(shù)組的長(zhǎng)度是33,而不是32,因?yàn)閕rdata[0]是用來存放引導(dǎo)碼的,還有一點(diǎn)非常值很注意,就是這32個(gè)有效的紅外數(shù)據(jù)接收完了之后,會(huì)有一個(gè)重復(fù)碼,這個(gè)重復(fù)碼和引導(dǎo)碼長(zhǎng)得很相似,這個(gè)我用示波器看過,這個(gè)重復(fù)碼可以看作是第34個(gè)波形,而且有一點(diǎn)非常值很注意,就是這個(gè)重復(fù)碼只要你按鍵不松手的話是一直會(huì)發(fā)的,所以如何處理這個(gè)重復(fù)碼的問題也是很關(guān)鍵的,至于這個(gè)問題我后面會(huì)有講到,現(xiàn)有我們先來將這個(gè)重復(fù)碼看成是第34個(gè)紅外碼,他的意義在于可以提供一個(gè)下降沿,有了這個(gè)下降沿就會(huì)將第32個(gè)紅外碼值存入data[32]中,所以最終的結(jié)果就是33個(gè)紅外編碼全部存入了容量為33的數(shù)組中,但是這時(shí)還有一個(gè)問題就是如果按鍵按下不放的話,后面還會(huì)有無數(shù)的波形啊,這時(shí)解碼程序還在不停的處理,后面的紅外編碼會(huì)存入第34,35,36……等后面的數(shù)組中,這是不希望看到的,這也會(huì)導(dǎo)致一個(gè)更加可怕的問題,那就是程序的溢出,那天在防真器上出現(xiàn)了這個(gè)問題決對(duì)就是這個(gè)原因.因?yàn)閿?shù)組只有33個(gè)元素,而在接收到這33個(gè)元素之后還沒有停止對(duì)紅外碼的接收,后面的元素繼續(xù)存入只有33個(gè)元素的數(shù)組中,必定會(huì)導(dǎo)致數(shù)據(jù)的溢出,也就是會(huì)彈出那樣的一個(gè)溢出的界面,我還記得當(dāng)天沒有接紅外接收管硬件的時(shí)候也會(huì)有這個(gè)溢出的窗口,那是因?yàn)楫?dāng)時(shí)沒有在中斷進(jìn)入這后將中斷標(biāo)志位清0,所以會(huì)一直有中斷進(jìn)來,從而這33個(gè)元素的數(shù)組就會(huì)很快存滿了,然后還在進(jìn)入不停的進(jìn)入中斷,最后導(dǎo)致這33個(gè)元素的數(shù)組全部存滿了還在不停的往里面存數(shù)據(jù),所以也會(huì)導(dǎo)致程序的溢出.所以以后就有了一條經(jīng)驗(yàn),那就是如果程序溢出了有一種可能性就是往一個(gè)固定長(zhǎng)度的數(shù)組中存入了大于其長(zhǎng)度的數(shù)據(jù).那么如何解決這個(gè)問題呢,一種可行的方法是這樣的,待33個(gè)紅外數(shù)據(jù)全部存完以后,置一個(gè)標(biāo)志,后面接收到的數(shù)據(jù)只要不是引導(dǎo)碼就做一次函數(shù)返回,當(dāng)接收到這個(gè)正確的引導(dǎo)碼以后才可以進(jìn)行下一輪數(shù)據(jù)的接收.

              上面的這個(gè)問題暫且放下(只要搖控器發(fā)出的波形只有34個(gè)脈沖就不會(huì)出現(xiàn)上面的問題 ,這種搖控器的特點(diǎn)就是只要你按下一個(gè)按鍵不論你是不松手,它都只會(huì)發(fā)出一幀數(shù)據(jù),不會(huì)有后面的故慮),下面考慮第二幀數(shù)據(jù)的接收情況,當(dāng)?shù)诙䦷瑪?shù)據(jù)來臨的時(shí)候,由于沒有清0 startflag,程序會(huì)進(jìn)入if(startflag)這一個(gè)分支,也就是會(huì)處理引導(dǎo)碼的情況,這里會(huì)到下面的一條語句if(irtime<63&&irtime>=33),而這時(shí)irtime是一個(gè)隨機(jī)的數(shù),所以說這條語句有可能能被執(zhí)行到也有可能不會(huì)被執(zhí)行到,無論其是否能被執(zhí)行到,都無所謂,等下一個(gè)下降沿到來的時(shí)候那個(gè)時(shí)候irtime存入的才是引導(dǎo)碼的數(shù)據(jù),也就是直到第二個(gè)下降沿到來的時(shí)候,irdata的下標(biāo)才會(huì)清0,這時(shí)才會(huì)將引導(dǎo)碼存入irdata的第0個(gè)格子里面.而后的數(shù)據(jù)會(huì)將先前的數(shù)據(jù)覆蓋掉,也就消除了第一次接收到的數(shù)據(jù)的不穩(wěn)定因素.

              如果有接收到第33個(gè)元素后將startflag清0.每次接收紅外的時(shí)候就和第一次的一樣了,還過即使是這樣也不能擺脫那個(gè)接收到重復(fù)碼的問題.下面是有startflag清0的程序.

/*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(startflag)                       

{

if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

 i=0;

}           

                      irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                      irtime=0;

                      i++;

                        if(i==33)

                        {

                                       irok=1;

                                          i=0;

                                          startflag=0;

                            }

}

           else

              {

                            irtime=0;

                            startflag=1;

              }

}

下面做一個(gè)解決重復(fù)碼問題的程序:

/*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(statflag==1)

{

              if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

                                                       i=0;

                                                        ir_flag=0;                                                                               //接收到正確的引導(dǎo)碼,開始接收數(shù)據(jù)

}

else

{

                                          return;                                                                                    //這個(gè)是33個(gè)紅外碼后面的重復(fù)碼,過濾掉他

}

If(ir_flag==0)                                                                        //如果接收到引導(dǎo)碼才開始解碼

{           

irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                                    irtime=0;

                                    i++;

                                                    if(i==33)

                                                    {

                                                                   irok=1;

                                                                      i=0;

                                          startflag=0;

                                                                      ir_flag=1;                                                                               //接收完33個(gè)數(shù)據(jù),清0接收數(shù)據(jù)位,即不再接收數(shù)據(jù)

                                                        }

 }

else

{

startflag==1

i=0;

                            return;

}

}

              這個(gè)程序有一個(gè)關(guān)鍵的地方,那就是那個(gè)引導(dǎo)碼的時(shí)間,程序就是通過這個(gè)時(shí)間來確定是否開始接收一幀數(shù)據(jù)的,真到接收到33個(gè)數(shù)據(jù)后將關(guān)閉數(shù)據(jù)的接收功能,直到有第二個(gè)引導(dǎo)碼的到來,才開始接收第二幀數(shù)據(jù).如果重復(fù)碼我這個(gè)引導(dǎo)碼很像,那么這個(gè)一點(diǎn)的時(shí)間的差別也是很關(guān)鍵的了,所以必須把握好這個(gè)時(shí)間,比如13.5ms,12M的晶振定時(shí)器計(jì)一次時(shí)間是256us比如把這個(gè)時(shí)間卡在13ms到14ms之間就應(yīng)該是13000/256=50,14000/256=54,也就是說應(yīng)該把兩個(gè)時(shí)間卡在50和54之間,這樣的精度才能保證將那些個(gè)重復(fù)碼的脈沖過濾掉,這個(gè)卡的越準(zhǔn)越好越小越好.也就這在邏輯上也是可行完美合理的程序.邏輯上就是要讓一幀數(shù)據(jù)接收完成之后停止數(shù)據(jù)的接收功能.上面各全局變量的初始化情況為ir_flag=0;startflag=0;

              想一想如果這個(gè)程序像下面這樣會(huì)有什么后果,即去掉startflag這個(gè)標(biāo)置,會(huì)有什么后果?

/*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

                                         i=0;

ir_flag=0;                                                                               //接收到正確的引導(dǎo)碼,開始接收數(shù)據(jù)

}

else

{

                                          return;                                                                                    //這個(gè)是重復(fù)碼,過濾掉他

}

If(ir_flag==0)

{           

irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                      irtime=0;

                      i++;

                        if(i==33)

                        {

                                       irok=1;

                                          i=0;

                                          ir_flag=1;                                                                               //接收完33個(gè)數(shù)據(jù),清0接收數(shù)據(jù)位,即不再接收數(shù)據(jù)

                            }

}

}

              這個(gè)程序沒有用startflag這個(gè)標(biāo)置,也就不能保證接收到的第一個(gè)脈沖是引導(dǎo)碼了,這時(shí)會(huì)有一個(gè)隨機(jī)的數(shù)存入irtime,如果這個(gè)隨機(jī)數(shù)是和引導(dǎo)碼的irtime相似的話,就會(huì)造成解碼的開啟,第二個(gè)碼,也就是引導(dǎo)碼會(huì)存入irdata[1]中,后面所有的碼就會(huì)依次往后推移一次,這樣的話第33個(gè)紅外碼就會(huì)丟失掉,也就去直接導(dǎo)致解碼的失敗.所以說完美的程序應(yīng)該是上面的那個(gè)程序.(這段話說的不對(duì),那個(gè)i=0的操作會(huì)把數(shù)組的下標(biāo)做一下清0,也就不存在移位的問題了.)

          特別糾正一下本文的錯(cuò)誤之處,上面的兩個(gè)程序都是有問題的,正確的程序應(yīng)該是下面的程序,看完這個(gè)程序再來說明上面程序不正確的地方.

              /*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

                                         i=0;

ir_flag=0;                                                                               //接收到正確的引導(dǎo)碼,開始接收數(shù)據(jù)

}

if(ir_flag==1)

{

                            irtime=0;

                                          return;                                                                                    //這個(gè)是重復(fù)碼,過濾掉他

}

If(ir_flag==0)

{           

irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                      irtime=0;

                      i++;

                        if(i==33)

                        {

                                       irok=1;

                                          i=0;

                                          ir_flag=1;                                                                               //接收完33個(gè)數(shù)據(jù),清0接收數(shù)據(jù)位,即不再接收數(shù)據(jù)

                            }

}

}

上面的那兩個(gè)程序都不能按照正常的算法實(shí)現(xiàn),關(guān)鍵在于有一個(gè)原因,那個(gè)else語句沒有做irtime清零的操作,這樣就會(huì)導(dǎo)致一個(gè)問題,就是下一個(gè)下降沿到來的時(shí)候不能反正確的兩個(gè)下降沿之間的時(shí)間存入數(shù)中,存入的是不確定的數(shù),所以說irtime清零這一步操作還是很有必要的,試想下一個(gè)正確的引導(dǎo)碼到的的時(shí)候,沒有irtime清0的操作也就不能識(shí)別能正確的引導(dǎo)碼,也就不能夠?qū)崿F(xiàn)解碼的開啟,也就不能夠?qū)崿F(xiàn)正確的解碼,不過上面的程序還是有一個(gè)問題,那就是他沒有用startflag,也就會(huì)存在上面提到的那個(gè)問題,也說是說當(dāng)有一個(gè)隨機(jī)數(shù),也就是下一幀數(shù)據(jù)開始接收時(shí)的第一個(gè)碼,那個(gè)數(shù)就是一個(gè)隨機(jī)數(shù),如果那個(gè)數(shù)剛好是在引導(dǎo)碼的時(shí)間區(qū)間內(nèi),那么就是惡夢(mèng)的開始,也就是說會(huì)和上面的錯(cuò)誤一樣,這個(gè)隨機(jī)數(shù)會(huì)存入irdata[0],引導(dǎo)碼會(huì)存入irdata[1]中,下面的所有碼都依次往下移一位,也說是說會(huì)有一位碼沒有存入這33個(gè)數(shù)據(jù)碼中(包括引導(dǎo)碼). (這段話說的不對(duì),那個(gè)i=0的操作會(huì)把數(shù)組的下標(biāo)做一下清0,也就不存在移位的問題了.)所以說這個(gè)程序可以說是一個(gè)比效完美的程序了

              下面是另一種編程的方法.

/*-----------------------------------------------------------------------------------------

                  外部中斷0中斷處理

-----------------------------------------------------------------------------------------*/

void EX0_ISR (void) interrupt 0 //外部中斷0服務(wù)函數(shù)

{

           static unsigned char  i;            //接收紅外信號(hào)處理

           static bit startflag;                //是否開始處理標(biāo)志位

if(statflag==1)

{

              if(irtime<=54&&irtime>=50)//引導(dǎo)碼 TC9012的頭碼,9ms+4.5ms

{

                                                       i=0;

                                                        ir_flag=0;                                                                               //接收到正確的引導(dǎo)碼,開始接收數(shù)據(jù)

}

if(ir_flag==0)

{

                            irtime=0;

                            startflag=0;

                                          return;                                                                                    //這個(gè)是33個(gè)紅外碼后面的重復(fù)碼,過濾掉他

}

If(ir_flag==1)                                                                        //如果接收到引導(dǎo)碼才開始解碼

{           

irdata[i]=irtime;//存儲(chǔ)每個(gè)電平的持續(xù)時(shí)間,用于以后判斷是0還是1

                                    irtime=0;

                                    i++;

                                                    if(i==33)

                                                    {

                                                                   irok=1;

                                                                      i=0;

                                          startflag=0;

                                                                      ir_flag=1;                                                                               //接收完33個(gè)數(shù)據(jù),清0接收數(shù)據(jù)位,即不再接收數(shù)據(jù)

                                                        }

 }

else

{

startflag==1

i=0;

                            return;

}

}

              這個(gè)程序的算法是那些重復(fù)碼會(huì)隔一個(gè)進(jìn)入解碼程序一個(gè),進(jìn)處解碼程序的那個(gè)又會(huì)被過濾掉,也說是說第一個(gè)重復(fù)碼的下降沿會(huì)進(jìn)入else   starflag=1……的那個(gè)語句.下一個(gè)重復(fù)碼的下降沿會(huì)被過濾掉,因?yàn)樗粷M足那個(gè)引導(dǎo)碼時(shí)間的那個(gè)條件.所以他會(huì)被過濾掉.這就要求那個(gè)引導(dǎo)碼的時(shí)間要足夠的準(zhǔn)確,范圍也要足夠的小,如果重復(fù)碼和引導(dǎo)碼比效相似的話那么事情就不妙了,那個(gè)條件就起不到過濾的作用了.這個(gè)嚴(yán)酷的條件也是這個(gè)程序的精髓.

本文未完下接<幾種比較流行和成熟的紅外解碼程序做一下研究和總結(jié)2>:http://www.zg4o1577.cn/mcu/4353.html

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 欧美极品视频在线观看 | 超碰520 | 蜜月aⅴ免费一区二区三区 99re在线视频 | 蜜桃av一区二区三区 | 国产美女永久免费无遮挡 | 亚洲精品成人av | 欧美黄色片 | 亚洲一区二区久久 | 国产亚洲精品久久久久动 | 成人性视频免费网站 | 国产免费一区二区三区最新6 | 日韩一二区在线 | 亚洲a在线观看 | 国产成人精品一区二区 | 三级成人在线观看 | 欧美一级在线观看 | 亚洲欧洲一区 | 韩国电影久久 | 免费同性女女aaa免费网站 | 日韩国产一区二区三区 | 91婷婷韩国欧美一区二区 | a级黄色网| 国产在线二区 | 久久综合久色欧美综合狠狠 | 久久久精品影院 | 国产精品久久久久久久久免费 | 99精品国产一区二区青青牛奶 | 亚洲成人天堂 | 久久久这里都是精品 | 日韩在线小视频 | 精品一二三 | 日韩一区二区福利 | 久久久xx | 99综合| 久久精品一级 | 日韩欧美网 | 四虎最新视频 | 亚洲高清久久 | 国产精品免费小视频 | 日韩成人在线视频 | 日韩中文字幕一区二区 |