打印

sc6121遥控单片机解码,现有一点不太**的问题.

[复制链接]
2167|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mikezhong|  楼主 | 2007-1-5 10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我做了一个音源切换的装置,有遥控和按键功能,现在遇到一个问题是,遥控不是很灵光,有时很灵,有时要按两三下才有,下列是我写的程序,对于遥控方面,各位有什么建议和好的方法.

我的方法是,采用外部下降沿(因为接收头之后反相)中断,一进入中断开启16位定时器1,开始计时,直到下一个下降沿到来,从而计到脉冲的时间,读码.



/******************************************************
音源切换装置
12M晶振,
定时器计时一次1us.
******************************************************/
#include "STC12C2052AD.h"
#include "intrins.h"

#define  channel_0  0xf7
#define  channel_1  0xfb
#define     channel_2  0xfd
#define  channel_3  0xfe


#define  LED_channel_0   CH_0_LED=0;CH_1_LED=1;CH_2_LED=1;CH_3_LED=1;
#define  LED_channel_1   CH_0_LED=1;CH_1_LED=0;CH_2_LED=1;CH_3_LED=1;
#define  LED_channel_2   CH_0_LED=1;CH_1_LED=1;CH_2_LED=0;CH_3_LED=1;
#define  LED_channel_3   CH_0_LED=1;CH_1_LED=1;CH_2_LED=1;CH_3_LED=0;

sbit CH_0_LED=P1^4;
sbit CH_1_LED=P1^5;
sbit CH_2_LED=P1^6;
sbit CH_3_LED=P1^7;
sbit CD4052_A=P3^4;
sbit CD4052_B=P3^5;

unsigned char key_old,key_temp;
unsigned int key_delay=0;
bit key_ok,remote_ok;

unsigned int p_width;
bit pulse_1;
unsigned char remote_count,remote_temp,user_code,level;

void T1_initial(void);
void Port_initial(void);
void key_scan(void);
void key_action(void);
void delay_10us(unsigned int t);
void remote_action(void);

void INT1_ISR(void) interrupt 2 //下降沿中断
{
   CH_3_LED=!CH_3_LED;
   if (TR1==0)
   {
     TH1=0;
     TL1=0;
     TR1=1; //启动计数
   }
   else 
   {
      TR1=0;//停止计数 
      p_width=TH1;
      p_width= (p_width<<8)+TL1;
     
      if(p_width>= 5000 && p_width <=40000) //13000->0x32c8,14000->0x368b 如果开始引导码有效。
       {
         pulse_1=1;
         TH1=0;
         TL1=0;
         TR1=1; //开始计数。
         
       }
      else 
      {
         if (pulse_1==1) //如果引导码有效,则开始接收用户码和数据码
           {
             if (p_width>=200 && p_width<=4550)//如果码有效,1000->0x03e8,2250->0x08ca
               {
                 if (p_width<=1400) level=0;
                 if (p_width>=1400) level=1;
                 remote_count++;
                 if (remote_count > 16) //用户码丢弃。只保存键码。
                 {
                    user_code= (user_code<<1)+level;
                    
                 }
                 if (remote_count==24) {remote_ok=1;remote_count=0;pulse_1=0;TR1=0;} //如果已经收到32个用户码和数据码,则重新开始检测遥控。
                 TH1=0;
                 TL1=0;
                 TR1=1; //开始计数。
               }

             else //码无效,则退出。
               {
                 pulse_1=0;
                 remote_ok=0;
                 remote_count=0;
                 TH1=0;
                 TL1=0;
                 TR1=0; //关闭定时器,重新开始下一个轮回。
                }
           }
         else {TH1=0;TL1=0;}
       }
      
   }

}
/*===================================================*/
void main(void)
{
   Port_initial();
   T1_initial();
   LED_channel_3;
   EA=1;
   
   while (1)
   {  
      key_scan();
      remote_action();
      key_action();
      //delay_10us(1); //1ms 100
      
   }


}

/***********************************************************
 Timer1初始化,测量脉宽
***********************************************************/
void T1_initial(void)
{
   TMOD=0X10; //Timer1工作在模式1方式。  16位定时器
   TCON=0x04; //开启外部中断1,并且选用下降沿触发。
   TH1=0;
   TL1=0;
   
   
   EX1=1;
   //TR1=0;//未开启定时器
}

/************************************************************
  PORT端口初始化
***********************************************************/
void Port_initial(void)
{
  
  P1M0=0X00;//全部为标准I/O口
  P1M1=0X00;
  P3M0=0x00; //P3。3设为输入。
  P3M1=0x00;
  P1=0XFF;
  P3=0Xff;
}
/***********************************************************
key_scan();
***********************************************************/
void key_scan(void)

  
  if ((P1|0xf0)!=0xff) //有键
   {
        key_temp=P1|0xf0;
        if (key_temp==key_old)
          {
            key_delay++;
          }
        else key_old=key_temp;
   }
  else 
   {
      if (key_delay >=60)
        {
           key_ok=1;
           key_delay=0;
          // return key_temp;//返回键值
        }
     
   }
  
}

/***********************************************************
key_action();
***********************************************************/
void key_action(void)
{
   unsigned char temp;
   if (key_ok)   { temp=key_temp; goto action;}
   if (remote_ok) { temp=remote_temp;}
   
action: switch (temp)
        {
          case channel_0: LED_channel_0;//执行按键功能1
                     CD4052_A=0;
                     CD4052_B=0;
                     key_ok=0;
                     remote_ok=0;
                     temp=0;
                     break; 
          case channel_1: LED_channel_1;//执行按键功能2
                     CD4052_A=1;
                     CD4052_B=0;
                     key_ok=0;
                     remote_ok=0;
                     temp=0;
                     break;
          case channel_2: LED_channel_2;//执行按键功能3
                     CD4052_A=0;
                     CD4052_B=1;
                     key_ok=0;
                     remote_ok=0;
                     temp=0;
                     break;
          case channel_3: LED_channel_3;//执行按键功能4
                     CD4052_A=1;
                     CD4052_B=1;
                     key_ok=0;
                     remote_ok=0;
                     temp=0;
                     break;
          default:break;
       }
 
}
/*********************************************************
  remote_action。
*********************************************************/
void remote_action(void)

    if (remote_ok)
    {
       switch (user_code)
       {
         case 0x50: remote_temp=channel_0;user_code=0;break;
         case 0xc8: remote_temp=channel_1;user_code=0;break;
         case 0x68: remote_temp=channel_2;user_code=0;break;
         //case 0x50af: remote_temp=channel_3;break;
         default:break;
       }

    }
 
}


/*********************************************************
  普通延时
*********************************************************/
void delay_10us(unsigned int t)
{
   unsigned char j; 
   for(;t>0;t--) 
     for(j=25;j>0;j--) 
     ;
}

相关帖子

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

本版积分规则

51

主题

250

帖子

1

粉丝