//---------------------------------------------------------------- //PIC16F887 紅外解碼程序 //指令周期1us, #include <htc.h> // header file with compiler macros, for // example __CONFIG // the processor header file, with register // and bit definitions (pic16f887.h) is // automatically included #define uchar unsigned char #define uint unsigned int // __CONFIG sets the PIC16F887 Configuration Words. See bottom of the header // file pic16f887.h for fuse option constants. __CONFIG(INTCLK & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS); __CONFIG(BORV40); // 2nd config word ////// /////////////////////////////////////////////////////////////////////////// uint shuju[3]={0}; //存放數(shù)據(jù) uint temp="0"; //臨時變量 uchar i,j; //數(shù)組及移位計(jì)數(shù)用 uchar biaozhi="0"; //起始碼標(biāo)志位 uchar flag="1"; //有鍵按下,打開定時器 void init_io(void) //初始化函數(shù) { TRISC = 0xFF; //置CCP1口為輸入態(tài) TRISD = 0x00; //置D口為輸出態(tài) CCP1CON=0x04; //CCP1模塊工作于捕捉方式 CCP1IE=1; //開中斷 CCP1IF=0; //清捕捉標(biāo)志位 PEIE=1; //開外部中斷 T1CON=0; //配置定時器T1不分頻,使用內(nèi)部時鐘,且先禁止T1 ei(); // enable global interrupts TMR1H=0; //計(jì)數(shù)值清0 TMR1L=0; PORTD=0; //輸出清0 } main() { init_io(); //初始化函數(shù) while(1); //等待CCP1模塊中斷產(chǎn)生 } void interrupt interrupt_service(void) //中斷 { if (CCP1IE && CCP1IF) //判斷是否為CCP1模塊中斷,當(dāng)在一個系統(tǒng)中時會用 { if(flag==1) { TMR1H=0; TMR1L=0; TMR1ON=1; //開定時器 flag=0; } else { TMR1ON=0; //先停定時器 temp=TMR1L+TMR1H*256; //取數(shù)據(jù)并判斷 TMR1H=0; //清0計(jì)數(shù)值 TMR1L=0; TMR1ON=1; //開定時器等待下一個脈沖到來 if(temp>12600&&temp<14600&&biaozhi==0) //起始碼 { biaozhi=1; //當(dāng)檢測到起始碼時,下次直接進(jìn)行入數(shù)據(jù)判斷 i=0; j=0; } else //數(shù)據(jù)判斷區(qū) { if((temp < 3200)&&(temp > 1200)) //時間在2.2ms左右的為數(shù)碼0 {shuju[i]=shuju[i]<<1;j++;} else if((temp < 5000)&&(temp > 3000)) //時間在4ms左右的為為數(shù)碼1 {shuju[i]=(shuju[i]<<1)+1;j++;} else biaozhi=0; //否則為終止碼,清0起始碼標(biāo)志位,準(zhǔn)備下一次按鍵的接收 } if(j==16&&i<2) //數(shù)組遞加,當(dāng)?shù)谝粋數(shù)組接收滿后,開始對下一個數(shù)組進(jìn)行接收 {i++;j=0;} else { if(j==16&&i==2) //當(dāng)接收滿后(共48位),對數(shù)據(jù)輸出 { if(shuju[0]==0xeb14) //為對應(yīng)的某一按鍵值 PORTD=0x10; //相應(yīng)端口輸出 if(shuju[0]==0xee11) //另一鍵值 PORTD=0xa0; //輸出 biaozhi=0; //接收完成,復(fù)位相應(yīng)標(biāo)志位 flag=1; i=0; j=0; } } } TMR1IF = 0; // clear Timer0 interrupt flag CCP1IF=0; //每次必須對CCP1IF位軟件清0 } }
注:本程序使用的是TOYO空調(diào)的遙控器,起始碼為13.6ms,0碼為2.2ms,1碼為4ms,停止碼為9ms.共48位數(shù)據(jù),單片機(jī)的指令周期為1us,這個程序還沒有加校驗(yàn).