⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2262_decode.c

📁 自己写的2262遥控解码程序
💻 C
字号:
#include <iom16v.h>
#include <macros.h>
#define  uchar unsigned char
#define  uint  unsigned int
#include "key_dis.c"

#pragma interrupt_handler capt:iv_TIMER1_CAPT
#pragma interrupt_handler ov1:iv_TIMER1_OVF

//STD z_wide 窄脉冲宽度(4.7M振荡电阻)450us/2,STDk_wide 宽脉冲宽度1350us/2  (4MHz)
//           窄脉冲宽度(3.3M振荡电阻)330us/2,STDk_wide 宽脉冲宽度990us/2  (4MHz)
//           窄脉冲宽度(2.2M振荡电阻)210us/2,STDk_wide 宽脉冲宽度630us/2  (4MHz)

//设置窄脉冲最大值 
#define z_widem 150     
//#define z_wide 112
//#define k_wide 337

uint capt_time[4];      //捕捉时TCR1的值
uint a_wide;            //捕捉的窄脉冲宽度
uint z_wide,k_wide;     //窄脉冲宽脉冲宽度

uchar capt_code[13];    //12位码字
//uchar capt_cs;          //捕捉次数
uchar number_byte;      //第几位位码
uchar cs_byte;          //边沿捕捉次数 

uchar have_capt;        //捕捉标志
uchar got_guide;        //检测到引导码

//因为当按住PT2262的按键不放的时候PT2262会把编码不断的送出
//设置lianji_flg位用来检测按键有没有放开过如果没有放开则不再响应
//lianji_flg; //按键没有放开过标志(1:连接 0:点击)

/*---------------------初始化子程序-----------------*/
void init(void)
{    
	uchar i;
	SREG&=~(1<<7);     //关闭CPU总中断请求
	init_1602();
	for(i=0;i<4;i++)    capt_time[i]=0;
	a_wide=z_wide=k_wide=0;

	DDRB|=(1<<DDB1);
	//DDRB|=(1<<DDB0);
	//PORTB|=(1<<PB0);	
	DDRB&=~(1<<DDB0);       //PBO set to input
}

/*---------------------T1捕捉初始化子程序-----------------*/
void t1_init(void)
{
    //capt_cs=0;            //捕捉次数清0
	have_capt=0;            //捕捉标志清0
	number_byte=0;          //字码位数清0
    cs_byte=0;              //边沿捕捉次数清0
	got_guide=0;            //引导码标志清0	
	
	TCCR1A=0x00;
	TCCR1B=0xC2;            //T1普通模式,上升沿捕捉,8分频
	TCNT1H=0X00;            //计数器初值
	TCNT1L=0X00;	
    TIMSK=0x00;
	TIMSK|=(1<<TICIE1);     //捕捉中断使能
	TIFR|=(1<<ICF1);        //捕捉中断标志清0  ***very important!!**
	SREG|=(1<<7);           //打开CPU总中断请求
}

/*---------------------T1捕捉中断处理子程序-----------------*/
void capt() 
{    
	SREG&=~(1<<7);           //关CPU总中断
	TIFR|=(1<<ICF1);         //捕捉中断标志清零
	
	capt_time[cs_byte]=ICR1;
	have_capt=1;
	//capt_cs++;
	if((TCCR1B&(1<<ICES1))==0x40)  TCCR1B&=~(1<<ICES1);
	else  TCCR1B|=(1<<ICES1);	  //捕捉边沿取反

	SREG|=(1<<7);           //开CPU总中断	
}

/*---------------------T1溢出中断处理子程序-----------------*/
void ov1() 
{  
    TCNT1H=0X00;            //计数器初值
	TCNT1L=0X00;    
}

/*---------------------位码判断子程序-----------------*/
uchar decode_byte()   
{
    uint wide_1,wide_2;
	uchar w1,w2,byte;
	
	//sreg=(SREG&BIT(7));       //保存SREG bit 7
    SREG&=~(1<<7);     //关闭CPU总中断请求
	
	wide_1=capt_time[1]-capt_time[0];   //位码两脉冲宽度
	wide_2=capt_time[3]-capt_time[2];
	w1=z_wide/3;         //%30余量
	w2=k_wide/3;
	
	if((wide_1>(z_wide-w1))&&(wide_1<(z_wide+w1)))      
	{
	   if((wide_2>(z_wide-w1))&&(wide_2<(z_wide+w1)))
	       byte='0';                                 //2窄,位码为0
	   else if((wide_2>(k_wide-w2))&&(wide_2<(k_wide+w2)))
	       byte='f';                                //窄宽,位码为f
	   else
	       byte=9;                                  //误码
	}
	else if((wide_1>(k_wide-w2))&&(wide_1<(k_wide+w2)))
	{
	   if((wide_2>(z_wide-w1))&&(wide_2<(z_wide+w1)))
	       byte=9;                                    //宽窄,误码
	   else if((wide_2>(k_wide-w2))&&(wide_2<(k_wide+w2)))
	       byte='1';                                  //宽宽,位码为1
	   else
	       byte=9;
	}
	else
	    byte=9;
    //SREG|=sreg;         //恢复SREG bit 7
	SREG|=(1<<7);            //开CPU总中断请求
	return byte;	   	
}

