打印

ATMEGA16控制NRF905进行简单的收发程序!!

[复制链接]
1905|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
darlin520|  楼主 | 2012-7-4 19:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
发送方代码:
#include <iom16v.h>
#include <macros.h>
#define uint  unsigned int
#define uchar unsigned char
#define   Low_TX_EN      PORTD&=~(1 << PD7)
#define   High_TX_EN     PORTB|= (1 << PD7)
#define   High_TRX_CE    PORTD|= (1 << PD6)  
#define   Low_TRX_CE     PORTD&=~(1 << PD6)
#define   High_PWR       PORTD|= (1 << PD5)
#define   Low_PWR        PORTD&=~(1 << PD5)
//--------------------------------SPI口定义-------------------------------------
#define   High_SCK       PORTB|=(1 << PB7)
#define   Low_SCK        PORTB&=~(1 << PB7)
#define   High_CSN       PORTB|= (1 << PB4)  
#define   Low_CSN        PORTB&=~(1 << PB4)            
#define   High_CD        PORTD|= (1 << PD4)
#define   Low_CD         PORTD&=~(1 << PD4)
#define   High_AM        PORTD|= (1 << PD3)
#define   Low_AM         PORTD&=~(1 << PD3)
#define   High_DR        PORTD |= (1 << PD2)
#define   Low_DR         PORTD &= ~(1 << PD2)
//----------------------------------905-SPI指令---------------------------------
#define WC  0x00
#define RC  0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
uchar TxBuf[4]={0x01,0x02,0x03,0x04};        //待发送的数据                        
uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc };   //发送的地址
uchar RFConf[11]=
{
  0x00,                             //配置命令//
  0x5f,                             //CH_NO,配置频段在915MHZ
  0x0b,                             //输出功率为+6db,不重发,节电为正常模式
  0x44,                             //地址宽度设置,为4字节
  0x04,0x04,                        //接收发送有效数据长度为4字节
  0xCC,0xCC,0xCC,0xCC,              //接收地址
  0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振,,输出时钟频率为4MHZ,
};
//--------------------------延时函数-------------------------------------------
void delay(uint z)
{
    uint i,j;
    for(i=z;i>0;i--)
      for(j=1714;j>0;j--);
}
void delayus(uint x)
{
    uint i;
    while(x--)
    for(i=0;i<80;i++);
}
//----------------------------------SPI初始化-----------------------------------
void Spi_initial(void)
{
  
    SPCR=0x50;
    SPSR=0x00;
    // SPCR   = (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<SPR0);   // 主机模式,fck/16, SPI方式0
}
//---------------------------------SPI写程序----------------------------------   
uchar SpiWrite(uchar Data)//r
{
    SPDR = Data;
    while(!(SPSR & (1<<SPIF) ))     //SPIF即等于7, 等待SPI发送完毕
     {};         // 等待SPI发送完毕
    return SPDR;
   
}
//---------------------------------系统状态初始化-------------------------------
void system_init(void)         
{
    High_CSN;            // Spi     disable
    Low_SCK;             // Spi clock line init low
    Low_DR;              // Init DR for input
    Low_AM;              // Init AM for input
    Low_CD;              // Init nrf905_CDfor input
    High_PWR;            // nRF905 power on
    Low_TRX_CE;          // 初始化为空闲模式
    Low_TX_EN ;          // 默认为接收模式
}
//--------------------------------NRF905寄存器初始化函数------------------------
void Config905(void)
{
    uchar i;
    Low_CSN;                   // Spi enable for write a spi command        
    //SpiWrite(WC);             // Write config command写放配置命令
    for (i=0;i<11;i++)          // Write configration words  写放配置字
    {
     SpiWrite(RFConf[i]);
    }
    High_CSN;                   // 关闭SPI
}
//--------------------------------NRF905待发数据打包----------------------------
void txpacket(void)
{
    uchar i;
    Low_CSN;                             // 使能Spi,允许对nrf905进行读写操作
    delayus(1);
    SpiWrite(WTP);               // 写数据前先写写数据命令
    for (i=0;i<4;i++)
    {
    SpiWrite(TxBuf[i]);      // 待发送的4字节数据
       }                 
     High_CSN;         // 关闭Spi,不允许对nrf905进行读写操作
       delayus(2);                           
     Low_CSN;          // 再次使能Spi,可以对SPI进行读写操作
       SpiWrite(WTA);               // 写地址前首先先写地址命令
    for (i=0;i<4;i++)                   // 写 4 bytes 地址
    {
       SpiWrite(TxAddress[i]);
    }
    High_CSN;                              // 关闭Spi
     High_TRX_CE;                 //   905的发送使能有效    ?????这一步是否是多余的呢??因为可以独立写发送函数。
      delayus(2);                             // 等待DR变高,也即发送数据完成
   Low_TRX_CE;                 // 设置TRX_CE=0,发送使能无效
}
//-------------------------------发送模式激发-----------------------------------
void setxmode(void)
{
    Low_TRX_CE;             //  905的发送使能有效
    High_TX_EN;              // 905设置为发送模式
    delayus(3);               // delay for mode change(>=650us)根据晶振不同要改变
}
//--------------主函数----------------------------------------------------------
void main(void)
{      
   
       DDRB=DDRB|BIT(4)|BIT(5)|BIT(7)&(~BIT(6));         //设置AVR的SS,MOSI,SCK为输出,MISO为输入。
       DDRC|=BIT(0);      //置PC0为输出.
       PORTC=0x00;    //端口C初始化.
       DDRD=0xff;           //刚开始时DDRD全为输出,便于system_init函数里把AM,DR,CD初始化为低。
       Spi_initial();
       system_init();
       DDRD=0xe3;      //初始化以后把AM,DR,CD引脚置为输入,开始侦测DR的引脚变化,文档里说数据发送完成后DR会置高。
       Config905();
       delayus(50);
    while(1)
    {
      setxmode();                 //激发发送模式
     txpacket();                  //发送数据打包
     if((PIND&0x04)!=0)                    //如果DR引脚变高,则让小灯闪。
     {
      PORTC|=BIT(0);
       delay(2000);
       PORTC&=~BIT(0);
       delay(2000);
       }     
      }   
      
     
}


