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

📄 necdecode.c

📁 MCU控制程序
💻 C
字号:
//ICC-AVR application builder : 2006-9-20 14:49:40
// Target : M16
// Crystal: 7.3728Mhz
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
#include "hptvstruct.h"
//#include "necdecode.h"
// time2的中断周期为102us
//接收NEC码起始位最小时间 118*102us=12.036ms
//接收NEC码起始位最大时间 147*102us=14.994ms
//接收逻辑0最小时长       10*102us=1.02ms
//接收逻辑0最大时长       13*102us=1.326ms
//接收逻辑1最小时长       20*102us=2.04ms
//接收逻辑1最大时长       25*102us=2.55ms
//重复码与上位的最小时长      980*102us=99.96ms
//重复码的最大时长      1176*102us=120.36ms
//当NEC开始接收还未接收完成同时又不是重复码时超过TimeNecOutoftime的时间将视为不是NEC码


#define NecStartBitMin         118
#define NecStartBitMax         147
#define NecBit0Min             10
#define NecBit0Max             13
#define NecBit1Min             20
#define NecBit1Max             25
#define BTvState                1
#define NecRepeatBitMin        103
#define NecRepeatBitMax        115
#define TimeNecRepeatMin       880
#define TimeNecRepeatMax       1180
#define TimeNecRepeatMins      372
#define TimeNecRepeatMaxs      450
#define TimeNecOutoftime       40             


unsigned char  BTheFirstFallEdge; //为0时说明为接收到第一个下降沿或接受到第一个;为1时认为已接收到了第一个或大于1个下降沿;做为起始时间基准
unsigned char  BReceiveStart;    //开始接收数据标志
unsigned char  BNecFallEdge;     //是否有下降边沿
unsigned char  TimeNecFallEdge;  //下降边沿时间长度
unsigned char  RTimeNecFallEdge; //下降边沿时间长度结果保存
unsigned char  BNecStartBit;	 //是否有起始位
unsigned char  NecData[4];		 //红外数据
unsigned int   NecDecodeNum;	 //红外数据位个数指针
unsigned int   i;
unsigned char  BHasReceiveNec;   //已收到一个NEC码 为进行接收重复码做准备
unsigned char  BPowerButton;     //有开机按键
unsigned int   NecRepeatCodeNum; //重复码与上一个NEC码时间间隔计数变量和重复码本身长度计数变量
unsigned int   RNecRepeatCodeNum;//重复码计数结果保存

unsigned char  BNecRepeat;       //重复码标志,置1为收到重复码
unsigned char  ResultNec;
unsigned char  RepeatCountFlag;  //为0时为还已收到了一个NEC码还未收到一次重复码,为1时为收到至少一个重复码
unsigned char  BRepeatStar;      //Repeat开始标志   
unsigned char  NecData_Map;

//加入的开关机控制变量和I2C变量
unsigned char power_key_open_enable;//
unsigned char power_on_close_enable;//
unsigned char tv_state;           //机器状态位
unsigned char irda_num,irda_b;
unsigned char  i2c_public;           //i2c使用权检测 
unsigned char irda_data;          //预发送数据
//Add end

extern unsigned char close_machine_enable,open_machine_enable;
unsigned char RepeatControl;
volatile unsigned char Powerdown_signal;
unsigned char Fac_mode;
unsigned char Fac_aging;

extern unsigned char Open_Panel_flag;
/*
typedef enum _TVstate
{
   standby,
   booting,
   delaying,
   working,
   halting
}TVstate_t;
*/

extern volatile TVstate_t System_State;



//test
union NecTime
{
   unsigned int NecRepeatNum;
   unsigned char a[2];
}NecTimeTest;

void Head_Reset_Nec_receive()
{
 BReceiveStart=0;
 TimeNecFallEdge=0;
 RTimeNecFallEdge=0;
 BNecStartBit=0;
 NecData[0]=0;
 NecData[1]=0;
 NecData[2]=0;
 NecData[3]=0;
 NecDecodeNum=0;
 BPowerButton=0;
 i=0; 
 RepeatControl=0;
}

void HasR_Head_Reset_Nec_receive()
{
 BReceiveStart=0;
 TimeNecFallEdge=0;
 RTimeNecFallEdge=0;
 BNecStartBit=0;
 NecDecodeNum=0;
 BPowerButton=0;
 i=0; 
}


