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

📄 ir_6121.c

📁 红外线遥控接收检测控制程序 V1.0 (For MCS51 C) 用于NEC6121发谢芯片
💻 C
字号:
 /**********************************************************************************************
*
*	                     红外线遥控接收检测控制程序 V1.0
*
*	                红外线接收检测用的子程序
*
*	文件名	: IR_KEY.C
*	设计者	: 李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************
*                                   功 能 描 述
*
*	1. 红外接收头必需接在外部中断的引脚上
*	2. 该程序需要占用一个计数器
************************************************************************************************/

/***********************************************************************************************
					硬件配置
************************************************************************************************/
#define 	IR_T			0					//使用使用计时器号;0=使用计时器0;1=计时器1
sbit		IR_IN	=		0xB4;				//红外线输入引脚地址

/***********************************************************************************************
					软件配置
************************************************************************************************/
#define	IR_USESCAN		1					//是否启用用户码扫描
#define	IR_USENO		0x00				//用户码
#define	IR_FOSC			11059200			//CPU FOSC




/***********************************************************************************************
					参数设置
************************************************************************************************/
sbit		IR_EA			=	0xAF;			//总中断开关
//****************************设置使用计数器地址*******************************//
sfr		IR_TMOD	=	0x89;			//定时器工作方式寄存器
#if IR_T==0							//使用计数器0
#define	IR_TINT			1				//设置计数器中断源
sfr		IR_TL		=	0x8A;			//设置使用计数器低8位位置	
sfr		IR_TH		=	0x8C;			//设置使用计数器高8位位置
sbit		IR_TR		=	0x8C;			//计数启动开样地址
sbit		IR_ET		=	0xA9;			//计时器中断许可位
sbit		IR_TF		=	0x8D;			//计时器中断溢出位
#endif
#if (IR_T==1)							//使用计数器1
#define	IR_TINT		3				//设置计数器中断源
sfr		IR_TL		=	0x8B;			//设置使用计数器低8位位置	
sfr		IR_TH		=	0x8D;			//设置使用计数器高8位位置
sbit		IR_TR		=	0x8E;			//计数启动开样地址
sbit		IR_ET		=	0xAB;			//计时器中断许可位
sbit		IR_TF		=	0x8F;			//计时器中断溢出位
#endif
//****************************设置时时间相关*******************************//
#if (IR_FOSC==12000000)
#define IR_Start_Time	9000				//同步头长度(单位为机器周期)
#define IR_Exp_Time		2500				//连发高电平的长度
#define IR_New_Time		4500				//为新代码的时高电平长度
#define IR_C0_Time		1120				//为0电平时的时时间长度
#define IR_C1_Time		2250				//为1电平时的时间长度
#define IR_Warp_Time	500					//偏差的最大时间长度
#define IR_RSTOUT		10					//
#endif
#if (IR_FOSC==11059200)
#define IR_Start_Time	8294				//同步头长度(单位为机器周期)
#define IR_Exp_Time		2304				//连发高电平的长度
#define IR_New_Time		4147				//为新代码的时高电平长度
#define IR_C0_Time		1032				//为0电平时的时时间长度
#define IR_C1_Time		2073				//为1电平时的时间长度
#define IR_Warp_Time	460					//偏差的最大时间长度
#define IR_RSTOUT		10					//
#endif
/***********************************************************************************************
					IRKEY全局变量声明
************************************************************************************************/
unsigned char IR_RSTNUM;

//****************************按键定义部份*******************************//

