打印

PT2262按键处理问题

[复制链接]
3168|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xieyajun888|  楼主 | 2013-7-19 09:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问,哪位单片机高手,PT2262无线遥控单片机软件解码,怎么判断按键是否放开?
我这里有从别处找来的程序,弄了很久都无从着手,请看源程序,可以直接编译通过的,已经可以控制LED的开关!

PT2262单片机解码程序:
#include<reg51.h>
#include <intrins.h>            //包含_nop_()函数的头文件
#define uchar unsigned char
#define uint unsigned int
//----------------------------------------------------------------------------------
sbit zhishi = P3^4;                   //密码正确指示灯

sbit RF=P3^2;                     //RF信号检测口

sfr P4=0xc0;
sbit deng_open=P3^5;            //继电器闭合控制        ,灯开关控制
bit xue_xi=0;        //每次上电后按住自学键后学习一次有效标志位
bit   jiesuo_yx=0;
bit  you_xiao=1;                        //解码有效标志,1有效,0无效
bit   ajok_flag=1;                        //按键放开标志
bit   lianji_flag;                                                                                                                        //连击键放开标志1:连击        0:点击
bit xuexi_key=1;            //自学习标志1有效0无效
bit ycx=0;        //每次上电后按住自学键后学习一次有效标志位
bit miao_key;                 //每次上电后按住自学键后学习1秒内一次有效标志位
bit get_out=0;//按键是否松开判断标志
bit an_jian;
//bit  open_deng;

//------------------- 变量列表------------------------------------------------------
uchar  ReadCode[3],GetCode;     //定义密码和数据变量3个数组全局变量
uchar  ReadCode2[3],ReadCode3[3],jm_chishu;   
uchar kai_guan_one;        //1灯总开关
uchar kai_guan_two;        //2灯总开关
uchar kai_guan_three;//3灯总开关
uchar kai_guan_four;////4灯总开关
uchar key; ////取键值单元
uchar open_key;//按键放开标志
uchar bao_data;//数据状态保持标志
uint data TimerReadKey=0;//计时按键
uchar data cont;//50毫秒计数器
uchar data miao;//1秒计数器
uchar  ji_shu;//        按键50毫秒内次数监测
uchar lianji_shu=0;   //记录50MS键盘按下的次数
//uchar add_temp;
static uchar mima_h4,mima_l4,mima_h4_2,mima_l4_2,mima_h4_3,mima_l4_3,yaokong_geshu; //定义高4位和低4位密码保存区

uchar bj_temp=0;
uchar jiesuo_sheng_cishu=0;
uchar sheng_h,sheng_l;
uchar th1_temp,sheng_cishu;

//---------------------------------函数列表------------------------------------
void delay_200(void);                                                 //200us精确延时
void delay_250(void);                                                 //250us精确延时
void delay_131(void);                                                 //131ms精确延时
//void init(void);                                                         //初始化子程序
//void INT0_intrupt();                                                 //中断处理子程序(解码程序)
void rf_jc(void);
void zixuexi_mima_du(void);
//-----------------------------主程序入口--------------------------------------
//******************************************************************************************
//                   声明与IAP/ISP/EEPEOM有关的特殊功能寄存器的地址
//  该单片机与普通51单片机有区别,特殊功能控制寄存器需要用 sfr 关键字定义地址否则无法使用
//******************************************************************************************
sfr  isp_data=0xc2;              //ISP/IAP操作时的数据寄存器,读出的和要写入的数据都放这里
sfr  isp_addrh=0xc3;             //ISO/IAP操作时的地址寄存器高8位,需要读出的和写入的地址高8位
sfr  isp_addrl=0xc4;             //ISO/IAP操作时的地址寄存器低8位,需要读出的和写入的地址低8位
sfr  isp_cmd=0xc5;               //ISP/IAP操作时的命令寄存器,须命令触发寄存器触发方可生效
sfr  isp_trig=0xc6;              //操作时的命令触发寄存器
sfr  isp_contr=0xc7;             //ISP/IAP控制寄存器
sfr  AUXR=0x8e;                  //特殊功能寄存器AUXR的地址声明
//==============定义FLASH操作等待时间及允许IAP/ISP/EEPROM操作的常数=============
#define enable_isp 0x82          //晶体<20MHZ时对ISP_CONTR设置此数
#define SYSclk 22529600L
#define T1MS (65536-SYSclk/1000)
#define T1MS (65536-SYSclk/12/1000)
static  uchar xieshuju;
static  uchar dushuju;
//****************************************************************************************
//关闭IAP功能函数,使CPU处于安全状态,一次连续的IAP操作之后建议关闭IAP功能,不需要每次都关.
//****************************************************************************************
void iap_disable(void)
{
  isp_contr=0;         //关闭IAP功能
  isp_cmd=0;           //清命令寄存器,使其无命令,此句也可不用
  isp_trig=0;          //清命令触发寄存器,使其无效,此句也可不用
  isp_addrh=0xff;      //指向非EEPROM区防止误操作
  isp_addrl=0xff;      //指向非EEPROM区防止误操作
}

