新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 紅外接收遙控解碼實驗

        紅外接收遙控解碼實驗

        作者: 時間:2016-11-24 來源:網(wǎng)絡(luò) 收藏

        //本解碼程序適用于NEC的upd6121及其兼容芯片的解碼,支持大多數(shù)遙控器 實驗板采用11.0592MHZ晶振
        #include //包含單片機寄存器的頭文件
        #include //包含_nop_()函數(shù)定義的頭文件
        sbit IR=P3^2; //將IR位定義為P3.2引腳
        sbit RS=P2^0; //寄存器選擇位,將RS位定義為P2.0引腳
        sbit RW=P2^1; //讀寫選擇位,將RW位定義為P2.1引腳
        sbit E=P2^2; //使能信號位,將E位定義為P2.2引腳
        sbit BF=P0^7; //忙碌標志位,,將BF位定義為P0.7引腳
        sbit BEEP = P3^6; //蜂鳴器控制端口P36
        unsigned char flag;
        unsigned char code string[ ]= {"1602IR-CODE TEST"};
        unsigned char a[4]; //儲存用戶碼、用戶反碼與鍵數(shù)據(jù)碼、鍵數(shù)據(jù)反碼
        unsigned int LowTime,HighTime; //儲存高、低電平的寬度
        /*****************************************************
        函數(shù)功能:延時1ms
        ***************************************************/
        void delay1ms()
        {
        unsigned char i,j;
        for(i=0;i<10;i++)
        for(j=0;j<33;j++)
        ;
        }
        /*****************************************************
        函數(shù)功能:延時若干毫秒
        入口參數(shù):n
        ***************************************************/
        void delay(unsigned char n)
        {
        unsigned char i;
        for(i=0;i delay1ms();
        }

        本文引用地址:http://www.104case.com/article/201611/320773.htm

        /*********************************************************/
        void beep()//蜂鳴器響一聲函數(shù)
        {
        unsigned char i;
        for (i=0;i<100;i++)
        {
        delay1ms();
        BEEP=!BEEP; //BEEP取反
        }
        BEEP=1; //關(guān)閉蜂鳴器
        delay(250); //延時
        }


        /*****************************************************
        函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
        返回值:result。result=1,忙碌;result=0,不忙
        ***************************************************/
        unsigned char BusyTest(void)
        {
        bit result;
        RS=0; //根據(jù)規(guī)定,RS為低電平,RW為高電平時,可以讀狀態(tài)
        RW=1;
        E=1; //E=1,才允許讀寫
        _nop_(); //空操作
        _nop_();
        _nop_();
        _nop_(); //空操作四個機器周期,給硬件反應(yīng)時間
        result=BF; //將忙碌標志電平賦給result
        E=0;
        return result;
        }
        /*****************************************************
        函數(shù)功能:將模式設(shè)置指令或顯示地址寫入液晶模塊
        入口參數(shù):dictate
        ***************************************************/
        void WriteInstruction (unsigned char dictate)
        {
        while(BusyTest()==1); //如果忙就等待
        RS=0; //根據(jù)規(guī)定,RS和R/W同時為低電平時,可以寫入指令
        RW=0;
        E=0; //E置低電平(根據(jù)表8-6,寫指令時,E為高脈沖,
        // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
        _nop_();
        _nop_(); //空操作兩個機器周期,給硬件反應(yīng)時間
        P0=dictate; //將數(shù)據(jù)送入P0口,即寫入指令或地址
        _nop_();
        _nop_();
        _nop_();
        _nop_(); //空操作四個機器周期,給硬件反應(yīng)時間
        E=1; //E置高電平
        _nop_();
        _nop_();
        _nop_();
        _nop_(); //空操作四個機器周期,給硬件反應(yīng)時間
        E=0; //當E由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令
        }
        /*****************************************************
        函數(shù)功能:指定字符顯示的實際地址
        入口參數(shù):x
        ***************************************************/
        void WriteAddress(unsigned char x)
        {
        WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"
        }
        /*****************************************************
        函數(shù)功能:將數(shù)據(jù)(字符的標準ASCII碼)寫入液晶模塊
        入口參數(shù):y(為字符常量)
        ***************************************************/
        void WriteData(unsigned char y)
        {
        while(BusyTest()==1);
        RS=1; //RS為高電平,RW為低電平時,可以寫入數(shù)據(jù)
        RW=0;
        E=0; //E置低電平(根據(jù)表8-6,寫指令時,E為高脈沖,
        // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
        P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
        _nop_();
        _nop_();
        _nop_();
        _nop_(); //空操作四個機器周期,給硬件反應(yīng)時間
        E=1; //E置高電平
        _nop_();
        _nop_();
        _nop_();
        _nop_(); //空操作四個機器周期,給硬件反應(yīng)時間
        E=0; //當E由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令
        }
        /*****************************************************
        函數(shù)功能:對LCD的顯示模式進行初始化設(shè)置
        ***************************************************/
        void LcdInitiate(void)
        {
        delay(15); //延時15ms,首次寫指令時應(yīng)給LCD一段較長的反應(yīng)時間
        WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點陣,8位數(shù)據(jù)接口
        delay(5); //延時5ms 
        WriteInstruction(0x38);
        delay(5);
        WriteInstruction(0x38);
        delay(5);
        WriteInstruction(0x0C); //顯示模式設(shè)置:顯示開,有光標,光標閃爍
        delay(5);
        WriteInstruction(0x06); //顯示模式設(shè)置:光標右移,字符不移
        delay(5);
        WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
        delay(5);
        }
        /************************************************************
        函數(shù)功能:對4個字節(jié)的用戶碼和鍵數(shù)據(jù)碼進行解碼
        說明:解碼正確,返回1,否則返回0
        出口參數(shù):dat
        *************************************************************/
        bit DeCode(void)
        {

        unsigned char i,j;
        unsigned char temp; //儲存解碼出的數(shù)據(jù)
        for(i=0;i<4;i++) //連續(xù)讀取4個用戶碼和鍵數(shù)據(jù)碼
        {
        for(j=0;j<8;j++) //每個碼有8位數(shù)字
        {
        temp=temp>>1; //temp中的各數(shù)據(jù)位右移一位,因為先讀出的是高位數(shù)據(jù)
        TH0=0; //定時器清0
        TL0=0; //定時器清0
        TR0=1; //開啟定時器T0
        while(IR==0) //如果是低電平就等待
        ; //低電平計時
        TR0=0; //關(guān)閉定時器T0
        LowTime=TH0*256+TL0; //保存低電平寬度
        TH0=0; //定時器清0
        TL0=0; //定時器清0
        TR0=1; //開啟定時器T0
        while(IR==1) //如果是高電平就等待
        ;
        TR0=0; //關(guān)閉定時器T0
        HighTime=TH0*256+TL0; //保存高電平寬度
        if((LowTime<370)||(LowTime>640))
        return 0; //如果低電平長度不在合理范圍,則認為出錯,停止解碼
        if((HighTime>420)&&(HighTime<620)) //如果高電平時間在560微秒左右,即計數(shù)560/1.085=516次
        temp=temp&0x7f; //(520-100=420, 520+100=620),則該位是0
        if((HighTime>1300)&&(HighTime<1800)) //如果高電平時間在1680微秒左右,即計數(shù)1680/1.085=1548次
        temp=temp|0x80; //(1550-250=1300,1550+250=1800),則該位是1
        }
        a[i]=temp;//將解碼出的字節(jié)值儲存在a[i]
        }
        if(a[2]=~a[3]) //驗證鍵數(shù)據(jù)碼和其反碼是否相等,一般情況下不必驗證用戶碼
        return 1; //解碼正確,返回1
        }

        /*------------------二進制碼轉(zhuǎn)換為壓縮型BCD碼,并顯示---------------*/

        void two_2_bcd(unsigned char date)
        {

        unsigned char temp;
        temp=date;
        date&=0xf0;
        date>>=4; //右移四位得到高四位碼
        date&=0x0f; //與0x0f想與確保高四位為0
        if(date<=0x09)
        {
        WriteData(0x30+date); //lcd顯示鍵值高四位
        }
        else
        {
        date=date-0x09;
        WriteData(0x40+date);
        }
        date=temp;
        date&=0x0f;
        if(date<=0x09)
        {
        WriteData(0x30+date); //lcd顯示低四位值
        }
        else
        {
        date=date-0x09;
        WriteData(0x40+date);
        }
        WriteData(0x48); //顯示字符H
        }
        /************************************************************
        函數(shù)功能:1602LCD顯示
        *************************************************************/
        void Disp(void)
        {
        WriteAddress(0x40); // 設(shè)置顯示位置為第一行的第1個字
        two_2_bcd(a[0]);
        WriteData(0x20);
        two_2_bcd(a[1]);
        WriteData(0x20);
        two_2_bcd(a[2]);
        WriteData(0x20);
        two_2_bcd(a[3]);

        }
        /************************************************************
        函數(shù)功能:主函數(shù)
        *************************************************************/
        void main()
        {
        unsigned char i;
        LcdInitiate(); //調(diào)用LCD初始化函數(shù)
        delay(10);
        WriteInstruction(0x01);//清顯示:清屏幕指令
        WriteAddress(0x00); // 設(shè)置顯示位置為第一行的第1個字
        i = 0;
        while(string[i] !=

        主站蜘蛛池模板: 六盘水市| 五寨县| 孟津县| 巧家县| 仁怀市| 法库县| 平塘县| 策勒县| 长垣县| 西安市| 绥化市| 蒙山县| 永昌县| 秦安县| 博客| 襄垣县| 宁蒗| 江油市| 呈贡县| 拉萨市| 衡南县| 老河口市| 六枝特区| 桂阳县| 九龙坡区| 铜鼓县| 象山县| 保定市| 隆德县| 鄢陵县| 宿迁市| 拉萨市| 安乡县| 台北市| 南澳县| 商南县| 滕州市| 东方市| 大埔区| 宁晋县| 平邑县|