找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 6040|回復(fù): 16
收起左側(cè)

關(guān)于紅外遙控器如何做長(zhǎng)按識(shí)別問(wèn)題,求大神指教一下

  [復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 30 黑幣 回復(fù)本帖可獲得 30 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
ID:607312 發(fā)表于 2021-7-6 09:15 | 顯示全部樓層 |閱讀模式
//*********************************************************
/*  文件名:TEST_61F02x_Timer2.c
*        功能:  FT61F02x-Time2功能演示
*   IC:    FT61F023 SOP16
*   晶振:  16M/2T                    
*   說(shuō)明:  當(dāng)DemoPortIn懸空或者高電平時(shí),
*                   DemoPortOut輸出5KHz占空比50%的波形-Tm2實(shí)現(xiàn)
*                   當(dāng)DemoPortIn接地時(shí),DemoPortOut輸出高電平.關(guān)定時(shí)器

*                  FT61F023  SOP16
*                 ----------------
*  VDD-----------|1(VDD)   (VSS)16|-----------GND     
*  NC------------|2(PA7)   (PA0)15|------------NC
*  NC------------|3(PA6)   (PA1)14|------------NC
*  NC------------|4(PA5)   (PA2)13|------------NC
*  DemoPortIn----|5(PC3)   (PA3)12|---DemoPortOut
*  NC------------|6(PC2)   (PC0)11|------------NC
*  NC------------|7(PA4)   (PC1)10|------------NC
*  NC------------|8(PC5)   (PC4)09|------------NC
*                              ----------------
*/
//*********************************************************
#include "SYSCFG.h"
//#include "Infrared_Rece_5104.h"

//**********************************************************


#define                REC                        PA4                                        //紅外接收IO,用戶請(qǐng)將相應(yīng)IO設(shè)置為輸入
#define         BootCode         0x0D                                //引導(dǎo)碼

typedef union
{
    unsigned char  all;
    struct
    {
       unsigned b0:1;
       unsigned b1:1;
       unsigned b2:1;
       unsigned b3:1;
       unsigned b4:1;
       unsigned b5:1;
           unsigned b6:1;
       unsigned b7:1;
    }one;
}bits;


volatile unsigned char RecCode;                        //5104碼除去引導(dǎo)碼 后的用戶碼
volatile bits RecWork;                                        //工作位域
#define Rflag                        RecWork.all
#define        Flag_RecOne                RecWork.one.b0        //收到5104碼標(biāo)志位        

void RecServer();
void InfraredReception();                                //接收函數(shù),在中斷中調(diào)用


//***********************宏定義*****************************
#define  unchar     unsigned char
#define  unint      unsigned int
#define  unlong     unsigned long

//#define                GREEN                RA7                        //0開(kāi) 1關(guān)
#define                Led1                PA7
#define                Led2                PC3                //1開(kāi) 0關(guān)

volatile bit B_MainLoop;

/*-------------------------------------------------
*  函數(shù)名:POWER_INITIAL
*        功能:  上電系統(tǒng)初始化
*  輸入:  無(wú)
*  輸出:  無(wú)
--------------------------------------------------*/
//********************************************************
//**************中斷處理**********************************
void interrupt ISR(void)           //PIC_HI-TECH使用
{
   static unsigned char times;
  //定時(shí)器2的中斷處理**********************
        if(TMR2IE && TMR2IF)           //100us中斷一次
        {
                TMR2IF = 0;
                if(++times >= 20)//20*125us = 2.5ms
                {
                        times = 0;
                        B_MainLoop = 1;
                }
               
                InfraredReception();                                        //調(diào)用紅外接收函數(shù)

        }
}
/*-------------------------------------------------
*  函數(shù)名:POWER_INITIAL
*        功能:  上電系統(tǒng)初始化
*  輸入:  無(wú)
*  輸出:  無(wú)
--------------------------------------------------*/        
void POWER_INITIAL (void)
{
         
        OSCCON = 0B01110001;    //WDT 32KHZ IRCF=111=16MHZ/2=8MHZ,0.125US/T
                                                //Bit0=1,系統(tǒng)時(shí)鐘為內(nèi)部振蕩器
                                                //Bit0=0,時(shí)鐘源由FOSC<2:0>決定即編譯選項(xiàng)時(shí)選擇
        INTCON = 0;             //暫禁止所有中斷
        PORTA = 0B00000000;
        TRISA = 0B00010000;            //PA輸入輸出 0-輸出 1-輸入
                                                    //PA3->輸出         
        PORTC = 0B00000000;
        TRISC = 0B00000000;            //PC輸入輸出 0-輸出 1-輸入                                                  
        WPUA = 0B00010000;      //PA端口上拉控制 1-開(kāi)上拉 0-關(guān)上拉
        WPUC = 0B00000000;      //PC端口上拉控制 1-開(kāi)上拉 0-關(guān)上拉
        OPTION = 0B00001000;        //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
                                                        //Bit3 預(yù)分頻器分配位 0-Timer0 1-WDT
                                                        //Bit7(PAPU)=0 ENABLED PULL UP PA
        MSCKCON = 0B00000000;   //Bit6->0,禁止PA4,PC5穩(wěn)壓輸出
                                                //Bit5->0,TIMER2時(shí)鐘為Fosc
                                                //Bit4->0,禁止LVR      
        CMCON0 = 0B00000111;    //關(guān)閉比較器,CxIN為數(shù)字IO口

}
/*-------------------------------------------------
* 函數(shù)名稱:   TIMER2_INITIAL
* 功能:      初始化設(shè)置定時(shí)器2
* 相關(guān)寄存器: T2CON TMR2 PR2 TMR2IE TMR2IF PEIE GIE
-------------------------------------------------*/
void TIMER2_INITIAL (void)
{
        T2CON = 0B00000001; //Bit[1,0]=01,T2時(shí)鐘分頻 1:4
                                    //Bit[6-3]=0000,T2輸出時(shí)鐘分頻1:1
        TMR2 = 0;           //TMR2賦初值
        PR2 = 200;          //設(shè)置TMR2輸出比較值定時(shí)100us=(1/16000000)*2*4*200(PR2)
                                                //16M-2T-4分頻
        TMR2IF = 0;         //清TIMER2中斷標(biāo)志
        TMR2IE = 1;         //使能TIMER2的中斷
        TMR2ON = 1;         //使能TIMER2啟動(dòng)
        PEIE=1;             //使能外設(shè)中斷
        GIE = 1;            //使能全局中斷

}

/***********************************************
函數(shù)名稱:RecServer
函數(shù)功能:5104紅外接收按鍵處理
入口參數(shù):無(wú)
出口參數(shù):無(wú)
備注:
************************************************/
void RecServer()
{
        if(1 == Flag_RecOne)
        {
                Flag_RecOne = 0;
                switch(RecCode)
                {
                    
                        case 0x0A:        Led1 = ~Led1; break;//測(cè)試
            case 0x15:        Led1 = ~Led1; break;//測(cè)試
            case 0x19:        Led1 = ~Led1; break;//測(cè)試


                //case 0x82:        Led1 = ~Led1; break;//開(kāi)/風(fēng)速                        
         //case 0x81:        Led1 = ~Led1; break;//關(guān)機(jī)
                //        case 0x90:        Led2 = ~Led2; break;//搖頭
                //        case 0x84:        Led1 = ~Led1; break;//風(fēng)類
                //        case 0xc3:        Led1 = ~Led1; break;//彩燈
                //case 0x88:        Led2 = ~Led2; break;// 定時(shí)
                        default:break;
                }                                
        }        
}

/***********************************************
函數(shù)名稱:InfraredReception
函數(shù)功能:5104紅外接收解碼
入口參數(shù):無(wú)
出口參數(shù):無(wú)
備注:
************************************************/
void InfraredReception()
{
        static unsigned char rlow = 0,rhigh = 0,rcount = 0,rdata = 0;
        
        if(!REC)
                rlow++;                                                                        //低電平計(jì)時(shí)
        else if(0 == rlow)
        {
                rhigh++;                                                                //高電平計(jì)時(shí)
                if(rhigh & (0x20))                                                //持續(xù)4ms高電平,重新接受引導(dǎo)碼
                {
                        Rflag &= 0b11101111;
                        rdata = 0;
                        if(rhigh & (0x80))                                        //持續(xù)20ms高電平,重新收碼
                        {
                                RecCode = 0;
                                rhigh = 0;
                                Rflag &= 0b01111111;                                
                        }
                }
        }
        else
        {
                rdata <<= 1;
                if(rlow >= (0x8))                                                //上升沿,判斷碼值,低電平大于1ms為1,否則為0
                        rdata |= 0x01;
               
                rlow = 0;
                rhigh = 0;
                if(0 == (Rflag & 0x10))                                        //是否已經(jīng)收到了引導(dǎo)碼
                {
                        if(BootCode == (rdata & 0x0f))                //還未收到引導(dǎo)碼,判斷是否是正確的引導(dǎo)碼
                        {
                                Rflag |= 0x10;                                        //收到引導(dǎo)碼標(biāo)志
                                rcount = 0;                                                //準(zhǔn)備接收數(shù)據(jù)碼
                                rdata = 0;
                        }
                }
                else
                {
                        rcount++;
                        if(rcount & 0x8)                                        //8位數(shù)據(jù)碼接收完成
                        {
                                if(RecCode == rdata)                        //收到2幀相同的碼才處理
                                {
                                        if(0 == (Rflag & 0x80))                //已經(jīng)響應(yīng)過(guò)了,不再重復(fù)處理
                                        {
                                                Rflag |= 0x01;                        //收到按鍵碼標(biāo)志
                                                Rflag |= 0x80;                        //用于判斷長(zhǎng)按鍵的標(biāo)志,持續(xù)20ms高電平才清零
                                        }
                                }               
                                else
                                        RecCode = rdata;
                        }
                }
        }
}


/*-------------------------------------------------
*  函數(shù)名: main
*        功能:  主函數(shù)
*  輸入:  無(wú)
*  輸出:  無(wú)
--------------------------------------------------*/
void main()
{
        POWER_INITIAL();            //系統(tǒng)初始化
        TIMER2_INITIAL();       //初始化T2
        
        while(1)
        {
                if(B_MainLoop)                                //2.5ms執(zhí)行一次
                {
                        B_MainLoop = 0;
               
                        RecServer();                        //紅外接收處理
                        //Led2 = 1;
                }
        }
}

回復(fù)

使用道具 舉報(bào)

ID:607312 發(fā)表于 2021-7-6 09:16 | 顯示全部樓層
代碼是可以執(zhí)行的遙控器短按,不過(guò)只能執(zhí)行一次,如何做到長(zhǎng)按遞增或者遞減呢
回復(fù)

使用道具 舉報(bào)

ID:814525 發(fā)表于 2021-7-6 12:01 | 顯示全部樓層
參考紅外NEC通訊協(xié)議,有長(zhǎng)按重復(fù)代碼
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2021-7-6 13:43 | 顯示全部樓層
你先要知到短按和長(zhǎng)按的紅外編碼的分別
回復(fù)

使用道具 舉報(bào)

ID:887202 發(fā)表于 2021-7-6 17:01 | 顯示全部樓層
短按時(shí)發(fā)送一個(gè)完整的紅外波形,包括引導(dǎo)碼,用戶碼,鍵碼,長(zhǎng)按的時(shí)候會(huì)先發(fā)送一次完整的波形,然后就會(huì)一直發(fā)送重復(fù)碼,不會(huì)再發(fā)送用戶碼和鍵碼,所以區(qū)別長(zhǎng)按和短按最好的方法就是去識(shí)別收到的波形時(shí)引導(dǎo)碼還是重復(fù)碼,因?yàn)橐龑?dǎo)碼和重復(fù)碼高電平分別為4.5ms和2.25ms,所以可在上升沿后定時(shí)器延時(shí)3.5ms,此時(shí)電平為高則是引導(dǎo)碼,那么就可以正常解碼,如果為低那么就是重復(fù)碼
回復(fù)