接收方代码:

#include <iom16v.h>
#include <macros.h>
#define uint  unsigned int
#define uchar unsigned char
#define   Low_TX_EN      PORTD&=~(1 << PD7)
#define   High_TX_EN     PORTB|= (1 << PD7)
#define   High_TRX_CE    PORTD|= (1 << PD6)  
#define   Low_TRX_CE     PORTD&=~(1 << PD6)
#define   High_PWR       PORTD|= (1 << PD5)
#define   Low_PWR        PORTD&=~(1 << PD5)
//--------------------------------SPI口定义-------------------------------------
#define   High_SCK       PORTB|=(1 << PB7)
#define   Low_SCK        PORTB&=~(1 << PB7)
#define   High_CSN       PORTB|= (1 << PB4)  
#define   Low_CSN        PORTB&=~(1 << PB4)            
#define   High_CD        PORTD|= (1 << PD4)
#define   Low_CD         PORTD&=~(1 << PD4)
#define   High_AM        PORTD|= (1 << PD3)
#define   Low_AM         PORTD&=~(1 << PD3)
#define   High_DR        PORTD |= (1 << PD2)
#define   Low_DR         PORTD &= ~(1 << PD2)
//----------------------------------905-SPI指令---------------------------------
#define WC  0x00
#define RC  0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24                     
uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc };   //发送的地址
uchar RFConf[11]=
{
  0x00,                             //配置命令//
  0x5f,                             //CH_NO,配置频段在915MHZ
  0x0b,                             //输出功率为10db,重发,节电为正常模式
  0x44,                             //地址宽度设置,为4字节
  0x04,0x04,                        //接收发送有效数据长度为4字节
  0xCC,0xCC,0xCC,0xCC,              //接收地址
  0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振,,输出时钟频率为4MHZ,
};
//--------------------------延时函数-------------------------------------------
void delay(uint z)
{
    uint i,j;
    for(i=z;i>0;i--)
      for(j=1714;j>0;j--);
}
void delayus(uint x)
{
    uint i;
    while(x--)
    for(i=0;i<80;i++);
}
//----------------------------------SPI初始化-----------------------------------
void Spi_initial(void)
{
  
    SPCR=0x50;
    SPSR=0x00;
     //SPCR   = (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<SPR0);   // 主机模式,fck/16, SPI方式0
}
//---------------------------------SPI写程序----------------------------------   
uchar SpiWrite(uchar Data)//r
{
    SPDR = Data;
    while(!(SPSR & (1<<SPIF) ))     //SPIF即等于7, 等待SPI发送完毕
      {};         // 等待SPI发送完毕
    return SPDR;
}
//---------------------------------系统状态初始化-------------------------------
void system_init(void)         
{
    High_CSN;            // Spi     disable
    Low_SCK;             // Spi clock line init low
    Low_DR;              // Init DR for input
    Low_AM;              // Init AM for input
    Low_CD;              // Init nrf905_CDfor input
    High_PWR;            // nRF905 power on
    Low_TRX_CE;          // 初始化为空闲模式
    Low_TX_EN ;          // 默认为接收模式
}
//--------------------------------NRF905寄存器初始化函数------------------------
void Config905(void)
{
    uchar i;
    Low_CSN;          //SPI有效
     delayus(2);   
    //SpiWrite(WC);             // Write config command写放配置命令
    for (i=0;i<11;i++)          // Write configration words  写放配置字
    {
     SpiWrite(RFConf[i]);
    }
    High_CSN;                   // 关闭SPI
}
void SetRxMode(void)
{
High_TRX_CE;
  Low_TX_EN;
  delayus(3);
}
//--------------主函数----------------------------------------------------------
void main(void)
{  
     DDRB=DDRB|BIT(4)|BIT(5)|BIT(7)&(~BIT(6));         //设置AVR的SS,MOSI,SCK为输出,MISO为输入。
     DDRC=0xff;
     DDRC=0x00; //设置AVR的PC4为输出,因为PC4接了小灯。
     DDRD=0xff;   //刚开始时DDRD全为输出,便于system_init函数里把AM,DR,CD初始化为低。
      Spi_initial();
      system_init();
      DDRD=0xe3;     //初始化以后把AM,DR,CD引脚置为输入,开始侦测CD和AM的引脚变化,文档里说检测到相同频率的载波后CD引脚会置高,接收到匹配的地址AM会置高
      Config905();
       delayus(50);
      while(1)
     {  
       SetRxMode();
      if((PIND&0x18)!=0)        //如果AM或CD引脚有一个是高,则小灯开始闪。
      PORTC|=BIT(4);
      delay(2000);
     PORTC&=~BIT(4);
     delay(2000);
    }
}

