找回密碼
         注冊會員
        搜索附件  
        MCU資訊論壇 附件中心 單片機論壇 51單片機論壇 5_3_8a406e32d893628.jpg

        5_3_8a406e32d893628.jpg

         

        紅外遙控解碼完全資料(LCD1602顯示):
        紅外遙控解碼實驗
        一. 實驗目的
        1. 了解紅外遙控編碼并用單片機捕捉信號及解碼
        2. 熟悉LCD1602的驅動
        二.紅外遙控器編碼
        遙控器編碼分好幾種,常見的32位編碼碼和42位編碼碼,目前我手中遙控器就是42位編碼,如圖1所示,當有按鍵時就會產一個9.12ms低電平和4.5ms高電平的起始碼,緊接著是26位系統碼,此系統碼能區別不同的電器設備,防止不同機種遙控碼互相干擾,接下來是8位數據碼和8位數據反碼,間隔23ms的高電平后,再發一個與啟始碼完全一樣的結束碼







        以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進制的“0”;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進制的“1”,其波形如圖2所示。



        圖2

        再回頭看圖1,大家不難看出,圖1是遙控器按鍵1的一串編碼



        三. 硬件連接
        接收電咱我們使用一化紅外接紅外接收管1838,不需要任何外接無件,就能完成從紅外線接收到輸出與TTL電平信號兼容的所有工作,實物如圖所示





        電路圖如下:




        四. 解碼
        以上我們了解了紅外遙控的編碼及硬件連接,現在就對其進行解碼,所謂解碼就是能用單片機把以不同寬度的脈沖區別開來,一種比較好思路就是計算兩次下降沿間隔時間,當單片機外部中斷1口有下降沿時中斷一次,并啟動定時器,定時器定50us,當下次下降沿到來時我們計算定時器中斷的次數,這樣我們就能很好的區分不同寬度的脈沖了。
        大家可能已經迫不急待的要開始解碼了,別急,我們先把注意事項先講一下,實際上,我們紅外接收頭收到的信號的是有毛刺的,放大后就如下圖,所以在下降沿中斷觸發后,要做延時去抖處理





        *************************************以下是完整解碼程序********************************




        /*********************************************
        **項目: 紅外遙控解碼(EE01學習板演示程序)

        **作者:一線工人

        **網站:電子工程師之家 www.eehome.cn

        **本程序適合42位碼遙控器,即26位系統碼,16位

        數據碼,如:57L5,55K2,54B4,KD-29,55K8,5Z26A,

        等型號的遙控器,轉貼請保持代碼的完整性
        *********************************************/

        #include<reg52.h>

        #define uint unsigned int
        #define uchar unsigned char


        sbit ir=P3^3;//紅外端口
        sbit dm=P1^4;//數碼管段碼控制位
        sbit wm=P1^5;//數碼管位碼控制位
        sbit led_cs=P1^6;//LED控制位
        sbit rs=P3^5;//1602數據命令選擇端
        sbit en=P3^4;//1602使能信號

        uchar num;
        uchar key_code=0;//遙控鍵值
        uchar new_code=0;//有無新按鍵
        uint buf_key_code=0;//鍵值暫存
        uchar key_bit_count=0;//鍵編碼脈沖計數
        uint count=0;//定時中斷次數計數
        uint buf_count=0;//定時中斷計數暫存
        uchar common_code_count=0;//前導碼脈沖計數
        uchar ir_status=0;//脈沖接收器所處的狀態,0:無信號,1:系統碼接收區,2:數據編碼接收區
        uchar code table[]="EE01 DEMO:IR";
        uchar code table1[]="code:";
        uchar code table2[]={'0','1','2','3','4','5','6','7','8','9',};

        void delay_10us(unsigned char y)///延時子程序10us
        {
        unsigned char x;
        for(x=y;x>0;x--);
        }
        void delay_ms(uint z)//延時子程序1ms
        {
        uint x,y;
        for(x=z;x>0;x--)
        for(y=113;y>0;y--);
        }


        void init(void)/////初始化
        {
        ir=1; //紅外端口寫1
        led_cs=0; //關閉LED
        EA=1; //開總中斷
        TMOD=0x02; //定時器0,模式2,8位自動裝載模式
        TH0=0Xd1; //定時50us
        TL0=0Xd1;
        IT1=1; //INT1下降沿觸發
        ET0=1; //允許定時器中斷
        EX1=1; //允許外部中斷
        }


        /***********************************************
        定時器中斷

        ***********************************************/
        void time0() interrupt 1///定時器中斷
        {
        count++;//定時器中斷次數累加
        }


        /**********************************************
        外部中斷,紅外解碼程序
        **********************************************/
        void int1() interrupt 2///外部中斷
        {

        TR0=1;//開定時器中斷
        if(count>12&&count<270)//如果信號合法,則放入buf_count,count清0,對下一個脈沖信號計時
        {
        buf_count=count;
        count=0;
        }
        delay_10us(10);//延時100us以消除下降沿跳變抖動
        if(ir==0)//INT1引腳穩定為低電平,則表法確實是信號,count重新計時,因上面延時了50us,故要補償1次TO中斷
        {
        count=2;
        }
        if(buf_count>12&&buf_count<270)//若收到的信號合法,則再進行信號分析
        {
        if(ir_status==0)//如果之前未收到引導碼
        {
        if(buf_count>210&&buf_count<270)//判斷是否引導碼13.5ms
        {
        ir_status=1;//系統標記
        buf_count=0;//
        }
        }
        else if(ir_status==1)///收到引導碼
        {

        if(common_code_count>=25)//若收完26個脈沖
        {

        ir_status=2;//數據解碼標記
        common_code_count=0;//系統碼計算清零
        buf_count=0;//中斷計數暫存清0
        }

        else if((buf_count>40&&buf_count<70)||(buf_count>12&&buf_count<32))
        {
        buf_count=0;
        common_code_count++;//每收到一個信號自加1
        }

        }

        else if(ir_status==2)//進入數據編碼接收
        {
        if(key_bit_count<8)//收到數據少于8位,則將收到的數據寫入buf_key_code
        {

        if(buf_count>40&&buf_count<70)
        {
        buf_count=0;
        buf_key_code>>=1;
        buf_key_code|=0x80;//收到1
        key_bit_count++;//數據脈沖累加
        }
        else if(buf_count>12&&buf_count<32)//收到0
        {
        buf_count=0;
        buf_key_code>>=1;//收到0
        key_bit_count++;
        }
        }

        else //若收完8位數據則做以下處理
        {

        ir_status=0;//接收狀態返回到空閑
        key_code=buf_key_code;
        key_bit_count=0;
        buf_key_code=0;
        buf_count=0;
        TR0=0;
        new_code=1;


        }
        }
        }
        }

        /**********************************************
        1062驅動程序
        **********************************************/


        void wirte_cmd(uchar cmd)//寫命令
        {
        rs=0;
        P0=cmd;
        en=1;
        delay_ms(5);
        en=0;

        }

        void wirte_data(uchar dat)//寫數據
        {
        rs=1;
        P0=dat;
        en=1;
        delay_ms(5);
        en=0;

        }
        void wirte_string(const unsigned char *s)//在第二行第5個字開始寫字符串
        {
        wirte_cmd(0x80+0x40+0x05);
        while(*s)
        {
        wirte_data(*s);
        s++;
        }
        }
        void init_1602()///1602初始化

        {
        dm=0;
        wm=0;
        led_cs=0;
        wirte_cmd(0x38);
        delay_ms(5);
        wirte_cmd(0x0c);
        delay_ms(5);
        wirte_cmd(0x06);

        }
        /*************************************
        主程序
        *************************************/
        void main()
        {
        init(); ///初始化
        init_1602(); //1602初始化
        while(!new_code);//判斷是否有新按鍵,如果有則執行下面程序,沒有則一直循環
        wirte_cmd(0x01);//1602清屏
        delay_ms(5);
        wirte_cmd(0x80);//在第一行寫入EE01 DEMO:IR
        for(num=0;num<12;num++)
        {
        wirte_data(table[num]);
        delay_ms(1);
        }
        wirte_cmd(0x80+0x40);//在第二行寫入code:
        for(num=0;num<5;num++)
        {
        wirte_data(table1[num]);
        delay_ms(1);
        }

        if(key_code<10)//如果按鍵小于10則寫入相應的數字
        {

        wirte_data(table2[key_code]);
        delay_ms(2);
        }
        else if(key_code<50)//大于10則寫入字符,與遙控器對應
        {

        switch(key_code)
        {
        case 21:wirte_string("mute");break;
        case 28:wirte_string("power");break;
        case 10:wirte_string("-/--");break;
        case 14:wirte_cmd(0x80+0x40+0x05);wirte_data(0x7f);wirte_data(0x7e);break;//先寫字符位置,然后寫字符,
        case 25:wirte_string("SLEEP");break;
        case 19:wirte_string("P.P");break;
        case 15:wirte_string("TV/AV");break;
        case 30:wirte_string("VOL-");break;
        case 31:wirte_string("VOL+");break;
        case 27:wirte_string("P+");break;
        case 26:wirte_string("P-");break;
        case 16:wirte_string("MENU");break;
        case 24:wirte_string("A-MODE");break;
        case 13:wirte_string("SYS");break;
        case 12:wirte_string("GAME");break;
        case 20:wirte_string("DISP");break;
        delay_ms(2);

        }
        new_code=0;

        }

        }

















        謝謝樓主 收藏了!{:soso_e183:}
        學習學習!!!!!!!!!!!!!!
        5_3_8a406e32d893628.jpg

        QQ|手機版|MCU資訊論壇 ( 京ICP備18035221號-2 )|網站地圖

        GMT+8, 2025-5-3 16:55 , Processed in 0.041491 second(s), 8 queries , Redis On.

        Powered by Discuz! X3.5

        © 2001-2025 Discuz! Team.

        返回頂部
        久久噜噜久久久精品66| 久久精品国产亚洲AV无码偷窥| 熟妇无码乱子成人精品| 亚洲精品色午夜无码专区日韩| videos欧美白嫩老师| …久久精品99久久香蕉国产| 国产精品亚洲综合一区| 自拍中文精品无码| 国产精品99精品久久免费| 精品久久久久久久久午夜福利| 四虎在线精品视频一二区| 欧美精品整片300页| 老汉精品免费AV在线播放| 91不卡在线精品国产| 亚洲精品第一国产综合精品99| 国产成人精品无码播放| 国产欧美日本精品| 欧美日韩综合精品| 国语自产少妇精品视频| 精品久久久久久成人AV| 精品久久久久久久中文字幕| 日本aⅴ精品中文字幕| 欧美亚洲成人精品| 99re这里只有精品国产精品| 亚洲精品人成无码中文毛片| 东京热TOKYO综合久久精品| 91av国产精品| 日韩精品亚洲人成在线观看| 91在线手机精品超级观看| 免费观看国产一区二区三区 | 久久久久无码精品国产| 国产精品久操视频| 日韩精品专区AV无码| 国产精品毛片无码| 亚洲国产精品18久久久久久| 国产精品五月天强力打造| 亚洲国产精品国自产拍AV| 国产精品无码久久四虎| 久久国产免费观看精品3| 久草热久草热线频97精品| 国产精品无码av在线播放|