基于51單片機的萬能紅外遙控器的設計資料分享給51hei的朋友們
這個單片機選擇的是STC15F2K60S2型高速單片機,這個遙控器主要分為兩種模式
(1)遙控模式
在這個模式下這個遙控器可以遙控其他的紅外設備,和正常的遙控器一樣。
(2)學習模式
這個模式是獲取其他遙控器的用戶碼以及鍵碼,然后把獲取的用戶碼和鍵碼儲存到單片機的EEPROM中,所以這個遙控器具有掉電不丟失的功能。
最后一點就是介紹一下遙控器的小燈的功能。小燈起的是指示的功能,在剛開機的時候,如果是遙控模式小燈閃兩下,學習模式小燈閃三下。在遙控模式下按鍵按一下,小燈閃一下。在學習模式下,紅外接收頭接收到一幀數據小燈閃兩下,連續接收兩幀數據小燈閃四下。按鍵按一下小燈閃一下。
制作出來的實物圖如下:
1526893249466.jpg (325.81 KB, 下載次數: 159)
下載附件
2018-5-21 17:03 上傳
Altium Designer畫的學習型紅外遙控器原理圖和PCB圖如下:(51hei附件中可下載工程文件)
TIM圖片20180521165334.png (176.49 KB, 下載次數: 164)
下載附件
2018-5-21 16:53 上傳
0.png (19.71 KB, 下載次數: 151)
下載附件
2018-5-21 17:21 上傳
0.jpg (35.42 KB, 下載次數: 155)
下載附件
2018-5-21 17:21 上傳
單片機學習型遙控器的源程序如下:
- /*
- 單片機型號STC15F2K60S2,晶振24MHZ
- */
- #include "config.h"
- #include "main.h"
- #include "keyboard.h"
- #include "PWM_Init.h"
- #include "EEPROM.h"
- #include "Infrared_Init.h"
- #include<intrins.h>
- uint8 IR_Send_Code[16][4];
- uint8 xdata IR_Send_Code2[16][4];
- uint8 Send_Flag[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- uint16 timebyte;
- uint8 T0RH = 0; //T0重載值的高字節
- uint8 T0RL = 0; //T0重載值的低字節
- uint8 LED_Control = 0;
- bit irflag = 0; //"紅外接收標志,收到一幀正確數據后置1"
- unsigned char ircode[4]; //"紅外代碼接收緩沖區"
- bit MODE = 1;
- volatile unsigned char CodeBuff=30;
- void main()
- {
- P1=0XFF;
- LED = 1;
- ConfigTimer2(); //定時器0 1KHZ
- EEPROM_Init(); //把所有的EEPROM中的數據讀到緩存區中
- EA=1; //總中斷打開
- if(Mode_CHO) //判斷要使用什么模式
- {
- MODE = 1; //遙控模式
- PWM_Init(); //產生38K載波
- LED_Control = 2; //小燈閃爍2次 代表控制模式
- }
- else
- {
- MODE = 0; //學習模式
- InitInfrared(); //紅外線接收初始化
- LED_Control = 3; //小燈閃爍2次 代表學習模式
- }
- while (1)
- {
- KeyDriver(); //按鍵驅動
- if(irflag&&(CodeBuff<16)) //irflag接收完成標志,
- {
- irflag=0;
- if(timebyte>=500)
- {
- IR_Send_Code[CodeBuff][0]=ircode[0]; //功能碼
- IR_Send_Code[CodeBuff][1]=ircode[1]; //功能碼反碼
- IR_Send_Code[CodeBuff][2]=ircode[2]; //鍵碼
- IR_Send_Code[CodeBuff][3]=ircode[3]; //鍵碼反碼
- Send_Flag[CodeBuff]=0;
- EEPROM_Write(); //接收第一個字節
- }
- if(timebyte<500) //在短時間內收到第二個字節則接收
- {
- IR_Send_Code2[CodeBuff][0]=ircode[0]; //功能碼
- IR_Send_Code2[CodeBuff][1]=ircode[1]; //功能碼反碼
- IR_Send_Code2[CodeBuff][2]=ircode[2]; //鍵碼
- IR_Send_Code2[CodeBuff][3]=ircode[3]; //鍵碼反碼
- Send_Flag[CodeBuff]=1;
- EEPROM_Write();
- LED_Control=5; //接收第二個字節
- }
- timebyte=0;//從接收到第一幀數據開始計時
- LED_Control += 2; //小燈閃爍2次 接收完成一次小燈閃爍兩次
- }
- }
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer2()
- {
- // AUXR &= ~0x04; //定時器2為12T模式
- // T2L = 0X60; //初始化計時值
- // T2H = 0Xf0;
- // AUXR |= 0x10; //定時器2開始計時
- // IE2 |= 0x04;
- AUXR &= 0xFB; //?????12T??
- T2L = 0x30; //??????
- T2H = 0xF8; //??????
- AUXR |= 0x10; //???2????
- IE2 |= 0x04;
- }
- void InterruptTimer2() interrupt 12
- {
- static unsigned int i=0,j=0;
- i++;
- timebyte++;//計算字節之間的時間
- if(LED_Control)
- {
- if(!(i%50))
- {
- LED=!LED;
- i=0;
- j++;
- }
- if(j==(2*LED_Control))
- {
- LED_Control=0;
- LED=1;
- j=0;
- }
- }
- if(timebyte>600)
- timebyte=600;
- KeyScan(); //執行按鍵掃描
- }
- //中斷服務程序
- void Interrupt38KPWM() interrupt 3 //中斷入口
- {
- IR = !IR;
- // IE2 &= ~0x04; //若需要手動清除中斷標志,可先關閉中斷,此時系統會自動清除內部的中斷標志
- // IE2 |= 0x04; //然后再開中斷即可
- }
- /* "INT1中斷服務函數,執行紅外接收及解碼 "*/
- void EXINT1_ISR() interrupt 2
- {
- unsigned char i, j;
- unsigned char byt;
- unsigned int time;
- // LED_Control=1;
- //"接收并判定引導碼的9ms低電平"
- time = GetLowTime();
- if ((time<8500*2) || (time>9500*2)) //"時間判定范圍為8.5~9.5ms," //((time<7833) || (time>8755))
- { //"超過此范圍則說明為誤碼,直接退出 "
- IE1 = 0; //"退出前清零INT1中斷標志"
- return;
- }
- //"接收并判定引導碼的4.5ms高電平"
- time = GetHighTime();
- if ((time<4000*2) || (time>5000*2)) //"時間判定范圍為4.0~5.0ms," //((time<3686) || (time>4608))
- { //"超過此范圍則說明為誤碼,直接退出"
- IE1 = 0;
- return;
- }
- //"接收并判定后續的4字節數據"
- for (i=0; i<4; i++) //"循環接收4個字節"
- {
- for (j=0; j<8; j++) //"循環接收判定每字節的8個bit"
- {
- //"接收判定每bit的560us低電平 "
- time = GetLowTime();
- if ((time<340*2) || (time>780*2)) //"時間判定范圍為340~780us, " //((time<313) || (time>718))
- { //"超過此范圍則說明為誤碼,直接退出"
- IE1 = 0;
- return;
- }
- //"接收每bit高電平時間,判定該bit的值"
- time = GetHighTime();
- if ((time>340*2) && (time<780*2)) //"時間判定范圍為340~780us," //((time>313) && (time<718))
- { //"在此范圍內說明該bit值為0"
- byt >>= 1; //"因低位在先,所以數據右移,高位為0"
- }
- else if ((time>1460*2) && (time<1900*2)) //"時間判定范圍為1460~1900us," //((time>1345) && (time<1751))
- { //"在此范圍內說明該bit值為1"
- byt >>= 1; //"因低位在先,所以數據右移, "
- byt |= 0x80; //"高位置1"
- }
- else //"不在上述范圍內則說明為誤碼,直接退出"
- {
- IE1 = 0;
- return;
- }
- }
- ircode[i] = byt; //"接收完一個字節后保存到緩沖區"
- }
- irflag = 1; //"接收完畢后設置標志"
- IE1 = 0; //"退出前清零INT1中斷標志"
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (42.58 KB, 下載次數: 161)
下載附件
2018-5-21 17:21 上傳
所有資料51hei提供下載:
紅外遙控.rar
(752.31 KB, 下載次數: 958)
2018-5-21 16:55 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|