void Nec_data_deal_fun(void)
  {
    //UDR=ResultNec;
	switch(ResultNec)
	  {
		case 15:
		 // 
		 
		 if(System_State==working)
		  {
//		    UDR=0x90;
			if(close_machine_enable==1)     //加入System_State后这个条件其实无用处了
			{
//				UDR=0x91;
				Powerdown_signal=1;
				i2c_public|=1<<7;
				irda_data=ResultNec|(1<<7); //发送键码最高位置1
			}
		  }
		  else
		  {
		   // infrared_open_enable=1;////开机
		    if(open_machine_enable==1)
			{
				power_key_open_enable=1;
				Open_Panel_flag=1;
			}	 
		  }
		break;

		case 50:                 //工厂遥控器开关机
		 // 
		 

		 if(System_State==working)
		  {
//		    UDR=0x90;
			if(close_machine_enable==1)
			{
//				UDR=0x91;
				Powerdown_signal=1;
				i2c_public|=1<<7;
				irda_data=ResultNec|(1<<7); //发送键码最高位置1
			}
		  }
		  else
		  {
		   // infrared_open_enable=1;////开机
		    if(open_machine_enable==1)
			{
				power_key_open_enable=1;
			}	 
		  }
		break;
		
		case 51:
		  if(System_State==working)
		  {
		   	if(Fac_aging==0xff)
			{	
				if(Fac_mode==0xff)
				{
				  Fac_mode=0;
				  EEPROMwrite(0x90,0x00);
				}
				else
				{
				  Fac_mode=0xff;
				  EEPROMwrite(0x90,0xff);
				}
			}	 
		  
		  i2c_public|=1<<7;
		  irda_data=ResultNec|(1<<7);
		  } 	  
		  
		  break;
		  
		case 52:
		  if(System_State==working)
		  {
		    if(Fac_mode==0)
		    {
		   	  Fac_aging=EEPROMread(0x80);
			  if(Fac_aging==0)
			  {
			   	EEPROMwrite(0x80,0xff);
			  }
			  else
			  {
			    EEPROMwrite(0x80,0x00);
			  }  
		    }
		    i2c_public|=1<<7;
    	    irda_data=ResultNec|(1<<7);
		  }   
		  break;
		
		
		default:          //开关机键不申请i2c通讯
		if(System_State==working)
		{
		 	i2c_public|=1<<7; //红外键码i2c发送申请
			//UDR=rc5_data_cmd;
			irda_data=ResultNec|(1<<7); //发送键码最高位置1
//			UDR=irda_data;
        }
		break;
	  
	  }
  }

void Nec_consumer_map()
{
   NecData_Map=NecData[2]; 
   switch(NecData_Map)
   {
    case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
	case 14:
	case 15:
	case 16:
	case 17:
	case 18:
	case 19:
	case 20:
	case 21:
	case 22:
	case 23:
	case 24:
	case 25:
	case 26:
	case 27:
	case 28:
	case 29:
	  	 ResultNec=NecData_Map;
		 break;
	case 64:
		 ResultNec=30;
		 break;		 	 
	case 66:
	 	 ResultNec=31;
		 break;
	case 67:
		 ResultNec=32;
		 break;
	case 68:
		 ResultNec=33;
		 break;
	case 72:
		 ResultNec=34;
		 break;
	case 73:
		 ResultNec=35;
		 break;
	case 65:               //dot button
		 ResultNec=36;
		 break;	 		 
	default:
		 ResultNec=49;	
		 break;

   }

}