使用道具 舉報(bào)

ID:887202 發(fā)表于 2021-7-6 17:02 | 顯示全部樓層
短按時(shí)發(fā)送一個(gè)完整的紅外波形,包括引導(dǎo)碼,用戶碼,鍵碼,長(zhǎng)按的時(shí)候會(huì)先發(fā)送一次完整的波形,然后就會(huì)一直發(fā)送重復(fù)碼,不會(huì)再發(fā)送用戶碼和鍵碼,所以區(qū)別長(zhǎng)按和短按最好的方法就是去識(shí)別收到的波形時(shí)引導(dǎo)碼還是重復(fù)碼,因?yàn)橐龑?dǎo)碼和重復(fù)碼高電平分別為4.5ms和2.25ms,所以可在上升沿后定時(shí)器延時(shí)3.5ms,此時(shí)電平為高則是引導(dǎo)碼,那么就可以正常解碼,如果為低那么就是重復(fù)碼
回復(fù)

使用道具 舉報(bào)

ID:607312 發(fā)表于 2021-7-6 17:41 | 顯示全部樓層
sadv 發(fā)表于 2021-7-6 17:01
短按時(shí)發(fā)送一個(gè)完整的紅外波形,包括引導(dǎo)碼,用戶碼,鍵碼,長(zhǎng)按的時(shí)候會(huì)先發(fā)送一次完整的波形,然后就會(huì)一 ...

