接收机
选频网,高通滤波,经过滤波整形后,又通过一个高通滤波器,信号送入运放,使之产生单片机可接受的电平信号。
发射机:
当DATA脚为高电平时三极管Q2导通,振荡电路工作,通过三极管发射出315MHz的载频信号。
工作流程
当发射机为高电平时,发射机发射出315MHz的频率信号。
接收机通过选频滤波和整形后也输出高电平
如果发射机持续输出315MHz信号,那么由于运放输入级存在一个高通滤波器,所以发射机持续的高电平会导致接收端高电平跌落。
当发射机DATA输入变化的电平时,也就是发射出断续的315MHz信号,也就是ook信号。通过导通和断开来表示0和1。
这个时候接收机识别到这些信号后,通过选频滤波整形,输出单片机可以接受的信号。
现实中存在的问题:
当发射机没有发射信号,或者接收机天线没有接受到任何信号的时候,由于电磁环境的影响,模块很容易受到环境的电磁波的影响,输出端OUT会输出无规则的高频信号,但是这类信号对于运放来说,输出的是相对频率较高的无规则电平信号,这个地方需要想办法将这种干扰去除。
通信协议:
经过无数次的测试,每次发射机高电平的时候,接收机大概能够持续100ms的高电平,应该取决于高通滤波器的通带。
同时,由于发射机和接收机都只有一个输入输出口,所以应该采用但总线协议。
又经过多次测试,采用如下的协议:
● 起始电平为20ms高电平信号
● 1:8ms高电平+4ms低电平
● 0:4ms高电平+8ms低电平
● 每个字节至少间隔100ms发送
起始电平的作用是为了滤除315模块输出的无规则电平信号。
其中定时用单片机定时器实现,定时周期1ms
单片机选用相对较为便宜的stc15W10x的sop8封装的单片机。
实测结果:
在50m内能够正常稳定的接受到数据,超出50m后很容易造成丢包现象。多远完全失效没有测试。
测试代码:
发射机:
#include <STC15F2K60S2.H>
#include<mytype.h>
void start_315(); //起始位
void send_1(bit t);//数据位t=0/1,发送一位
void send_8(uchar seg); //发送一个字符;
void TimerInit();
sbit Dat=P3^5; //单总线接口
uchar n; //定时器循环次数
void main()
{
TimerInit();
Dat=1;
delay(100);
while(1)
{
send_8(0x12);
delay(500);
}
}
void delay(uint ms)
{
uint i;
while(ms--)
{i=645;while(i--);}
}
void TimerInit()
{
AUXR|=0x80;
TMOD&=0xf0;
TH0=0xfb;
TL0=0x50;
ET0=1;
TR0=0;
EA=1;
}
void start_315()
{
n=80;
Dat=0;
TR0=1;
while(n);
TR0=0;
Dat=1;
n=80;
TR0=1;
while(n);
TR0=0;
}
void send_1(bit t)
{
uchar temp;
if(t==1)
n=10;
else
n=30;
temp=n;
Dat=0; TR0=1; while(n); TR0=0; Dat=1; //充电,n位高电平时间(100us/n)
n=temp;
TR0=1; while(n); TR0=0; //等待放电
n=40-temp;
Dat=0; TR0=1; while(n); TR0=0; Dat=1;
n=40-temp;
TR0=1; while(n); TR0=0;
}
void send_8(uchar seg)
{
uchar i=8;
start_315();
while(i--)
{
send_1((seg>>i)&0x01);
}
delay(100);
}
void Timer0() interrupt 1
{
n--;
}
接收机代码:
//#include <STC15F2K60S2.H>
#include <STC12C5A60S2.H>
#include<mytype.h>
/******** 0xff为校验数据,不能作为有效数据 ********/
uchar get_315();
void TimerInit();
void UartInit(void); //9600bps@12.000MHz
sbit Dat=P3^5; //单总线接口
sbit qwe=P2^0;
uint n; //定时器循环次数
void main()
{
uchar RS;
TimerInit();
qwe=0;
// Dat=0;
delay(100);
while(1)
{
if(Dat==1)
{
RS=get_315();
if(RS!=0XFF)
{
UartInit();
delay(2);
SBUF=RS;
while(TI==0);
TI=0;
TimerInit();
delay(2);
qwe=!qwe;
}
}
}
}
void delay(uint ms)
{
uint i;
while(ms--)
{i=645;while(i--);}
}
void TimerInit()
{
AUXR&=0x3f;
TMOD=0x21;
TH0=0x00;
TL0=0x00;
TH1=0x9c;
TL1=0x9c;
ET0=1;
ET1=1;
TR0=0;
TR1=0;
EA=1;
}
void UartInit(void) //9600bps@12.000MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xD9; //设定定时初值
TH1 = 0xD9; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
uchar get_315() //获取数据
{
ulong temp[2]=0 ;
uchar i,result=0;
TR1=1;
n=40;
while(n)
{
if(Dat==0)
return 0xff;
}
while(Dat);
n=40;
while(n)
{
if(Dat==1)
return 0xff;
}
TR1=0;
result=0;
i=8;
while(i--)
{
TH0=0x00;
TL0=0x00;
while(!Dat);
TR0=1;
while(Dat);
temp[0]=TH0*256;
TR0=0;
TH0=0x00;
TL0=0x00;
while(!Dat);
TR0=1;
while(Dat);
TR0=0;
temp[1]=TH0*256+TL0;
if(temp[0]>temp[1])
result|=0x80;
else
result&=0x7f;
result>>=1;
}
return result;
}
void Timer0() interrupt 1
{
n++;
TH0=0x00;
TL0=0x00;
}
void Timer1() interrupt 3
{
n--;
}