定时器超外差解码

参考例程

链接:SYN480R模块解码EV1527教程.

  • 单片机SN8F5711 SOP16
  • 开发环境keil

单片机解码需要带自唤醒功能,看门狗或者定时器唤醒以实现低功耗。

解码头文件

#ifndef _DECODE_H_
#define _DECODE_H_

#include "..\Include\config.h"

#define rfRead   	 P24   //数据口

#define RF_EN  	 		 1
#define RF315M_EN  	 0
#define RF433M_EN  	 1

#if RF_EN
#define INTREVAL   		100  			//定时器中断周期 INTREVAL(us)
#define RELEASE_CNT   100  			//松手计数      大于同步头时间长度即可   100*100=10(ms)
#define ECOUNT        3  				//按键有效计数
#define DELAY_SLEEP   4     //进入低功耗计数   延迟时间=DELAY_SLEEP*扫描周期(ms)



#define EV1527_ADDRESS    0xB6CF   //EV1527  2字节地址码
//逻辑分析仪实际测量

#if  RF315M_EN
#define _start_us_min   (11500/INTREVAL)   //12.5ms
#define _start_us_max   (13500/INTREVAL)   

#define _num0_us_min 	  (1000/INTREVAL)    //1.2ms
#define _num0_us_max 	  (1400/INTREVAL)

#define _num1_us_min    (100/INTREVAL)     //0.48ms
#define _num1_us_max    (800/INTREVAL)

#endif


#if RF433M_EN

#define _start_us_min   (8000/INTREVAL)   //8.8ms
#define _start_us_max   (9500/INTREVAL)   

#define _num0_us_min 	  (500/INTREVAL)    //0.83ms
#define _num0_us_max 	  (1100/INTREVAL)

#define _num1_us_min    (0/INTREVAL)     //0.26ms
#define _num1_us_max    (600/INTREVAL)

#endif

void soft_count(void);
void soft_decode(void);
void setStaticAddress(u8 writeAddh,u8 writeAddl);
u16 getStaticAddress (void);
u16 getRemoteAddress(void);

u8 acceptingData(void);
u8 getRemotekeyData(void);
u8 getRemotelongpressCnt(void);
bit  getSyncFlag(void);

//extern u8  	release_key_cnt;    //松手计数
//extern u16  RF_Value_Cnt;  //长按计数
extern bit  IR_OVER;       //接收完一帧数据
extern bit 	pair_flag;
extern u8 Address_h;
extern u8 Address_l;
#endif



#endif

解码C文件

#include "decode.h"

#if RF_EN
       
u8   release_key_cnt=0;       //松手计数
u8   RF_Value_Cnt=0;	        //长按计数
u8   Temp_addrl=0,Temp_addrh=0,Address_l=0,Address_h=0;
u8   cntint=0,IR_Key=0;


u16  Low=0;	 						//低电平计数
u32 RF_data=0;          //24位数据码

bit start_flag=0;     	 //解码开始标志
bit IR_OVER=0;       		//一组数据接收完成标志
bit Jump_flag=0;     		//电平跳变标志

bit pair_flag=0;     		//对码标志
u8  tranCnt=0;

//---------定时中断扫描函数-------------------
void soft_count()
{
	if(tranCnt>0)
		tranCnt--;   //松手计数
	
	if(rfRead==0)
	{
		Low++;       //低电平累加计数
		if(Jump_flag)Jump_flag=0;
	}
	else if(rfRead==1)
	{
		if(!Jump_flag)
		{
			Jump_flag=1;
			soft_decode();   //上升沿进入解码程序。
			Low=0;
		}
	}
}