大神可以在我的代碼上班修改一下嗎?讓代碼實(shí)現(xiàn)長(zhǎng)短按
回復(fù)

使用道具 舉報(bào)

ID:607312 發(fā)表于 2021-7-6 17:42 | 顯示全部樓層
lkc8210 發(fā)表于 2021-7-6 13:43
你先要知到短按和長(zhǎng)按的紅外編碼的分別

怎么區(qū)分呢,指教一下,
回復(fù)

使用道具 舉報(bào)

ID:887202 發(fā)表于 2021-7-7 09:06 | 顯示全部樓層
cdiyy 發(fā)表于 2021-7-6 17:41
大神可以在我的代碼上班修改一下嗎?讓代碼實(shí)現(xiàn)長(zhǎng)短按

別人跟你改你是學(xué)不到東西的啦,要自己思考,理解紅外協(xié)議,理解為一行代碼作用是什么,這樣子才算學(xué)到了。給你一份我用過(guò)的代碼,因?yàn)槲抑骱瘮?shù)里面處理的東西比較多,所以這里是直接在中斷中解碼的,低電平觸發(fā)進(jìn)中斷。TR0,TL0是什么不用我說(shuō)了,test[]這個(gè)數(shù)組主要是為了TH0<=X中X的值具體取多少而設(shè)置的,實(shí)際解碼用不到的,把X的值都填上去以后可以注釋掉。仔細(xì)看看吧,我覺(jué)得還是寫(xiě)的挺詳細(xì)的了
       UINT8 i,j;
        TR0=0;  
        TL0=0;
        TH0=0;
        TR0=1;
        test[3]=P2;
        while((P2&0x20) ==0&&TH0<=0x4E);                //等待9ms低電平過(guò)去       
        test[4]=P2;
        test[1]=TH0;
        test[1] =test[1]<<8;
        test[1] |=TL0;
        if((P2&0x20))
        {
                TR0=0;
                TL0=0;
                TH0=0;
                TR0=1;
                while((P2&0x20)&&TH0<0x14);                //等待3ms高電平
                if(!(P2&0x20))                //查看IR電平狀態(tài),為低說(shuō)明是重復(fù)碼,退出函數(shù)
                {
                        return;
                }       
                TR0=0;
                TL0=0;
                TH0=0;
                TR0=1;
                while((P2&0x20)&&TH0<0xF);                //等待2ms高電平
                test[5]=P2;
                test[2]=TH0;
                test[2] =test[2]<<8;
                test[2] |=TL0;
                for(i=0;i<4;i++)
                {
                        for(j=0;j<8;j++)
                        {
                                TR0=0;
                                TH0=0;
                                TL0=0;
                                TR0=1;

                                while((P2&0x20)==0&&TH0<=5);                //等待560us低電平過(guò)去
                                while((P2&0x20));                               
                                IR_DATA>>=1;
                                if(TH0>=13)
                                {
                                        IR_DATA|=0x80;
                                       
                                }
                        }
                }
                it_flag=1;
        }
        else
                error1=1;
