天天看点

四极管:红外之AVR 红外解码

/****************************************
 函数功能:定时器写红外
 函数说明:定时器使用定时器0,外部中断0
          
 使用环境:    硬件: MCU: ATmega32L 
                      F_CPU = 16000000
                      外部:16000000 
		       解码遥控器:基地制衣厂版:RC-E16T			  
			  
 编译环境:WinAVR-20080610	
 显示说明:  
 包含文件 :time0_init.c				  
 日期:2009年8月9日
 作者:杨琦
 修改者:		   	(日期:  )		
*****************************************/
 //!!!!!!红外数据读取成功标识,在中断中使用标志位,必须加Volatile,防止编译器对程序进行优化处理!!!!!
volatile    uint8_t     got_hw = 0 ;	
	//!!!!!!红外数据读取成功标识,在中断中使用标志位,必须加Volatile,防止编译器对程序进行优化处理!!!!!
uint8_t first_flag_hw = 0 ,	//第一起始信号到来标识
	    second_flag_hw= 0 ;	//第二起始信号到来标识 

uint8_t	data_cnt_hw = 0 ,	//红外数据位数计数清零
		addr_cnt_hw = 0 ,	//红外地址位数计数清零
		addr_hw = 0 ,		//红外地址值清零
		data_hw = 0 ;		//红外数据值清零
volatile uint32_t cnt_100us = 0 ; //用于计时器0中的 100us计数器  TIME = T * cnt_100us    T为记时周期:100us
/****************************************
** 函数名:hw_judge_in_int0(void)
** 功能  :红外数据处理
** 子函数:无
** 变量  :无
** 外部标识:got_hw 
****************************************/
void hw_judge_in_int0(void)
{
	char cnt = cnt_100us ;
	cnt_100us = 0 ;
	if( cnt < 7 ) //下降沿间隔低于1.04ms的,则是错误信号 
	{
		//数据位数计数清零
		first_flag_hw = 0 ;	//第一起始信号清零
		second_flag_hw= 0 ;	//第二起始信号清零 
		data_cnt_hw = 0 ;	//数据位数计数清零
		addr_cnt_hw = 0 ;	//地址位数计数清零
		addr_hw = 0 ;		//地址值清零
		data_hw = 0 ;		//数据值清零		
	}
	else if( cnt > 8 && cnt < 14 )  //	下降沿间隔1.04ms是'0'信号 		//实测值:cnt_100us == 9
	{
		if( first_flag_hw==1 && second_flag_hw==1 )    //在接收数据的阶段
		{
			if( data_cnt_hw < 8 )//确保数据值不被移出
			{			
				data_cnt_hw++ ;	 //数据位数计数自增
				data_hw <<= 1 ;	 //存入'0',从高位接起  最后放入的是低位	
				if( data_cnt_hw == 8 )  
				{
					got_hw = 1 ;
					
				}				
			}	
		
		}	
		else if( first_flag_hw==1 && second_flag_hw==0 )//在接收地址的阶段
		{
			if( addr_cnt_hw < 8 )//确保地址值不被移出
			{
				addr_cnt_hw++ ;	 //地址位数计数自增
				addr_hw <<= 1 ;	 //存入'0',从高位接起  最后放入的是低位			
				
			}

		}
		else  //否则出错  回到原来状态
		{
			//数据位数计数清零
			first_flag_hw = 0 ;	//第一起始信号清零
			second_flag_hw= 0 ;	//第二起始信号清零 
			data_cnt_hw = 0 ;	//数据位数计数清零
			addr_cnt_hw = 0 ;	//地址位数计数清零
			addr_hw = 0 ;		//地址值清零
			data_hw = 0 ;		//数据值清零			

		}		
	}
	else if( cnt > 18 && cnt < 23 ) //  下降沿间隔2.12ms是'1'信号			  //实测值:cnt_100us == 18(有时候是19)
	{
		if( first_flag_hw==1 && second_flag_hw==1 )    //在接收数据的阶段
		{
			if( data_cnt_hw < 8 )//确保数据值不被移出
			{			
				data_cnt_hw++ ;	 //数据位数计数自增
				data_hw <<= 1 ;	 data_hw |= 0x01 ;//存入'1',从高位接起  最后放入的是低位	
				if( data_cnt_hw == 8 )  
				{
					got_hw = 1 ;

				}
			}			
		}	
		else if( first_flag_hw==1 && second_flag_hw==0 )//在接收地址的阶段
		{
			if( addr_cnt_hw < 8 )//确保地址值不被移出
			{
				addr_cnt_hw++ ;	 //地址位数计数自增
				addr_hw <<= 1 ;	 addr_hw |= 0x01 ;//存入'1',从高位接起  最后放入的是低位				
			}

		}
		else  //否则出错  回到原来状态
		{
			//数据位数计数清零
			first_flag_hw = 0 ;	//第一起始信号清零
			second_flag_hw= 0 ;	//第二起始信号清零 
			data_cnt_hw = 0 ;	//数据位数计数清零
			addr_cnt_hw = 0 ;	//地址位数计数清零
			addr_hw = 0 ;		//地址值清零
			data_hw = 0 ;		//数据值清零	
		 
		}
	}		
	else if( cnt > 45 && cnt < 50 ) //  下降沿间隔4.72ms是第二起始信号	  //实测值:cnt_100us == 42
	{
		if( first_flag_hw == 1)//如果收到过第一起始信号 而且 收到过8位地址	 && addr_cnt_hw == 8 
		{
			second_flag_hw= 1 ;	//第二起始信号置一
			addr_cnt_hw = 0 ;	//地址位数计数清零
			data_cnt_hw = 0 ;	//数据位数计数清零		
		
		}
		else  //否则出错  回到原来状态
		{
			//数据位数计数清零
			first_flag_hw = 0 ;	//第一起始信号清零
			second_flag_hw= 0 ;	//第二起始信号清零 
			data_cnt_hw = 0 ;	//数据位数计数清零
			addr_cnt_hw = 0 ;	//地址位数计数清零
			addr_hw = 0 ;		//地址值清零
			data_hw = 0 ;		//数据值清零		
		}	
	}
	else if( cnt > 120 && cnt < 130 ) //  下降沿间隔12.6ms是第一起始信号 	  //实测值:cnt_100us == 112 
	{
		first_flag_hw = 1 ;	//第一起始信号置一
		second_flag_hw= 0 ;	//第二起始信号清零
		data_cnt_hw = 0 ;	//数据位数计数清零
		addr_cnt_hw = 0 ;	//地址位数计数清零		
	}
	else //大于12.6ms则不是起始信号    			 //实测值:cnt_100us == 250
	{
		//数据位数计数清零
		first_flag_hw = 0 ;	//第一起始信号清零
		second_flag_hw= 0 ;	//第二起始信号清零 
		data_cnt_hw = 0 ;	//数据位数计数清零
		addr_cnt_hw = 0 ;	//地址位数计数清零
		addr_hw = 0 ;		//地址值清零
		data_hw = 0 ;		//数据值清零
	}
}













转载请注明出处。作者:四极管。广西师范大学 电子工程学院大学生科技创新基地 邮箱: [email protected]。









           

继续阅读