|
********** 用單片機代替PT2272解碼PT2262的程序 ********** 晶振: 12MHz 說 明 *********************************** 接收到的信號為發(fā)送信號的反碼因為每檢測到按鍵有效一次PT2262 都發(fā)送四次編碼我們可以 利用這一特點來解碼先檢測有沒有接收到信息當有的時候我們就去掉第一次編碼的信號檢測5ms 的 高電平來檢測編碼的開始信號接收到5ms 的高電平后才開始解碼我們可以發(fā)現(xiàn)每個碼的長度都是1.2ms 左右每一個編碼都是由低電平開始然后到高電平又到低電平又回到高電平我們從第一個高電平 的寬度可以把1 碼區(qū)分出來剩下的懸空碼和0 碼可以從第二個高電平的寬度區(qū)分出來 具體的單片機譯碼方法如下 由高電平開始檢測到下降沿時就延時300us 讀取接收的狀態(tài)記為A0 然后再檢測下一個下降沿 降沿后又延時300us 讀取接收的狀態(tài)記為A1 這樣就把一個編碼給譯出來了 A0 A1 和懸空1 碼0 碼的關(guān)系如下: A0 A1 代碼 0 0 1 碼 0 1 錯誤 1 0 懸空 1 1 0 碼 ******************************************************************************/ #i nclude <STC516AD.H>
#define uchar unsigned char #define uint unsigned int //定義共用體 union { uint word; struct { //結(jié)構(gòu)bytes uchar byte_addr; uchar byte_data; }bytes; }a_0,a_1; //位定義 sbit W_REM =P3^3; //遙控接收輸入腳 sbit LED0 =P1^0; sbit LED2 =P1^2; bit bdata recv_flg, //接收正確位標志(1:正確 0:錯誤) //因為當按住PT2262的按鍵不放的時候PT2262會把編碼不斷的送出 //設(shè)置lianji_flg位用來檢測按鍵有沒有放開過如果沒有放開則不再響應(yīng) lianji_flg; //按鍵沒有放開過標志(1:連接 0:點擊) uchar // addr_a0, //接收的8位地址編碼A0 // addr_a1, //接收的8位地址編碼A1 // data_a0, //接收的4位數(shù)據(jù)編碼A0 // data_a1, //接收的4位數(shù)據(jù)編碼A1 addr_user_a0, //設(shè)定的8位地址密碼A0 addr_user_a1; //設(shè)定的8位地址密碼A1 // led_out; //輸出控制 //------------------------------------- sub functon ---------------------------------------------- //------------------------------------- sub functon ---------------------------------------------- //------------------------------------- sub functon ---------------------------------------------- //------------------------------------- sub functon ---------------------------------------------- //------------------------------------- sub functon ----------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //void d1ms (uint ljh_in) /*1mS延時函數(shù)*/ //{ // uint data ljh_i; // uchar data ljh_j; // for(ljh_i=0;ljh_i<ljh_in;ljh_i++){ // for(ljh_j=0;ljh_j<108;ljh_j++){ // _nop_(); _nop_(); // _nop_(); _nop_(); // _nop_(); _nop_(); // } // } //} //<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> void d50us(uchar n) //50uS延時 { uchar data i,j; for(j=n;j;j--) { //[1T+2T+(2i+2)T+1T+2T]*n+1T+2T+2T=(2i+8)*n+5T for(i=21;i;i--) ;//延時2T+2T*i=(2i+2)T } } //<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PT2272_deco() //解碼 { uchar i,cnt; if(recv_flg) ; else { //清除上次解碼內(nèi)容 cnt =12; //接收12位編碼 //解碼 ------------------------------------------------------------------------ //先找出接收碼的開頭即5ms左右的高電平 ---------------------------------- //設(shè)置高電平時間為4~6ms //檢測和等待4ms的高電平 for(i=80;i;i--) { //延時4mS if(!W_REM) i=80; else d50us(1); } //等待在2ms內(nèi)接收到的低電平 -------------------------------------------- for(i=40;i;i--) { //延時4mS if(!W_REM) break; else d50us(1); } //4ms到6ms內(nèi)接收到下降沿則跳去解碼否則返回 //超出6ms接收錯誤返回 if(i) { recv_flg =0; //清按鍵沒有放開過標志 goto PT2272_deco_exit; //返回 -------------------------------- } //等待300us后采集接收信號 d50us(6); //采集接收信號并記錄 a_0.word=a_1.word=0; for(i=0;i<6;i++) { if(W_REM) { a_0.word |=0x01; } a_0.word <<=1; // MOV C,W_REM //讀A0數(shù)據(jù) // MOV A,DATA_A0 // RLC A // MOV DATA_A0,A //保存相應(yīng)位的A0 // MOV A,ADD_A0 // RLC A // MOV ADD_A0,A //高位轉(zhuǎn)移 //等待第二個下降沿 while(!W_REM) ; while(W_REM) ; // JNB W_REM,$ // JB W_REM,$ //等待300us后采集接收信號 d50us(6); // MOV 40H,#150 //2T // DJNZ 40H,$ //2T 延時:2T+2T*150=302T if(W_REM) { a_1.word |=0x01; } a_1.word <<=1; // MOV C,W_REM //讀A1數(shù)據(jù) // MOV A,DATA_A1 // RLC A // MOV DATA_A1,A //保存相應(yīng)位的A1 // MOV A,ADD_A1 // RLC A // MOV ADD_A1,A //高位轉(zhuǎn)移 //等待第二個碼值的下降沿 while(!W_REM) ; //___wd___ while(W_REM) LED2=~LED2; // JNB W_REM,$ // JB W_REM,$ // DJNZ 34H,REMOTE6 //接收12 位編碼 -------------------------------- } //把接收的編碼左移4位將8位密碼放在同一字節(jié)上---------------------------- a_0.word <<=4; a_1.word <<=4; // MOV 40H,#4 //REMOTE7: // CLR C // MOV A,DATA_A0 // RLC A //送出低8位的bit7 // MOV DATA_A0,A //低8位的A0左移1位 // MOV A,ADD_A0 // RLC A //接收低8位的bit7 // MOV ADD_A0,A //高8位的A0左移1位 // CLR C // MOV A,DATA_A1 // RLC A //送出低8位的bit7 // MOV DATA_A1,A //低8位的A1左移1位 // MOV A,ADD_A1 // RLC A //接收低8位的bit7 // MOV ADD_A1,A //高8位的A1左移1位 // DJNZ 40H,REMOTE7 //左移4位 // //把4位數(shù)據(jù)編碼由高4位移到低4位上 --------------------------------- // MOV A,DATA_A0 // SWAP A // MOV DATA_A0,A //把4位數(shù)據(jù)編碼A0由高4位移到低4位? // MOV A,DATA_A1 // SWAP A // MOV DATA_A1,A //把4位數(shù)據(jù)編碼A1由高4位移到低4位? //比較密碼 -------------------------------------------------------------- if((a_0.bytes.byte_addr==addr_user_a0)&&(a_1.bytes.byte_addr==addr_user_a1)) { recv_flg =1; lianji_flg =1; } else { recv_flg =0; lianji_flg =0; } // MOV A,ADD_A0 // XRL A,ADD_USER_A0 // JNZ REMOTE8 //密碼不正確則跳轉(zhuǎn) // // MOV A,ADD_A1 // XRL A,ADD_USER_A1 // JNZ REMOTE8 //密碼不正確則跳轉(zhuǎn) // //置接收正確位 --------------------------------------------------------- // SETB RECEIVE // //置ENABLE 用于檢測按鍵有沒有放開 -------------------------------- // SETB ENABLE // RET //接收正確返回 ----------------------------------------- //REMOTE8: // CLR ENABLE // CLR RECEIVE // RET //接收不正確返回 --------------------------------------- } PT2272_deco_exit: return; } //<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> void remote_2272_deco() //接收遙控碼(解碼程序) { uint i; //檢測50ms內(nèi)有沒有編碼接收 for(i=1000;i;i--) { if(!W_REM) { PT2272_deco(); //解碼 break; } else d50us(1); //50uS延時 } recv_flg =0; //清按鍵沒有放開過標志 } //<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-< //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> void work() //控制輸出 //把選中的LED取反 { if(recv_flg) { //接收不正確,退出 recv_flg=0; //清接收正確標志位 a_0.bytes.byte_data =~a_0.bytes.byte_data; P1 =P1^a_0.bytes.byte_data; } //WORK: // JNB RECEIVE,WORK_END //接收不正確,退出 // //每次按鍵都一次響應(yīng) // CLR RECEIVE //清接收正確標志位 // MOV A,DATA_A1 // CPL A // ORL A,#0FH //屏蔽低4位 // MOV DATA_A1,A // MOV A,LCD_OUT // XRL A,DATA_A1 // ORL A,#0FH // MOV LCD_OUT,A // MOV P1,LCD_OUT // NOP //WORK_END: // RET // END } //<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-< // ==================================== main function ============================================ // ==================================== main function ============================================ // ==================================== main function ============================================ // ==================================== main function ============================================ // ==================================== main function ============================================ // ==================================== main function ============================================ void main (void) { //上電初始化 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P1 =0xff; P3 =0xff; for(addr_user_a1=100;addr_user_a1;addr_user_a1--) d50us(200); //50uS延時 //編碼設(shè)定為:A0~A7地址編碼為:懸空 +++++++++++++++++++++++++++++++++++++++++++++ addr_user_a0 =0xff; addr_user_a1 =0x00; //start: //================================================================================ while(1) { remote_2272_deco(); //接收遙控碼 work(); //控制輸出 LED0 =!LED0; } }
|