|
四路學(xué)習(xí)型315m無線開關(guān) 因能學(xué)習(xí)到一種阻值信號學(xué)習(xí)不到其他 阻值的遙控
現(xiàn)在走到一款,自適應(yīng)多阻值實現(xiàn)2262、1527解碼,學(xué)習(xí)的,測試過支持很多阻值的遙控,把兩個程序上傳給大家看看什樣把解碼移值到現(xiàn)在這個,四路學(xué)習(xí)型315m無線開關(guān)程序,上傳給大家看看什樣修改,上傳謝謝大家
單片機源程序如下:
- /**************************************************************************/
- //-----------------兼容2262 1527的解碼實驗程序----------------//
- //測試單片機:兼容STC全系
- //晶振:11.0592M (外部)
- //復(fù)位方式:內(nèi)部復(fù)位
-
- //串口通訊:波特率9600/數(shù)據(jù)位8/停止位1/無校驗
- //調(diào)試環(huán)境:KEIL4
- //程序功能:實現(xiàn)2262、1527解碼,學(xué)習(xí)、自適應(yīng)多阻值,片內(nèi)EEPROM,存儲60個遙控器數(shù)據(jù)
-
- // 不依賴硬件,不占用硬件資源。移植更加方便
- // 學(xué)習(xí)遙控器:按一下學(xué)習(xí)鍵,學(xué)習(xí)燈點亮,松開學(xué)習(xí)鍵,按動要學(xué)習(xí)的遙控器按鍵,學(xué)習(xí)燈熄滅,學(xué)習(xí)成功。重復(fù)上述操作可學(xué)習(xí)多個遙控器.
- //
- // 清除:按住學(xué)習(xí)鍵不放,直到學(xué)習(xí)燈自動熄滅,擦除成功.
- /**********************************************************/
- #include <STC15W408AS.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit RF = P1^1; //信號輸入
- sbit LED = P1^0; //學(xué)習(xí)指示燈
- sbit set = P3^5; //學(xué)習(xí)鍵
- sbit D0 = P3^6; //解碼輸出
- sbit D1 = P3^7;
- sbit D2 = P3^3;
- sbit D3 = P3^2;
- sbit VT = P1^7; //解碼指示燈
-
- bit decode_ok; //解碼成功
- bit rf_ok; //收到有效數(shù)據(jù)
- bit study; //學(xué)習(xí)標志
- bit jmnx; //編碼類型 0是2262,1是1527
- uchar da1527[2][3]; //解碼過程中臨時數(shù)組
- uchar key_d; //遙控器按鍵碼
- uchar short_k; //窄脈沖寬度
- uchar idata key_number[181]; //遙控器編碼數(shù)組,存放60個遙控器
- void delay_1ms(uint x) //1毫秒延時
- {
- uchar b,c;
- for(x;x>0;x--)
- {
- for(b=3;b>0;b--)
- {
- for(c=150;c>0;c--);
- }
- }
- }
- void delay(uint ms)//
- {
- while(ms--)
- {
- ms++;
- ms--;
- }
- }
- //====================================================
- /////////片內(nèi)EEPROM讀寫驅(qū)動程序///////////////////////////
- //====================================================
- void IAP_Disable() //關(guān)閉IAP
- {
- //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
- //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
- IAP_CONTR = 0; //關(guān)閉IAP 功能
- IAP_CMD = 0; //清命令寄存器,使命令寄存器無命令,此句可不用
- IAP_TRIG = 0; //清命令觸發(fā)寄存器,使命令觸發(fā)寄存器無觸發(fā),此句可不用
- IAP_ADDRH = 0;
- IAP_ADDRL = 0;
- }//
- //讀一字節(jié),調(diào)用前需打開IAP 功能,入口:DPTR = 字節(jié)地址,返回:A = 讀出字節(jié)
- uchar read_add(uint addr) //讀EEPROM
- {
- IAP_DATA = 0x00;
- IAP_CONTR = 0x84; //打開IAP 功能, 設(shè)置Flash 操作等待時間
- IAP_CMD = 0x01; //IAP/ISP/EEPROM 字節(jié)讀命令
- IAP_ADDRH = addr>>8; //設(shè)置目標單元地址的高8 位地址
- IAP_ADDRL = addr&0xff; //設(shè)置目標單元地址的低8 位地址
- EA = 0;
- IAP_TRIG = 0x5a; //先送 46h,再送B9h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
- IAP_TRIG = 0xa5; //送完 B9h 后,ISP/IAP 命令立即被觸發(fā)起動
- _nop_();
- EA = 1;
- IAP_Disable(); //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
- //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
- return (IAP_DATA);
- }//------------------------------------------------------------------------------
- //字節(jié)編程,調(diào)用前需打開IAP 功能,入口:DPTR = 字節(jié)地址, A= 須編程字節(jié)的數(shù)據(jù)
- void write_add(uint addr,uchar ch) //直接寫EEPROM
- {
- IAP_CONTR = 0x84; //打開 IAP 功能, 設(shè)置Flash 操作等待時間
- IAP_CMD = 0x02; //IAP/ISP/EEPROM 字節(jié)編程命令
- IAP_ADDRH = addr>>8; //設(shè)置目標單元地址的高8 位地址
- IAP_ADDRL = addr&0xff; //設(shè)置目標單元地址的低8 位地址
- IAP_DATA = ch; //要編程的數(shù)據(jù)先送進IAP_DATA 寄存器
- EA = 0;
- IAP_TRIG = 0x5a; //先送 46h,再送B9h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
- IAP_TRIG = 0xa5; //送完 B9h 后,ISP/IAP 命令立即被觸發(fā)起動
- _nop_();
- EA = 1;
- IAP_Disable(); //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
- //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
- }//------------------------------------------------------------------------------
- //擦除扇區(qū), 入口:DPTR = 扇區(qū)地址
- void Sector_Erase(uint addr) //扇區(qū)擦除
- {
- IAP_CONTR = 0x84; //打開IAP 功能, 設(shè)置Flash 操作等待時間
- IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇區(qū)擦除命令
- IAP_ADDRH =addr>>8; //設(shè)置目標單元地址的高8 位地址
- IAP_ADDRL =addr&0xff; //設(shè)置目標單元地址的低8 位地址
- EA = 0;
- IAP_TRIG = 0x5a; //先送 46h,再送B9h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
- IAP_TRIG = 0xa5; //送完 B9h 后,ISP/IAP 命令立即被觸發(fā)起動
- _nop_();
- EA = 1;
- }//------------------------------------------------------------------------------
- //============================接收解碼部分========================================//
- void RF_decode()
- {
- uchar ii=0,j=0,k=0,rep=0;
- uint head_k=0; //短脈沖寬度
- uchar s;
- //-------------------------------數(shù)據(jù)接收-----------------------------------------
- short_k=0;
- while(RF && j<250) //檢測頭信號前一個高脈沖的寬度
- {
- delay(1);
- short_k++;
- }
- while(!RF)
- {
- delay(1);
- head_k++;
- } //檢測頭脈沖的寬度
- if(((short_k*24)<head_k) && (head_k<(short_k*38))) //引導(dǎo)碼寬度是窄脈沖的32倍 24/38
- {
- for(rep=0;rep<2;rep++)
- {
- for(ii=0;ii<3;ii++)//3字節(jié)
- {
- for(k=0;k<8;k++)//每個字節(jié)8位
- {
- j=0;
- while(RF && j<245)
- {
- delay(1);
- j++;
- }//
- 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));
- else {return;} //亂碼退出
- j=0;
- while(!RF && j<150){delay(2);j++;} //跳過低電平
- }
- }//for(ii=0;ii<12;ii++)
- j=0;while(RF && (j<200)){delay(1);j++;} //跳個最后一個高脈沖
- head_k=0;while(!RF) {delay(1);head_k++;} //檢測下一個前導(dǎo)信號的寬度
- if((head_k<(short_k*26)) || (head_k>(short_k*38))) {return;} //引導(dǎo)碼寬度是窄脈沖的32倍 //亂碼退出
- }
- //+++++++++++++++++++++++++2262與1527數(shù)據(jù)分離處理++++++++++++++++++++++++++++++++++++++++
- if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1]) && (da1527[0][2]==da1527[1][2])) //兩次接收到的數(shù)據(jù)相同
- {
- uchar u,i,x;
- rf_ok=1;
- 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的按鍵數(shù)據(jù)
- da1527[0][2]=00; //2262無后4位地址,全為0
- jmnx=0; //為0是2262,1是1527
- }
-
- if (!study) //非學(xué)習(xí)狀態(tài)
- {
- rf_ok=0;
- for(x=0;x<60;x++)
- {
- if((da1527[0][0]==key_number[x*3+1])&&(da1527[0][1]==key_number[x*3+2])
- &&(da1527[0][2]==key_number[x*3+3]))//判斷是否已學(xué)習(xí)過的編碼
- {
- D0=!(key_d&0x08); //取得按鍵碼
- D1=!(key_d&0x04);
- D2=!(key_d&0x02);
- D3=!(key_d&0x01);
-
- decode_ok=1;
- VT=0;
- s=100;
- break;
- }
-
- }
-
-
- }
- }
-
- }
- if(decode_ok) //解碼有效信號,類似2272 PT腳
- {
- s--;
- if(!s)
- {
- decode_ok=0;
- VT=1;
- }
- }
-
-
- }
- void key_buffer() //把遙控器碼從 EEPROM 復(fù)制到DATA
- {
- uchar n;
- for(n=0;n<181;n++)
- {
- key_number[n]=read_add(0x0000+n);
- }
- }
- void KEY_study() //遙控器學(xué)習(xí)
- {
- uchar num_rf;
- uint d_num;
- if(study)
- {
- rf_ok=0;
- d_num=0;
-
- while(!rf_ok)
- {
- RF_decode();
- d_num++;
- if(d_num>50000) break;
- }
- d_num=0;
- if(rf_ok==1)
- {
- num_rf=key_number[0]; //取已學(xué)習(xí)的遙控器數(shù)量
- if(num_rf>60){num_rf=0;} //如果遙控器數(shù)量超過10個,覆蓋最先學(xué)習(xí)的
- key_number[num_rf*3+1]=da1527[0][0];
- key_number[num_rf*3+2]=da1527[0][1];
- key_number[num_rf*3+3]=da1527[0][2];
- key_number[0]=num_rf+1;
- Sector_Erase(0x0000);
- for(num_rf=0;num_rf<181;num_rf++)
- {
- write_add(0x0000+num_rf,key_number[num_rf]);
-
- }
- rf_ok=0;
- LED=1; //學(xué)習(xí)成功
- }
- else
- {
- rf_ok=0;
- for(num_rf=0;num_rf<8;num_rf++) //操作超時
- {
- LED=!LED;
- delay_1ms(100);
- }
- LED=1;
-
- }
- d_num=0;
- study=0;
- }
- }
- void system_res() //系統(tǒng)清零
- {
-
- Sector_Erase(0x0000);
- write_add(0x0000,0x00);
- key_buffer();
- }
- void set_scan() //判斷學(xué)習(xí)鍵狀態(tài)
- {
- uchar h=0;
- while(!set)
- {
- if(h>5)
- {
- study=1;
- h=0;
- LED=0;
- while(!set)
- {
- delay_1ms(100);
- h++;
- if(h>80)
- {
- study=0;
- h=0;
- system_res();
- LED=1;
- while(!set);
- }
-
- }
- }
- delay_1ms(100);
- h++;
- }
- if(study)
- {
- KEY_study();
- }
- }
- void system_start() //上電初始化
- {
- AUXR=0xb5;
- P0=0xfe;
- P1=0xff;
- P3=0xff;
- key_buffer();
- }
- void main()
- {
- system_start();
- while(1)
- {
- RF_decode();
- set_scan();
- }
- }
復(fù)制代碼 |
|