void Nec_fac_map()
{
   NecData_Map=NecData[2]; 
   switch(NecData_Map)
   {
   	case 16:
		 ResultNec=50;
		 break;
	case 0:
		 ResultNec=51;
		 break;
	case 21:
		 ResultNec=52;
		 break; 
	case 23:
		 ResultNec=53;
		 break; 		 
	case 94:
		 ResultNec=54;
		 break;
	case 71:
		 ResultNec=55;
		 break; 	  		  		  	 		 
	case 25:
		 ResultNec=56;
		 break; 		 	 		 
	case 67:
		 ResultNec=57;
		 break; 		 		 
	case 13:
		 ResultNec=58;
		 break; 
 	case 5:
		 ResultNec=59;
		 break; 
 	case 1:
		 ResultNec=60;
		 break; 
 	case 10:
		 ResultNec=61;
		 break; 
	case 27:
		 ResultNec=62;
		 break; 
	case 93:
		 ResultNec=63;
		 break; 
	case 4:
		 ResultNec=64;
		 break;     
	case 17:
		 ResultNec=65;
		 break; 	
	case 6:
		 ResultNec=66;
		 break; 	
	case 80:
		 ResultNec=67;
		 break;
	case 70:
		 ResultNec=68;
		 break; 		  
	case 76:
		 ResultNec=69;
		 break; 
	case 90:
		 ResultNec=70;
		 break; 		 
	case 73:
		 ResultNec=71;
		 break; 		 
	case 74:
		 ResultNec=72;
		 break; 	
	case 68:
		 ResultNec=73;
		 break; 
	case 65:
		 ResultNec=74;
		 break; 
	case 75:
		 ResultNec=75;
		 break; 		 
	case 81:
		 ResultNec=76;
		 break; 		 
	case 8:
		 ResultNec=77;
		 break; 	
	case 69:
		 ResultNec=78;
		 break; 	
	case 78:
		 ResultNec=79;
		 break; 
	case 66:
		 ResultNec=80;
		 break; 
	case 84:
		 ResultNec=81;
		 break; 	
	case 9:
		 ResultNec=82;
		 break; 	
	case 29:
		 ResultNec=83;
		 break; 	
	case 31:
		 ResultNec=84;
		 break; 	
	case 20:
		 ResultNec=85;
		 break; 	
	case 15:
		 ResultNec=86;
		 break; 	
	case 91:
		 ResultNec=87;
		 break; 	
	case 30:
		 ResultNec=88;
		 break; 
	case 24:
		 ResultNec=89;
		 break; 
	case 89:
		 ResultNec=90;
		 break; 
	case 88:
		 ResultNec=91;
		 break; 
	case 86:
		 ResultNec=92;
		 break; 		 
	case 72:
		 ResultNec=93;
		 break; 
	case 83:
		 ResultNec=94;
		 break; 	
	case 28:
		 ResultNec=95;
		 break; 	
	case 79:
		 ResultNec=96;
		 break;
	default:
	     ResultNec=126;
		 break;	  		 
   }
}