void soft_decode()
{
	if(!start_flag)
	{
		if(( Low > _start_us_min ) && ( Low < _start_us_max ))	 //同步码
		{
			start_flag=1;
			cntint=0;  					//数据长度清零
			IR_Key=0;
			RF_data=0;
			tranCnt=RELEASE_CNT;
			//IR_OVER=0;
		}
		
		//---------松手计数 有缺陷 解码完成的下降沿和来临的第一个上升沿 时间为150ms---------
		else
		{
			RF_Value_Cnt=0;
			pair_flag=0;               //对码标志位清零
			if(++release_key_cnt>=10)  //这里累加的是150ms的低电平的个数,并不是松手后的绝对时间  易受环境干扰
			{
				release_key_cnt=10;
			}
		}
	}
	else if((start_flag)&&(cntint<24))
	{
		
						//--------数据码0判断--------
		if(( Low > _num0_us_min ) && ( Low < _num0_us_max ))
		{
			RF_data=RF_data<<1;
			cntint++;
			
			tranCnt=RELEASE_CNT;
		}
					//--------数据码1判断--------
		else if(( Low > _num1_us_min ) && ( Low < _num1_us_max ))	
		{
			RF_data=RF_data<<1;
			RF_data|=1;
			cntint++;
			
			tranCnt=RELEASE_CNT;
		}
					//--------数据码判断错误--------
		else 
		{
			start_flag=0;
			cntint=0;
		}	
	}
	else ;
	
	
	//---------315解码完毕大概需要52ms-----------------
	//---------433解码完毕大概需要37ms-----------------
	if(cntint==24)
	{
		release_key_cnt=0;
		RF_Value_Cnt++;
		if(RF_Value_Cnt>100)RF_Value_Cnt=100;
		cntint=0;
		start_flag=0;
		IR_Key=RF_data&0x0000000f;	//按键码
		Temp_addrl=(RF_data>>4)&0x000000ff; //低8位地址码
		Temp_addrh=(RF_data>>12)&0x000000ff; //高8位地址码
		
		//-----连续接收到3个正确的码才是有效的--------------
		if(RF_Value_Cnt>=ECOUNT) pair_flag=1;    //对码标志位

		IR_OVER=1;  	//解码完成
	}
}


//------设置静态遥控地址码------------
void setStaticAddress(u8 writeAddh,u8 writeAddl)
{
	
	Address_h=writeAddh;
	Address_l=writeAddl;
	
}
//------得到静态遥控地址码------------
u16 getStaticAddress (void)
{
	u16 address=0;
	address=(Address_h<<8)+Address_l;
	return address;
}

//------得到临时遥控地址码------------
u16 getRemoteAddress(void)
{
	u16 address=0;

	address=(Temp_addrh<<8)+Temp_addrl;
	
	return address;
}

//------返回按键键码---------------
u8 getRemotekeyData(void)
{
	 return IR_Key;
}

//------得到长按计数值--------------
u8 getRemotelongpressCnt(void)
{
	 return RF_Value_Cnt;
}


//------是否正在接受遥控数据--------
u8 acceptingData(void)
{
	
	if(tranCnt==0)
		return 1;
	
	return 0;
	
}

bit  getSyncFlag(void)
{
	return start_flag;
}

/*
//-----------------------进入打嗝模式------------------------
void burp_mode(void)
{
	
	static unchar sleep_cnt=DELAY_SLEEP;
	
	if(-- sleep_cnt==0)
	{
		sleep_cnt=DELAY_SLEEP;
		if((!getSyncFlag()))
		{
			pwr_timer0();       //开启定时唤醒功能
			_clrwdt();          //喂狗
			//red=1;  //周期测试
			_nop_();
			_nop_();
			STOP();
			_nop_();
			_nop_();
			//red=0;  //周期测试
			timer0_close();
		}
	}
}

*/


#endif

定时器头文件

#ifndef _TIMER_H_
#define _TIMER_H_

#include "..\Include\config.h"

#define timer0_EN  0

#define T0EXT_LOSC_SET		0x80		//flosc
#define T0RATE_128				0x00
#define T0RATE_64					0x10
#define T0RATE_32					0x20
#define T0RATE_16					0x30
#define T0RATE_8					0x40
#define T0RATE_4					0x50
#define T0RATE_2					0x60
#define T0RATE_1					0x70

#define T1RATE_128				0x00
#define T1RATE_64					0x10
#define T1RATE_32					0x20
#define T1RATE_16					0x30
#define T1RATE_8					0x40
#define T1RATE_4					0x50
#define T1RATE_2					0x60
#define T1RATE_1					0x70


//遥控器按下连续发4个数据包 要保证至少接收到一个则  3*52=156ms  
//遥控器按下连续发4个数据包 要保证至少接收到一个则  3*37=111ms  
/****	
16K/64=0.25K 
125/0.25=500ms
*/
#define WAKE_T0RATE_SET		T0RATE_64

#define WAKE_TIMER_CNT		(256-50)	


void pwr_timer0(void);
void timer0_close(void);
void time1_init(void);
u16 getSYSTimer(void);



#if timer0_EN
void init_timer0(void);
#endif

#endif

定时器C文件

#include "timer.h"



unint SYS_TIMER=0;   //时基


