433遥控器无线解码 1527中断方式解码 51单片机

433遥控器无线解码 1527中断方式解码 51单片机

这版为1527遥控器解码,是为了项目洗臀器做遥控器控制。1527遥控器原理如下。

码分别为:同步码 地址码20位 键码4位(也可以同步码16位 键码八位)
本方法的核心思想先判断同步码是否接收成功,如果接收成功开始接收后面的24位数据并且存入三个字节当中,最后一个字节的后四位就是键码,然后通过键码的不同确定不同的功能。

本实验所使用遥控器,因为遥控器发出波形时间会有误差,所以下面都是大概值 程序中也会以范围方式判断。
每桢码间隔时间为12MS (即同步码)
同步码:0.4MS+12MS
0:0.4MS+1.2MS 为0
1:1.2MS+0.4MS 为1
以下就是这次的代码了

#include <stc15.h>
#include <intrins.h>

#define uchar unsigned char 
#define uint  unsigned int


sbit RF		   	=	P0^5;	   //信号输入
sbit LED		=	P3^4;	   //
						  					
sbit D0			=	P3^6;	  //用于后面按位取键值
sbit D1			=	P3^7;
sbit D2			=	P4^1;
sbit D3			=	P4^2;
sbit VT			=	P3^5;     //解码成功



bit  decode_ok;		 //解码成功标志
uchar  hh_w,ll_w;           //高低电平宽度
uchar  ma_x;                //接收到第几位编码
uchar  bma1,bma2,bma3,bma4; //四个字节存放编码   第一次的
uchar idata mmb1,mmb2,mmb3,mmb4; // 存放编码  第二次  当两次一样才算一次有效按键

bit rf_ok1,rf_ok2;		 //临时成功接收标志  分别第一次和第二次
bit rf_ok;               //接收成功 可以解码
bit old_rc5;             //接收到24为码可以开始解码
bit tb_ok;               //同步码接收成功标志

uchar  mma1,mma2,mma3,mma4; //四个字节用来存放编码
uchar temp_h;temp_l;
bit bt_auto;     //自动设置遥控接收波特率标志 根据码不同的长度做不同的波特率
uint s,s1;用于系统延迟 分别为留时间做第二次解码 和 留时间实现功能  目的保证系统稳定性


