本帖最后由 hurong 于 2013-6-7 22:51 編輯
2262+1527解碼,da1527[0][0],da1527[0][1],da1527[0][2]存地址,key_d存按鍵值;未學習,led慢閃;按3S按鍵進入學習,LED常亮,學習成功后閃兩下,后LED再常亮,進入下一個搖控器的學習, 如此循環,過程中再短按一下按鍵,LED滅,退出學習;長按8S清除學習過的內容,3S時燈亮,8時燈滅再閃7下;短按IO口致反。 兩種方式退出學習:1、學習過程中,短按按鍵;2、學習過程中,不進行任何操作,10S自動退出學習。STC_11xx.H根據自己單片機型號選擇!STC15F104e- //RF_IN_OUT.H頭文件
- #define MAIN_Fosc5529000//定義主時鐘, 模擬串口和紅外接收會自動適應。5~36MHZ
- #define T0_YS 50 //t0定時時間50MS
- sbit led=P3^4;
- sbit P_TXD1 = P3^1;//定義模擬串口發送腳,打印信息用
- sbit p_rxd=P3^4; //定義模擬串口接收腳
- sbit RFIN = P3^5; //RF接收腳
- sbit out22=P3^3; //RF發射腳
- sbit k1=P3^0;
- //----------------------------------------------------------------------
- voidPrintString(unsigned char code *puts);
- voidsend_char(uchar dat);//9600,N,8,1發送一個字節
- voidBitTime(void);
- uchar uart_rx_da[10];uchar rx_da_num=0;// 串口接收數據緩存
- led_ss(uchar h){uchar y;TR0=0;for(y=0;y<h;y++){led=0;delays(8);led=1;delays(8);}TR0=1;}//在這里只能用TR0=0,不能用EA=0,不然會多收到一個OXFF;
- //***********************************************************
- void TIME0_INT() interrupt 1 using 0 //time0中斷程序,模擬外中斷,用于串口接收
- {
- uchar ii,u,tem;
- BitTime(); //開始信號
- for(ii=0;ii<8;ii++)
- {
- if(p_rxd==0)
- {
- tem&=(~(1<<ii));
- }
- else if(p_rxd==1)
- {
- tem|=(1<<ii);
- }
- BitTime();
- }
- BitTime(); //停止脈沖
- for (u=10;u>1;u--)uart_rx_da[u-1]=uart_rx_da[u-2]; //已收到的數據后移
- uart_rx_da[0]=tem; //新數據始終放在最前面
- rx_da_num++;
- TH0=0XFF;TL0=0XFF;
- }
- //***********************************************************
- /********************** 模擬串口相關函數************************/
- voidBitTime(void)//位時間函數
- {
- uint i;
- i = ((MAIN_Fosc / 100) * 104) / 140000 - 1;//根據主時鐘來計算位時間
- while(--i);
- }
- //模擬串口發送
- void send_char(uchar dat)//9600,N,8,1發送一個字節
- {
- uchari;
- EA = 0;
- P_TXD1 = 0;
- BitTime();
- for(i=0; i<8; i++)
- {
- if(dat & 1)P_TXD1 = 1;
- elseP_TXD1 = 0;
- dat >>= 1;
- BitTime();
- }
- P_TXD1 = 1;
- EA = 1;
- BitTime();
- BitTime();
- }
- void send_str(unsigned char code *puts)//發送一串字符串
- {
- for (; *puts != 0;puts++) send_char(*puts); //遇到停止符0結束
- }
- //************************************************************************
- //IO.H頭文件
- uchar rf_en=0;
- bit jmnx=0; //為0是2262,1是1527
- uchar da1527[2][3],key_d;
- uchar short_k=0; //短脈沖脈部寬度,在發射前可用此數據初始成與接收相同脈沖寬度
- void RF_IN()
- {
- uchar ii=0,j=0,k=0,rep=0;
- uint head_k=0; //短脈沖及頭脈沖寬度
- if(rf_en==0)
- {
- //-------------------------------數據接收-----------------------------------------
- short_k=0;while(RFIN && j<250) {delay(1);short_k++;} //檢測信號前一個高脈沖的寬度
- while(!RFIN) {delay(1);head_k++;} //檢測頭信號的寬度
- if(((short_k*24)<head_k) && (head_k<(short_k*38))) //頭信號的寬度是短脈沖的32倍
- {
- for(rep=0;rep<2;rep++)
- {
- for(ii=0;ii<3;ii++)//3字節
- {
- for(k=0;k<8;k++)//每個字節8位
- {
- j=0;while(RFIN && j<245) {delay(1);j++;}// 16us(6mhz:2~5)
- if(j>(short_k-short_k/2-short_k/3)&&j<(short_k*1.96)) da1527[rep][ii]&=~(1<<((7-k)));
- else if(j>(short_k*1.96)&&j<(short_k*5))da1527[rep][ii]|=(1<<(7-k)); //%25 長脈沖的寬度是短脈沖的3倍
- else {rf_en=0;return;} //亂碼退出
- j=0;while(!RFIN && j<150){delay(2);j++;} //跳過低電平
- }
- }//for(ii=0;ii<12;ii++)
- j=0;while(RFIN && (j<200)){delay(1);j++;} //跳個最后一個高脈沖
- head_k=0;while(!RFIN) {delay(1);head_k++;} //檢測下一個前導信號的寬度
- if((head_k<(short_k*26)) || (head_k>(short_k*38))) {rf_en=0;return;} //頭信號的寬度是短脈沖的32倍 //亂碼退出
- }
- //+++++++++++++++++++++++++2262與1527數據分離處理++++++++++++++++++++++++++++++++++++++++
- if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1]) && (da1527[0][2]==da1527[1][2]))//兩次接收到的數據相同,就執行
- {
- uchar u,i;
- for(i=0;i<3;i++) //判定2262與1527
- {
- for(u=0;u<4;u++) {if(((da1527[0][i]>>(u*2)) & 3)==2) {i=80;break;}} //有10則為1527
- if(i==80) break;
- }
- if(i==80) //1527
- {
- key_d=da1527[1][2] & 0x0f; //分出1527的按鍵值
- da1527[0][2]=da1527[1][2]>>4; //分出1527的后4位地址
- jmnx=1; //為0是2262,1是1527
- }
- else //2262
- {
- key_d=0;
- for(i=0;i<4;i++){if(((da1527[0][2]>>(i*2))&3)==3) key_d|=1<<i;} //計算出2262的按鍵數據
- da1527[0][2]=00; //2262無后4位地址,全為0
- jmnx=0; //為0是2262,1是1527
- }
- rf_en=4;
- }
- }
- }//if(rf_en==0)
- }
- //^^^^^^^^^^^^rf接收END^^^^^^^
- //*******************rf發射********
- ////uchar wid發射脈沖寬度,//
- //發送8次數據的時間為120ms.=(0.96+0.34)*12*8
- //dat1,dat2,dat3為2262與1527地址,dat4為按鍵值,wid為發射脈沖的寬度一般為60
- //****************************************************************8
- out0();//發射0
- out1();//發射1
- uchar short_width=60; //初始發射的短脈沖寬度
- send_bat(uchar dat);
- send_rf(uchar dat1,uchar dat2,uchar dat3,uchar dat4,uchar wid)//1527編碼發射
- {
- unsigned char dd,b;
- EA=0;short_width=wid;
- // ---------------------2262與1527自動按鍵值處理-------------------------------------
- for(b=0;b<4;b++){if(((dat1>>(b*2)) & 3)==2) {b=80;break;}} //有10則為1527
- if(b!=80)for(b=0;b<4;b++){if(((dat2>>(b*2)) & 3)==2) {b=80;break;}} //有10則為1527
- if(b!=80)for(b=0;b<2;b++){if((((dat3)>>(b*2)) & 3)==2) {b=80;break;}} //有10則為1527
- if(b==80) dat3=dat3*16+dat4; //1527
- else //2262
- {
- dd=0;
- for (b=0;b<4;b++) if((dat4>>b)&1==1)dd|=3<<(b*2); //還原按鍵值的2262編碼
- dat3=dd;
- }
- //------------------------------------------------------------------------------------
- for(dd=0;dd<8;dd++) //發送相同的8組碼
- {
- send_bat(dat1);send_bat(dat2);send_bat(dat3);
- out22=1;delay(short_width); out22=0;delay(short_width*32);//這幾句是發射結束碼及頭信號
- }
- EA=1;
- }
- send_bat(uchar dat)
- {
- uchar a;
- for (a=0;a<8;a++)//發送一個字節數據
- {
- if((dat>>(7-a))&1==1)out1();
- else out0();
- }
- }
- out0()//發射0
- {
- out22=1;delay(short_width); //延時320us.
- out22=0;delay(short_width*3); //長脈衝信號是短脈衝寬度的3倍.
- }
- out1()//發射1
- {
- out22=1;delay(short_width*3); //延時960us.
- out22=0;delay(short_width); //延時320us.
- }
復制代碼- //>>>>>>>>>>>>>>>>>>>>>>>> rf發射end >>>>>>>>>>>>>>>>>>>>>>>>>
- //主程序
- #include <intrins.h>
- #include <STC_11xx.H>
- #include <IO.H>
- #include <RF_IN_OUT.H>
- uchar key_d=0;
- #define time_long 160 //8s
- #define time_short 60 //3s
- uchar tim_ys=0; //未學習時閃燈計時
- uchar ys_t1=0;//學習中未收到信號定時計時,自動退出學習
- uint key_time=0; //按鍵時間長短計時
- uchar start_en=0;//學習標志,
- uchar start_num=0;// 學習個數
- show_jm();
- //**************************
- main()
- {
- uchar i;
- out22=0;RFIN=1;p_rxd=1; //輸出腳初始
- //**********定時器0,初始化,模擬中斷,用于串口接收**************
- TMOD|=0X05; //定時器0計數模式,模擬外部中斷
- TH0=0XFF;TL0=0XFF;
- ET0=1; TR0=1; //打開中斷,//啟動定時器0,
- EA=1;
- //--------------定時器1--50ms定時用----------------
- TMOD|=0X10; //定時器0設為16位定時器模式,方式1.方式0為13位定時器
- clrbit(AUXR,6);//AUXR&=~(1<<7); //t1 12Tmode
- TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS; //50MS定時器計數設定
- ET1=1; TR1=1; //打開中斷,//啟動定時器0,
- EA=1;
- //******************************************************
- //************初始學習個數*************
- start_num=bat_read(0x3fe);
- if(start_num<1 || start_num>12) //沒學習過
- {
- bat_prog(0x00);bat_prog(0x200);start_num=0;
- }
- //************************************
- led_ss(2);
- while(1)
- {
- //-----------------------------------------------------------
- if(key_time>3 && key_time<10) //短按發射
- {
- delays(20);
- if(key_time<10)
- {
- led^=1; //取反
- }
- }
- else if(key_time>time_short && key_time<(time_long-10)) {bat_prog(0x000);led=0;start_en=1;ys_t1=0;} //3S正常學習
- else if(key_time>time_long) {led=1;delays(80);bat_prog(0x00);bat_prog(0x200);start_num=0;start_en=0;led_ss(7);}//8S清除,3S時燈亮,8時燈滅再閃7下
- //---------------------------------------------------------------------------------------------------------------------------------------------------------
- RF_IN(); //2262接收
- if(rf_en==4) //表示已接收到數據
- {
- uchar u;
- for(i=0;i<3;i++){send_char(da1527[0][i]);}send_char(key_d);//串口發送接收到的數據
- show_jm(); //串口中文顯示收到的數據
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
- if(start_en==1) //學習狀態
- {
- if(start_num<11) //個數未到最大學習個數
- {
- for(u=0;u<3;u++)bat_white(start_num*4+u,da1527[0][u]); //存地址
- bat_white(start_num*4+3,key_d); //存鍵值
- start_num++;bat_prog(0x200);bat_white(0x3fe,start_num); //存學習個數
- led_ss(2);led=0; //led閃后常亮,繼續學習
- }
- }
- else //控制狀態
- {
- for(u=0;u<start_num;u++) //一個一個的地址讀出比較
- {
- if(da1527[0][0]==bat_read(u*4) && da1527[0][1]==bat_read(u*4+1) && da1527[0][2]==bat_read(u*4+2)) //地址比較
- {
- if(key_d==1) //按鍵值相同則執行
- {
- led^=1; //取反
- u=20; //退出FOR循環
- }
- }
- }
- }
- rf_en=0;//
- }
- }
- }
- //***************************************************
- void TIME1_INT() interrupt 3 using 0 //time0中斷程序(50ms)
- {
- //********************************
- if(!k1) {key_time++;if(key_time<time_short)led=1;if(start_en>0 && key_time<time_short){led_ss(5);start_en=0;}} //按鍵時間計數,學習中按鍵退出學習
- else key_time=0;
- //********************學習中計數****************************
- if(start_en==1) {ys_t1++;}
- if(ys_t1>200){ys_t1=0;led_ss(5);start_en=0;} //退出學習。
- //********************
- TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS; //50MS定時器
- }
- //***********************************************************
- show_jm()
- {
- uchar i;uint da2262h;da2262h=da1527[0][0]*256+da1527[0][1];
- if(!jmnx) //2262
- {
- //***********************************//發射收到并經轉換后的數據2262*******************************************************************
- send_str("\r\n");
- send_str(" 本次解碼結果如下:\r\n\r\n");
- send_str(" 解碼類型:2262 \r\n\r\n");
- send_str("地址:OX");for(i=0;i<4;i++)if(((da2262h>>(12-(i*4)))&0x0f)>9)send_char(((da2262h>>(12-(i*4)))&0x0f)+0x37);else send_char(((da2262h>>(12-(i*4)))&0x0f)+0x30);
- send_str(" 地址管腳配制:");
- for(i=0;i<8;i++) //以字符的方式發送接收到的數據
- {
- if(((da2262h>>((7-i)*2))& 3)==3)send_char(1+0x30);
- else if(((da2262h>>((7-i)*2))& 3)==1)send_char('F');
- else send_char(0+0x30);
- }
- send_str("\r\n\r\n");
- send_str("按鍵值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);
- send_str(" 按鍵管腳狀態:");
- for(i=0;i<4;i++){send_char(((key_d>>(3-i))&1)+0x30);}
- send_str("\r\n\r\n");
- send_str("震蕩電阻參考值:OX");
- if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);
- if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);
- send_str("\r\n\r\n");
- }
- //************************************************************************************************************************
- else
- {
- send_str("\r\n");
- send_str(" 本次解碼結果如下:\r\n\r\n");
- send_str(" 解碼類型:1527 \r\n\r\n");
- send_str("地址:OX");for(i=0;i<4;i++)if(((da2262h>>(12-(i*4)))&0x0f)>9)send_char(((da2262h>>(12-(i*4)))&0x0f)+0x37);else send_char(((da2262h>>(12-(i*4)))&0x0f)+0x30);
- if(da1527[0][2]>9)send_char(da1527[0][2]+0x37);else send_char(da1527[0][2]+0x30);
- send_str("\r\n\r\n");
- send_str("按鍵值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);
- send_str("震蕩電阻參考值:OX");
- if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);
- if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);
- send_str("\r\n\r\n");
- }
- }
復制代碼
作者:mcuc 來源:智凡單片機
|