新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機紅外接受解碼程序成功版

        單片機紅外接受解碼程序成功版

        作者: 時間:2016-12-01 來源:網絡 收藏
        unsigned char hc[8]; //數碼管顯示緩存
        unsigned char DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 顯示段碼值0~F
        unsigned char WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位碼。顯示的位置
        unsigned char sj[33]; //接收脈沖時間數組
        char w=0; //數碼管顯示緩存指針(0~7)
        unsigned char i; //脈沖個數記錄
        unsigned char mcsj; //脈沖時間(大于0.56ms小于1.125ms為0,大于1.125ms小于2.25ms)
        bit MC=0; //接收紅外脈沖開始標志(0:脈沖已經結束,1:脈沖剛開始)
        bit JS=0; //脈沖接收結束標志位(1標志接收結束)
        bitJM=0; //解碼完成標志位(1:解碼完成)
        void Delay(unsigned char f);
        void dsq_0() interrupt 1 using 1 //定時器T0中斷服務函數
        {
        mcsj++; //256
        }
        void wbzd_0() interrupt 0 //外部中斷服務函數
        {
        if(MC)
        {
        if(mcsj>32) //判斷是不是引導碼。(如果是i=0)
        i=0;
        sj[i]=mcsj; //把脈沖時間存入sj這個數組里
        mcsj=0; //清空脈沖時間準備接收下一個脈沖時間
        i++;
        if(i==33) //判斷是否接收完脈沖時間
        {
        i=0;
        JS = 1; //接收完成標志位置1
        MC=0; //紅外脈沖結束
        }
        }
        else
        {
        MC=1; //紅外脈沖開始
        mcsj=0; //清空脈沖時間
        }
        }
        void csh_dsq_0() //初始化定時器0
        {
        TMOD = 0x02;
        TH0=0x00; //定時器0的重裝數據
        TL0=0x00; //初始化
        ET0=1; //打開定時器0中斷
        TR0=1; //啟用定時器0
        }
        void csh_wbzd_0() //初始化外部中斷0
        {
        IT0=1; //外部中斷0下降沿觸發
        EX0=1; //啟用外部中斷0
        EA=1; //打開總中斷
        }
        void hwjm(unsigned char *p) //紅外解碼函數
        {
        unsigned char i,j,k=1;
        for(i=0;i<4;i++) //4組數據的計數
        {
        for(j=0;j<8;j++) //每組數據中的8位數據計算
        {
        p[i] >>= 1; //數據右移一位
        if(sj[k]>7) //脈沖時間大于7的就是1
        p[i] |= 0x80;
        k++;
        }
        }
        JS = 0; //分析完成清零JS
        JM = 1; //解碼完成JM置1
        }
        unsigned char xhc(unsigned char *p) //紅外按鍵匹配函數
        {
        /*
        hc[0]=DM[p[1]/16]; //客戶碼
        hc[1]=DM[p[1]%16]; //客戶碼
        hc[2]=0x40;
        hc[3]=DM[p[2]/16]; //數據
        hc[4]=DM[p[2]%16]; //數據
        hc[5]=0x40;
        hc[6]=DM[p[3]/16]; //數據反碼
        hc[7]=DM[p[3]%16]; //數據反碼
        以上注釋的代碼是顯示
        紅外解碼后的原始數據
        */
        switch(p[2]) //匹配按鍵
        {
        case 0x16:hc[w]=DM[0];break; //按鍵0
        case 0x0c:hc[w]=DM[1];break; //按鍵1
        case 0x18:hc[w]=DM[2];break; //按鍵2
        case 0x5e:hc[w]=DM[3];break; //按鍵3
        case 0x08:hc[w]=DM[4];break; //按鍵4
        case 0x1c:hc[w]=DM[5];break; //按鍵5
        case 0x5a:hc[w]=DM[6];break; //按鍵6
        case 0x42:hc[w]=DM[7];break; //按鍵7
        case 0x52:hc[w]=DM[8];break; //按鍵8
        case 0x4a:hc[w]=DM[9];break; //按鍵9
        case 0x09: //熄滅所有數碼管(清零)
        {
        hc[0]=0x00; //熄滅所有數碼管
        w=7; //準備清空數碼管顯示緩存(不是真的清空)
        break;
        }
        default: return 0; //如果沒有匹配的按鍵就結束函數
        }
        if(w<7) //數碼管顯示緩存寫入指針不能大于7
        {
        w++; //顯示緩存指針加一
        hc[w]=0x00; //設置數碼管掃描結束標志
        }
        else
        w=0;//顯示緩存指針清零
        JM=0;
        }
        void Delay(unsigned char f) //延時
        {
        while(f--);
        }
        void main()
        {
        unsigned char k=0; //數碼管掃描的位置
        unsigned char jmsj[4]; //紅外接收解碼后的所有數據
        csh_dsq_0(); //初始化定時器0
        csh_wbzd_0(); //初始化外部中斷0
        while(1)
        {
        if(JS) //脈沖接收結束后調用解碼函數解碼
        {hwjm(jmsj);}
        if(JM) //解碼完成后調用按鍵匹配函數
        {xhc(jmsj);}
        //下面的代碼是數碼管掃描
        P1 = 0; //消影
        dm = 1;
        dm = 0;
        P1 = WM[k]; //寫入位碼
        wm = 1;
        wm = 0;
        P1 = hc[k]; //寫入段碼
        dm = 1;
        dm = 0;
        if( k<7 && hc[k]!=0 ) //控制數碼管顯示的位數
        k++;
        else
        k=0;
        Delay(50);
        }
        }

        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 孟津县| 德江县| 休宁县| 应用必备| 普陀区| 陵水| 郴州市| 固原市| 准格尔旗| 于田县| 门源| 阳高县| 沧源| 江孜县| 游戏| 尼玛县| 米脂县| 丰都县| 威海市| 北票市| 房山区| 金昌市| 浦北县| 衡山县| 信宜市| 宁化县| 承德市| 四川省| 滨海县| 昭觉县| 翼城县| 方城县| 鄂托克旗| 石棉县| 于田县| 广灵县| 赣榆县| 武平县| 绥德县| 达孜县| 鲁甸县|