英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

标题: [转帖]PIC单片机红外线遥控接收解码 [打印本页]

作者: star    时间: 2012-8-20 10:51
标题: [转帖]PIC单片机红外线遥控接收解码
#include<pic.h>
__CONFIG(0x1832);        
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define uchar unsigned char
#define uint   unsigned int
void delay(char x,char y);
#define bitset(var,bitno)((var)|=1<<(bitno))
#define bitclr(var,bitno)((var)&=~(1<<(bitno)))
union {
      struct {
         unsigned b0:1;
         unsigned b1:1;
         unsigned b2:1;
         unsigned b3:1;
         unsigned b4:1;
         unsigned b5:1;
         unsigned b6:1;
         unsigned b7:1;
         }oneBit;
        unsigned char allBits;
       } myFlag;
#define CNT2_1 myFlag.oneBit.b1
#define CNT2_2 myFlag.oneBit.b2
#define CNT2_3 myFlag.oneBit.b3
#define CNT2   myFlag .allBits

static bit FLAGS ;
static bit Bitin;
        
union Csr
     { unsigned long i;
         unsigned char Csra[4];
     }myCsra;
#define RMT   RA1                              // ;遥控接收输入脚位地址(RA。1)
#define BITIN 7                               //遥控接收数据位位标志
uchar CNT0, CNT3,CNT4;                         //用户临时寄存器1--4
uint   CNT1;
uchar TABADD;                                  //数码管显示码取码用寄存器
uchar CSR0;                                    //;遥控键码反码寄存器
uchar CSR1;                                    //;遥控器键码寄存器
uchar CSR2;                                    //;遥控器用户码高8位寄存器
uchar CSR3;                                    //;遥控器用户码低8位寄存器
uchar FLAGS2;                                  //;临时寄存器
uchar CSR2A ;                                  //遥控接收32位数据暂存寄存器

const uchar table[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90,0x88,0x83,0x0C6,0x0a1,0x86,0x8e,};//0x00
                    // 0,     1,    2,   3,    4,   5,    6,   7,   8,   9,   a,   b,    c,   d,    e,    f,