//*************************************************************************************************
//            定时器1初始化
//*************************************************************************************************
void time1_csh(void) //50毫秒@5.5296MHz                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
{
    AUXR = 0x00;                //定时器时钟12T模式
           TMOD = 0x00;                //设置定时器模式
           TL1 = T1MS;                //设置定时初值
           TH1 = T1MS>>8;                //设置定时初值
           TF1 = 0;                //清除TF1标志
                                ET1 =1;
           TR1 = 1;                //定时器1开始计时
                                EA=1;
                                cont=0;       
                                miao=0;
}






        void delay_200(void)
{
    uchar i,j;

           for(i=5;i>0;i--) //5(STC12C2052外4MHz);5(AT89C2051外12MHz)
           for(j=72;j>0;j--);//72(STC12C2052外4MHz);18(AT89C2051外12MHz)

}
/*-------------------------------250us精确延时---------------------------------*/
void delay_250(void)
{
    uchar i,j;       

           for(i=5;i>0;i--)   //5(STC12C2052外4MHz);5(AT89C2051外12MHz)
           for(j=92;j>0;j--); ////92(STC12C2052外4MHz);23(AT89C2051外12MHz)
}
/*-------------------------------131ms精确延时--------------------------------*/
void delay_131(void)
{
    uchar i,j;

           for(i=254;i>0;i--)
           for(j=254;j>0;j--);
}
//----------------- 读出自学习遥控器密码 --------------------------------------------------------
void zixuexi_mima_du(void)
{
   e2prom_du(0,0); yaokong_geshu=dushuju;                             //读出已经保存的遥控器个数
   e2prom_du(1,0);mima_h4=dushuju;e2prom_du(1,1);mima_l4=dushuju;     //读出保存的第1个遥控器密码
   e2prom_du(2,0);mima_h4_2=dushuju;e2prom_du(2,1);mima_l4_2=dushuju; //读出保存的第2个遥控器密码
   e2prom_du(3,0);mima_h4_3=dushuju;e2prom_du(3,1);mima_l4_3=dushuju; //读出保存的第3个遥控器密码
}
//----------------- 写入自学习遥控器密码----------------------------------------------------------------
void zixuexi_mima_xie(void)
{
    mima_h4=ReadCode2[0];mima_l4=ReadCode2[1];    //当前要写入的密码
    e2prom_du(0,0);yaokong_geshu=dushuju;         //读出已经学习好的遥控数量
    if(yaokong_geshu >3){yaokong_geshu=0;}        //遥控最多3个
    if(yaokong_geshu <3){yaokong_geshu++;}else{yaokong_geshu=1;}  //超过3个则覆盖第1个遥控

    switch(yaokong_geshu)
    {
                                    case 1:
                                                                   {
                                                                                            sector_erase(0,0);              //檫除0扇区
               e2prom_xie(0,0,yaokong_geshu);  //写入目前学习好的遥控个数
               sector_erase(1,0);              //檫除1扇区
                                    e2prom_xie(1,0,mima_h4);e2prom_xie(1,1,mima_l4);  //保存第1个遥控器密码
                         break;
                         }
       case 2:
                                                            {  
                                                                                     sector_erase(0,0);              //檫除0扇区
               e2prom_xie(0,0,yaokong_geshu);  //写入目前学习好的遥控个数
               sector_erase(2,0);              //檫除2扇区
                                    e2prom_xie(2,0,mima_h4);e2prom_xie(2,1,mima_l4);  //保存第2个遥控器密码
                         break;
                         }

              case 3:
                                                           {   
                                                                             sector_erase(0,0);              //檫除0扇区
              e2prom_xie(0,0,yaokong_geshu);  //写入目前学习好的遥控个数
              sector_erase(3,0);              //檫除3扇区
                                   e2prom_xie(3,0,mima_h4);e2prom_xie(3,1,mima_l4);  //保存第3个遥控器密码
                        break;
                        }
     }
}

/*-------------------------定时器1子程序入口---------------------------*/

