[讨论] 用ATMEGA16控制NRF905进行简单的收发,调了一周了,希望哪位大侠能帮俺播开云雾!!

darlin520   2012-7-4 18:15 楼主

发送段代码:

 

#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);
    }
    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);      // 待发送的4字节数据
       }           
     High_CSN;         // 关闭Spi,不允许对nrf905进行读写操作
       delayus(2);                          
     Low_CSN;          // 再次使能Spi,可以对SPI进行读写操作
       SpiWrite(WTA);               // 写地址前首先先写地址命令
    for (i=0;i<4;i++)                   // 写 4 bytes 地址
    {
       SpiWrite(TxAddress);
    }
    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);
    }
    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);
    }
}

 

哪位用过此模块的高手帮帮小弟吧。

回复评论 (1)

最好能贴下关键电路,否则谁是编译器帮你分析问题?
点赞  2013-2-20 10:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复