软件解码315M超外差收发机

接收机
接收机原理图

选频网,高通滤波,经过滤波整形后,又通过一个高通滤波器,信号送入运放,使之产生单片机可接受的电平信号。

发射机:
发射机原理图

当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--;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值