void timeint() interrupt 1    //定时器中断
   {   	

	  if(!bt_auto)	  //
		   {
		   	 	TL0=0x70;             //   90
				TH0=0xfB;				//fc     定时器100us
		else
			{
				TL0=temp_l;             // 
				TH0=temp_h;			
			}

	  TF0=0;                // 
           
      if (!RF)
       { ll_w++;old_rc5=0; }           //接收到低电平
      	else                                      // 接收到高电平
       	{ hh_w++;
         if (!old_rc5)                          // 检测到从低到高的跳变  表示接收到一个完整的(高-低)电平周期
          { if (((hh_w>=2)&&(hh_w<=8))&&((ll_w>=50)&&(ll_w<=190)))          // 满足同步码时长   H:0.4ms L:12ms
             { 
				if((ll_w>=110)&&(ll_w<=140)){ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=0;}	 //根据更精确的时长确定波特率和后面的定时器长度 保证精确
			 	  else
					{  
					  if((ll_w>140)&&(ll_w<=160))
					  	{ ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=1;temp_h=0xfe;temp_l=0x6b; }				  
					   else
						 {  
						  if((ll_w>160)&&(ll_w<=190))
						  	{ ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=1;temp_h=0xfd;temp_l=0xdc; }
							else
								{					  
								  if((ll_w>70)&&(ll_w<=90))
								  	{ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=1;temp_h=0xff;temp_l=0x30; }
									else
										{
										  if((ll_w>90)&&(ll_w<=110))
								  			{ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=1;temp_h=0xff;temp_l=0x00; }
											else
											  {
												 if((ll_w>=50)&&(ll_w<=70))
								  					{ma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=1;temp_h=0xff;temp_l=0x7a; }									
											  }
										}
								}							  
						 }
					  }			
             }
            else if ((tb_ok)&&((ll_w>=10)&&(ll_w<=14))) 	//  已经接收到同步码  且下一个电平周期的低电平时长满足H:0.4ms L:1.2ms 判0 
				{ 	
					ma_x++;			//取编码的数量  达到24表示接收到一个完整的码
					if(ma_x>23)
						{
						   if(!rf_ok1)第一次接收到
						  	{
							  mma1=bma1;mma2=bma2;mma3=bma3;mma4=bma4;//将接收到的码放入解码寄存器    (第一次解码的寄存器)                       
                              rf_ok1=1;                                // 可以解码
                              tb_ok=0;
							  bt_auto=0;
							  s=1500;								
							}
							else  //第二次接收到
								{
								  mmb1=bma1;mmb2=bma2;mmb3=bma3;mmb4=bma4;//将接收到的码放入解码寄存器 (第二次解码的寄存器)                                           
                                  rf_ok2=1;                                //可以解码
                                  tb_ok=0;
								  bt_auto=0;																			
								}
						}
				 }  
            else if ((tb_ok)&&((ll_w>=2)&&(ll_w<=8)))  		 // 已经接收到同步码  且下一个电平周期的低电平时长满足H:1.2ms L:0.4ms 判1     
                  { switch (ma_x)  //判1   所以按位或等于取1
                     { 
					   case 0 : { bma1=bma1 | 0x80; break; }//遥控编码第一位
                       case 1 : { bma1=bma1 | 0x40; break; }
                       case 2 : { bma1=bma1 | 0x20; break; }
                       case 3 : { bma1=bma1 | 0x10; break; }
                       case 4 : { bma1=bma1 | 0x08; break; }
                       case 5 : { bma1=bma1 | 0x04; break; }
                       case 6 : { bma1=bma1 | 0x02; break; }
                       case 7 : { bma1=bma1 | 0x01; break; }
                       case 8 : { bma2=bma2 | 0x80; break; }
                       case 9 : { bma2=bma2 | 0x40; break; }
                       case 10: { bma2=bma2 | 0x20; break; }
                       case 11: { bma2=bma2 | 0x10; break; }
                       case 12: { bma2=bma2 | 0x08; break; }
                       case 13: { bma2=bma2 | 0x04; break; }
                       case 14: { bma2=bma2 | 0x02; break; }
                       case 15: { bma2=bma2 | 0x01; break; }
                       case 16: { bma3=bma3 | 0x80; break; }
                       case 17: { bma3=bma3 | 0x40; break; }
                       case 18: { bma3=bma3 | 0x20; break; }
                       case 19: { bma3=bma3 | 0x10; break; }
                       case 20: { bma4=bma4 | 0x80; break; }//°´¼ü״̬µÚ1λ
                       case 21: { bma4=bma4 | 0x40; break; }
                       case 22: { bma4=bma4 | 0x20; break; }
                       case 23: { bma4=bma4 | 0x10;
					   if(!rf_ok1)
								  	{								  mma1=bma1;mma2=bma2;mma3=bma3;mma4=bma4;//将接收到的编码复制到寄存器中  前面是最后一个键值为0  这里是最后一个键值为1        (为1的第一次用于解码的寄存器)                  
	                                  rf_ok1=1;                                // 可以解码
	                                  tb_ok=0;
									  bt_auto=0;
									  s=1500;
									  break;									
									}
									else
										{
										  mmb1=bma1;mmb2=bma2;mmb3=bma3;mmb4=bma4;//将接收到的编码复制到寄存器中  前面是最后一个键值为0  这里是最后一个键值为1      (为1的第二次用于解码的寄存器)
		                                  rf_ok2=1;                                // 可以解码
		                                  tb_ok=0;
										  bt_auto=0;
										  break;																			
										} 
                                   
                                }
                     } 
                    ma_x++;
					
                  }
            else {ma_x=0; tb_ok=0; bt_auto=0;bma1=0; bma2=0; bma3=0; bma4=0;hh_w=1;ll_w=0;}      //没有接收到同步码
    	   ll_w=0;hh_w=1; 
  			 }          
         old_rc5=1;      // 记录本次电平
       }
	if(rf_ok1)		//成功接收两次编码有效
		{
			s--;
			if(!s) rf_ok1=0;
			if(rf_ok2) 
				{
				  if((mma1==mmb1)&&(mma2==mmb2)&&(mma3==mmb3)&&(mma4==mmb4))//两次编码相等  为有效
				  	 {
					  rf_ok=1;   //解码有效 接收成功的标志
					  rf_ok1=0;
					  rf_ok2=0;					 
					 }
					 else
					   {
						  rf_ok=0;
						  rf_ok1=0;
						  rf_ok2=0;			 
					   }		  				
				}					
		}
    if((rf_ok))		 //解码有效  接收成功
			{  	
				EA=0;
				rf_ok=0;											
				D3=mma4 & 0x80;    //取出键码
				D2=mma4 & 0x40;
				D1=mma4 & 0x20;
				D0=mma4 & 0x10;
//				D4=mma4 & 0xC0;
				decode_ok=1;
				VT=0;		
				s1=1500;
				EA=1;
			}


   if(decode_ok)   //接收成功标志
	  	{
			s1--;
			if(!s1)
				{
					VT=1;//接收成功亮灯
					decode_ok=0;//接收成功标志位置零 用于下一次
				}				  
	  	}
   }

void system_start()   //系统初始化		
 	AUXR=0xb5;   	
	P0M0=0x01;
	P0M1=0x20;
	P3M0=0xC0;
	P3M1=0x00;
	P4M0=0x06;
	P4M1=0x00;
	P0=0xfe;
  	P3=0x3f;	 //将LED灯拉低电平 判高电平亮
	P4=0xf9;
  TMOD =   0x11;   //T1/T0改为定时器方式1
	TL0=0xb5;
	TH0=0xfb;
	ET0=1;
	TR0=1;			
	EA=1;
}

void main()
{
  system_start();
  while(1);
}
                             这次有点累了  下次补查询方式解码 下次用2262来写吧  有不明白的可以下面提出来
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值