专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

PIC16F887红外解码程序

作者:佚名   来源:本站原创   点击数:  更新时间:2011年03月16日   【字体:
//----------------------------------------------------------------
//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};   //存放数据
uint temp="0";     //临时变量
uchar i,j;     //数组及移位计数用
uchar biaozhi="0";   //起始码标志位
uchar flag="1";    //有键按下,打开定时器
void init_io(void)   //初始化函数
{
    TRISC = 0xFF;   //置CCP1口为输入态
    TRISD = 0x00;   //置D口为输出态
 CCP1CON=0x04;   //CCP1模块工作于捕捉方式
 CCP1IE=1;    //开中断
 CCP1IF=0;    //清捕捉标志位
 PEIE=1;     //开外部中断

 T1CON=0;    //配置定时器T1不分频,使用内部时钟,且先禁止T1
    ei();                   // enable global interrupts
 TMR1H=0;    //计数值清0
 TMR1L=0;
 PORTD=0;    //输出清0
}
main()
{
init_io();     //初始化函数
while(1);     //等待CCP1模块中断产生
}

void interrupt interrupt_service(void)  //中断
{
    if (CCP1IE && CCP1IF)     //判断是否为CCP1模块中断,当在一个系统中时会用
        {
  if(flag==1)          
   {
   TMR1H=0;
   TMR1L=0;
   TMR1ON=1;      //开定时器
   flag=0;
   }
  else
   {
   TMR1ON=0;       //先停定时器
   temp=TMR1L+TMR1H*256;   //取数据并判断
   TMR1H=0;      //清0计数值
   TMR1L=0;
   TMR1ON=1;      //开定时器等待下一个脉冲到来
    if(temp>12600&&temp<14600&&biaozhi==0)     //起始码
     {
     biaozhi=1;          //当检测到起始码时,下次直接进行入数据判断
     i=0;
     j=0;
     }
    else         //数据判断区
     {
     if((temp < 3200)&&(temp > 1200)) //时间在2.2ms左右的为数码0
      {shuju[i]=shuju[i]<<1;j++;}
     else
      if((temp < 5000)&&(temp > 3000)) //时间在4ms左右的为为数码1
       {shuju[i]=(shuju[i]<<1)+1;j++;}
      else
       biaozhi=0;      //否则为终止码,清0起始码标志位,准备下一次按键的接收
     }
    if(j==16&&i<2)      //数组递加,当第一个数组接收满后,开始对下一个数组进行接收
     {i++;j=0;}
    else
     {
     if(j==16&&i==2)     //当接收满后(共48位),对数据输出
      {
      if(shuju[0]==0xeb14)  //为对应的某一按键值
      PORTD=0x10;     //相应端口输出
      if(shuju[0]==0xee11)  //另一键值
      PORTD=0xa0;     //输出
      biaozhi=0;     //接收完成,复位相应标志位
      flag=1;
      i=0;
      j=0;
      }
     
     }
   }    
         TMR1IF = 0;             // clear Timer0 interrupt flag
   CCP1IF=0;        //每次必须对CCP1IF位软件清0
  }
}

注:本程序使用的是TOYO空调的遥控器,起始码为13.6ms,0码为2.2ms,1码为4ms,停止码为9ms.共48位数据,单片机的指令周期为1us,这个程序还没有加校验.

关闭窗口

相关文章