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

📄 1838yaokongjiemac51.c

📁 单片机C语言解码1838红外遥控
💻 C
字号:
/************************************
红外遥控解码函数

遥控器发射距离:有效距离》8M  ,用户码“00FF”
振荡频率:455KHZ
载波频率:37.92+-0.18KHZ
红外波长:940NM
功能键数:15个
适用环境:-10-+60
接收器:一体化红外接收器MDK-1838B
接收器输出脉冲宽度:Tpwl[500,700](600US典型值,Tpwh=[500,900]
波形图为:低电平脉冲宽度600US,高电平900US
//----------------------------------------------
键码分布图
		1		2		3
		4		5		6
		7		8		9
		*		0		#
		EXIT	ADD		CALL
对应的码值表为
		0X00	0X01	0X02
		0X04	0X05	0X06
		0X08	0X09	0X0A
		0X0C	0X0D	0X0E
		0X10	0X11	0X12
//-------------------------


/****************************************************************/
#define		YKTh05MS		0XD8	  //D8
#define		YKTl05MS		0XF0	  //  F0
#define		YKTh03MS		0XE8	//E8		 3MS
#define		YKTl03MS		0X90	//	90
#define		YKTh004MS		0xFC	//400US		FCE0
#define		YKTl004MS		0xE0
#define		YKTh01MS		0xF8	//1MS F830
#define		YKTl01MS		0X30
#define		YKTh01MS5		0XF4		//1MS5	 F448
#define		YKTl01MS5		0X48
#define		YKOneBit		0X80//数据1标识
#define		YKZeroBit		0X00//数据0标识
#define		YKNoBit			0XFF//无效数据
#define		YKBit1			1
#define		YKBit0			0
#define		XKey			0x10//*
#define		CALLKey			0x11//CALL
#define		EXITKey			0x12//EXIT
#define		ADDKey			0X13//ADD
#define		BKey			0x14//#
#define		BadPro			0x00
#define		SecussPro		0x88
#define		EXITPro			0xff
#define		Secuss6			0x60
/*************************************************************/
/**********************************************************
*函数功能:将码值转换成数值
*入口参数:码值
*返回值:已转换的值
*********************************************************/
INT8U	YKCodeValueTRA(INT8U	CodeNum)
{
  switch (CodeNum)
  {
  	case	0X00:
				return(0x01); //1
		 		break;
	case	0x01:
				return (0x02); //2
				break;
	case	0X02:
				return(0x03); //3
		 		break;
	case	0x04:
				return (0x04); //4
				break;
	case	0X05:
				return(0x05); //5
		 		break;
	case	0x06:
				return (0x06); //6
				break;
	case	0X08:
				return(0x07); //7
		 		break;
	case	0x09:
				return (0x08); //8
				break;
	case	0X0A:
				return(0x09); //9
		 		break;
	case	0x0C:
				return (XKey); //*
				break;
 	case	0X0D:
				return(0x00); //0
		 		break;
	case	0x0E:
				return (BKey); //#
				break;
	case	0X10:
				return(EXITKey); //EXIT
		 		break;
	case	0x11:
				return (ADDKey); //ADD
				break;
	case	0X12:
				return(CALLKey); //CALL
		 		break;	
	default:	return (YKNoBit);//无效数据
				break;
}
 }
/*************************************************************
*			  YKt0initial()
*函数功能:定时器0初始化,T0与普通51一样,不倍频
*入口参数:无
*返回:无	 (9MS检测)
*************************************************************/
void	YKt0initial(void)	
{TF0	=	0;
 TR0	=	0;
 TMOD	=	(TMOD|0X0F)&0XF1;//不影响定时器1,定时器0工作模式为M1,M0=01
 //------AUXR	=	0X5F; //T0不倍频,与普通51一致 ,当作波特率发生器时,T1要倍频
// AUXR	=	0X0F; //T0不倍频,与普通51一致
 CKCON	=	0X00;//T0,T1设置为普通12T时钟	
 TH0	=	YKTh05MS;
 TL0	=	YKTl05MS;
 TR0	=	1;
}

/************************************************************
*		RYKDt0start()
*函数功能:启动定时器0
*入口参数:定时时间值
*返回:无
*************************************************************/
void	YKt0start(INT8U	YKTH0,INT8U YKTL0)
{ TR0	=	0;
  TF0	=	0;
  TH0	=	YKTH0;
  TL0	=	YKTL0;
  TR0	=	1;
}

