www.openedv.com
您好,欢迎您!    会员注册 | 登入 
公告:欢迎访问www.openedv.com开源电子网,开源共享共同进步,祝您新年快乐,万事如意!
设为首页 | 加入收藏
论坛首页 » AVR单片机 前往: 
我的AVR资料[程序篇] AVR的315M无线模块通讯源码(源码2)
发表人 内容
[Down] [Up]
[楼主位] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

     这是第二个源码.利用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[i]=0;i++;}//识别0
        else if(juder>14&&juder<32){result[i]=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
 PORTA=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);
    }
}  
     以上是快速版本.还有一个慢速版本的.这里不贴出来了,见附件.

     总结一下,像这种自己定义协议的无线通信,示波器是必不可少的工具,另外要花大力气才能写出稳定可靠的传输协议,我这个仅仅是比较简单的,还有很多需要完善.有时间的朋友,可以去研究一下.






我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
[Down] [Up]
[1楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

 又找到一个51版本的.上传了.

 





我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
 
前往: 

Powered by ALIENTEK工作室 © 粤ICP备12000418号-1