您的位置:控制工程论坛网论坛 » 教程与手册 » 红外线遥控读码机

xilinxue

xilinxue   |   当前状态:在线

总积分:16186  2024年可用积分:0

注册时间: 2008-06-26

最后登录时间: 2020-03-22

空间 发短消息加为好友

红外线遥控读码机

xilinxue  发表于 2008/9/17 13:16:27      1757 查看 3 回复  [上一主题]  [下一主题]

手机阅读

/*;红外线遥控读码机,用本实例配合本站套件可读出任何6121或6122(CD6121/CD6122/SC6121/SC6122)及其兼容芯片的红外线遥控器的用户码、键码。
;本例是一个红外线遥控接收解码程序,程序中数码管显示用的是定时器中断法的动态扫描
;动态显示二位数码管的方法,中断法,我们以3MS中断一次从而交换两位数码管轮流点亮。
;对准实验板红外线接收头轻按要测定的遥控器的待测按键一次,此时实验板的中间两位数码管将显示该键的键码,
;(显示为16进制的),轻触实验板的S10此时显示器切换为显示当前遥控器用户码的低8位, 轻触实验板的S11此时显示器切换为显示当前遥控器用户码的高8位,
;轻触实验板的S9此时显示再一次回到显示当前键的键码.
;注意:所有的显示均为16进制,'A'显示为'A','B'显示为'b','C'显示为'c','D'显示为'd','E'显示为'E','F'显示为'F'.
;注意6121的遥控器发射码依次为:同步头(引导码)+32位数据码(用户码低8位+用户码高8位+键码+键码的反码)
;引导码是由9MS的高电平加4.5MS的低电平构成,我们接收到的刚好反相为9MS的低电平加4.5MS的高电平.
;数据码'0'是由560US的高电平加560US的低电平构成,接收时反相为560US的低电平加560US的高电平构成.
;数据码'1'是由560US的高电平加1.69MS的高电平构成,接收时反相为560US的低电平加1.69MS的高电平构成.
*/#include<pic.h>
 
#define uchar  unsigned char
#define uint   unsigned int
//#define ulong unsigned long

//__CONFIG(XT&UNPROTECT&PWRTEN&BORDIS&WDTEN);

#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;
 
//  bit FLAGS3 ; 
       
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  FLAGS;       //显示位选标志位
uchar  DISPBUF_H;     //显示器高位
uchar  DISPBUF_L;     //显示器低位
uchar  CSR0;          //;遥控键码反码寄存器
uchar  CSR1;          //;遥控器键码寄存器
uchar  CSR2;          //;遥控器用户码高8位寄存器
uchar  CSR3;          //;遥控器用户码低8位寄存器
uchar  FLAGS2;        //;临时寄存器
//uchar  CSR0A ;      //;遥控接收32位数据暂存寄存器
//uchar  CSR1A ;      //;遥控接收32位数据暂存寄存器
uchar  CSR2A ;        //遥控接收32位数据暂存寄存器
//uchar  CSR3A ;      //遥控接收32位数据暂存寄存器
 
const uchar table[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90,0x88,0x83,0x0a7,0x0a1,0x86,0x8e,};//0x00
                    // 0,     1,    2,   3,    4,   5,    6,   7,   8,   9,   a,   b,    c,   d,    e,    f,

//------------------中断-------------------------
void  interrupt TMR0SERV()
 {
   PORTC =0x0ff;//  先熄灭所有数码管以免闪烁
   RA4=1;
   RA5=1;
   RA0=1;
   RA2=1;
   RA3=1;
  if( FLAGS)
       {PORTC=table[ DISPBUF_L];RA2=0;} //;送RC口显示,位选通
  else {PORTC=table[ DISPBUF_H];RA3=0;}
    FLAGS= !FLAGS;
     TMR0=155;  //送定时器初值
     T0IF =0;   //清定时器0溢出中断标志位
}