void time(void)interrupt 3        using 1
{
  
               
                           
    cont++;            //计数单元到1秒
                                //if(cont>10&&cont<20&&miao_key==1)xuexi_key=1;       

   if(cont==20)
     {   
                                            cont=0;
         miao++;
                                                               
                                                                       
         if(miao==10)        //计数单元到10秒
         {
                     miao=0;
                                                                                                //        xuexi_key=0;        //自学习标志1有效0无效
                                                                                                //        miao_key=0;
                                                                                                 zhishi=0;
                                                                                                        //deng_open=0;
             //TR1=0;
          }
         
         
      }               

                               
                        /*        if(lianji_shu>1)
     {
                                            ji_shu++;
                                                                        if(ji_shu==1&&lianji_shu>3)
                                            {  
                                                                                  
                                                                                                                                       
                                                                                                                                        lianji_shu=0;
                                                                                                            get_out=1;
                                                                                                                                        zhishi=1;
                                                                                                                                        ji_shu=0;
                                                                        }
                                                                 else            
                                                                        {
                                                                                                           get_out=0;
                                                                                                                                //
                                                                                                                               
                                                                                                                                you_xiao=0;

                                                                        }
                                        }                */
               
                                                                       

                                               
               
       
}

/*-------------------------外部中断0子程序(解码程序)---------------------------*/
//void INT0_intrupt(void) interrupt 0 using 1
void rf_jc(void)
{
   uchar i,j;bit BitState_2;                                          
//        EX0=0;
  
                          if(RF==0)
                                        {                       
                                                               
      
//////////////////////////////找起始位//////////////////////////////////////////
       for(i=0;i<100;i++);         //低电平持续时间
                                               

                                                        if(RF==1)  goto kk;     //非法电平退出
                                                        while(RF==0);
                                                        for(i=0;i<50;i++);         //高   
                                                        if(RF==0)  goto kk;
                                               
                                                        delay_200();
                                                        if(RF==1)  goto kk;
                                                        for(i=15;i>0;i--)                 //重复20次,检测在3750微秒内出现高电平就退出解码程序
                                                        {   
                                                                  delay_200();                    
                                                                  if(RF==1) goto kk;
                                                        }                                          
                                                        while(RF==0);
                                                ///////////////////////////////接收数据///////////////////////////////////////////
                                                        for(j=0;j<3;j++)           //按照顺序分别保存密码高4位和低4位及数据位                    
                                                        {
                                                                  for(i=0;i<8;i++)       //每个数组为8位
                                                                  {  
                                                       delay_250();       //按照射频检测口电平高低保存到各自数组里
                                                                            BitState_2=RF;   //读入射频检测口电平
                                                       
                                                                                                        switch(jm_chishu)
                                                                                                        {
                                                                                                            case 0:
                                                                                                                                           {
                                                                                                                                                                    ReadCode[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
                                                                                                                   ReadCode[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
                                                                                                                             break;
                                                                                                                             }
                                                                                                            case 1:
                                                                                                                                           {
                                                                                                                                                                    ReadCode2[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
                                                                                                                   ReadCode2[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
                                                                                                                             break;
                                                                                                                             }
                                                                                                           case 2:
                                                                                                                            {
                                                                                                                                                             ReadCode3[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
                                                                                                                   ReadCode3[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
                                                                                                                            break;
                                                                                                                            }
                                                                                                        }
                                                                               
                                                                                                        if(RF==1) while(RF==1);//等待变成低电平
                                                                                                        while(RF==0);            //低电平出现一次电平处理保存完成直到所以地址码和数据位
                                                                                                                                               //处理保存完毕才退出FOR循环
                                                                                }
                                                        }
                                                ////////////////////////////////校验及运算数据/////////////////////////////////////
                                                 if(jm_chishu==2 )
                                                 {
                                                           jm_chishu=0;
                                                           if(ReadCode2[0]==ReadCode3[0])
                                                    {
                                                              for(i=0;i<3;i++)
                                                       {
                                                                                                           if((~(ReadCode2[i]|0x55))&((ReadCode2[i]&0x55)<<1)!=0x00)
                                                                                                                                 
                                                                                                                       
                                                                                                                                         goto kk;
                                                                                                                               
                                                                                                        }  
                                                                                                       
                                                                                               
                                                                                                       
                                                                                                          //校验
                                                      // vt=0;for(i=0;i<5;i++){delay_131();}//接收到的8位密码都正确VT有效指示灯亮一下
                                                          if(xuexi_key==1&&miao<10)             //自学习按键为低且一次上电只学一次
                                                                 {
                                                                                                                                  //miao_key=0;
                                                                           zixuexi_mima_xie();                        //自学习后写入保存密码函数
                                                                        }//----------------------------------------------------------------------------------------
                                                                 else  //不是自学习状态 ,按正常密码比较执行
                                                                        {
                                                             if(((ReadCode2[0]==mima_h4)&(ReadCode2[1]==mima_l4))   //3个遥控器中任意一个密码正确就正式解码
                                                                             |((ReadCode2[0]==mima_h4_2)&(ReadCode2[1]==mima_l4_2))
                                                                                    |((ReadCode2[0]==mima_h4_3)&(ReadCode2[1]==mima_l4_3)))
                                                                                    {
                                                                                                                                                                            

                                                                                                                                                                                                        goto ok;
                                                                                                                                                                 }

                                                                                                                                          else{goto kk;}
                                                                 }
                                                           ok:
                                                          GetCode=0x00;                       //遥控的数据位清0
                                                          for(i=0;i<8;i++)                    //接收到的4位数据位运算处理
                                                          {
                                                             GetCode |=((ReadCode[2]>>i)&(ReadCode[2]>>(i+1))&0x01<<i); //2262运算出数据位
                                                        // GetCode=ReadCode[2]; //1527运算出数据位
                                                          }
                                                //////////////////////////////////////////////////////////////////////////////////
                                                          you_xiao=1;//for(i=0;i<5;i++){delay_131();}//接收到的8位密码都正确VT有效指示灯亮一下
                                                                                                                               
                                                                 goto mm;
                                                            }
                                                                                        else{goto kk;}
                                                  }
                                                                else{jm_chishu++;if(jm_chishu>2){jm_chishu=0;}}

                             kk: ajok_flag=1; you_xiao=0;// EX0=1;                              //退出中断
                             mm:;
     }
               
}



//***********************************************************************************************
//          延时函数
//***********************************************************************************************
void delayy(int t)
{
   uint i,j;
   for(i=t;i>0;i--)
   for(j=255;j>0;j--);;
}

//***********************************************************************************************
//          主循环函数
//***********************************************************************************************

//--------------------
main()
{       
   uchar add_temp;

                        deng_open=1;
                        //xuexi_key=1;                                //自学习标志1有效        0无效

                        zhishi=1;            
//init();  
                 //初始化子程序
          time1_csh();   
                                   //定时器0初始化
          zixuexi_mima_du();        //读出保存的遥控密码
       
          while(1)
   {
                          

             
                                                  rf_jc();                  //软件RF检测解码函数
                                       
                                                       
              
                                                  
                                                        if(you_xiao==1)
                                                        {
                                                                       
                                                                                        //解码有效
                                        
                                                    
                                                             add_temp=~GetCode|0xf0;   //输出4位数据位-用于控制对象-本程序里只有密码正确才有输出
                                        add_temp=GetCode&0x0f;    //分离4位按键数据
                                        switch(add_temp)
                                        {
                                                                                                    
                       
                                            case 0x01:                                                   //按键1
                                                                                                                                               
                                                                                                                                                           
                                                                                                                                                                                       
                                                                                                                                                                                  
                                                                                                                                                                       
                                                                                                                                                                           deng_open=~deng_open;
                                                                                                                                                                                 
                                                        
                                                          break;
                                                                                                                            
                       
                                                                                                                                case 0x02:                                                                                                                //按键2
                                                                                                                                        
                                                                                                                                                                       
                                                                                                                                                                           deng_open=~deng_open;
                                                                                                                                                                                         //you_xiao=0;
                                                                                                                                                                                                //ajok_flag=0;
                                                                               break;
                                                                                                  
                       
                                           /*case 0x04:                                                                        //按键3
                                                                                                                            
                                                                                                                                      if(miao<9)TR1 = 1;                //定时器1开始计时
                                                                deng_open=~deng_open;
                                                          break;                        */
                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                        //按键4
                                            /*case 0x08:
                                                                                                       
                                                                                                                                       if(miao<9)TR1 = 1;        //定时器1开始计时
                                                                                                                                                                                        deng_open=~deng_open;
                       
                                                          break;                                                                */
                                                                                                                                     
                                         }
                                                                                                 
                                              }
                                                                               
                                                }                               
      
}

相关帖子

沙发
dirtwillfly| | 2013-7-19 10:41 | 只看该作者
电路是怎么样的?程序要和实际电路配套才行

使用特权

评论回复
板凳
airwill| | 2013-7-19 15:28 | 只看该作者
其实 2262 的解码很简单, 搞这么长的代码, 看着头大.
遇到什么问题了呢? 先检查同步, 地址解码是否正常.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