PIC16f1937 nRF24L01
SLAVE:
//#include
#include
#define uint8 unsigned char
#define uint16 unsigned int
__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF
&BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF);
__CONFIG(WRT_OFF&VCAPEN_OFF&PLLEN_OFF&STVREN_OFF&BORV_19&LVP_OFF);
#define CSN RE1
#define IRQ RE0
#define CE RE2
#define MOSI RC4
#define MISO RC5
#define SCK RC3
#define BACK_LED RC1
#define TX_ADR_WIDTH 5
#define RX_ADR_WIDTH 5
#define RX_PLOAD_WIDTH 32
#define TX_PLOAD_WIDTH 32
uint8 TX_ADDRESS[TX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 RX_ADDRESS[RX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,
0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb
,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};
uint8 Rx_Buf[RX_PLOAD_WIDTH];
uint8 sta=0;//NRF24L01状态
/***********************寄存器指令***********************/
#define READ_REG 0X00 //读寄存器指令
#define WRITE_REG 0X20 //写寄存器指令
#define RD_RX_PLOAD 0X61 //读取接收数据指令
#define WR_TX_PLOAD 0XA0 //写待发数据指令
#define FLUSH_TX 0XE1 //清除发送FIFO指令
#define FLUSH_RX 0XE2 //清除接收FIFO指令
#define REUSE_TX_PL 0XE3 //定义重复装载数据指令
//#define NOP 0XFF //保留
/***********************寄存器地址***********************/
#define CONFIG 0X00 //配置收发状态,CRC校验及收发响应方式
#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 CD 0X09 //地址检测
#define RX_ADDR_P0 0X0A //频道0接收数据地址
#define RX_ADDR_P1 0X0B //频道1接收数据地址
#define RX_ADDR_P2 0X0C //频道2接收数据地址
#define RX_ADDR_P3 0X0D //频道3接收数据地址
#define RX_ADDR_P4 0X0E //频道4接收数据地址
#define RX_ADDR_P5 0X0F //频道5接收数据地址
#define TX_ADDR 0X10 //发送地址寄存器
#define RX_PW_P0 0x11 // 接收频道0接收数据有效数据长度
#define RX_PW_P1 0x12 // 接收频道1接收数据有效数据长度
#define RX_PW_P2 0x13 // 接收频道2接收数据有效数据长度
#define RX_PW_P3 0x14 // 接收频道3接收数据有效数据长度
#define RX_PW_P4 0x15 // 接收频道4接收数据有效数据长度
#define RX_PW_P5 0x16 // 接收频道5接收数据有效数据长度
#define FIFO_STATUS 0X17 //FIFO栈入栈出状态寄存器设置
#define MAX_RT 0X10 //MAX_RTD在第5位|
#define TX_DS 0X20 //TX_DS在第6位 | 在读回STATUS时与其相与,就知道该位是否为1
#define RX_DR 0X40 //RX_DR在第7位 |
void delay(uint16 us)//延时函数
{
while(us--);
}
/*****************************************************************/
/*void SpiInit()
{
TRISC=0XD7;//设置RC3/SCK,RC5/SDO为输出
TRISE=0X01;//IRQ为输入,CE,CSN为输出
SSPSTAT=0XC0;
SSPCON3=0X00;
SSPCON1=0X20; //CKE=1,CKP=0;主模式,时钟为FOSC/4
GIE=1;
PEIE=1;
CSN=1;
}
uint8 SPI_RW(uint8 data)//通过SPI写一个字节
{ uint8 status;
CSN=0;
SSPBUF=data;
while(!BF);//当SSPBUF被读取后BF清0
status=SSPBUF;
SSPIF=0;
CSN=1;
return(status);
}*/
void SpiInit()
{
TRISC=0X20;//设置RC3/SCK,RC5/SDO为输出
ANSELE=0X00;
TRISE=0X01;//IRQ为输入,CE,CSN为输出
//SSPSTAT=0XC0;
//SSPCON3=0X00;
//SSPCON1=0X20; //CKE=1,CKP=0;主模式,时钟为FOSC/4
//GIE=1;
//PEIE=1;
CSN=1;
}
uint8 SPI_RW(uint8 byte)
{
uint8 bit_ctr;
//DI();
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
if(byte & 0x80)
MOSI = 1;
else
MOSI = 0;
byte = (byte < 1); // shift next bit into MSB..
SCK = 1; // Set nRF24L01_SCK high..
if(MISO) byte |= 1;
NOP();NOP();NOP();NOP();
SCK = 0; // ..then set nRF24L01_SCK low again
NOP();NOP();NOP();NOP();
}
//EI();
return(byte);
}
/*uint8 SPI_Read() //通过SPI读一个字节
{
CSN=0;
SSPBUF=0X00;//读一个字节前必需先写入一个字节
while(!BF);
CSN=1;
return(SSPBUF);
}*/
uint8 SPI_Read(uint8 reg)
{
uint8 reg_val;
CSN=0;
SPI_RW(reg);
reg_val=SPI_RW(0);
CSN=1;
return(reg_val);
}
uint8 SPI_RW_Reg(uint8 reg,uint8 value)//向寄存器写一个字节,同时返回状态字
{
uint8 status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
}
uint8 SPI_Write_Buf(uint8 reg,uint8 *pBuf,uint8 bytes)//向寄存器写入一个字符串
{
uint8 status,byte_ctr;
CSN=0;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr
SPI_RW(*pBuf++);
}
CSN=1;
return(status);
}
/***************************以上为SPI通讯程序**********************************/
/******************************************************************************/
//接收模式代码
void RX_MODE(void)
{
CE=0;
SPI_RW_Reg(FLUSH_TX,0X00);
//SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
//SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1a);
SPI_RW_Reg(WRITE_REG+RF_CH,40);
SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+CONFIG,0X0f);
CE=1;
delay(50000);
}
uint8 SPI_Read_Buf(uint8 reg,uint8 *pBuf,uint8 uchars)
{
uint8 status,uchar_ctr;
CSN=0;
status=SPI_RW(reg);
for(uchar_ctr=0;uchar_ctr
pBuf[uchar_ctr]=SPI_RW(0);
}
CSN=1;
return(status);
}
uint8 nRF24l01_RxPacket(uint8 *rx_buf)
{
uint8 revale=0;
sta=SPI_Read(STATUS);
if(sta&RX_DR)
{
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);
revale=1;
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);
return(revale);
}
void main()
{
uint8 recv=0;
//delay(1);
//TRISA=0X00;
OSCCON=0X60;//set clock
delay(100);
SpiInit();
CE=0;
CSN=1;
SCK=0;
IRQ=1;
BACK_LED=0;
RX_MODE();
while(1)
{
if(nRF24l01_RxPacket(Rx_Buf))
{
//PORTA=0XFE;
BACK_LED=1;
delay(50000);
BACK_LED=0;
delay(30);
}
}
}
PIC16f1937nRF24L0 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)