功能:主机按一下按键,发送一次数据,对应的LED指示灯会闪一下;从机接收到信号后对应的LED指示灯会闪一下;
HOST:
//#include
#include
//const rom unsigned int CONFIG=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状态
/***********************寄存器指令***********************/
#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=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 data)//通过SPI写一个字节
{ uint8 status;
CSN=0;
SSPBUF=data;
while(!BF);//当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读一个字节
{
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 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);//禁止重发
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状态
/***********************寄存器指令***********************/
#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);
}
}
}
上一篇:PICC编程的位操作示例程序
下一篇:PIC 寄存器不能赋值问题
推荐阅读最新更新时间:2024-03-16 15:11
设计资源 培训 开发板 精华推荐
- 【XILINX 主题分享月】 设计工具资料大搜集!!!
- 有奖直播【如何在几分钟之内完成高效可靠的USB PD电源设计——PI Expert™分步教程】(9:30开始入场)
- 阅1SP0350V SCALE-2单通道即插即用型门极驱动器,参与PI答题享好礼!
- 瑞萨电子RL78/G14 demo板低价开团 19.9元包邮
- TE有奖直播:未来感知 由我先知-传感器在物联网中的最新应用
- TI 工业知识挑战赛开启,一起争霸前20强,赢取属于你的荣耀!
- Microchip电源评估板促销,还有红包送!
- 有奖直播|是德科技感恩月—遇见KeysightCare - 贵重仪器安全避坑指南
- 模电怎么学?TI帮你定制课程清单!体验“模电选课测试”功能,赢精彩好礼
- TE Connectivity 小有乾坤蕴藏无限可能