1楼 0 0 回复
  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/9/17 13:15:38

    //-------------系统初始化子程序------------------------------
    void  initial (void)
    {
            PORTA="0";
            PORTB="0";     //初始化IO口
            ADCON1=7;    // ;设置RA口全部为普通数字IO口
            TRISA="0x0c2"; // 将RMT设置为输入,其它所有IO口设置为输出
            TRISB= 0x0FF;//;RB口全部为输入 
            TRISC="0";     // ;RC口全部为输出
            OPTION="4";    //预分频器分配给定时器0,分频比1:32;开启RB口弱上拉.
            TMR0=155;    //定时器送初值(255-155)*32US=3.2MS,每3.2MS一次中断
            PORTC="0xFF";  //先让数码管全部不显示
            DISPBUF_L=0; //数码管先显示00
            DISPBUF_H=0;
            T0IF=0;
            T0IE=1;     ///定时器0溢出中断允许
            GIE="1";      //总中断允许
    }
    //-------------将键码送显示---------------------------------------
    void  KEY1(void)
    {       
             CNT0 =0;        //消除键抖动
             CNT1 =100;
         while( CNT1--&& CNT0!=8)
                {
                   if(RB1)    
                   CNT0++;
                   if(!RB1)
                   CNT0=0;
                }
                  if( CNT0!=8)
                  {
                   DISPBUF_H = CSR1>>4;       //;键码值高低位交换,先处理高位
                                             //;屏蔽掉高位 存入寄存器
                   DISPBUF_L= CSR1&0x0f;     //;键码值低位处理
                                            //;屏蔽掉高位//;存入寄存器
                    while(!RB1);           //;等待键释放
                  }
    }
    //----------------将用户码低8位送显示-------------------------------
    void  KEY2(void)
    {                              
                 CNT0 =0;        //消除键抖动
                 CNT1 =100;
           while( CNT1--&& CNT0!=8)
             {
                   if (RB2)    
                       CNT0++;
                    if(!RB2)
                       CNT0=0;
              }
                 if( CNT0!=8)
                {
                 DISPBUF_H=CSR3>>4;      //;用户码低8位 高低位交换,先处理高位
                                         //;屏蔽掉高位,存入寄存器
                 DISPBUF_L=CSR3&0x0f;    //;用户码低8位 低位处理
                                         //;屏蔽掉高位,存入寄存器
                     while(!RB2);       //;等待键释放
                }


    }
    //---------------将用户码高8位送显示-------------------------------
    void  KEY3(void)
    {
               CNT0 =0;        //消除键抖动
               CNT1 =100; 
        while( CNT1--&& CNT0!=8)
             {
                   if (RB3)    
                       CNT0++;
                    if(!RB3)
                       CNT0=0;
              }
                 if( CNT0!=8)
               {
                 DISPBUF_H=CSR2>>4;      //;用户码低8位 高低位交换,先处理高位
                                         //;屏蔽掉高位,存入寄存器
                 DISPBUF_L=CSR2&0x0f;    //;用户码低8位 低位处理
                                         //;屏蔽掉高位,存入寄存器
                     while(!RB3);       //;等待键释放
                }
            
    }
    //--------------------------------------------------------------------------------------------

    2楼 回复本楼

    引用 xilinxue 2008/9/17 13:15:38 发表于2楼的内容

  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/9/17 13:16:27

    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位
                          CSR0=myCsra. Csra[0];
                          CSR1=myCsra. Csra[1];
                          CSR2=myCsra. Csra[2];
                          CSR3=myCsra. Csra[3];
                         CSR2A= ~CSR3;  //;比较键码的反码取反后是否等于键码
                                        //;不等于则接收到的是错误的信息
                                       // 将键码送显示
                          if(CSR2==CSR2A)
                                 { 
                                      DISPBUF_H = CSR2>>4; //;键码值高低位交换,先处理高位
                                                           //;屏蔽掉高位 存入寄存器
                                      DISPBUF_L= CSR2&0x0f;// 键码值低位处理
                                                           //;屏蔽掉高位//;存入寄存器
                                 }
                       }  //if((CNT2_3) && 0<CNT1&&CNT1<300)


                }// if((CNT2_3) && 0<CNT1&&CNT1<301)


       } // if(RMT)是干扰退出


    }
    //----------------主程序---------------------------
     void main(void)
    {     
           initial ();  //系统初始化子程序
            while(1)
            {
                 if(!RB1)     // ;是否按下S9
                    KEY1();   // ;跳转键处理
                 if(!RB2)     // ;是否按下S10
                   KEY2();    //  ;跳转键处理
                 if(!RB3)    // ;是否按下S11
                   KEY3();    //  ;跳转键处理
                 if(!RMT)     // ;是否有遥控器按下
                   RCV();     // ;跳转遥控接收程序
                              //反复检测;
             }
    }
     
    /*;    进入该实战演练的工序流程如下:
    ;    1.创建源文件和编辑源文件;在此介绍一种不同于前面讲的创建源文件的方法,用Windows附件中的”记事本”
    ;   这个为大家所熟知和好用的文件编辑器,并且可以方便的加入中文注释.不过有两点需要注意,一是注释前面的
    ;   分号”;”必须用西文半角输入;二是必须用”.asm”扩展名存储到事先建立的一个专用子目录下.
    ;    2.打开MPLAB集成开发环境:首先在WINDOWS环境下,选用开始>程序>Microchip MPLAB>MPLAB命令,启动MPLAB
    ;   并进入MPLAB的桌面.
    ;    3.创建项目:选用菜单File>New或Project>New Project,在事先建立的一个专用子目录下创建一个新项目,将
    ;   用记事本创建的源文件加入到该项目中.
    ;    4.建立项目中的目标文件:选择菜单Project >Build All(项目>建立所有文件),MPLAB将自动调用MPASM将项目
    ;   文件管理下的源文件(.asm)汇编成十六进制的目标文件(.hex).
    ;    5.ICD参数设置:通过菜单命令Project>Edit Project或者Option>Development Mode,将开发模式设置为
    ;   ”MPLAB ICD Debugger”,点击OK按钮,打开ICD的工作窗口,在调试阶段,可以按照说明书图2-10设置各项,但需注意
    ;   OSCILLATOR应设置为XT方式,尤其需要说明的是,选中“Enable Debug Mode”(使能调试模式)选项,在向目
    ;   标单片机烧写机器码程序时,会将调试临控程序同时写入单片机的指定程序存储器区域,然后才允许用ICD方式调试。
    ;    6.电路设置:将演示板的S1全部拔到OFF,S13的第3位拔到ON其它位OFF,S4全部拔到ON,S5的第5第6位拔到ON其它位OFF,LCD不要插在演示板上,
    ;   将用于选择频率的插针跳线插到”XT OSC”位置上,板上93CXX、24CXX应拿下。
    ;    7.向目标单片机烧写目标程序:用户在点击功能按钮”Program”向目标单片机烧写机器码程序时,会等待一段时间,
    ;   并且在条状的状态信息栏中,出现提示信息。有一点需要引起注意,就是PIC16F87X单片机的FLASH程序存储器的擦写
    ;   周期是有限的,大约为1000次,应尽量节省它的使用寿命。
    ;    8.运行和调试用户程序和用户电路:在各项参数设置好后,将ICD的工作窗口最小化,利用前面讲的”运行及调试”中介
    ;   绍的几种方法进行调试.当用自动单步方式调试时,建议临时禁止廷时子程序发挥作用,具体的方法是,可在CALL DELAY指
    ;   令前添加一个分号,并且重新汇编一次.为了学习目的,在调试过程中可以人为地加入一些软件漏洞(BUG)或硬件故障,来模
    ;   仿单片机端口引脚的片内或片外故障.
    ;    9.定型烧写目标单片机;经过多次重复上述步骤的反复修改和调试,使得程序和电路在联机状态完全正常,这时可以进行
    ;   定型烧写,即将ICD窗口中的”Enable Debug Mode”(使能调试模式)选项消除,不再将调试临控程序写入单片机中.
    ;    10.独立运行验收:上一步中的烧写过程完成后,即可将ICD模块和ICD仿真头(或演示板)之间的6芯电缆断开,让单片机在
    ;   演示板独立运行,观察实际效果.
    ;
    ;*/

    3楼 回复本楼

    引用 xilinxue 2008/9/17 13:16:27 发表于3楼的内容

  • yy380736204

    yy380736204   |   当前状态:在线

    总积分:141  2024年可用积分:0

    注册时间: 2012-08-31

    最后登录时间: 2012-10-13

    空间 发短消息加为好友

    yy380736204   发表于 2012/9/10 10:31:53

    感觉红外线遥控读码机 好难啊
    4楼 回复本楼

    引用 yy380736204 2012/9/10 10:31:53 发表于4楼的内容

总共 , 当前 /