NRF24L01多路通讯调试成功的关键__附程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

NRF24L01多路通讯调试成功的关键
(附基于串口助手的无线通讯工具源代码)
本文档部分内容摘自网络,由于按照网上教程调试总不成功,特此分享自己
的失败经验(红字加重)。

一、收发端共同的设置
1、设置信道工作频率(收发必须一致)如:SPI_RW_Reg(WRITE_REG+RF_CH,40);
2、设置发射速率(2mbps或1mbps)和发射功率(收发必须一致);
如:SPI_RW_Reg(WRITE_REG+RF_SETUP,0x0f); //发射速率为2Mbps,发射功率
最大为0dB
二、接收端的设置(最关键)
1、设置频道0-5,自动ACK应答允许
如: SPI_RW_Reg(WRITE_REG+EN_AA,0x3f);
2、设置接收通道全部允许
如: SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x3f);
3、向发送地址寄存器写入本地地址(5byte)
4、向各个频道的接收地址寄存器写入接收地址(调试成不成功的关键)
频道0:5个字节的地址
频道1:5个字节的地址(和频道0的地址必须不同)
频道2:1个字节的地址(为该通道发射机地址的最后一个字节·)
有一个配置为发射模式的24l01要通过该通道与接收机通信,发射机的本地地址
为{0x37,0xa1,0xb3,0xc9,0xda};则接收机频道2的地址为(0x37)
频道3:1个字节的地址(同上)
频道4:1个字节的地址(同上)
频道5:1个字节的地址(同上)
5、向每个频道(用那个写那个,需要在上面配置允许通道接收和ack·)接收数
据长度寄存器写入接收数据宽度(最快均为32)
频道n:SPI_RW_Reg(WRITE_REG + RX_PW_Pn, RX_PLOAD_WIDTH);
如:
频道5:SPI_RW_Reg(WRITE_REG + RX_PW_P5, RX_PLOAD_WIDTH);
6、配置为接收模式
如:
SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);
下面附上我的程序
/***************************头文件******************************/
#ifndef __NRF24L01_H__
#define __NRF24L01_H__
sbit CE = P1^2;
sbit CSN = P1^3;
sbit IRQ = P1^4;
sbit MOSI = P1^5;
sbit MISO = P1^6;
sbit SCK = P1^7;
void NRF24L01_init(); //初始化模块
ucharTX_packet(uchar *tx_buf); //返回值判断是否成功
ucharRX_packet(uchar *rx_buf); //返回值判断是否成功
void TX_MODE(); //发送模式
void RX_MODE(); //接收模式
//****************************************************************//
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
//***************************************************//
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address #define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address #define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address #define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address #define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
//***************************************************************//
#endif
/*********************************程序***********************************/ #include<reg52.h>
#include"define.h"
#include"DELAY.h"
#include"NRF24L01.h"
uchar code TX_ADDRESS[5] = {0,1,1,1,1};
uchar code RX_ADDRESS_P0[5] = {0,1,1,1,1};
uchar code RX_ADDRESS_P1[5] = {1,1,1,1,1};
uchar code RX_ADDRESS_P2[1] = {2};
uchar code RX_ADDRESS_P3[1] = {3};
uchar code RX_ADDRESS_P4[1] = {4};
uchar code RX_ADDRESS_P5[1] = {5};
uchar code Data_width = 1;
uchar code Data_rt = 15;
uchar SPI_RW(uchardat) // SPI读写指令
{
uchar i;
for(i=0;i<8;i++)
{
SCK = 0;
MOSI = (dat&0x80);
dat<<= 1;
SCK = 1;
dat |= MISO;
}
SCK = 0;
returndat;
}
uchar NRF24L01_read_reg(ucharreg) //读某个寄存器的状态
{
uchar value;
CSN=0; //拉低CSN,允许操作
SPI_RW(reg); //写寄存器指令
value = SPI_RW(0); //读寄存器值
CSN=1; //拉高CSN,禁止操作
return value; //返回寄存器状态
}
uchar NRF24L01_write_reg(ucharreg,uchar value) //写向某个寄存器写指令,并读出状态
{
uchar status;
CSN=0; //拉低CSN,允许操作
status = SPI_RW(reg); //写寄存器指令,并读出寄存器状态
SPI_RW(value); //写寄存器值
CSN=1; //拉高CSN,禁止操作
return status; //返回寄存器之前的值
}
uchar NRF24L01_read_buf(ucharreg,uchar *pbuf,uchar n)
{
uchari,status;
CSN=0; //拉低CSN,允许操作
status = SPI_RW(reg); //写寄存器指令,并读出寄存器状态
for(i=0;i<n;i++)
pbuf[i] = SPI_RW(0);//从寄存器读出一字节数据
CSN = 1; //拉高CSN,禁止操作
return status;
}
uchar NRF24L01_write_buf(ucharreg,uchar *pbuf,uchar n)
{
uchari,status;
CSN=0; //拉低CSN,允许操作
status = SPI_RW(reg); //写寄存器指令,并读出寄存器状态
for(i=0;i<n;i++)
SPI_RW(pbuf[i]); //写一字节数据到寄存器
CSN = 1; //拉高CSN,禁止操作
return status;
}
void NRF24L01_init()
{
CE = 0; //射频电路工作使能,高电平工作,低电平停止
CSN = 1; //SPI操作高电平允许,低电平禁止
SCK = 0; //时钟拉低,禁止读写寄存器
IRQ = 1; //中断复位,等待产生中断信号
NRF24L01_write_reg(WRITE_REG + EN_AA, 0x3f); //所有接受通道允许自动应答
NRF24L01_write_reg(WRITE_REG + EN_RXADDR, 0x3f); //接收通道全部打开
NRF24L01_write_reg(WRITE_REG + SETUP_AW, 0x03); //设置接收/发射地址宽度为5字节
NRF24L01_write_reg(WRITE_REG + SETUP_RETR, Data_rt); //自动发送间隔250+86us,次数15
NRF24L01_write_reg(WRITE_REG + RF_CH, 0x00); //设置信道工作为2.4Ghz,收发必须一致
NRF24L01_write_reg(WRITE_REG + RX_PW_P0, Data_width); //设置通道0数据字节数
NRF24L01_write_reg(WRITE_REG + RX_PW_P1, Data_width); //设置通道1数据字节数
NRF24L01_write_reg(WRITE_REG + RX_PW_P2, Data_width); //设置通道2数据字节数
NRF24L01_write_reg(WRITE_REG + RX_PW_P3, Data_width); //设置通道3数据字节数
NRF24L01_write_reg(WRITE_REG + RX_PW_P4, Data_width); //设置通道4数据字节数
NRF24L01_write_reg(WRITE_REG + RX_PW_P5, Data_width); //设置通道5数据字节数
NRF24L01_write_reg(WRITE_REG + RF_SETUP, 0x0f); //发送速率为1Mhz,发送功率最大值0db
NRF24L01_write_buf(WRITE_REG + TX_ADDR,TX_ADDRESS,5); //写本机地地址NRF24L01_write_buf(WRITE_REG + RX_ADDR_P0,RX_ADDRESS_P0,5); //写数据通道0接收机地址
NRF24L01_write_buf(WRITE_REG + RX_ADDR_P1,RX_ADDRESS_P1,5); //写数据通道1接收机地址
NRF24L01_write_buf(WRITE_REG + RX_ADDR_P2,RX_ADDRESS_P2,1); //写数据通道2接收机地址
NRF24L01_write_buf(WRITE_REG + RX_ADDR_P3,RX_ADDRESS_P3,1); //写数据通道3接收机地址
NRF24L01_write_buf(WRITE_REG + RX_ADDR_P4,RX_ADDRESS_P4,1); //写数据通道4接收机地址
NRF24L01_write_buf(WRITE_REG + RX_ADDR_P5,RX_ADDRESS_P5,1); //写数据通道5接收机地址
void RX_MODE()
{
NRF24L01_write_reg(WRITE_REG + CONFIG, 0x0f);//IRQ收发完成中断响应,16位CRC,接收模式
CE = 1;
}
void TX_MODE()
{
NRF24L01_write_reg(WRITE_REG + CONFIG, 0x0e);//IRQ收发完成中断响应,16位CRC,发送模式
CE = 1;
}
ucharTX_packet(uchar *tx_buf)
{
uchartx_flag = 1;
CE = 0; //停止射频电路工作
NRF24L01_write_reg(WRITE_REG + STATUS,0xff); //清除中断标志位
NRF24L01_write_buf(WR_TX_PLOAD,tx_buf,Data_width); //装载要发送的数据CE = 1; //置高CE,激发数据发送
Delay_ms(Data_rt/2);
if(NRF24L01_read_reg(STATUS)&0x10)
tx_flag = 0;
return(tx_flag);
}
ucharRX_packet(uchar *rx_buf)
{
uchar revalue = 0,sta;
sta = NRF24L01_read_reg(STATUS); //读状态寄存器
if(sta&0x40) //如果接受中断标志位为1
{
CE = 0; //SPI使能
NRF24L01_read_buf(RD_RX_PLOAD,rx_buf,Data_width); //读取数据
revalue = 1; //读取数据完成标志置1
NRF24L01_write_reg(WRITE_REG + STATUS,0xff); //清除中断标志位}
CE = 1;
return revalue;//返回读取数据完成标志
}。

相关文档
最新文档