回復(fù)

使用道具 舉報(bào)

ID:607312 發(fā)表于 2021-7-7 10:48 | 顯示全部樓層
sadv 發(fā)表于 2021-7-7 09:06
別人跟你改你是學(xué)不到東西的啦,要自己思考,理解紅外協(xié)議,理解為一行代碼作用是什么,這樣子才算學(xué)到了 ...

感謝大神,在你這個(gè)參考上我完美的解決長(zhǎng)按了,不過(guò)還不是很靈敏,我再調(diào)試一下,感謝感謝
回復(fù)

使用道具 舉報(bào)

ID:951816 發(fā)表于 2021-7-11 16:28 | 顯示全部樓層
簡(jiǎn)單點(diǎn)的話,其實(shí)也可以用定時(shí)器,比如你定時(shí)器記一個(gè)time的數(shù),那么在整個(gè)遙控的過(guò)程中,time不會(huì)大于( 隔110ms左右發(fā)一次引導(dǎo)碼(重復(fù)),并不帶任何數(shù)據(jù)(全部為高電平))150/256us約等于600,那么你在一個(gè)循環(huán)里就可以寫(xiě) ps:定時(shí)器我用的8位自動(dòng)重裝
if(time<600)
回復(fù)

使用道具 舉報(bào)

ID:548551 發(fā)表于 2021-7-11 16:41 | 顯示全部樓層
FMD 的單片機(jī)?
回復(fù)

