分享一個最近用STC89C52單片機做的433遙控解碼程序,帶學習功能的,可以存8組遙控碼,如果不夠可以自行增加。電路圖如下:
歡迎各位大神提出寶貴意見!
單片機源程序如下:
- 1、EV1527/PT2262 按鍵解碼輸出,并有解碼有效輸出端。
- 2、程序采用中斷嵌套結構,定時時間準確,可輕松集成到您現有程序中,解碼精度不受其他程序塊影響。
- 3、通過學習鍵可學習40個遙控器編碼,使用芯片自帶EEPROM,無需外掛存儲。
- 4、提供keil5 c代碼,有詳細注釋,提供網絡技術支持。
- 該源碼適合初學者研究,或想在原有產品中增加功能又缺乏此類經驗的朋友。
- !!!按一下學習鍵指示燈亮一下滅,松開,再按一下遙控器,學習指示燈閃一下,表示學習成功
- 學習成功后,才能接收此遙控器的數據,否則沒反應!!!
- !!!按下學習按鍵6秒之內松開,超過6秒后無效并清除以前存儲的遙控器數據
- */
- #include "main.h"
- uint TMR0;
- void system_init(void) //上電初始化
- {
-
- #if defined(SYS_CY_12T)
- // /*//12T
- AUXR &= 0x7F; //定時器時鐘12T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0x01; //設置定時器模式
- TL0 = 0x9C; //設置定時初值
- TH0 = 0xFF; //設置定時初值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- ET0 = 1; //定時器0中斷允許
-
- AUXR &= 0xBF; //定時器時鐘12T模式
- TMOD &= 0x0F; //設置定時器模式
- TMOD |= 0x10; //設置定時器模式
- TL1 = 0; //設置定時初值
- TH1 = 0; //設置定時初值
- TF1 = 0; //清除TF1標志
- //TR1 = 1; //定時器1開始計時
- // ET1 = 1;
- //*/
- #endif
-
- LM_SEL=1;
- RF=1;
- SET=1;
-
- EA = 1; //允許CPU中斷
-
- }
- void tm0_isr() interrupt 1 using 1
- {
- rx_data();
- }
- void main()
- {
- system_init();
-
- while(1)
- {
- set_scan();
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
rx.c源程序如下:
- #include "main.h"
- bit old_bit; //保存上一次查詢到的電平狀態
- bit tb_ok; //接收到同步的馬時置1
- bit rf_ok; //接收到一個完整的遙控命令后置1,通知解碼程序可以解碼了
- bit study; //進入學習狀態標志
- bit bt_auto=0; //自動設置遙控接收波特率標志
- bit rf_ok1,rf_ok2; //接收成功臨時標志
- uchar hh_w,ll_w; //高,低電平寬度
- uchar ma_n; //接收到第幾位編碼了
- uchar bma1,bma2,bma3,bma4; //用于接收過程存放遙控編碼
- uchar mma1,mma2,mma3,mma4; //第一次接收到的編碼,用于解碼過程
- uchar mmb1,mmb2,mmb3,mmb4; //第二次接收到的編碼
- uchar temp_T0; //t初值
- uint s_tim; //定時
- #if 1
- void rx_data()
- {
- uchar x;
-
- if(!bt_auto)//自動設置遙控接收波特率標志
- {
- TMR0=100;
- TMR00;
- }
- else
- {
- TMR0=temp_T0;
- TMR00;
- }
-
-
- if (!RF) { ll_w++;old_bit=0; } // 檢測到低電平 低電平時間加1,記錄本次電平狀態 old_rc5=保存上一次查詢到的電平狀態
-
-
-
- else // 檢測到高電平
- {
-
-
- hh_w++;//記錄高電平時間
-
- if (!old_bit)// 檢測到從低到高的跳變,已檢測到一個完整(高-低)電平周期
- {
-
-
-
-
- if (((hh_w>=2)&&(hh_w<=7))&&((ll_w>=50)&&(ll_w<=180))) //判同步碼
- { //下面是同步碼低電平判斷
- if((ll_w>=100)&&(ll_w<=180))//4.7m電阻
- {ma_n=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bma4=0;bt_auto=0;//temp_T0=100;
- }
-
- }
-
-
- else if ((tb_ok)&&((ll_w>=10)&&(ll_w<=16))) //數據低電平
- {
- ma_n++; //已經接收到同步碼,判為0
- if(ma_n>23)
- {
- if(!rf_ok1)
- {
- mma1=bma1;mma2=bma2;mma3=bma3;mma4=bma4;//將接收到的編碼復制到解碼寄存器中
- rf_ok1=1;
- ma_n=0;
- tb_ok=0;
- bt_auto=0;
- s_tim=2500;
- }
- else
- {
- mmb1=bma1;mmb2=bma2;mmb3=bma3;mmb4=bma4;//將接收到的編碼復制到解碼寄存器中
- rf_ok2=1;
- ma_n=0;
- tb_ok=0;
- bt_auto=0;
- }
-
- }
- }
-
-
-
-
- else if ((tb_ok)&&((ll_w>=3)&&(ll_w<=6))) //數據高電平
- { switch (ma_n)
- {
- case 0 : { bma1=bma1 | 0x80; break; }//遙控地址編碼第1位
- case 1 : { bma1=bma1 | 0x40; break; }
- case 2 : { bma1=bma1 | 0x20; break; }
- case 3 : { bma1=bma1 | 0x10; break; }
- case 4 : { bma1=bma1 | 0x08; break; }
- case 5 : { bma1=bma1 | 0x04; break; }
- case 6 : { bma1=bma1 | 0x02; break; }
- case 7 : { bma1=bma1 | 0x01; break; }
- case 8 : { bma2=bma2 | 0x80; break; }
- case 9 : { bma2=bma2 | 0x40; break; }
- case 10: { bma2=bma2 | 0x20; break; }
- case 11: { bma2=bma2 | 0x10; break; }
- case 12: { bma2=bma2 | 0x08; break; }
- case 13: { bma2=bma2 | 0x04; break; }
- case 14: { bma2=bma2 | 0x02; break; }
- case 15: { bma2=bma2 | 0x01; break; }
- case 16: { bma3=bma3 | 0x80; break; }//2262按鍵碼第1位
- case 17: { bma3=bma3 | 0x40; break; }
- case 18: { bma3=bma3 | 0x20; break; }
- case 19: { bma3=bma3 | 0x10; break; }
- case 20: { bma4=bma4 | 0x80; break; }//1527按鍵碼第1位
- case 21: { bma4=bma4 | 0x40; break; }
- case 22: { bma4=bma4 | 0x20; break; }
- case 23:
- { bma4=bma4 | 0x10;
- if(!rf_ok1)
- {
- mma1=bma1;mma2=bma2;mma3=bma3;mma4=bma4;//將接收到的編碼復制到解碼寄存器中
- rf_ok1=1;
- tb_ok=0;
- bt_auto=0;
- ma_n=0;
- s_tim=2500;
- break;
- }
- else
- {
- mmb1=bma1;mmb2=bma2;mmb3=bma3;mmb4=bma4;//將再次接收到的編碼復制到解碼寄存器中,
- rf_ok2=1;
- tb_ok=0;
- bt_auto=0;
- ma_n=0;
- break;
- }
-
- }
- }
- ma_n++;
-
- }
-
-
- else {ma_n=0; tb_ok=0; bt_auto=0;bma1=0; bma2=0; bma3=0; bma4=0;hh_w=1;ll_w=0;} //接收到不符合的高-低電平序列
-
- ll_w=0;hh_w=1;
- }
-
-
- old_bit=1; // 記錄本次電平狀態
- }
-
-
-
-
-
- if(rf_ok1) //規定時間內接受到2幀相同的編碼數據才有效
- {
-
-
-
- s_tim--;
- if(!s_tim) rf_ok1=0;
- if(rf_ok2)
- {
-
-
- if((mma1==mmb1)&&(mma2==mmb2)&&(mma3==mmb3)&&(mma4==mmb4))//比較兩次接收到的編碼是否一致 OK
- {
-
- rf_ok=1;
- rf_ok1=0;
- rf_ok2=0;
- }
- else//接收數據無效
- {
- rf_ok=0;
- rf_ok1=0;
- rf_ok2=0;
- }
-
- }
- }
-
-
-
-
- #if defined(STUDY_NOSET)
- if(rf_ok) //判斷
- {
- GIE=0;
- rf_ok=0;
- if(((mma3==0xc0)&&(!mma4))|((mma3==0x30)&&(!mma4))|((!mma3)&&(mma4==0xc0))|((!mma3)&&(mma4==0x30))) //判斷是2262編碼
- {
- D0=(mma3 - 0xc0); //取按鍵碼
- D1=(mma3 - 0x30);
- D2=(mma4 - 0xc0);
- D3=(mma4 - 0x30);
-
- decode_ok=0;
- s=1500;
-
- }
- else //判斷是1527編碼
- {
-
- D0=(mma4 - 0x80); //取按鍵碼
- D1=(mma4 - 0x40);
- D2=(mma4 - 0x20);
- D3=(mma4 - 0x10);
-
- decode_ok=0;
- s=1500; //解碼有效輸出時間
-
- }
- GIE=1;
- }
- #endif
-
-
-
- #if defined(STUDY_SET)
- ////////////////////////////////////////////////////////////////////
- if((rf_ok)&&(!study)) //判斷是否是學習狀態
- {
-
- rf_ok=0;
- if(((mma3==0xc0)&&(!mma4))|((mma3==0x30)&&(!mma4))|((!mma3)&&(mma4==0xc0))|((!mma3)&&(mma4==0x30))) //判斷是2262編碼
- {
- for(x=0;x<40;x++)
- {
- if((mma1==EEPROM_read(x*3+1))&&(mma2==EEPROM_read(x*3+2)))
- {
- D0=(mma3 - 0xc0); //取按鍵碼
- D1=(mma3 - 0x30);
- D2=(mma4 - 0xc0);
- D3=(mma4 - 0x30);
-
- decode_ok=0;
- s_tim=1500;
- break;
- }
-
- }
-
- }
- else //判斷是1527編碼
- {
- for(x=0;x<40;x++)
- {
- if((mma1==EEPROM_read(x*3+1))&&(mma2==EEPROM_read(x*3+2))&&(mma3==EEPROM_read(x*3+3)))
- {
- D0=(mma4 - 0x80); //取按鍵碼
- D1=(mma4 - 0x40);
- D2=(mma4 - 0x20);
- D3=(mma4 - 0x10);
-
- decode_ok=0;
- s_tim=1500; //解碼有效輸出時間
- break;
- }
-
- }
-
- }
-
- }
- /////////////////////////////////////////////////////////////////////////
- #endif
-
-
-
- if(!decode_ok)//解碼有效輸出
- {
- s_tim--;
- if(!s_tim)
- {
- decode_ok=1;//關信號燈
- if(!LM_SEL) // 鎖存/暫態 選擇
- {
- D0=1;
- D1=1;
- D2=1;
- D3=1;
- }
- }
-
- }
- }
- #endif
-
-
- void KEY_study() //遙控器學習
- {
- uchar num_rf;
- uchar d_num=0;
-
- while(!rf_ok)//等待按鍵
- {
- delay_ms(100);
- d_num++;
- if(d_num>200) break;
- }
-
-
- d_num=0;
-
- if(rf_ok)
- {
- GIE=0;
- num_rf=EEPROM_read(0x00); //取已學習的遙控器數量
- if(num_rf>40){num_rf=0;} //如果遙控器數量超過40個,覆蓋最先學習的
-
-
-
- EEPROM_write(0,num_rf+1);
-
- EEPROM_write(num_rf*3+1,mma1);
- EEPROM_write(num_rf*3+2,mma2);
- EEPROM_write(num_rf*3+3,mma3);
-
-
-
-
-
- LED=0;
- delay_ms(200);
- LED=1;
- rf_ok=0;
- GIE=1;
-
- }
- else
- {
- rf_ok=0; //操作超時
- }
- d_num=0;
-
-
- }
- void system_res() //系統清零,清除學習過的遙控器編碼
- {
- GIE=0;
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
51單片機433遙控解碼(帶學習功能).rar
(205.31 KB, 下載次數: 1234)
2017-11-22 21:54 上傳
點擊文件名下載附件
433遙控解碼
|