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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5960|回復: 16
打印 上一主題 下一主題
收起左側

關于紅外遙控器如何做長按識別問題,求大神指教一下

  [復制鏈接]
回帖獎勵 30 黑幣 回復本帖可獲得 30 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:607312 發表于 2021-7-6 09:15 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
//*********************************************************
/*  文件名:TEST_61F02x_Timer2.c
*        功能:  FT61F02x-Time2功能演示
*   IC:    FT61F023 SOP16
*   晶振:  16M/2T                    
*   說明:  當DemoPortIn懸空或者高電平時,
*                   DemoPortOut輸出5KHz占空比50%的波形-Tm2實現
*                   當DemoPortIn接地時,DemoPortOut輸出高電平.關定時器

*                  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,用戶請將相應IO設置為輸入
#define         BootCode         0x0D                                //引導碼

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碼除去引導碼 后的用戶碼
volatile bits RecWork;                                        //工作位域
#define Rflag                        RecWork.all
#define        Flag_RecOne                RecWork.one.b0        //收到5104碼標志位        

void RecServer();
void InfraredReception();                                //接收函數,在中斷中調用


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

//#define                GREEN                RA7                        //0開 1關
#define                Led1                PA7
#define                Led2                PC3                //1開 0關

volatile bit B_MainLoop;

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

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

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

}

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


                //case 0x82:        Led1 = ~Led1; break;//開/風速                        
         //case 0x81:        Led1 = ~Led1; break;//關機
                //        case 0x90:        Led2 = ~Led2; break;//搖頭
                //        case 0x84:        Led1 = ~Led1; break;//風類
                //        case 0xc3:        Led1 = ~Led1; break;//彩燈
                //case 0x88:        Led2 = ~Led2; break;// 定時
                        default:break;
                }                                
        }        
}

/***********************************************
函數名稱:InfraredReception
函數功能:5104紅外接收解碼
入口參數:無
出口參數:無
備注:
************************************************/
void InfraredReception()
{
        static unsigned char rlow = 0,rhigh = 0,rcount = 0,rdata = 0;
        
        if(!REC)
                rlow++;                                                                        //低電平計時
        else if(0 == rlow)
        {
                rhigh++;                                                                //高電平計時
                if(rhigh & (0x20))                                                //持續4ms高電平,重新接受引導碼
                {
                        Rflag &= 0b11101111;
                        rdata = 0;
                        if(rhigh & (0x80))                                        //持續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))                                        //是否已經收到了引導碼
                {
                        if(BootCode == (rdata & 0x0f))                //還未收到引導碼,判斷是否是正確的引導碼
                        {
                                Rflag |= 0x10;                                        //收到引導碼標志
                                rcount = 0;                                                //準備接收數據碼
                                rdata = 0;
                        }
                }
                else
                {
                        rcount++;
                        if(rcount & 0x8)                                        //8位數據碼接收完成
                        {
                                if(RecCode == rdata)                        //收到2幀相同的碼才處理
                                {
                                        if(0 == (Rflag & 0x80))                //已經響應過了,不再重復處理
                                        {
                                                Rflag |= 0x01;                        //收到按鍵碼標志
                                                Rflag |= 0x80;                        //用于判斷長按鍵的標志,持續20ms高電平才清零
                                        }
                                }               
                                else
                                        RecCode = rdata;
                        }
                }
        }
}


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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:607312 發表于 2021-7-6 09:16 | 只看該作者
代碼是可以執行的遙控器短按,不過只能執行一次,如何做到長按遞增或者遞減呢
回復

使用道具 舉報

板凳
ID:814525 發表于 2021-7-6 12:01 | 只看該作者
參考紅外NEC通訊協議,有長按重復代碼
回復

使用道具 舉報

地板
ID:161164 發表于 2021-7-6 13:43 | 只看該作者
你先要知到短按和長按的紅外編碼的分別
回復

使用道具 舉報

5#
ID:887202 發表于 2021-7-6 17:01 | 只看該作者
短按時發送一個完整的紅外波形,包括引導碼,用戶碼,鍵碼,長按的時候會先發送一次完整的波形,然后就會一直發送重復碼,不會再發送用戶碼和鍵碼,所以區別長按和短按最好的方法就是去識別收到的波形時引導碼還是重復碼,因為引導碼和重復碼高電平分別為4.5ms和2.25ms,所以可在上升沿后定時器延時3.5ms,此時電平為高則是引導碼,那么就可以正常解碼,如果為低那么就是重復碼
回復

使用道具 舉報

6#
ID:887202 發表于 2021-7-6 17:02 | 只看該作者
短按時發送一個完整的紅外波形,包括引導碼,用戶碼,鍵碼,長按的時候會先發送一次完整的波形,然后就會一直發送重復碼,不會再發送用戶碼和鍵碼,所以區別長按和短按最好的方法就是去識別收到的波形時引導碼還是重復碼,因為引導碼和重復碼高電平分別為4.5ms和2.25ms,所以可在上升沿后定時器延時3.5ms,此時電平為高則是引導碼,那么就可以正常解碼,如果為低那么就是重復碼
回復

使用道具 舉報

7#
ID:607312 發表于 2021-7-6 17:41 | 只看該作者
sadv 發表于 2021-7-6 17:01
短按時發送一個完整的紅外波形,包括引導碼,用戶碼,鍵碼,長按的時候會先發送一次完整的波形,然后就會一 ...

大神可以在我的代碼上班修改一下嗎?讓代碼實現長短按
回復

使用道具 舉報

8#
ID:607312 發表于 2021-7-6 17:42 | 只看該作者
lkc8210 發表于 2021-7-6 13:43
你先要知到短按和長按的紅外編碼的分別

怎么區分呢,指教一下,
回復

使用道具 舉報

9#
ID:887202 發表于 2021-7-7 09:06 | 只看該作者
cdiyy 發表于 2021-7-6 17:41
大神可以在我的代碼上班修改一下嗎?讓代碼實現長短按

別人跟你改你是學不到東西的啦,要自己思考,理解紅外協議,理解為一行代碼作用是什么,這樣子才算學到了。給你一份我用過的代碼,因為我主函數里面處理的東西比較多,所以這里是直接在中斷中解碼的,低電平觸發進中斷。TR0,TL0是什么不用我說了,test[]這個數組主要是為了TH0<=X中X的值具體取多少而設置的,實際解碼用不到的,把X的值都填上去以后可以注釋掉。仔細看看吧,我覺得還是寫的挺詳細的了
       UINT8 i,j;
        TR0=0;  
        TL0=0;
        TH0=0;
        TR0=1;
        test[3]=P2;
        while((P2&0x20) ==0&&TH0<=0x4E);                //等待9ms低電平過去       
        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電平狀態,為低說明是重復碼,退出函數
                {
                        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低電平過去
                                while((P2&0x20));                               
                                IR_DATA>>=1;
                                if(TH0>=13)
                                {
                                        IR_DATA|=0x80;
                                       
                                }
                        }
                }
                it_flag=1;
        }
        else
                error1=1;
