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
#include
#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=50)&&(ll_wma_x=0;tb_ok=1;bma1=0; bma2=0; bma3=0; bt_auto=0;} //根据更精确的时长确定波特率和后面的定时器长度 保证精确
else
{
if((ll_w>140)&&(ll_w
if((ll_w>160)&&(ll_w
if((ll_w>70)&&(ll_w
if((ll_w>90)&&(ll_w
if((ll_w>=50)&&(ll_w
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
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来写吧 有不明白的可以下面提出来
|