void Deal_Repeat()
{
  if((NecData[1]==0x05)&&(NecData[0]==0x86)) //用户码正确 for bestbuy
  {
 	Nec_consumer_map();
	
//	ResultNec=NecData[2];
//	UDR=0x20;
	irda_num++;  
	irda_b=1;
	if(RepeatControl==3)
	{
		if(System_State==standby||System_State==working)
		{
		   Nec_data_deal_fun();
		}   
	}
	else
	{
	 	RepeatControl++;
	}		
  }
  else
  {
    
/*	UDR=0x20;
	while(!(UCSRA&(1<<UDRE)));
	UDR=NecData[0];
	while(!(UCSRA&(1<<UDRE)));
	UDR=NecData[1];
	while(!(UCSRA&(1<<UDRE)));
	UDR=NecData[2];
	while(!(UCSRA&(1<<UDRE)));
	UDR=NecData[3];
*/	
	
	if((NecData[1]==0xfc)&&(NecData[0]==0x00)) //用户码正确 for fac
  	{
 	   Nec_fac_map();
	
//	ResultNec=NecData[2];
//	UDR=0x20;
	   irda_num++;  
	   irda_b=1;
	   if(RepeatControl==3)
	   {
		 if(System_State==standby||System_State==working)
		 {
		    Nec_data_deal_fun();
		 }	
	   }
	   else
       {
    	 RepeatControl++;
       }		
    }
  } 	
  HasR_Head_Reset_Nec_receive();
}
void Nec_Decode()
{
	 
//  if(((NecData[1]==0xbf)||(NecData[1]==0xfc))&&(NecData[0]==0x00)) //用户码正确 for hisense
  if((NecData[1]==0x05)&&(NecData[0]==0x86)) //用户码正确 for bestbuy
  {
//    UDR=0x66;
//	while(!(UCSRA&(1<<UDRE)));
//	UDR=NecData[2];
	
	Nec_consumer_map();
// 	ResultNec=NecData[2];
//	UDR=0x10;
	irda_num++;  
	irda_b=1;
	if(System_State==standby||System_State==working)
	{
    	Nec_data_deal_fun();
	}		
  }
  else
  {

    if((NecData[1]==0xfc)&&(NecData[0]==0x00)) //用户码正确 for bestbuy
    {
//	  UDR=0x10;
	  Nec_fac_map();		
// 	  ResultNec=NecData[2];
//    UDR=0x10;
	  irda_num++;  
	  irda_b=1;
	  if(System_State==standby||System_State==working)
	  {
	     Nec_data_deal_fun();
      }		 
	}  	  
  }
  HasR_Head_Reset_Nec_receive();
}
void RepeatReceive()
{	
	if(RepeatCountFlag==0)
	{
		if(BRepeatStar==0)           
		{
    	 	if((RNecRepeatCodeNum>=TimeNecRepeatMins)&&(RNecRepeatCodeNum<=TimeNecRepeatMaxs))                        //识别是否在重复码的最大发送时间之内
	    	{
//				UDR=0x65;
				BRepeatStar=1;                               
				return;
			}
			else
			{
		   	    BHasReceiveNec=0;                         
		   		RNecRepeatCodeNum=0;
    	   		Head_Reset_Nec_receive();
		   		return;
			}
		}
		else
		{
			if((RNecRepeatCodeNum>=NecRepeatBitMin)&&(RNecRepeatCodeNum<=NecRepeatBitMax))
		    {
//			   UDR=0x66;																		  
			   RepeatCountFlag=1;                 
		       BRepeatStar=0;
		       Deal_Repeat();
//		       Head_Reset_Nec_receive();
		       return;
		    }
		    else
		    {
		      BHasReceiveNec=0;
		      BRepeatStar=0;
		      Head_Reset_Nec_receive();
			  return;
		    }
		}		
	}
	if(RepeatCountFlag==1)
	{
		if(BRepeatStar==0)
		{
			if((RNecRepeatCodeNum>=TimeNecRepeatMin)&&(RNecRepeatCodeNum<=TimeNecRepeatMax))
			{
//				UDR=0x67;
				BRepeatStar=1;
				return;
			}
			else
			{
//		   	    UDR=0x91;
				BHasReceiveNec=0;
				NecRepeatCodeNum=0;
		   		RNecRepeatCodeNum=0;
				RepeatCountFlag=0;
    	   		Head_Reset_Nec_receive();
		   		return;
			}
        }
		else
		{
		    if((RNecRepeatCodeNum>=NecRepeatBitMin)&&(RNecRepeatCodeNum<=NecRepeatBitMax))
		    {
//		       UDR=0x68;
			   BRepeatStar=0;
		       Deal_Repeat();
//		       Head_Reset_Nec_receive();
		       return;
		    }
		    else
		    {
			   RepeatCountFlag=0;		 	
		       BHasReceiveNec=0;
			   NecRepeatCodeNum=0;
       		   RNecRepeatCodeNum=0;
			   RepeatCountFlag=0;
		       BRepeatStar=0;
		       Head_Reset_Nec_receive();
			   return;
		    }
	   }
	}
}
void Nec_Receive()
{
 i=NecDecodeNum/8;
 if(BNecStartBit==0)
 {
	if((RTimeNecFallEdge>=NecStartBitMin)&&(RTimeNecFallEdge<=NecStartBitMax))  //识别起始位
	{
		BNecStartBit=1;
		return;
    }
	else
	{
		Head_Reset_Nec_receive();
	    return;
	}
 }	
 else
 {

   if((RTimeNecFallEdge>=NecBit0Min)&&(RTimeNecFallEdge<=NecBit0Max)) 
   {
		NecData[i]>>=1;
	    NecDecodeNum++;
   }
   else
   {
   	   if((RTimeNecFallEdge>=NecBit1Min)&&(RTimeNecFallEdge<=NecBit1Max))
   	   {
			NecData[i]>>=1;
			NecData[i]+=0x80;
			NecDecodeNum++;
       }
  		else 									//如果不是0或1,重新开始
		{
			Head_Reset_Nec_receive();
			return;
		}
   }
 }  

 if(NecDecodeNum==32)                  //一个NEC码接收完成
 {									   
	BHasReceiveNec=1;
	RepeatControl=0;
	BNecStartBit=0;
	Nec_Decode();
 	return;  			 
 }
}
//call this routine to initialize all peripherals
void IR_var_init()
{
 BTheFirstFallEdge=0;
 BReceiveStart=0;
 BNecFallEdge=0;
 TimeNecFallEdge=0;
 RTimeNecFallEdge=0;
 BNecStartBit=0;
 NecData[0]=0;
 NecData[1]=0;
 NecData[2]=0;
 NecData[3]=0;
 NecDecodeNum=0;
 BHasReceiveNec=0;
 BPowerButton=0;
 NecRepeatCodeNum=0;
 BNecRepeat=0;
 RepeatCountFlag=0;
 i=0;
 RepeatControl=0;
 Powerdown_signal=0;
 Fac_mode=EEPROMread(0x90);
 Fac_aging=0;

}

⌨️ 快捷键说明

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