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

📄 irrexample.c

📁 本代码是红外遥控器接收通用代码
💻 C
字号:
/////////////////////////////
以下程序是用扫描方法读取红外遥控器波形
若有条件(如使用AVR),可以使用捕获脉宽中断,更容易编程
//////////////////////////


//T1计数值,区分红外传输的位值.1个计数=2us(Fosc=4MHz)
#define IRR_DECODE_DELAY  120   //解码延时限制,单位ms
#define IRR_H_DELAY  8          //高电平延时限制,单位ms
#define IRR_L_DELAY  5          //低电平延时限制,单位ms

#define IRR_HEAD_MINTIME  1950   //2250-300  //4500us, 300us为估计2次扫描之间最大延时
#define IRR_HEAD_MAXTIME  2550   //2250+300
#define IRR_0_MAXTIME  430  //280+150  //560us
#define IRR_0_MINTIME  130  //280-150
#define IRR_1_MAXTIME  1000  //850+150  //1700us
#define IRR_1_MINTIME  700  //850-150



/*********读取红外接收值IRR********/
//PA7
//TL1838B一体化红外接收管:无接收,输出H,接收到38kHz载波输出L. 2套信号之间要求隔开25ms以上
//输出:非零表示H,0表示L
unsigned char read_IRR(void)
{
 return PINA&0x80;   //PA7
}

/***********扫描红外遥控器按键输入IRR:PC2  解码子程序***************
1)遥控器以upd6121G或HT6221为主控芯片遥控器
2)发出的信号电平变化最小间隔为0.56ms.必须保证在0.56ms内程序能够至少扫描1次!
3)位定义:测量接收波形中高电平的脉宽:4.5ms为引导码(起始),0: 0.56ms,1: 1.7ms
4)一次键码共4Byte 32位:地址码+地址码反码+键码+键码反码; LSB(D0)先出
5)扫描的结果会把键值放在IRRkey
******注意2次扫描之间间隔应该远小于0.56ms!!!
*/
void scan_IRR_decode(void)
{unsigned char i;
 unsigned int tempt;
     //不断读取1路IRR,获取波形信息
	 newIRR=read_IRR();
	    if((!oldIRR)&&(newIRR)) //上升沿
	       {delay_IRR_L=0;  //关闭低电平延时计时
		    delay_IRR_H=1;  //开始高电平延时计时
			//oldTCNT1=TIM16_ReadTCNT1();    //开始对高电平计时
			TIM16_WriteTCNT1(0);  //清零TIMER1,开始对高电平计时(可以节省运算减法的时间)
		   }
		else if((oldIRR)&&(!newIRR)) //下降沿
		   {delay_IRR_L=1;  //开始低电平延时计时
		    delay_IRR_H=0;  //关闭高电平延时计时
		    //计算此段低电平时间差
		    /*tempt=TIM16_ReadTCNT1();
			if (tempt>oldTCNT1) IRRtime=tempt-oldTCNT1;
			else IRRtime=0xffff-oldTCNT1+tempt+1;*/
			  IRRtime=TIM16_ReadTCNT1();
		    //判断收到的位信息
		    if ((IRRtime>IRR_HEAD_MINTIME)||(IRRtime<IRR_0_MINTIME))                  
		       {//IRRbyte=0; //收到长高电平(引导码,4.5ms)或是干扰,复位
			    IRRbit_prt=0;  //位指针清零
			   }
			else  //有效数据位
			   {
			    if (IRRtime<IRR_0_MAXTIME) IRRbit[IRRbit_prt]=0;   //收到0
				else if (IRRtime>IRR_1_MINTIME) IRRbit[IRRbit_prt]=0xff;   //收到1
				else IRRbit[IRRbit_prt]=2;   //错码
				IRRbit_prt++;
			    if (IRRbit_prt==32) //已收满32位,取键值
				  {IRRkey=judge_IRRkey();
				   //IRRbit_prt=0;
				  }
			   }  
		    }
	 oldIRR=newIRR;
}
//已收满32位,判断键值
//无效键值:NOKEY=0xff
unsigned char judge_IRRkey(void)
{ unsigned char i,j;
                   //先判断反码
				   j=0;
				   for(i=0;i<8;i++)
				      {if (IRRbit[i+8]!=(~IRRbit[i]))
					      {j=1;
						   break;
						  }
					   if (IRRbit[i+24]!=(~IRRbit[i+16]))
					      {j=1;
						   break;
						  }
					  }
				   if(j) return NOKEY;  //解码错误
				   //判断地址码是否正确
				   j=0;
				   for(i=0;i<8;i++)
				     {if(IRRbit[i]) j|=(1<<i);  //低位先收
					 }
				   if (j!=IRR_CUSTOMCODE) return NOKEY;  //地址码错误
				   //返回键值
				   j=0;
				   for(i=16;i<24;i++)
				     {if(IRRbit[i]) j|=(1<<(i-16));
					 }
				   return j;
}				  
//扫描红外遥控器按键输入
//先扫描红外遥控器按键输入引导区: 低电平持续9ms
//只有探测到下降沿,且低电平>IRR_L_DELAY(5ms),即可能出现引导码,才进入扫描键盘子程序

void scan_IRRkey(void)
{
     IRRkey=NOKEY;   //上次扫描获得的键值不保留,需马上利用
     //不断读取1路IRR,获取波形信息
	 newIRR=read_IRR();
	 if((oldIRR)&&(!newIRR)) //下降沿
		   {delay_IRR_L=1;  //开始低电平延时计时
		   }
	 else if(newIRR) delay_IRR_L=0;       //关闭低电平延时计时
	 
	 if (delay_IRR_L>IRR_L_DELAY)   //可能进入引导区,开始连续扫描键盘
	    {delay_IRR_L=1;       //开始低电平延时计时
		 delay_IRR_H=1;       //开始高电平延时计时
		 delay_IRR_decode=1;  //开始解码延时计时
		 IRRbit_prt=0;
		 //开始解码
		 //若低电平或高电平持续时间过长,或者解码时间超出108ms,退出解码程序
		 while((delay_IRR_L<=(IRR_L_DELAY*3))&&(delay_IRR_H<=IRR_H_DELAY)&&(delay_IRR_decode<=IRR_DECODE_DELAY)&&(IRRbit_prt<32))
		    {scan_IRR_decode();  //解码后才获得键值IRRkey
			}
		 delay_IRR_L=0;       //关闭低电平延时计时
		 delay_IRR_H=0;       //关闭高电平延时计时
		 delay_IRR_decode=0;  //关闭解码延时计时
		}
	 
	 oldIRR=newIRR;
}

⌨️ 快捷键说明

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