这是第二个源码.利用mega8做发射,mege16做接收.无线模块用的是很便宜的315M模块,大概10元一对.协议是自己定的.
协议格式是参考PT2226/PT2227的,为:前导码+地址+数据+地址反码.
发送端代码:
#include <mega8.h>
#include <delay.h>
#define OUT PORTC.0
void sendbyte(uchar add,uchar data)
{
uchar t,temp;
temp=~add;
for(t=0;t<4;t++)//发送前导命令
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(250);
}
for(t=0;t<4;t++) //发送地址
{
if(add&0x01)
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(100);
}
else
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(175);
}
add>>=1;
}
for(t=0;t<8;t++)//发送数据
{
if(data&0x01)
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(100);
}
else
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(175);
}
data>>=1;
}
for(t=0;t<4;t++)//发送地址反码
{
if(temp&0x01)
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(100);
}
else
{
OUT=1;
delay_us(150);
OUT=0;
delay_us(175);
}
temp>>=1;
}
OUT=1;
delay_us(150);
OUT=0;
delay_us(250);//发送结束帧
OUT=1;
}
void main()
{
uchar t,i;
t=0;
DDRC=0XFF;
PORTC=0XFF;
while(1)
{
for(i=0;i<10;i++)
sendbyte(0x0a,t);
t++;
//delay_ms(1000);
}
}
接收端代码:
#include <mega16.h>
#include<delay.h>
#define IN PIND.2 //无线数据输入端口
//无线数据传输辅助变量
uchar mark,i,result[16];
/*--------------n的m次方计算-----------------
返回值:n^m
参数:n 底数
m 指数
注:n^m不能超过255!!!
--------------------------------------------*/
unsigned char pow(unsigned char n,unsigned char m)
{
unsigned char t,BACK=1;
for(t=0;t<m;t++){BACK=n*BACK;}
return BACK;
}
/*--------------检查低电平的时间-----------------
返回值:低电平持续时间(单位:10uS)
参数:无
注:错误时返回0
-------------------------------------------------*/
uchar check(void)
{
uchar jud=0;
while(!IN)//检测低电平持续时间
{
delay_us(5);jud++;
if(jud>54)return 0;//排除长0的干扰
}
if(jud<15)return 0;//排除短0的
return jud;
}
/*--------------检查低电平的时间-----------------
返回值:无
参数:无
-------------------------------------------------*/
void Clear(void)
{
uchar t;
i=mark=0;
for(t=0;t<16;t++)result[t]=0;
}
/*---------数据检测接收函数(中断函数)----------
返回值:无
参数:无
注意:识别0:15-19,识别1:8-14,此区间内稳定性最好
test data
if(juder>19&&juder<31)(200-340us)1
if(juder>30&&juder<41)(340-500us)0
if(juder>40&&juder<54)(500-600us)guide
if(juder>53&&juder<63)(600-700us)start
-------------------------------------------------*/
interrupt [EXT_INT0] void ext_int0_isr(void)//接收处理函数
{
uchar juder;
juder=check();//获得低电平脉宽
if(juder>44&&juder<54)mark++;//识别前导
else if(mark>3)//条件强弱判定
{
if(juder>31&&juder<45){result=0;i++;}//识别0
else if(juder>14&&juder<32){result=1;i++;}//识别1
else {Clear();return;} //清除杂波
}
else mark=0;//排除短0的干扰
}
/*--------------无线数据处理程序-----------------
返回值:0 未获得数据
1 获得数据
参数:*Cmd 地址暂存(或者命令\低四位有效)
*Numb 数据暂存(0-255)
-------------------------------------------------*/
uchar Get_Radio(uchar *Cmd,uchar *Numb)
{
uchar k;
if(result[0]==!result[12]&&result[1]==!result[13]
&&result[2]==!result[14]&&result[3]==!result[15])
{
*Cmd=*Numb=0;
for(k=0;k<4;k++)*Cmd+=pow(2,k)*result[k];
for(k=0;k<8;k++)*Numb+=pow(2,k)*result[k+4];
Clear();
return 1;
}
return 0 ;
}
/*----------------数码管显示程序-----------------
返回值:无
参数:number 要显示的数字(0-9)
position 要显示的位置(1-8)
-------------------------------------------------*/
void display(unsigned char number,unsigned char position)//digtial show function
{
DDRA=0Xff;//set PORTA output
  ORTA=0XFF;//set PORTA output in high level
switch(position)//choice the position
{
case 1:{PORTA&=0xf8;break;}
case 2:{PORTA&=0xf9;break;}
case 3:{PORTA&=0Xfa;break;}
case 4:{PORTA&=0Xfb;break;}
case 5:{PORTA&=0Xfc;break;}
case 6:{PORTA&=0Xfd;break;}
case 7:{PORTA&=0Xfe;break;}
case 8:{PORTA&=0Xff;break;}
}
switch(number)//show number
{
case 0:{PORTA&=0x87;break;} //0
case 1:{PORTA&=0x8f;break;} //1
case 2:{PORTA&=0x97;break;} //2
case 3:{PORTA&=0x9f;break;} //3
case 4:{PORTA&=0xa7;break;} //4
case 5:{PORTA&=0xaf;break;} //5
case 6:{PORTA&=0xb7;break;} //6
case 7:{PORTA&=0xbf;break;} //7
case 8:{PORTA&=0xc7;break;} //8
case 9:{PORTA&=0xcf;break;} //9
default:{PORTA=0xff;break;} //null
}
}
void main(void)
{
uchar res=0,*number,*add;
DDRD&=0XFB;
DDRB=0XFF;
PORTB=0XFF;
PORTD|=0x04;//INT0开启上拉电阻
GICR|=0x40;//开启中断0
MCUCR=0x02;//下降沿触发
//GIFR=0x40;
#asm("sei")
while (1)
{
if(Get_Radio(add,number))res=*number;
display(res/100,5);delay_us(50);
display((res%100)/10,6);delay_us(50);
display(res%10,7);delay_us(50);
}
}
以上是快速版本.还有一个慢速版本的.这里不贴出来了,见附件.
总结一下,像这种自己定义协议的无线通信,示波器是必不可少的工具,另外要花大力气才能写出稳定可靠的传输协议,我这个仅仅是比较简单的,还有很多需要完善.有时间的朋友,可以去研究一下. |