PIC16f1937 nRF24L01
功能:主機(jī)按一下按鍵,發(fā)送一次數(shù)據(jù),對應(yīng)的LED指示燈會(huì)閃一下;從機(jī)接收到信號后對應(yīng)的LED指示燈會(huì)閃一下;
本文引用地址:http://butianyuan.cn/article/201611/315600.htmHOST:
//#include
#include
//const rom unsigned intCONFIG=0x0101;
#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 KEY RB7
#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 sta=0;//NRF24L01狀態(tài)
/***********************寄存器指令***********************/
#define READ_REG 0X00 //讀寄存器指令
#define WRITE_REG 0X20 //寫寄存器指令
#define RD_RX_PLOAD 0X61 //讀取接收數(shù)據(jù)指令
#define WR_TX_PLOAD 0XA0 //寫待發(fā)數(shù)據(jù)指令
#define FLUSH_TX 0XE1 //清除發(fā)送FIFO指令
#define FLUSH_RX 0XE2 //清除接收FIFO指令
#define REUSE_TX_PL 0XE3 //定義重復(fù)裝載數(shù)據(jù)指令
//#define NOP 0XFF //保留
/***********************寄存器地址***********************/
#define CONFIG 0X00 //配置收發(fā)狀態(tài),CRC校驗(yàn)及收發(fā)響應(yīng)方式
#define EN_AA 0X01 //自動(dòng)應(yīng)答功能設(shè)置
#define EN_RXADDR 0X02 //可用信道設(shè)置
#define SETUP_AW 0X03 //收發(fā)地址寬度設(shè)置
#define SETUP_RETR 0X04 //自動(dòng)重發(fā)功能設(shè)置
#define RF_CH 0X05 //工作頻率設(shè)置
#define RF_SETUP 0X06 //發(fā)送速率,功耗功能設(shè)置
#define STATUS 0X07 //狀態(tài)寄存器
#define OBSERVE_TX 0X08 //發(fā)送監(jiān)測功能
#define CD 0X09 //地址檢測
#define RX_ADDR_P0 0X0A //頻道0接收數(shù)據(jù)地址
#define RX_ADDR_P1 0X0B //頻道1接收數(shù)據(jù)地址
#define RX_ADDR_P2 0X0C //頻道2接收數(shù)據(jù)地址
#define RX_ADDR_P3 0X0D //頻道3接收數(shù)據(jù)地址
#define RX_ADDR_P4 0X0E //頻道4接收數(shù)據(jù)地址
#define RX_ADDR_P5 0X0F //頻道5接收數(shù)據(jù)地址
#define TX_ADDR 0X10 //發(fā)送地址寄存器
#define RX_PW_P0 0x11 // 接收頻道0接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P1 0x12 // 接收頻道1接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P2 0x13 // 接收頻道2接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P3 0x14 // 接收頻道3接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P4 0x15 // 接收頻道4接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P5 0x16 // 接收頻道5接收數(shù)據(jù)有效數(shù)據(jù)長度
#define FIFO_STATUS 0X17 //FIFO棧入棧出狀態(tài)寄存器設(shè)置
#define MAX_RT 0X10 //MAX_RTD在第5位|
#define TX_DS 0X20 //TX_DS在第6位 | 在讀回STATUS時(shí)與其相與,就知道該位是否為1
#define RX_DR 0X40 //RX_DR在第7位 |
void delay(uint16 us)
{
while(us--);
}
/*****************************************************************/
void SpiInit()
{
TRISC=0X20;//設(shè)置RC3/SCK,RC5/SDO為輸出
ANSELE=0X00;
TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
//SSPSTAT=0XC0;
//SSPCON3=0X00;
//SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為FOSC/4
//GIE=1;
//PEIE=1;
CSN=1;
}
/*uint8 SPI_RW(uint8 data)//通過SPI寫一個(gè)字節(jié)
{ uint8 status;
CSN=0;
SSPBUF=data;
while(!BF);//當(dāng)SSPBUF被讀取后BF清0
status=SSPBUF;
SSPIF=0;
CSN=1;
return(status);
}*/
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); // return read byte
}
/*uint8 SPI_Read() //通過SPI讀一個(gè)字節(jié)
{
CSN=0;
SSPBUF=0X00;//讀一個(gè)字節(jié)前必需先寫入一個(gè)字節(jié)
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)//向寄存器寫一個(gè)字節(jié),同時(shí)返回狀態(tài)字
{
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)//向寄存器寫入一個(gè)字符串
{
uint8 status,byte_ctr;
CSN=0;
status=SPI_RW(reg);
for(byte_ctr=0;byte_ctr
SPI_RW(*pBuf++);
}
CSN=1;
return(status);
}
/***************************以上為SPI通訊程序**********************************/
/******************************************************************************/
//發(fā)送模式代碼
void TX_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,0X00);//禁止重發(fā)
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,0X0e);
CE=1;
delay(50000);
}
void Transmit(uint8 *tx_buf)
{
CE=0;
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_RW_Reg(FLUSH_TX,0X00);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
CE=1;
delay(100);
}
void main()
{
uint8 back=100;
OSCCON=0X60;
delay(100);
//TRISA=0X00;
SpiInit();
TRISB=0X80;
KEY=1;
CE=0;
CSN=1;
SCK=0;
IRQ=1;
BACK_LED=0;
//delay(50000);
/* while(1)
{ //back=0x02;
CE=0;
SPI_RW_Reg(WRITE_REG+EN_AA,0X03);
back=SPI_Read(EN_AA);
if(back==0x03)
{
BACK_LED=1;
}
else
{
BACK_LED=0;
}
delay(50000);
}*/
TX_MODE();
Transmit(Tx_Buf);
delay(50000);
sta=SPI_Read(READ_REG+STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
CE=0;
while(1)
{
if(KEY==0)
{
delay(1000);
if(KEY==0)
{
while(KEY==0);
BACK_LED=1;
delay(50000);
BACK_LED=0;
//TX_MODE();
Transmit(Tx_Buf);
delay(50000);
sta=SPI_Read(READ_REG+STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
CE=0;
}
}
}
/*{
delay(100);
sta=SPI_Read(READ_REG+STATUS);
if(sta&TX_DS)
{
BACK_LED=1;
delay(1000);
SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
}
if(sta&MAX_RT)
{
BACK_LED=0;
delay(1000);
SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
}
delay(50000);
BACK_LED=0;
delay(50000);
}*/
}
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狀態(tài)
/***********************寄存器指令***********************/
#define READ_REG 0X00 //讀寄存器指令
#define WRITE_REG 0X20 //寫寄存器指令
#define RD_RX_PLOAD 0X61 //讀取接收數(shù)據(jù)指令
#define WR_TX_PLOAD 0XA0 //寫待發(fā)數(shù)據(jù)指令
#define FLUSH_TX 0XE1 //清除發(fā)送FIFO指令
#define FLUSH_RX 0XE2 //清除接收FIFO指令
#define REUSE_TX_PL 0XE3 //定義重復(fù)裝載數(shù)據(jù)指令
//#define NOP 0XFF //保留
/***********************寄存器地址***********************/
#define CONFIG 0X00 //配置收發(fā)狀態(tài),CRC校驗(yàn)及收發(fā)響應(yīng)方式
#define EN_AA 0X01 //自動(dòng)應(yīng)答功能設(shè)置
#define EN_RXADDR 0X02 //可用信道設(shè)置
#define SETUP_AW 0X03 //收發(fā)地址寬度設(shè)置
#define SETUP_RETR 0X04 //自動(dòng)重發(fā)功能設(shè)置
#define RF_CH 0X05 //工作頻率設(shè)置
#define RF_SETUP 0X06 //發(fā)送速率,功耗功能設(shè)置
#define STATUS 0X07 //狀態(tài)寄存器
#define OBSERVE_TX 0X08 //發(fā)送監(jiān)測功能
#define CD 0X09 //地址檢測
#define RX_ADDR_P0 0X0A //頻道0接收數(shù)據(jù)地址
#define RX_ADDR_P1 0X0B //頻道1接收數(shù)據(jù)地址
#define RX_ADDR_P2 0X0C //頻道2接收數(shù)據(jù)地址
#define RX_ADDR_P3 0X0D //頻道3接收數(shù)據(jù)地址
#define RX_ADDR_P4 0X0E //頻道4接收數(shù)據(jù)地址
#define RX_ADDR_P5 0X0F //頻道5接收數(shù)據(jù)地址
#define TX_ADDR 0X10 //發(fā)送地址寄存器
#define RX_PW_P0 0x11 // 接收頻道0接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P1 0x12 // 接收頻道1接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P2 0x13 // 接收頻道2接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P3 0x14 // 接收頻道3接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P4 0x15 // 接收頻道4接收數(shù)據(jù)有效數(shù)據(jù)長度
#define RX_PW_P5 0x16 // 接收頻道5接收數(shù)據(jù)有效數(shù)據(jù)長度
#define FIFO_STATUS 0X17 //FIFO棧入棧出狀態(tài)寄存器設(shè)置
#define MAX_RT 0X10 //MAX_RTD在第5位|
#define TX_DS 0X20 //TX_DS在第6位 | 在讀回STATUS時(shí)與其相與,就知道該位是否為1
#define RX_DR 0X40 //RX_DR在第7位 |
void delay(uint16 us)//延時(shí)函數(shù)
{
while(us--);
}
/*****************************************************************/
/*void SpiInit()
{
TRISC=0XD7;//設(shè)置RC3/SCK,RC5/SDO為輸出
TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
SSPSTAT=0XC0;
SSPCON3=0X00;
SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為FOSC/4
GIE=1;
PEIE=1;
CSN=1;
}
uint8 SPI_RW(uint8 data)//通過SPI寫一個(gè)字節(jié)
{ uint8 status;
CSN=0;
SSPBUF=data;
while(!BF);//當(dāng)SSPBUF被讀取后BF清0
status=SSPBUF;
SSPIF=0;
CSN=1;
return(status);
}*/
void SpiInit()
{
TRISC=0X20;//設(shè)置RC3/SCK,RC5/SDO為輸出
ANSELE=0X00;
TRISE=0X01;//IRQ為輸入,CE,CSN為輸出
//SSPSTAT=0XC0;
//SSPCON3=0X00;
//SSPCON1=0X20; //CKE=1,CKP=0;主模式,時(shí)鐘為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讀一個(gè)字節(jié)
{
CSN=0;
SSPBUF=0X00;//讀一個(gè)字節(jié)前必需先寫入一個(gè)字節(jié)
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)//向寄存器寫一個(gè)字節(jié),同時(shí)返回狀態(tài)字
{
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)//向寄存器寫入一個(gè)字符串
{
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);
}
}
}
評論