/**************************************************************
		RYKDt0Off
		关定时器0
函数功能:关定时器0,读出TH0,TL0
入口参数:无
返回:无
**************************************************************/
void	YKt0Off(void)
{
  TF0	=	0;
  TR0	=	0;	
}
//---------抽样判断电平信号是1还是0--------------------
bit  YKbitCHK(void)
{
   INT8U	YKcont1;
   INT8U	YKcont0;
   YKcont1	=	0xff;
   YKcont0	=	0xff;
   while (1){
  //WDT_CONTR=0x3C;
    if (YKDATA==1)
	 YKcont1--;
	  else 
	   YKcont0--;
	if (YKcont1<0xF8)
	 return (YKBit1);
	  else
	   if (YKcont0<0xF8)  //e8
	    return (YKBit0);
		 else continue;	 	
	}
}
//----------检测560US低电平是否有效函数
//-------调用前已经启动T0
bit		YKLowbitCHK(void)
{
 	YKt0start(YKTh004MS,YKTl004MS);//检测低电平的时间
	while (TF0==0){
	   if (YKbitCHK()==YKBit1) {  //低电平时间不够400US,则退出
	    YKt0Off();
		return(ERR);  }
	      }
	  YKt0start(YKTh004MS,YKTl004MS);//等待高电平
	  	while (YKbitCHK()==YKBit0){
	   if (TF0==1) {  //低电平总时间超过800US,则退出
	    YKt0Off();
		return(ERR);  }
	      }
	return  (OK);
}
/**************************************************************
	YKCODEbitCHK
函数功能:读一个键值码位,
入口参数:无
返回:读到数据1,1;数据0,返回0;不对,返回0FF
使用时必须先调用 YKHeadCHK()函数
**************************************************************/
INT8U	YKCODEbitCHK(void)
{
 	if (YKLowbitCHK()==ERR){	//检测低电平时间是否正确!
 	YKt0Off();
 	return(YKNoBit); 	} 
     //----检测高电平时间
	 	YKt0start(YKTh004MS,YKTl004MS);//检测高电平的时间
	    while (TF0==0){
	    if (YKbitCHK()==YKBit0) {  //高电平时间不够400US,则退出
	    YKt0Off();
		return(YKNoBit);  }
	      }
	  YKt0start(YKTh004MS,YKTl004MS);//等待低电平
	  	while (YKbitCHK()==YKBit1){
	   if (TF0==1)   //高电平总时间超过800US,则检测是否是数据1
	    break;
	      }	
		  if (TF0!=1){
		  YKt0Off();
		  return(YKZeroBit); //高电平的时间在400-800US之间,则是数据0
		  }
		  else{
		   YKt0start(YKTh01MS5,YKTl01MS5);	 //1.5MS内检测高电平!
		    while (YKbitCHK()==YKBit1){
			 if (TF0==1){
			  YKt0Off();
				return(YKNoBit); 
			  }
			 }
			 YKt0Off();
			 return ( YKOneBit);
		   }
}
/*************************************************************
*			 YKHeadCHK()
*函数功能:找遥控的引导码和用户码,引导码为9MS低电平+4.5MS高电平+“用户码16位”
			用户码默认为 00FF
*入口参数:无
*返回:正确OK,无效ERR,
注:红外发射数据的格式是:引导码9MS+4.5MS关断时间+用户码+键值+键值反码
************************************************************/

bit		YKHeadCHK(void)
{  INT8U	YKcon;//计数器  
   if (YKbitCHK()==YKBit0){
   	YKt0initial();
	while(TF0==0){ //低电平的时间要是9MS,不够9MS则退出
	if (YKbitCHK()==YKBit1){
	YKt0Off();
	return(ERR); }
	   }
	YKt0start(YKTh05MS,YKTl05MS);	 //等待变为高电平
	while (YKbitCHK()==YKBit0){
	if (TF0==1){
	 YKt0Off();
	 return(ERR); 
	 }	//低电平时间超时,则退出!
	}
	//-------------------------检测关断时间 	 
    YKt0start(YKTh03MS,YKTl03MS);//引导码9MS后,检测4.5MS的关断时间(高电平)
 	 while (TF0==0) {   //高电平时间4.5MS
	 	if (YKbitCHK()==YKBit0){
			YKt0Off();
			return(ERR); }
	               }
	 	YKt0start(YKTh03MS,YKTl03MS);	 //等待变为低电平
		while (YKbitCHK()==YKBit1){
			if (TF0==1){
	 		YKt0Off();
	 		return(ERR); 
	   			}	//高电平时间超时,则退出!
    		}
  
				   //-开始读用户码00FF

	for (YKcon=0;YKcon<8;YKcon++){
	
	 if (YKCODEbitCHK()!=YKZeroBit){
	    YKt0Off();
		return (ERR);   }
	   }	 
	  for (YKcon=0;YKcon<8;YKcon++){ 	 
	    if (YKCODEbitCHK()!=YKOneBit)  {
	 	YKt0Off();
		return (ERR);   }
	   }
	  return (OK); 			  
   }	
  return (ERR);

   }	

/********************************************************************
		YKCODEByte()
函数功能:解键值码	,从低位到高位发送
入口参数:无
出口参数:返回键值,无效返回0XFF
********************************************************************/
INT8U	 YKCODEByte(void)
{
	INT8U	YKCBCont;//计数器
	INT8U	YKCBDataTmp;
	INT8U	YKCBDataJM;////键值码
	INT8U	YKCBDataFM;	//键值反码
	YKCBDataTmp=0xFF;
	YKCBDataFM=0xFF;
	YKCBDataJM=0xFF;
	if (YKHeadCHK()==OK){
	//先解键值码
	for (YKCBCont=0x00;YKCBCont<8;YKCBCont++){
	  YKCBDataTmp=YKCODEbitCHK();
	 if (YKCBDataTmp!=YKNoBit){
	   YKCBDataJM=(YKCBDataJM>>1)&0x7F;
	   YKCBDataJM=YKCBDataJM|YKCBDataTmp;}		   
	  else{
	   	YKt0Off();
		return (YKNoBit);
	   }
	 }
	  //---再解键值反码
	  for (YKCBCont=0x00;YKCBCont<8;YKCBCont++){
	  YKCBDataTmp=YKCODEbitCHK();
	  if (YKCBDataTmp!=YKNoBit)
	   YKCBDataFM=((YKCBDataFM>>1)&0x7f)|YKCBDataTmp;		   
	  else{
	   	YKt0Off();
		return (YKNoBit);
	   }
	 }
	 if (YKCBDataJM==~YKCBDataFM){
	  SFDisplayOK();//按键解码成功提示
	  return(YKCodeValueTRA(YKCBDataJM)); }	
	  else
	   return	(YKNoBit);
	}
	return	(YKNoBit);
}
//-------------------------------------------------------------------------------

⌨️ 快捷键说明

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