/***********************************************************************************************
函数名称:	IRKEY 计数器加载子程序
函数原型:	void IRKEY_SETT(unsigned int TS,bit ET)
函数功能:	初始化计数器的数值
输入参数:	TH	:加载到计数器的高8位值
			TL	:加载到计数器的低8位值
			ET	:计数器溢出时是否进入中断程序
返回参数:	无
创建日期:	2008年4月10日
修改日期:	
有关说明:	
编写作者:	李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/	
void IR_SETT(unsigned int TS)
{unsigned char TH,TL;
	unsigned int TempTS;
	IR_TR=0;									//停止计数
	IR_ET=0;									//设置是否中断
	TempTS=TS;
	TempTS>>=8;
	TH=(int)(TempTS);
	TL=(int)(TS&0x00FF);
	IR_TH=TH;									//加载高8位数值
	IR_TL=TL;									//加载低8位数值
	IR_TR=1;									//开始计数
}
/***********************************************************************************************
函数名称:	IRKEY 读取计数器子程序
函数原型:	unsigned int IRKEY_ReadT(void)
函数功能:	初始化计数器的数值
输入参数:	TH	:加载到计数器的高8位值
			TL	:加载到计数器的低8位值
			ET	:计数器溢出时是否进入中断程序
返回参数:	无
创建日期:	2008年4月10日
修改日期:	
有关说明:	
编写作者:	李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/	
unsigned int IR_ReadT(void)
{
	unsigned int TimeT;
	IR_TR=0;
	TimeT=IR_TH;
	TimeT<<=8;
	TimeT=TimeT|IR_TL;
	return(TimeT);
}
/***********************************************************************************************
函数名称:	IRKEY启动设置
函数原型:	void IRKEY_Start(void)
函数功能:	初始化及启动IR及KEY的设置
输入参数:	无
返回参数:	无
创建日期:	2008年4月10日
修改日期:	
有关说明:	
编写作者:	李东荣(EMAIL:JDLDR@21CN.COM,QQ:20475125)
************************************************************************************************/
unsigned char IR_Scan(void)
{
	unsigned int Time_Width;				//脉冲宽度
	unsigned char IR_Scan[4]={0xFF,0xFF,0xFF,0xFF};				//存储红外编码用
	unsigned char	Index1,Index2,TMODT;			//用于计数器
	IR_EA=0;							//关中断
if (!IR_IN) 
{
	//****************************设置计数器计数方式*******************************//	
	//设置计数器计数方式为方式1
	IR_TR=0;
	IR_TF=0;
	#if	(IR_T==0)			//使用计数器0时				
		TMODT=IR_TMOD;
		TMODT=TMODT&0xF0;
		TMODT=TMODT|0x01;
		IR_TMOD=TMODT;
	#endif
	#if	(IR_T==1)			//使用计数器1时
		TMODT=IR_TMOD;
		TMODT=TMODT&0x0F;
		TMODT=TMODT|0x10;
		IR_TMOD=TMODT;
	#endif
	//********************************************************************************************
	//						检测同步头(9ms)
	//********************************************************************************************
	IR_SETT(0xFFFF-IR_Start_Time-IR_Warp_Time);				//设置计数为计数初值 9ms+偏差值
	while ((!IR_IN)&&(!IR_TF));
	//Time_Width=IR_ReadT()-(0xFFFF-IR_Start_Time-IR_Warp_Time);
	//********************************************************************************************
	//						区分 连发代码 与 新代码
	//********************************************************************************************
	IR_SETT(0xFFFF-IR_New_Time-IR_Warp_Time);				//设置计数为计数初值 4.5ms+偏差值
	while ((IR_IN)&&(!IR_TF));
	Time_Width=IR_ReadT()-(0xFFFF-IR_New_Time-IR_Warp_Time);
	//********************************************************************************************
	//						连发代码处理子程序
	//********************************************************************************************
	if ((Time_Width<(IR_Exp_Time+IR_Warp_Time))&&(Time_Width>(IR_Exp_Time-IR_Warp_Time))) 	//在如高脉冲长约为2.5ms,则为重复按键已按下
		{
			//发出重复命令
			IR_RSTNUM++;
			if (IR_RSTNUM>IR_RSTOUT) {
				IR_Scan[2]=0xFE;
				IR_RSTNUM=0;}
		}
	//********************************************************************************************
	//						新代码处理子程序
	//********************************************************************************************
	if ((Time_Width<(IR_New_Time+IR_Warp_Time))&&(Time_Width>(IR_New_Time-IR_Warp_Time)))	//在如高脉冲长约为4.5ms,则为新按键按下
		{
			//检测新的按键码
		  	for(Index1=0;Index1<4;Index1++)				//检测四个用户码
		  		{
		  		 for(Index2=0;Index2<8;Index2++)
		  		 	{
						IR_SETT(0xFFFF-IR_C1_Time-IR_Warp_Time);					//延时2.75ms
			 			while((!IR_IN)&&(!IR_TF));
						if (IR_TF) goto IR_SCAN_ERR;			//如果超时测退出
						while((IR_IN)&&(!IR_TF));
						if (IR_TF) goto IR_SCAN_ERR;			//如果超时测退出
						Time_Width=IR_ReadT()-0xF542;
						if((Time_Width<(IR_C0_Time+IR_Warp_Time))&&(Time_Width>(IR_C0_Time-IR_Warp_Time)) )
							{	
								IR_Scan[Index1]>>=1;			
							}
						if((Time_Width<(IR_C1_Time+IR_Warp_Time))&&(Time_Width>(IR_C1_Time-IR_Warp_Time)))
							{
								IR_Scan[Index1]>>=1;
								IR_Scan[Index1]=IR_Scan[Index1]|0x80;
							}		
		  		 	}
		  		}
			IR_SETT(0xFFFF-IR_C1_Time-IR_Warp_Time);					//延时2.75ms	最后的结束码
			while(!IR_TF);
			IR_RSTNUM=0;
	//********************************************************************************************
	//						验计用户码及校验
	//********************************************************************************************
		#if (IR_USESCAN)									//用户码校验
			if (IR_USENO!=IR_Scan[0]) {
				IR_Scan[0]=0xFF;
				IR_Scan[1]=0xFF;
				IR_Scan[2]=0xFF;
				IR_Scan[3]=0xFF;
				}
		#endif
		
		}
}
IR_SCAN_ERR:
IR_EA=1;							//关闭中断
return(IR_Scan[2]);	

}

⌨️ 快捷键说明

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