//main.c
//作者:ChanRa1n Myfpga.cn
//转载请写明出自!
#include <STC15F2K60S2.H>
#include <RF.h>
void main()//发送模式
{
unsigned char ucPayload[8]={1,2,3,4,5,6,7,8};
RF_Init(); //在此函数中,应该确保和接收端的通信模式,RF 地址,Channel,发送速率和Payload长度一致。
RF_TxMode();
while(1)
{
switch(ucRF_GetStatus())
{
case TX_DS_FLAG: // 普通型发送完成 或 增强型发送成功
// ...
RF_ClearFIFO();
RF_ClearStatus ();
break;
case REUSE_TX_PL: //发送成功且收到payload
// ...
RF_ClearFIFO();
RF_ClearStatus ();
break;
case MAX_RT_FLAG: // 增强型发送超时失败
// ...
RF_ClearFIFO();
RF_ClearStatus ();
break;
default: // rf 处于空闲状态才发送数据
RF_TxData(ucPayload,PAYLOAD_WIDTH);
break;
}
}
}
void main()//接收模式
{
unsigned char ucPayload[8]={0};
RF_Init();//在此函数中,应该确保和发送端的通信模式,RF 地址,Channel,发送速率和Payload长度一致。
RF_RxMode();
while(1)
{
if(ucRF_DumpRxData(ucPayload, PAYLOAD_WIDTH))
{
//接收成功
}
}
}
//RF.c
#include "RF.H"
#include <intrins.h>
const unsigned char TX_ADDRESS_DEF[5] = {0xcc,0xCC,0xCC,0xCC,0xCC}; //RF 地址:接收端和发送端需一致
//const unsigned char TX_ADDRESS_DEF[5] = {0x4B,0x4E,0x44,0x5A,0x4B}; //RF 地址:接收端和发送端需一致
/******************************************************************************/
// SPI_init
// init spi pin input/out mode
/******************************************************************************/
void SPI_init(void)
{
CSN_HIGH; //CSN PIN output High pulling push
SCK_LOW; //SCK PIN output Low pulling push
SPI_DATA_HIGH; //DATA PIN output DEFAULT High pulling push
}
/******************************************************************************/
// SPI_WW
// SPI Write a byte for write regiest
/******************************************************************************/
void SPI_WW(unsigned char R_REG)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SCK_LOW;
if(R_REG & 0x80)
{
SPI_DATA_HIGH;
}
else
{
SPI_DATA_LOW;
}
R_REG = R_REG << 1;
SCK_HIGH;
}
SCK_LOW;
}
/******************************************************************************/
// RF_WriteReg
// Write Data(1 Byte Address ,1 byte data)
/******************************************************************************/
void RF_WriteReg( unsigned char reg, unsigned char wdata)
{
CSN_LOW;
SPI_WW(reg);
SPI_WW(wdata);
CSN_HIGH;
}
/******************************************************************************/
// RF_WriteBuf
// Write Buffer
/******************************************************************************/
void RF_WriteBuf( unsigned char reg, unsigned char *pBuf, unsigned char length)
{
unsigned char j;
CSN_LOW;
j = 0;
SPI_WW(reg);
for(j = 0;j < length; j++)
{
SPI_WW(pBuf[j]);
}
j = 0;
CSN_HIGH;
}
/******************************************************************************/
// SPI_WR
// SPI Write a byte for read regiset
/******************************************************************************/
void SPI_WR(unsigned char R_REG)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SCK_LOW;
if(R_REG & 0x80)
{
SPI_DATA_HIGH;
}
else
{
SPI_DATA_LOW;
}
R_REG = R_REG << 1;
SCK_HIGH;
}
SPI_DATA_INPUT_MODE;
SCK_LOW;
}
/******************************************************************************/
// ucSPI_Read
// SPI Read BYTE
/******************************************************************************/
unsigned char ucSPI_Read(void)
{
unsigned char i,data1;
data1 = 0;
for(i = 0; i < 8; i++)
{
SCK_LOW;
data1 = data1 << 1;
SCK_HIGH;
if(SPI_DATA_STATUS)
{
data1 |= 0x01;
}
}
SCK_LOW;
return data1;
}
/******************************************************************************/
// ucRF_ReadReg
// Read Data(1 Byte Address ,1 byte data return)
/******************************************************************************/
unsigned char ucRF_ReadReg( unsigned char reg)
{
unsigned char data1;
CSN_LOW;
SPI_WR(reg);
data1 = ucSPI_Read();
SPI_DATA_OUTPUT_MODE;
CSN_HIGH;
return data1;
}
/******************************************************************************/
// RF_ReadBuf
// Read Data(1 Byte Address ,length byte data read)
/******************************************************************************/
void RF_ReadBuf( unsigned char reg, unsigned char *pBuf, unsigned char length)
{
unsigned char byte_ctr;
CSN_LOW;
SPI_WR(reg);
for(byte_ctr=0;byte_ctr<length;byte_ctr++)
pBuf[byte_ctr] = ucSPI_Read();
SPI_DATA_OUTPUT_MODE;
CSN_HIGH;
}
void delay_ms(unsigned char x) //@11.0592MHz
{
unsigned char i, j;
while(x--)
{
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
}
/******************************************************************************/
// RF_TxMode
// Set RF into TX mode
/******************************************************************************/
void RF_TxMode(void)
{
CE_LOW;
RF_WriteReg(W_REGISTER + CONFIG, 0X8E); // 将RF设置成TX模式
delay_ms(10);
CE_HIGH; // Set CE pin high 开始接收数据
delay_ms(10);
}
/******************************************************************************/
// RF_RxMode
// 将RF设置成RX模式,准备接收数据
/******************************************************************************/
void RF_RxMode(void)
{
unsigned char RF_cal_data[] = {0x06,0x37,0x5D};
CE_LOW;
RF_WriteReg(W_REGISTER + CONFIG, 0X8F ); // 将RF设置成RX模式
#if(RF_MODE == RxMode_RTTE)
RF_WriteBuf(W_REGISTER + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
#endif
delay_ms(10);
CE_HIGH; // Set CE pin high 开始接收数据
delay_ms(10);
}
/******************************************************************************/
// RF_GetStatus
// read RF IRQ status,3bits return
/******************************************************************************/
unsigned char ucRF_GetStatus(void)
{
return ucRF_ReadReg(STATUS)&0x70; //读取RF的状态
}
/******************************************************************************/
// ucRF_GetRSSI
// 读取rssi 值
/******************************************************************************/
unsigned char ucRF_GetRSSI(void)
{
return (ucRF_ReadReg(DATAOUT)); //读取RF RSSI
}
/******************************************************************************/
// RF_ClearStatus
// clear RF IRQ
/******************************************************************************/
void RF_ClearStatus(void)
{
RF_WriteReg(W_REGISTER + STATUS,0x70); //清除RF的IRQ标志
}
/******************************************************************************/
// RF_ClearFIFO
// clear RF TX/RX FIFO
/******************************************************************************/
void RF_ClearFIFO(void)
{
RF_WriteReg(FLUSH_TX, 0); //清除RF 的 TX FIFO
RF_WriteReg(FLUSH_RX, 0); //清除RF 的 RX FIFO
}
/******************************************************************************/
// RF_SetChannel
// Set RF TX/RX channel:Channel
/******************************************************************************/
void RF_SetChannel( unsigned char Channel)
{
// CE_LOW;
RF_WriteReg(W_REGISTER + RF_CH, Channel);
}
void delay_10us(unsigned char x) //@11.0592MHz
{
unsigned char i;
while(x--)
{
i = 35;
while (--i);
}
}
/******************************************************************************/
// 发送数据:
// 参数:
// 1. ucPayload:需要发送的数据首地址
// 2. length: 需要发送的数据长度
// length 通常等于 PAYLOAD_WIDTH
/******************************************************************************/
void RF_TxData( unsigned char *ucPayload, unsigned char length)
{
if(0==ucRF_GetStatus()) // rf free status
{
RF_WriteBuf(W_TX_PAYLOAD, ucPayload, length);
// CE_HIGH; //rf entery tx mode start send data
// delay_10us(2); //keep ce high at least 600us
// CE_LOW; //rf entery stb3
delay_ms(2);
ucRF_ReadReg(CONFIG);
delay_10us(2);
}
}
/******************************************************************************/
// ucRF_DumpRxData
// 读出接收到的数据:
// 参数:
// 1. ucPayload:存储读取到的数据的Buffer
// 2. length: 读取的数据长度
// Return:
// 1. 0: 没有接收到数据
// 2. 1: 读取接收到的数据成功
// note: Only use in Rx Mode
// length 通常等于 PAYLOAD_WIDTH
/******************************************************************************/
unsigned char ucRF_DumpRxData( unsigned char *ucPayload, unsigned char length)
{
if(ucRF_GetStatus()&RX_DR_FLAG)
{
// CE_LOW;
RF_ReadBuf(R_RX_PAYLOAD, ucPayload, length); //将接收到的数据读出到ucPayload,且清除rxfifo
RF_ClearFIFO();
RF_ClearStatus (); //清除Status
// CE_HIGH; //继续开始接
return 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// 以下部分与RF通信相关,不建议修改
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
// PN006_Initial
// Initial RF
/******************************************************************************/
void RF_Init(void)
{
#if(DATA_RATE == DR_1M)
unsigned char BB_cal_data[] = {0x0A,0x6D,0x67,0x9C,0x46}; //1M速率配置
unsigned char RF_cal_data[] = {0xF6,0x37,0x5D};
unsigned char RF_cal2_data[] = {0x45,0x21,0xef,0x2C,0x5A,0x50};
unsigned char Dem_cal_data[] = {0x01};
unsigned char Dem_cal2_data[] = {0x0b,0xDF,0x02};
#elif(DATA_RATE == DR_250K)
/*
// unsigned char BB_cal_data[] = {0x0A,0x6D,0x67,0x9C,0x46}; //250K速率配置
unsigned char BB_cal_data[] = {0x0A,0xeD,0x7F,0x9C,0x46};
unsigned char RF_cal_data[] = {0xF6,0x37,0x5D};
unsigned char RF_cal2_data[] = {0xD5,0x21,0xeb,0x2C,0x5A,0x40};
unsigned char Dem_cal_data[] = {0x1e};
unsigned char Dem_cal2_data[] = {0x0b,0xDF,0x02};
*/
unsigned char BB_cal_data[] = { 0x12,0xec,0x6f,0xa1,0x46};
unsigned char RF_cal_data[] = {0xF6,0x37,0x5d};
unsigned char RF_cal2_data[] = {0xd5,0x21,0xeb,0x2c,0x5a,0x40};
unsigned char Dem_cal_data[] = {0x1f};
unsigned char Dem_cal2_data[] = {0x0b,0xdf,0x02};
#endif
SPI_init();
RF_WriteReg(RST_FSPI, 0x5A); //Software Reset
RF_WriteReg(RST_FSPI, 0XA5);
// RF_WriteReg(W_REGISTER + FEATURE, 0x20); // enable Software control ce
if(PAYLOAD_WIDTH <33)
{
RF_WriteReg(W_REGISTER +FEATURE, 0x27); //切换到32byte模式 使能CE
}
else
{
RF_WriteReg(W_REGISTER +FEATURE, 0x38); //切换到64byte模式
}
CE_LOW;
RF_WriteReg(FLUSH_TX, 0); // CLEAR TXFIFO
RF_WriteReg(FLUSH_RX, 0); // CLEAR RXFIFO
RF_WriteReg(W_REGISTER + STATUS, 0x70); // CLEAR STATUS
RF_WriteReg(W_REGISTER + EN_RXADDR, 0x01); // Enable Pipe0
RF_WriteReg(W_REGISTER + SETUP_AW, 0x03); // address witdth is 5 bytes
RF_WriteReg(W_REGISTER + RF_CH, DEFAULT_CHANNEL); // 2478M HZ
RF_WriteReg(W_REGISTER + RX_PW_P0, PAYLOAD_WIDTH); // 8 bytes
RF_WriteBuf(W_REGISTER + TX_ADDR, ( unsigned char*)TX_ADDRESS_DEF, sizeof(TX_ADDRESS_DEF)); // Writes TX_Address to PN006
RF_WriteBuf(W_REGISTER + RX_ADDR_P0,( unsigned char*)TX_ADDRESS_DEF, sizeof(TX_ADDRESS_DEF)); // RX_Addr0 same as TX_Adr for Auto.Ack
RF_WriteBuf(W_REGISTER + BB_CAL, BB_cal_data, sizeof(BB_cal_data));
RF_WriteBuf(W_REGISTER + RF_CAL2, RF_cal2_data, sizeof(RF_cal2_data));
RF_WriteBuf(W_REGISTER + DEM_CAL, Dem_cal_data, sizeof(Dem_cal_data));
RF_WriteBuf(W_REGISTER + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
RF_WriteBuf(W_REGISTER + DEM_CAL2, Dem_cal2_data,sizeof(Dem_cal2_data));
RF_WriteReg(W_REGISTER + DYNPD, 0x00);
RF_WriteReg(W_REGISTER + RF_SETUP, RF_POWER); // 13DBM
#if(TRANSMIT_TYPE == TRANS_ENHANCE_MODE)
RF_WriteReg(W_REGISTER + SETUP_RETR,0x03); // 3 retrans...
RF_WriteReg(W_REGISTER + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
#elif(TRANSMIT_TYPE == TRANS_BURST_MODE)
RF_WriteReg(W_REGISTER + SETUP_RETR,0x00); // Disable retrans...
RF_WriteReg(W_REGISTER + EN_AA, 0x00); // Disable AutoAck
#endif
}
/******************************************************************************/
// 进入载波模式
/******************************************************************************/
void RF_Carrier( unsigned char ucChannel_Set)
{
unsigned char BB_cal_data[] = {0x0A,0x6D,0x67,0x9C,0x46};
unsigned char RF_cal_data[] = {0xF6,0x3B,0x5D};
unsigned char RF_cal2_data[] = {0x45,0x21,0xEF,0x2C,0x5A,0x50};
unsigned char Dem_cal_data[] = {0xE1};
unsigned char Dem_cal2_data[] = {0x0B,0xDF,0x02};
RF_WriteReg(RST_FSPI, 0x5A); //Software Reset
RF_WriteReg(RST_FSPI, 0XA5);
RF_WriteReg(W_REGISTER + FEATURE, 0x20);
CE_LOW;
delay_ms(200);
RF_WriteReg(W_REGISTER + CONFIG, 0X8e);
RF_WriteReg(W_REGISTER + RF_CH, ucChannel_Set); //单载波频点
RF_WriteReg(W_REGISTER + RF_SETUP, RF_POWER); //13dbm
RF_WriteBuf(W_REGISTER + BB_CAL, BB_cal_data, sizeof(BB_cal_data));
RF_WriteBuf(W_REGISTER + RF_CAL2, RF_cal2_data, sizeof(RF_cal2_data));
RF_WriteBuf(W_REGISTER + DEM_CAL, Dem_cal_data, sizeof(Dem_cal_data));
RF_WriteBuf(W_REGISTER + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
RF_WriteBuf(W_REGISTER + DEM_CAL2, Dem_cal2_data,sizeof(Dem_cal2_data));
delay_ms(200);
}
/***************************************end of file ************************************/
//RF.H
#ifndef _RF_PN006_H_
#define _RF_PN006_H_
/******************** Control I/O *****************************/
#include <STC15F2K60S2.H> //根据单片机型号修改
sbit CSN = P1^5;
sbit SCK = P1^4;
sbit DATA = P1^3;
#define HIGH (1)
#define LOW (0)
#define CSN_HIGH (CSN |= HIGH)
#define CSN_LOW (CSN &= LOW)
#define SCK_HIGH (SCK |= HIGH)
#define SCK_LOW (SCK &= LOW)
#define SPI_DATA_HIGH (DATA |= HIGH)
#define SPI_DATA_LOW (DATA &= LOW)
#define SPI_DATA_STATUS (DATA)
#define SPI_DATA_OUTPUT_MODE ;
#define SPI_DATA_INPUT_MODE ;
#define CE_HIGH RF_WriteReg(CE_FSPI_ON, 0)
#define CE_LOW RF_WriteReg(CE_FSPI_OFF, 0)
////////////////////////////////////////////////////////////////////////////////
// 以下为声明部分,不建议修改 //
////////////////////////////////////////////////////////////////////////////////
/********************SPI REGISTER ********************/
#define R_REGISTER 0x00 //SPI read RF data
#define W_REGISTER 0x20 //SPI write RF data
#define R_RX_PAYLOAD 0x61 //Read RX Payload
#define W_TX_PAYLOAD 0xA0 //Write TX Payload
#define FLUSH_TX 0xE1 //Flush RX FIFO
#define FLUSH_RX 0xE2 //Flush TX FIFO
#define REUSE_TX_PL 0xE3 //Reuse TX Payload
#define ACTIVATE 0x50 //ACTIVATE
#define DEACTIVATE 0x50 //DEACTIVATE
#define R_RX_PL_WID 0x60 //Read width of RX data
#define W_ACK_PAYLOAD 0xA8 //Data with ACK
#define W_TX_PAYLOAD_NOACK 0xB0 //TX Payload no ACK Request
#define CE_FSPI_ON 0xFD // CE HIGH
#define CE_FSPI_OFF 0xFC // CE LOW
#define RST_FSPI 0x53 // RESET
#define NOP_N 0xFF
/******************CONTROL REGISTER*******************/
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define DATAOUT 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DEM_CAL 0x19
#define RF_CAL2 0x1A
#define DEM_CAL2 0x1B
#define DYNPD 0x1C
#define FEATURE 0x1D
#define RF_CAL 0x1E
#define BB_CAL 0x1F
/////////////////////////////////////////////////////////////////////////////////////
/*************************CONTROL CMD***********************************************/
#define RF13dBm 0x3F // 13dBm 发射档位功率设置
#define RF10dBm 0X0F // 10dBm
#define RF8dBm 0x15 // 8dbm
#define RF7dBm 0x07 // 7dbm
#define RF5dBm 0x2c // 5dbm
#define RF4dBm 0x06 // 4dbm
#define RF2dBm 0x05 // 2dbm
#define RF0dBm 0X0B // 0dBm
#define RF_3dBm 0x04 // -3dBm
#define RF_6dBm 0x0A // -6dBm
#define RF_10dBm 0x02 // -10dBm
#define RF_18dBm 0x01 // -18dBm
#define RF_30dBm 0x00 // -30dBm
#define DR_1M 0X00 //通信速率 1Mbps
#define DR_2M 0X40 //通信速率 2Mbps
#define DR_250K 0XC0 //通信速率 250Kbps
#define RX_DR_FLAG 0X40 // 接收中断标志位
#define TX_DS_FLAG 0X20 // 发送完成中断标志位
#define RX_TX_CMP_FLAG 0X60 // 发送接收完成中断标志位,ack_payload 模式下使用
#define MAX_RT_FLAG 0X10 // 发送重传超时中断标志位
#define TRANS_ENHANCE_MODE 1 //传输类型增强型
#define TRANS_BURST_MODE 2 //传输类型普通型
#define RxMode 1
#define RxMode_RTTE 2
///////////////////////////////////////////////////////////////////////////////
// 根据用户应用,以下部分可能需要修改 //
///////////////////////////////////////////////////////////////////////////////
/******************* Function declare *******************/
void delay_ms(unsigned char x);
void delay_10us(unsigned char x);
void SPI_WW(unsigned char R_REG);
void RF_WriteReg( unsigned char reg, unsigned char wdata);
void RF_WriteBuf( unsigned char reg, unsigned char *pBuf, unsigned char length);
void SPI_WR(unsigned char R_REG);
unsigned char ucSPI_Read(void);
unsigned char ucRF_ReadReg( unsigned char reg);
void RF_ReadBuf( unsigned char reg, unsigned char *pBuf, unsigned char length);
void RF_TxMode(void);
void RF_RxMode(void);
unsigned char ucRF_GetStatus(void);
unsigned char ucRF_GetRSSI(void);
void RF_ClearStatus(void);
void RF_ClearFIFO(void);
void RF_SetChannel( unsigned char Channel);
void RF_TxData( unsigned char *ucPayload, unsigned char length);
unsigned char ucRF_DumpRxData( unsigned char *ucPayload, unsigned char length);
void RF_Carrier( unsigned char ucChannel_Set);
void RF_Init(void);
/******************Parameter define **********************/
#define DEFAULT_CHANNEL 78 //初始化时的频率: 2478 MHz
#define PAYLOAD_WIDTH 16 //Payload宽度: 8bytes
#define TRANSMIT_TYPE TRANS_BURST_MODE //使用普通型模式 TRANS_BURST_MODE TRANS_ENHANCE_MODE
#define DATA_RATE DR_1M //通信速率1Mbps DR_2M DR_1M DR_250K
#define RF_POWER (RF13dBm |DATA_RATE) //发射功率13dBm
#define RF_MODE RxMode_RTTE // RxMode_RTTE
#endif
/**************************************************************/
/****************************************end of file********************************************/