//-----------切换到低速时钟,进入定时唤醒模式----------------
void pwr_timer0(void)
{
		TMOD |= 0x06;     			 // Mode 2 of Timer 1 as a 8-bit auto-reload Timer 
		TH0 = WAKE_TIMER_CNT;		//200MS;
		TL0 = WAKE_TIMER_CNT;		//200MS;

		TCON0 &= 0x0f;    // T1RATE is Fosc/128
		TCON0 |= (T0EXT_LOSC_SET|WAKE_T0RATE_SET);	// 16K  
		ET0 = 1;          // Timer 0 isr disable
		TR0 = 1;          // enable Timer 0 Run control
		SYSMOD |= 0X01;   //STOP模式下低速时钟运行
}

void timer0_close(void)
{
	SYSMOD &= 0xfe;
	ET0=0;
	TR0=0;
}

//-----------切换到高速时钟,普通模式用---------------
#if timer0_EN
	
void init_timer0(void)
{
	TMOD |= 0x06;     // Mode 2 of Timer 0 as a 8-bit auto-reload Timer 
  TH0 = (256-125);		//500uS;
  TL0 = (256-125);		//500uS;

  TCON0 &= 0x0f;    // 切换到高速时钟
	TCON0 |= T0RATE_64;    // T0RATE is Fosc/64
  ET0 = 1;          // Timer 0 isr disable
  TR0 = 1;          // enable Timer 0 Run control
	
}
#endif


/***************************************************************
		time1   1ms定时
****************************************************************/
void time1_init(void)
{
	TMOD |= 0x60;          						// T1 8位自动装载
	#if RF_EN
	TH1 = (256-25);             			// Initial values
	TL1 = (256-25);
	#else
	TH1 = (256-250);             			// Initial values
	TL1 = (256-250);
	
	#endif
	
	TCON0 &=0xf0;        	         // fosc/128=32M/128=250K     (256-6)/250K=0.001s=1ms
	TCON0 |= T1RATE_128;
	ET1 = 1;                    	// Timer 1 isr enable
	TR1 = 1;                    	// enable Timer 1 Run control
}

u16 getSYSTimer(void)
{
	return SYS_TIMER;
}


void Timer1_ISR (void) interrupt ISRTimer1   // Vector @  0x1B
{
	#if RF_EN
	
	static unchar isr_cnt=10;
	soft_count();

	//定时溢出标志自动清零。
	if(--isr_cnt==0)
	{
		isr_cnt=10;
		SYS_TIMER++; 
		//red=!red;     //周期测试
	}
	
 #else
		SYS_TIMER++; 
	#endif
}

按键处理例程

void decodeKey_handle(void)
{
	//同一个按键不能同时实现按下触发和长按的功能
	u8 IR_key=0;
	u8 IR_addh=0;
	u8 IR_addl=0;
	static u8 key_lock=0;
	
	IR_key=getRemotekeyData();                //得到按键码
	IR_addh=(u8)(getRemoteAddress()>>8);			//得到地址码
	IR_addl=(u8)getRemoteAddress();
	
	
//-------------松手后10ms使能短按按键处理,否则锁死--------------
	if(key_lock)       
	{
		if(acceptingData())
			key_lock=0;
	}
	
	//--------------对码并写入flash  超过5S则重新对码---------
	if(pair_start)   //按键按下,则pair_start置位,开始对码
	{
		green=1;    //指示灯
		
		if(getSYSTimer()-PAIR_TIMER>=5000) //5S没有对码则结束对码
		{
			pair_start=0;
			green=0;
			pair_flag=0;
		}
		
		if(pair_flag)
		{
			pair_flag=0;
			green=0;
			pair_start=0;
			
//-----------把遥控器的地址码保存到flash中-------------------
			ROMByteWrite(ROMADDRH,&IR_addh);
			_nop_();_nop_();
			ROMByteWrite(ROMADDRL,&IR_addl);
			_nop_();_nop_();
			
			setStaticAddress(IR_addh,IR_addl);  //设置静态地址
			key_lock=1;   //按键自锁
		}
	}
	 
	
	//if((IR_addh==(u8)(getStaticAddress()>>8)) && (IR_addl==(u8)getStaticAddress))
	
	
		if(IR_OVER)
		{
			IR_OVER=0;
			if((IR_addh==(u8)(getStaticAddress()>>8)) && (IR_addl==(u8)getStaticAddress()))
			//if((IR_addh==0xb6) && (IR_addl==0xcf))
			{
			//------------------短按按键处理---------------------
				if(!key_lock)
				{
					switch(IR_key)
					{						
						case 0x04:led=!led;key_lock=1;break;           					  					
						default:break;
					}
				}
		 }
	}
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值