/*---------------------解码子程序-----------------*/
uchar decode()
{
    uchar decode,byte_code;

	while(number_byte<12)    //已解码12位位码?
	{
	   if(have_capt==1)
	   {
          have_capt=0;		  
		  if(cs_byte==3)
		  {		      		  		  
			  cs_byte=0;
			  byte_code=decode_byte();  //解码位码
			  if(byte_code==9)
			  {
			      decode=0;
				  goto bb;
			  }
			  else
			      capt_code[number_byte]=byte_code;   //位码输出
			  number_byte++;					  
		  }
		  else
		      cs_byte++;
	   }
    }
	//TIMSK&=~(1<<TICIE1);     //关捕捉中断
	decode=1;
bb:	number_byte=0;          //字码位数清0
    return decode;
}

/*---------------------引导码检测子程序-----------------*/
uchar detect_guide()
{
    uchar i,b,guide,sreg;
	uint low_cs;                //检测低电平次数	
	//TIMSK&=~(1<<TICIE1);      //关捕捉中断
	//sreg=(SREG&BIT(7));       //保存SREG bit 7
	SREG&=~(1<<7);              //关闭CPU总中断请求
	a_wide=capt_time[1]-capt_time[0];   //计算脉冲宽度
	if(a_wide>=z_widem)         //大于窄脉冲最大值,非引导码,返回
	{
	    guide=0;
		goto kk;
	}
	//delay50(1);
	
	low_cs=a_wide*16*2/50;        //4MHz
    //间隔50us,连续检测PB0低电平low_cs次(约16倍窄脉冲时间),均为低时确认为引导码	
	for(i=0;i<low_cs;i++) 
	{
		b=PINB;
		if((PINB&(1<<PB0))==0x01)
		{
		    guide=0;
			goto kk;
		}
		delay50(1);
	}
	guide=1;    //检测到引导码返回1
	z_wide=a_wide;    //确定窄脉冲和宽脉冲宽度
	k_wide=z_wide*3;

kk: //TIMSK|=(1<<TICIE1);      //开捕捉中断
	SREG|=(1<<7);            //开CPU总中断请求
    //SREG|=sreg;         //恢复SREG bit 7
	return guide;
}

/*---------------------错误处理子程序-----------------*/
void error_code(uchar i)
{
	write_com(0X01);   //display clear
	wait1602ready();
	setxy_1602(0,0);
	switch(i)
	{
	    case 1:
		write_str("decode error!!");
		case 2:
		write_str("not guide!!");
		default:
		write_str("no type error!!");
	}
	delay(1);
}

/*---------------------输出控制子程序-----------------*/
void work() 
{
    write_com(0X01);   //display clear
	wait1602ready();	
	setxy_1602(0,0);
	write_str(capt_code);
	setxy_1602(0,1);
	write_dat(capt_code[1]);
	delay(5);
}

/********************主程序*************************/
void  main()
{
	uchar k,l,gd,de,sreg;
	init();	
	delay(1);     //4M  1000us 
	delay50(1);   //4M  49.75us
	delay50(5);   //4M  195.25us

    t1_init();      //T1捕捉初始化
	
    while(1) 
	{
       //按键处理
	   //TIMSK|=(1<<TICIE1);     //开捕捉中断
	   sreg=(SREG&BIT(7));       //保存SREG bit 7
	   SREG&=~(1<<7);            //关闭CPU总中断请求     
	   k=key_press();
       if(k)
       {          
		  write_com(0X01);   //display clear
		  //delay(5);
	      wait1602ready();	
		  l=key_scan();
		  switch(l)
	      {	          
			  case(1):
	              PORTB|=(1<<PB1);
			      setxy_1602(1,0);
	              write_str("remote open");
				  delay(1);				                    
	              break;
	          case(2):			      
	              PORTB&=~(1<<PB1);
			      setxy_1602(1,0);
	              write_str("remote close");
				  delay(1);		      	 
	              break;
	          default:	
	              delay(1);				  
	      }
		  k=0;		  
       }	
	   SREG|=sreg;         //恢复SREG bit 7   

	   if(have_capt==1)
	   {	       
		   have_capt=0;
		   cs_byte++;
		   if(cs_byte>=2)
		   {
		       cs_byte=0;
			   gd=detect_guide();       //引导码判断
	           if(gd)  
	           {
	               t1_init();          //T1捕捉初始化
				   de=decode();        //解码
		           if(de)    
		           {
		               SREG&=~(1<<7);     //关闭CPU总中断请求
			           work();            //输出
			           delay(100);
					   SREG|=(1<<7);            //开CPU总中断请求					   
		           }
		           else
		           {    
		               SREG&=~(1<<7);     //关闭CPU总中断请求
			           error_code(1);      //报错
			           delay(100);
					   SREG|=(1<<7);            //开CPU总中断请求
		           }
			   }
			   /*else
			   {
			       SREG&=~(1<<7);     //关闭CPU总中断请求
			       error_code(2);     //报错
			       delay50(1);
				   SREG|=(1<<7);            //开CPU总中断请求
			   }	*/		   
	      }
	   }	   
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -