class nRFObj{ public: nRFObj(void);//nRFObj的构造函数 void Init(void);//初始化 void ReceiveCallback(void);//接收无线回调函数 void SendCallback(void);//发送无线回调函数 private: void SpiInit(void);//SPI接口初始化 void nRFInit(void);//RF模块初始化 unsigned char SpiReadWrite(unsigned char);//SPI一体化读写程序 unsigned char ReadStatus(void);//读RF模块状态 void SetConfig(unsigned long);//配置nRF905 void SetReceiveMode(void);//设置接收模式 void SetSendMode(void);//设置发送模式 void SendStart(void);//开始发送 public: unsigned char ReceiveBuffer[32];//RF接收缓冲区 unsigned char SendBuffer[32];//RF发送缓冲区 unsigned char ReceiveCount;//RF接收缓冲区接收个数 unsigned char SendCount;//RF发送缓冲区发送个数 };
nRFObj::nRFObj(void) { Init (); }
void nRFObj::Init(void) { SpiInit (); nRFInit (); }
void nRFObj::nRFInit(void) { PORTC |= (0 << TX_EN)//设置接收方式 |(0 << TRX_CE)//设置nRF905为待机方式 |(1 << PWR)//nRF905上电 |(0 << UPLCK); PORTD |= (0 << CD) |(0 << DR) |(0 << AM);
DDRC |= (1 << TX_EN) |(1 << TRX_CE) |(1 << PWR) |(0 << UPLCK);
EICRA = (0 << ISC11) |(1 << ISC10) |(0 << ISC01) |(1 << ISC00); EIMSK = (1 << INT1) | (1 << INT0); SetConfig(0); SetReceiveMode();//设置接收模式 for (int i = 0; i < 32; i ++) { SendBuffer = 0; ReceiveBuffer = 0; } }
void nRFObj::SpiInit(void) { /* 设置MOSI 和SCK 及SS 为输出,其他为输入 */ PORTB |= (1 << MOSI) |(1 << MISO) |(1 << SCK) |(1 << SS);//关闭SPI DDRB |= (1 << MOSI) |(1 << MISO) |(1 << SCK) |(1 << SS); /* 使能SPI 主机模式,设置时钟速率为fck/16 ,SPI方式0*/ SPCR = (1 << SPE) |(1 << MSTR) |(0 << CPOL) |(0 << SPR0); }
unsigned char nRFObj::SpiReadWrite(unsigned char cData) { /* 启动数据传输 */ SPDR = cData; /* 等待传输结束 */ while(!(SPSR & (1 << SPIF))) { // __watchdog_reset (); } return SPDR; }
unsigned char nRFObj::ReadStatus(void) { unsigned char val; PORTB &= ~(1 << SS);//打开SPI val = SpiReadWrite(RC);//读状态 PORTB |= (1 << SS);//关闭SPI return val;//返回nRF905状态字 }
void nRFObj::SetSendMode(void)//设置发送模式 { __nop();/// __nop();/// __nop();/// PORTC |= (1 << TX_EN); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); PORTC &= ~(1 << TRX_CE);//设置nRF905为待机方式 __delay_cycles(1000); }
void nRFObj::SetReceiveMode(void)//设置接收模式 { __nop(); __nop(); __nop(); PORTC &= ~(1 << TX_EN); __nop(); PORTC |= (1 << TRX_CE);//设置nRF905为工作方式 __nop(); __nop(); __nop(); }
void nRFObj::SendStart(void) { __nop(); __nop(); __nop(); /// _delay_loop_(1); PORTC |= (1 << TRX_CE);//设置nRF905为工作方式 /// _delay_loop_(10); __nop(); __nop(); __nop(); /* __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); */ PORTC &= ~(1 << TRX_CE);//设置nRF905为待机方式 /// _delay_loop_(1); __nop(); __nop(); __nop(); }
void nRFObj::SetConfig(unsigned long nRFAddr)//配置nRF905 { PORTC &= ~(1 << TRX_CE);//设置nRF905为待机方式 __nop(); PORTB &= ~(1 << SS);//打开SPI SpiReadWrite(WC); // Write config command SpiReadWrite(CH_NO_BYTE); //中心频率低8位 SpiReadWrite(PA_PWR_10dBm | HFREQ_PLL_433MHz); //发射+10dBm,发射频率433MHz,中心频率第9位=0 SpiReadWrite(TX_AFW_4BYTE | RX_AFW_4BYTE); //接收地址宽度4字节,发送地址宽度4字节 SpiReadWrite(RX_PW_32BYTE); //接收数据宽度32字节 SpiReadWrite(TX_PW_32BYTE); //发送数据宽度32字节 SpiReadWrite((nRFAddr >> 24)); //接收有效地址第1字节 SpiReadWrite((nRFAddr >> 16) & 0xff); //接收有效地址第2字节 SpiReadWrite((nRFAddr >> 8) & 0xff); //接收有效地址第3字节 SpiReadWrite(nRFAddr & 0xff); //接收有效地址第4字节 SpiReadWrite(CRC16_EN | XOF_16MHz); //CRC16模式使能,晶体振荡器频率16MHz PORTB |= (1 << SS);//关闭SPI if (PORTC & (1 << TX_EN))//再回到原来的无线收发模式 { PORTC &= ~(1 << TRX_CE);//设置nRF905为待机方式 } else { PORTC |= (1 << TRX_CE);//设置nRF905为工作方式 } }
void nRFObj::ReceiveCallback(void)//无线接收模块 { SetReceiveMode();//设置接收模式 if ((PIND & (1 << CD))//接收到CD信号 && ((PIND & ((1 << AM) | (1 << DR))) == 0))//此时不应该有AM和DR信号 { PORTC &= ~(1 << TRX_CE);//设置nRF905为待机方式 __nop(); PORTB &= ~(1 << SS);//打开SPI SpiReadWrite(RRP); for (int i = 0; i < 32; i ++) { ReceiveBuffer = SpiReadWrite(0xff); } PORTB |= (1 << SS);//关闭SPI ReceiveCount = 32;//接收到32个字节的数据 PORTC |= (1 << TRX_CE);//设置nRF905为工作方式 // if ((ReceiveBuffer[30] == 0x55) && (ReceiveBuffer[31] == 0xaa)) // if (ReceiveBuffer[31] == 0xaa) // { PORTB |= (1 << BUZZER); PORTB |= (1 << LED); // } } }
void nRFObj::SendCallback(void)//无线发送模块 { if ((PIND & ((1 << CD) | (1 <<AM) | (1 << DR))) == 0)//周边无射频信号 { SetSendMode();//设置发送模式 PORTB |= (1 << LED); __nop(); __nop(); __nop(); PORTB &= ~(1 << SS);//打开SPI SpiReadWrite(WTA);//写发送地址 for (int i = 0; i < 4; i ++) { SpiReadWrite(SendBuffer); } PORTB |= (1 << SS);//关闭SPI __nop(); __nop(); __nop(); PORTB &= ~(1 << SS);//打开SPI SendBuffer[30] = 0x55; SendBuffer[31] = 0xaa; SpiReadWrite(WTP);// Write payload command for (int i = 0; i < 32; i ++) { SpiReadWrite(SendBuffer); } PORTB |= (1 << SS);//关闭SPI SendCount = 32;//接收到32个字节的数据 SendStart();//开始发送 SetReceiveMode();//设置接收模式 PORTB &= ~(1 << LED); } }
//以下是nRF905.h
#define RX_ADDRESS 0x00000000 //接收有效地址(本方) #define TX_ADDRESS 0x12345678 //发送有效地址(对方)
#define CH_NO_FREQ_422_4MHz 0x000 //工作频率422.4MHz(433MHz频段最低频率) #define CH_NO_FREQ_422_5MHz 0x001 //工作频率422.5MHz #define CH_NO_FREQ_425_0MHz 0x01a //工作频率425.0MHz #define CH_NO_FREQ_427_5MHz 0x033 //工作频率427.5MHz
#define CH_NO_FREQ_430_0MHz 0x04c //工作频率430.0MHz #define CH_NO_FREQ_433_0MHz 0x06a //工作频率433.0MHz(433MHz频段基准频率) #define CH_NO_FREQ_433_1MHz 0x06b //工作频率433.1MHz #define CH_NO_FREQ_433_2MHz 0x06c //工作频率433.2MHz #define CH_NO_FREQ_434_7MHz 0x07b //工作频率434.7MHz #define CH_NO_FREQ_473_5MHz 0x1ff //工作频率473.5MHz(433MHz频段最高频率)
#define CH_NO_FREQ_844_8MHz 0x000 //工作频率844.8MHz(868MHz频段最低频率)
#define CH_NO_FREQ_862_0MHz 0x056 //工作频率862.0MHz #define CH_NO_FREQ_868_0MHz 0x074 //工作频率868.0MHz(868MHz频段基准频率) #define CH_NO_FREQ_868_2MHz 0x075 //工作频率868.2MHz #define CH_NO_FREQ_868_4MHz 0x076 //工作频率868.4MHz #define CH_NO_FREQ_869_8MHz 0x07d //工作频率869.8MHz #define CH_NO_FREQ_895_8MHz 0x0ff //工作频率895.8MHz #define CH_NO_FREQ_896_0MHz 0x100 //工作频率896.0MHz #define CH_NO_FREQ_900_0MHz 0x114 //工作频率900.0MHz #define CH_NO_FREQ_902_2MHz 0x11f //工作频率902.2MHz #define CH_NO_FREQ_902_4MHz 0x120 //工作频率902.4MHz #define CH_NO_FREQ_915_0MHz 0x15f //工作频率915.0MHz(915MHz频段基准频率) #define CH_NO_FREQ_927_8MHz 0x19f //工作频率927.8MHz
#define CH_NO_FREQ_947_0MHz 0x1ff //工作频率947.0MHz(915MHz频段最高频率)
#define CH_NO_FREQ CH_NO_FREQ_430_0MHz //工作频率433.0MHz //#define CH_NO_FREQ CH_NO_FREQ_844_8MHz //工作频率433.0MHz
#define CH_NO_BYTE CH_NO_FREQ & 0xff //工作频率低8位 Byte0 01101100
#define AUTO_RETRAN 0x20 //重发数据包 Byte1.5 0 #define RX_RED_PWR 0x10 //接收低功耗模式 Byte1.4 0 #define PA_PWR__10dBm 0x00 //输出功率-10dBm Byte1.3~2 00 #define PA_PWR_2dBm 0x04 //输出功率+2dBm Byte1.3~2 #define PA_PWR_6dBm 0x08 //输出功率+6dBm Byte1.3~2 #define PA_PWR_10dBm 0x0c //输出功率+10dBm Byte1.3~2 #define HFREQ_PLL_433MHz 0x00 //工作在433MHz频段 Byte1.1 0 #define HFREQ_PLL_868MHz 0x02 //工作在868MHz频段 Byte1.1 #define HFREQ_PLL_915MHz 0x02 //工作在915MHz频段 Byte1.1 #define CH_NO_BIT8 CH_NO_FREQ >> 8 //工作频率第9位 Byte1.0 0
#define TX_AFW_1BYTE 1 * 16 //发送地址宽度1字节 Byte2.7~4 #define TX_AFW_2BYTE 2 * 16 //发送地址宽度2字节 Byte2.7~4 #define TX_AFW_3BYTE 3 * 16 //发送地址宽度3字节 Byte2.7~4 #define TX_AFW_4BYTE 4 * 16 //发送地址宽度4字节 Byte2.7~4 100 #define RX_AFW_1BYTE 1 //接收地址宽度1字节 Byte2.3~0 #define RX_AFW_2BYTE 2 //接收地址宽度2字节 Byte2.3~0 #define RX_AFW_3BYTE 3 //接收地址宽度3字节 Byte2.3~0 #define RX_AFW_4BYTE 4 //接收地址宽度4字节 Byte2.3~0 100
#define RX_PW_1BYTE 1 //接收数据宽度1字节 Byte3.5~0 #define RX_PW_32BYTE 32 //接收数据宽度32字节 Byte3.5~0 00100000 #define TX_PW_1BYTE 1 //发送数据宽度1字节 Byte4.5~0 #define TX_PW_32BYTE 32 //发送数据宽度32字节 Byte4.5~0 00100000 #define RX_ADDRESS_0 RX_ADDRESS >> 24 //接收有效地址第1字节 Byte5 11100111 #define RX_ADDRESS_1 (RX_ADDRESS >> 16) & 0xff //接收有效地址第2字节 Byte6 11100111 #define RX_ADDRESS_2 (RX_ADDRESS >> 8) & 0xff //接收有效地址第3字节 Byte7 11100111 #define RX_ADDRESS_3 RX_ADDRESS & 0xff //接收有效地址第4字节 Byte8 11100111
#define CRC_MODE_16BIT 0x80 //CRC16模式 Byte9.7 1 #define CRC_MODE_8BIT 0x00 //CRC8模式 Byte9.7 #define CRC_EN 0x40 //CRC使能 Byte9.6 1 #define CRC16_EN 0xc0 //CRC16模式使能 Byte9.7~6 11 #define CRC8_EN 0x40 //CRC8模式使能 Byte9.7~6 #define XOF_20MHz 0x20 //晶体振荡器频率20MHz Byte9.5~3 #define XOF_16MHz 0x18 //晶体振荡器频率16MHz Byte9.5~3 100 #define XOF_12MHz 0x10 //晶体振荡器频率12MHz Byte9.5~3 #define XOF_8MHz 0x08 //晶体振荡器频率8MHz Byte9.5~3 #define XOF_4MHz 0x00 //晶体振荡器频率4MHz Byte9.5~3 #define UP_CLK_EN 0x40 //输出时钟使能 Byte9.2 1 #define UP_CLK_FREQ_500kHz 0x03 //输出时钟频率500kHz Byte9.1~0 11 #define UP_CLK_FREQ_1MHz 0x02 //输出时钟频率1MHz Byte9.1~0 #define UP_CLK_FREQ_2MHz 0x01 //输出时钟频率2MHz Byte9.1~0 #define UP_CLK_FREQ_4MHz 0x00 //输出时钟频率4MHz Byte9.1~0
#define UP_CLK_EN_500kHz 0x43 //输出时钟频率500kHz Byte9.2~0 111 #define UP_CLK_EN_1MHz 0x42 //输出时钟频率1MHz Byte9.2~0 #define UP_CLK_EN_2MHz 0x41 //输出时钟频率2MHz Byte9.2~0 #define UP_CLK_EN_4MHz 0x40 //输出时钟频率4MHz Byte9.2~0
#define TX_ADDRESS_0 TX_ADDRESS >> 24 //发送有效地址第1字节 #define TX_ADDRESS_1 (TX_ADDRESS >> 16) & 0xff //发送有效地址第2字节 #define TX_ADDRESS_2 (TX_ADDRESS >> 8) & 0xff //发送有效地址第3字节 #define TX_ADDRESS_3 TX_ADDRESS & 0xff //发送有效地址第4字节
/*----------------------------------------------- nrf905命令控制字 ------------------------------------------------*/ #define WC 0x00 // Write configuration register command #define RC 0x10 // Read configuration register command #define WTP 0x20 // Write TX Payload command #define RTP 0x21 // Read TX Payload command #define WTA 0x22 // Write TX Address command #define RTA 0x23 // Read TX Address command #define RRP 0x24 // Read RX Payload command
//PORTB #define BUZZER 0 #define LED 1 #define SS 2 #define MOSI 3 #define MISO 4 #define SCK 5
//PORTC #define TX_EN 0 #define TRX_CE 1 #define PWR 2 #define UPLCK 3
//PORTD #define CD 2 #define DR 3 #define AM 4
|