回復

使用道具 舉報

10#
ID:607312 發表于 2021-7-7 10:48 | 只看該作者
sadv 發表于 2021-7-7 09:06
別人跟你改你是學不到東西的啦,要自己思考,理解紅外協議,理解為一行代碼作用是什么,這樣子才算學到了 ...

感謝大神,在你這個參考上我完美的解決長按了,不過還不是很靈敏,我再調試一下,感謝感謝
回復

使用道具 舉報

11#
ID:951816 發表于 2021-7-11 16:28 | 只看該作者
簡單點的話,其實也可以用定時器,比如你定時器記一個time的數,那么在整個遙控的過程中,time不會大于( 隔110ms左右發一次引導碼(重復),并不帶任何數據(全部為高電平))150/256us約等于600,那么你在一個循環里就可以寫 ps:定時器我用的8位自動重裝
if(time<600)
回復

使用道具 舉報

12#
ID:548551 發表于 2021-7-11 16:41 | 只看該作者
FMD 的單片機?
回復

使用道具 舉報

13#
ID:61261 發表于 2021-7-12 07:46 | 只看該作者
添加計時器也是不錯的辦法
回復

使用道具 舉報

14#
ID:781863 發表于 2021-7-29 14:01 | 只看該作者
長按的話,可以用mode的形式,定義一個mode全局變量,正點原子那個有參考的
回復

使用道具 舉報

15#
ID:954677 發表于 2021-7-29 19:17 | 只看該作者
定時器和按鍵觸發延時
回復

使用道具 舉報

16#
ID:607312 發表于 2021-7-31 09:27 | 只看該作者
1024153202 發表于 2021-7-29 14:01
長按的話,可以用mode的形式,定義一個mode全局變量,正點原子那個有參考的

用鏈接嗎?
回復

使用道具 舉報

17#
ID:948865 發表于 2021-7-31 23:19 | 只看該作者
增加定時器程序,等到按鍵按下后監測按鍵時長,等到按鍵彈起停止計時,每次計數完成記得清零
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品国产一区二区三区性色av | 成人综合视频在线观看 | 欧美一区视频 | 91成人在线视频 | 亚洲成人一区 | 国产高清视频在线观看 | chengrenzaixian | 国产精品亚洲一区 | 国产三级在线观看播放 | 免费v片在线观看 | 欧美黄视频 | 久久久久久综合 | 一区二区精品 | 五月激情婷婷网 | 久久99精品国产自在现线小黄鸭 | 1区2区视频 | 黄色国产大片 | 亚洲成人精品国产 | 国产精品久久性 | 精品视频亚洲 | 久久精品国产久精国产 | 久久久91精品国产一区二区三区 | 国产1区2区3区| 国产在线对白 | 久久国内精品 | 久久久久久高潮国产精品视 | 亚洲三区在线观看 | 国产一级视频在线 | 男女免费在线观看视频 | 久久不射网 | 久久成人免费 | 雨宫琴音一区二区在线 | 美日韩免费 | 国产精品视频播放 | 国产视频精品视频 | 国产男女猛烈无遮掩视频免费网站 | 91视频在线 | 免费在线看黄 | caoporn免费在线视频 | 久久久久久久久中文字幕 | 亚洲欧美日韩精品久久亚洲区 |