使用道具 舉報(bào)

ID:61261 發(fā)表于 2021-7-12 07:46 | 顯示全部樓層
添加計(jì)時(shí)器也是不錯(cuò)的辦法
回復(fù)

使用道具 舉報(bào)

ID:781863 發(fā)表于 2021-7-29 14:01 | 顯示全部樓層
長(zhǎng)按的話,可以用mode的形式,定義一個(gè)mode全局變量,正點(diǎn)原子那個(gè)有參考的
回復(fù)

使用道具 舉報(bào)

ID:954677 發(fā)表于 2021-7-29 19:17 | 顯示全部樓層
定時(shí)器和按鍵觸發(fā)延時(shí)
回復(fù)

使用道具 舉報(bào)

ID:607312 發(fā)表于 2021-7-31 09:27 | 顯示全部樓層
1024153202 發(fā)表于 2021-7-29 14:01
長(zhǎng)按的話,可以用mode的形式,定義一個(gè)mode全局變量,正點(diǎn)原子那個(gè)有參考的

用鏈接嗎?
回復(fù)

使用道具 舉報(bào)

ID:948865 發(fā)表于 2021-7-31 23:19 | 顯示全部樓層
增加定時(shí)器程序,等到按鍵按下后監(jiān)測(cè)按鍵時(shí)長(zhǎng),等到按鍵彈起停止計(jì)時(shí),每次計(jì)數(shù)完成記得清零
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表