微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > 用ATMEGA16控制NRF905进行简单的收发,调了一周了,希望哪位大侠能帮俺播开云雾!

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

时间:10-02 整理:3721RD 点击:

发送段代码:

#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);
}
}

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

最好能贴下关键电路,否则谁是编译器帮你分析问题?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top