希望高人指点一下,积分或物质方面奖励好商量!!

相关帖子

沙发
qjy_dali| | 2012-7-8 23:32 | 只看该作者
好好看看你这个函数。给奖励吧。。。
//-------------------------------发送模式激发-----------------------------------
void setxmode(void)
{
    Low_TRX_CE;             //  905的发送使能有效
    High_TX_EN;              // 905设置为发送模式
    delayus(3);               // delay for mode change(>=650us)根据晶振不同要改变
}

使用特权

评论回复
板凳
zigbeeTI| | 2012-7-9 11:42 | 只看该作者
我有CC1101的

使用特权

评论回复
地板
darlin520|  楼主 | 2012-7-9 22:09 | 只看该作者
谢谢你们的回复,2楼的大侠,我那个函数没问题的,延时我改过N次了,这里只是准备要发送,在txpacket函数里才真正的发送,我用51的模拟时序调出来了,在这里还是要感谢你!!!

使用特权

评论回复
5
darlin520|  楼主 | 2012-7-9 22:11 | 只看该作者
追问二楼的高手,915MHZ时第一个配置字是多少,我怎么算都和他们的不一样!!

使用特权

评论回复
6
qjy_dali| | 2012-7-10 14:48 | 只看该作者
如果你用915MHz的话,注意HFREQ_PLL那个位,应该设置为“1”。

使用特权

评论回复
7
darlin520|  楼主 | 2012-7-10 22:43 | 只看该作者
大侠呀,我想我是被骗了,我配置成915M时通不了,用433M的能通,里面写的第一,二个字分别是0x28,0x0c,我怎么算也不是这个数,因为HFREQ_PLL是在第二个字的第二位,C的二进制是1100啊,哪来的1啊,真坑爹!!433M和915M有几个电容值是不一样的!!

使用特权

评论回复
8
darlin520|  楼主 | 2012-7-10 22:43 | 只看该作者
大侠呀,我想我是被骗了,我配置成915M时通不了,用433M的能通,里面写的第一,二个字分别是0x28,0x0c,我怎么算也不是这个数,因为HFREQ_PLL是在第二个字的第二位,C的二进制是1100啊,哪来的1啊,真坑爹!!433M和915M有几个电容值是不一样的!!

使用特权

评论回复
9
darlin520|  楼主 | 2012-7-10 22:47 | 只看该作者
那第一第二个字是0x28,0x0c肯定是有问题吧,C不是1100吗,HFREQ_PLL就是0了,坑爹啊,433M与915M的外设电容不是有很大的区别吗,我不会被骗了吧,我算得第一,二个字是0X5f,0X0b啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

107

帖子

0

粉丝