//-------------系统初始化子程序------------------------------
void initial (void)
{
        PORTA=0;
        ADCON1=7;                                // 设置RA口全部为普通数字IO口
        TRISA=0x02;                              // 将RMT设置为输入,其它所有IO口设置为输出
        TRISD=0;                                 // ;RC口全部为输出
        PORTD=0xFF;                              //先让数码管全部不显示
}
//--------------------------------------------------------------------------------------------
void   RCV()
{
if(!RMT)
{   
             CNT1=640;                            //4*256*10us 640*16=10。24ms
             CNT2=0;
       //RCV1
         do {                                     // ;先检测引导码的9MS低电平_____┏┓
                                                  // ;每一个循环16US
              if(RMT)
               CNT2=CNT2++;
              if(!RMT)
                CNT2=0;
              if(CNT2_2)                          //高电平大于8*10US=80US则为有效高电平,
                break;                            //否则是一些干扰信号16*4=64us
            } while (CNT1--);                     //低电平大于4*256*10US=10.24MS则是错误脉冲
            
       //RCV2
        if(CNT2_2&&(0<CNT1)&&(CNT1<320))          //;低电平小于2*256*10US=5.12MS┏┒____
          {                                       //320*16=5。12ms则是错误脉冲
             CNT1=480;                            //;3*256*10us 480*16=7.68
             CNT2=0;
         
                                                  //RCV3          //;每一个循环16US
                       
              do {      
                  if(!RMT)
                   CNT2=CNT2++;
                  if (RMT)
                    CNT2=0;
                  if(CNT2_2)                       // 低电平大于8*10US=80US则为有效低电平,否则是一些干扰信号
                    break;                         //RCV4,否则是一些干扰信号16*4=64us
                                                   // 高电平大于3*256*10US=7.68MS则是错误的               
                } while (CNT1--);
               //RCV4
                if(CNT2_2 && (0<CNT1)&&(CNT1<320)) //高电平小于1*256*10US=2.56MS则是错误的
                 {                                 //480-320=160 *16= 2.56ms
                       CNT3 =32;                   //接收数据共32位,16位用户码,8位控制码加8位控制码的反码
                //RCV5     
                  do {
                         CNT2=0;
                         CNT0=86;                  //低电平大于256-170=86*10US=860US错误 86*10 __┌┐
                         CNT4=200;                 //高电平大于256-56=200*10US=2MS错误   200*10
                  //RCV5_HI            
                           do {                    //;每一个循环10US
                                if(RMT)
                                  CNT2=CNT2++;
                                if(!RMT)
                                   CNT2=0;
                                if(CNT2_3)         //;高电平大于8*10US=80US则为有效高电平
                                   break;          //RCV6否则是一些干扰信号16*4=64us
                          
                                                   //;低电平大于860US则是错误的
                               } while (CNT0--);
                   //CV6           
                      if((CNT0==0)||(CNT2_3==0))   break;
                        
                                      CNT2=0;
                   //RCV6_LO              
                                    do {                    //┌┐__
                                         if(!RMT)
                                           CNT2=CNT2++;
                                          if(RMT)
                                           CNT2=0;
                                           if(CNT2_3)    //低电平大于10*8US=80US则是有效低电平
                                            break ;      // COMPARE 否则是一些干扰信号16*4=64us
                                        } while (CNT4--);//高电平大于256-56=200*10US=2MS错误
                                   
                                  if((CNT4==0)||(CNT2_3==0))   break;

                                   //OMPARE        
                                      CNT0=(86-CNT0)+(200-CNT4) ;
                                         //;减CNT0的值 等于实际低电平计数值
                                         // ;减CNT4的值 等于实际高电平计数值
                                         // ;将高低电平的计数加在一起并存入CNT0,通过比较高低电平总的时间来确定是1还是0
                                         // ;总的值大于255(即时间大于255*10US=2.55MS)则错误 255*10=2.55
                                         // ;总的时间小于70*10US=700US则是错误的            70*10=700
                                     if(( (70<CNT0)&&(CNT0<130))||((160<CNT0)&&(CNT0<230) ) ) // ;130*10=1.3MS   
                                         {     
                                               if((70<CNT0)&&(CNT0<130))
                                                          //COMPARE_H   // ;时间大于1.3MS转去确定是否1
                                                         
                                                     Bitin=0;           //;时间在700US-1.3MS之间则是0
                                              else// if (160<CNT0<230) //;小于160*10US=1.6MS,则错误   
                                                                        //;大于230*10US=2.3MS,则错误
                                                    Bitin=1;            // ;时间在1.6MS-2.3MS之间则是1
                                            myCsra.i= myCsra.i>>1;      //;将每一位移入相应寄存器
                                             if(Bitin)
                                                      bitset ( myCsra. Csra[3],7);
                                              else    bitclr ( myCsra. Csra[3],7);
                                          }
                                       else break;
                                          
                    } while (CNT3--); //;是否接收完32位
                      CSR3=myCsra. Csra[0];
                      CSR2=myCsra. Csra[1];
                      CSR1=myCsra. Csra[2];
                      CSR0=myCsra. Csra[3];
                     CSR2A= ~CSR0; //;比较键码的反码取反后是否等于键码
                                    //;不等于则接收到的是错误的信息
                                    // 将键码送显示   
                   }
            }
   }
}
//-------------------------------------------------
void display()
   {
     int i;                        //定义查表变量
     i=CSR3&0x0f;                  //求秒的个位
     PORTD=table;               //送D口显示
     PORTA=0x3e;                   //点亮秒的个位
     delay(5,70);                  //延长一段时间,保证亮度
     
     i=CSR3&0xf0;                  //求秒的十位
     i=i>>4;                       //右移4位
     PORTD=table;               //送D口显示
     PORTA=0x3d;                   //点亮秒的十位
     delay(5,70);                  //延长一段时间,保证亮度
     
     i=CSR2&0x0f;                  //求分的个位
     PORTD=table;               //送D口显示,并显示小数点
     PORTA=0x37;                   //点亮分的个位
     delay(5,70);                  //延长一段时间,保证亮度

     i=CSR2&0xf0;                  //求分的十位
     i=i>>4;                 
     PORTD=table;               //送D口显示
     PORTA=0x3b;                   //点亮分的十位
     delay(5,70);                  //延长一段时间,保证亮度
     i=CSR1&0x0f;                  //求时的个位
     PORTD=table;               //送D口显示,并加上小数点
     PORTA=0x2f;                   //点亮时的个位
     delay(5,70);                  //延长一段时间,保证亮度
   
     i=CSR1&0xf0;                  //求时的十位
     i=i>>4;   
     PORTD=table;               //送D口显示
     PORTA=0x1f;                   //点亮时的十位
     delay(5,70);                  //延长一段时间,保证亮度
   }
//----------------主程序---------------------------
void main(void)
{      
       initial ();                //系统初始化子程序
        while(1)
        {
             RCV();               //遥控接收程序
             display();           //解码显示程序
        }
}
//------------------------------------------------
//延时函数
void delay(char x,char y)
{
char z;
do{
      z=y;
      do{;}while(--z);
     }while(--x);
}
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。






欢迎光临 英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 (http://enroobbs.com/) Powered by Discuz! X3.2