nrf24l01收发程序详解

nrf24l01驱动程序分享 nrf24l01的发送程序: #include 《reg51.h》
#define uchar unsigned char
#define uint unsigned int
sbit ce = p1^0; // chip enable pin signal (output)
sbit csn = p1^1; // slave select pin, (output to csn, nrf24l01)
sbit irq = p1^5; // interrupt signal, from nrf24l01 (input)
sbit miso = p1^4; // master in, slave out pin (input)
sbit mosi = p1^3; // serial clock pin, (output)
sbit sck = p1^2; // master out, slave in pin (output)
// 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
#define tx_adr_width 5 // 5字节宽度的发送/接收地址
#define tx_pload_width 4 // 数据通道有效数据宽度
uchar code tx_address[tx_adr_width] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
uchar rx_buf[tx_pload_width];
uchar tx_buf[tx_pload_width];
uchar flag;
uchar data = 0x01;
uchar bdata sta;
sbit rx_dr = sta^6;
sbit tx_ds = sta^5;
sbit max_rt = sta^4;
void init_io(void)
{
ce = 0; // 待机
csn = 1; // spi禁止
sck = 0; // spi时钟置低
irq = 1; // 中断复位
}
void delay_ms(uchar x)
{
uchar i, j;
i = 0;
for(i=0; i《x; i++)
{
j = 250;
while(--j);
j = 250;
while(--j);
}
}
uchar spi_rw(uchar byte)
{
uchar i;
for(i=0; i《8; i++) // 循环8次
{
mosi = (byte & 0x80); // byte最高位输出到mosi
byte 《《= 1; // 低一位移位到最高位
sck = 1; // 拉高sck,nrf24l01从mosi读入1位数据,同时从miso输出1位数据
byte |= miso; // 读miso到byte最低位
sck = 0; // sck置低
}
return(byte); // 返回读出的一字节
}
uchar spi_rw_reg(uchar reg, uchar value)
{
uchar status;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
spi_rw(value); // 然后写数据到该寄存器
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
uchar spi_read(uchar reg)
{
uchar reg_val;
csn = 0; // csn置低,开始传输数据
spi_rw(reg); // 选择寄存器
reg_val = spi_rw(0); // 然后从该寄存器读数据
csn = 1; // csn拉高,结束数据传输
return(reg_val); // 返回寄存器数据
}
uchar spi_read_buf(uchar reg, uchar * pbuf, uchar bytes)
{
uchar status, i;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
for(i=0; i《bytes; i++)
pbuf = spi_rw(0); // 逐个字节从nrf24l01读出
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
uchar spi_write_buf(uchar reg, uchar * pbuf, uchar bytes)
{
uchar status, i;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
for(i=0; i《bytes; i++)
spi_rw(pbuf); // 逐个字节写入nrf24l01
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
void rx_mode(void)
{
ce = 0;
spi_write_buf(write_reg + rx_addr_p0, tx_address, tx_adr_width); // 接收设备接收通道0使用和发送设备相同的发送地址
spi_rw_reg(write_reg + en_aa, 0x01); // 使能接收通道0自动应答
spi_rw_reg(write_reg + en_rxaddr, 0x01); // 使能接收通道0
spi_rw_reg(write_reg + rf_ch, 40); // 选择射频通道0x40
spi_rw_reg(write_reg + rx_pw_p0, tx_pload_width); // 接收通道0选择和发送通道相同有效数据宽度
spi_rw_reg(write_reg + rf_setup, 0x07); // 数据传输率1mbps,发射功率0dbm,低噪声放大器增益
spi_rw_reg(write_reg + config, 0x0f); // crc使能,16位crc校验,上电,接收模式
ce = 1; // 拉高ce启动接收设备
}
void tx_mode(uchar * buf)
{
ce = 0;
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); // 为了应答接收设备,接收通道0地址和发送地址相同
spi_write_buf(wr_tx_pload, buf, tx_pload_width); // 写数据包到tx fifo
spi_rw_reg(write_reg + en_aa, 0x01); // 使能接收通道0自动应答
spi_rw_reg(write_reg + en_rxaddr, 0x01); // 使能接收通道0
spi_rw_reg(write_reg + setup_retr, 0x0a); // 自动重发延时等待250us+86us,自动重发10次
spi_rw_reg(write_reg + rf_ch, 40); // 选择射频通道0x40
spi_rw_reg(write_reg + rf_setup, 0x07); // 数据传输率1mbps,发射功率0dbm,低噪声放大器增益
spi_rw_reg(write_reg + config, 0x0e); // crc使能,16位crc校验,上电
ce = 1;
}
uchar check_ack(bit clear)
{
while(irq);
sta = spi_rw(nop); // 返回状态寄存器
if(max_rt)
if(clear) // 是否清除tx fifo,没有清除在复位max_rt中断标志后重发
spi_rw(flush_tx);
spi_rw_reg(write_reg + status, sta); // 清除tx_ds或max_rt中断标志
irq = 1;
if(tx_ds)
return(0x00);
else
return(0xff);
}
unsigned char nrf24l01_rxpacket(unsigned char* rx_buf)
{
unsigned char revale=0;
//setrx_mode();
sta=spi_read(status); // read register status‘s value
if(rx_dr) // if receive data ready (rx_dr) interrupt
{
ce = 0;
spi_read_buf(rd_rx_pload,rx_buf,tx_pload_width);// read receive payload from rx_fifo buffer
revale =1;//we have receive data
}
spi_rw_reg(write_reg+status,sta);// clear rx_dr or tx_ds or max_rt interrupt flag
return revale;
}
void main(void)
{
uchar a[5]={0xfe,0xfd,0xfc,0xf0,0x1d};
uchar i;
init_io(); // 初始化io
// rx_mode(); // 设置为接收模式
while(1)
{
for(i=0;i《5;i++)
{
tx_buf = a; // 数据送到缓存
tx_mode(tx_buf); // 把nrf24l01设置为发送模式并发送数据
check_ack(1); // 等待发送完毕,清除tx fifo
delay_ms(250);
delay_ms(250);
// rx_mode();
}
}
}
nrf24l01的接收程序: #include 《reg51.h》
#define uchar unsigned char
#define uint unsigned int
sbit ce = p0^0; // chip enable pin signal (output)
sbit csn = p0^1; // slave select pin, (output to csn, nrf24l01)
sbit irq = p0^5; // interrupt signal, from nrf24l01 (input)
sbit miso = p0^4; // master in, slave out pin (input)
sbit mosi = p0^3; // serial clock pin, (output)
sbit sck = p0^2; // master out, slave in pin (output)
// 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
#define tx_adr_width 5 // 5字节宽度的发送/接收地址
#define tx_pload_width 4 // 数据通道有效数据宽度 因为这个4,导致发送接收的数据缺少第五个!改成5则正常!
#define led p1
uchar code tx_address[tx_adr_width] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
uchar rx_buf[tx_pload_width];
uchar tx_buf[tx_pload_width];
uchar flag;
uchar data = 0x01;
uchar bdata sta;
sbit rx_dr = sta^6;
sbit tx_ds = sta^5;
sbit max_rt = sta^4;
void init_io(void)
{
ce = 0; // 待机
csn = 1; // spi禁止
sck = 0; // spi时钟置低
irq = 1; // 中断复位
led = 0xff; // 关闭指示灯
}
void delay_ms(uchar x)
{
uchar i, j;
i = 0;
for(i=0; i《x; i++)
{
j = 250;
while(--j);
j = 250;
while(--j);
}
}
uchar spi_rw(uchar byte)
{
uchar i;
for(i=0; i《8; i++) // 循环8次
{
mosi = (byte & 0x80); // byte最高位输出到mosi
byte 《《= 1; // 低一位移位到最高位
sck = 1; // 拉高sck,nrf24l01从mosi读入1位数据,同时从miso输出1位数据
byte |= miso; // 读miso到byte最低位
sck = 0; // sck置低
}
return(byte); // 返回读出的一字节
}
uchar spi_rw_reg(uchar reg, uchar value)
{
uchar status;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
spi_rw(value); // 然后写数据到该寄存器
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
uchar spi_read(uchar reg)
{
uchar reg_val;
csn = 0; // csn置低,开始传输数据
spi_rw(reg); // 选择寄存器
reg_val = spi_rw(0); // 然后从该寄存器读数据
csn = 1; // csn拉高,结束数据传输
return(reg_val); // 返回寄存器数据
}
uchar spi_read_buf(uchar reg, uchar * pbuf, uchar bytes)
{
uchar status, i;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
for(i=0; i《bytes; i++)
pbuf = spi_rw(0); // 逐个字节从nrf24l01读出
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
uchar spi_write_buf(uchar reg, uchar * pbuf, uchar bytes)
{
uchar status, i;
csn = 0; // csn置低,开始传输数据
status = spi_rw(reg); // 选择寄存器,同时返回状态字
for(i=0; i《bytes; i++)
spi_rw(pbuf); // 逐个字节写入nrf24l01
csn = 1; // csn拉高,结束数据传输
return(status); // 返回状态寄存器
}
void rx_mode(void)
{
ce = 0;
spi_write_buf(write_reg + rx_addr_p0, tx_address, tx_adr_width); // 接收设备接收通道0使用和发送设备相同的发送地址
spi_rw_reg(write_reg + en_aa, 0x01); // 使能接收通道0自动应答
spi_rw_reg(write_reg + en_rxaddr, 0x01); // 使能接收通道0
spi_rw_reg(write_reg + rf_ch, 40); // 选择射频通道0x40
spi_rw_reg(write_reg + rx_pw_p0, tx_pload_width); // 接收通道0选择和发送通道相同有效数据宽度
spi_rw_reg(write_reg + rf_setup, 0x07); // 数据传输率1mbps,发射功率0dbm,低噪声放大器增益
spi_rw_reg(write_reg + config, 0x0f); // crc使能,16位crc校验,上电,接收模式
ce = 1; // 拉高ce启动接收设备
}
void tx_mode(uchar * buf)
{
ce = 0;
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); // 为了应答接收设备,接收通道0地址和发送地址相同
spi_write_buf(wr_tx_pload, buf, tx_pload_width); // 写数据包到tx fifo
spi_rw_reg(write_reg + en_aa, 0x01); // 使能接收通道0自动应答
spi_rw_reg(write_reg + en_rxaddr, 0x01); // 使能接收通道0
spi_rw_reg(write_reg + setup_retr, 0x0a); // 自动重发延时等待250us+86us,自动重发10次
spi_rw_reg(write_reg + rf_ch, 40); // 选择射频通道0x40
spi_rw_reg(write_reg + rf_setup, 0x07); // 数据传输率1mbps,发射功率0dbm,低噪声放大器增益
spi_rw_reg(write_reg + config, 0x0e); // crc使能,16位crc校验,上电
ce = 1;
}
uchar check_ack(bit clear)
{
while(irq);
sta = spi_rw(nop); // 返回状态寄存器
if(max_rt)
if(clear) // 是否清除tx fifo,没有清除在复位max_rt中断标志后重发
spi_rw(flush_tx);
spi_rw_reg(write_reg + status, sta); // 清除tx_ds或max_rt中断标志
irq = 1;
if(tx_ds)
return(0x00);
else
return(0xff);
}
unsigned char nrf24l01_rxpacket(unsigned char* rx_buf)
{
unsigned char revale=0;
//setrx_mode();
sta=spi_read(status); // read register status‘s value
if(rx_dr) // if receive data ready (rx_dr) interrupt
{
ce = 0;
spi_read_buf(rd_rx_pload,rx_buf,tx_pload_width);// read receive payload from rx_fifo buffer
revale =1;//we have receive data
}
spi_rw_reg(write_reg+status,sta);// clear rx_dr or tx_ds or max_rt interrupt flag
return revale;
}
void main(void)
{
uchar i;
uchar reveal;
init_io(); // 初始化io
rx_mode(); // 设置为接收模式
while(1)
{
reveal=nrf24l01_rxpacket(rx_buf);
if(reveal==1) // 接受完成
{
reveal = 0;
for(i=0;i《5;i++)
{
led = rx_buf;
delay_ms(250);
delay_ms(250);
}
}
}
}

关于VM系列振弦传感器读数模块如何连接电脑并进行配置说明
勿要混淆 详解LED LED背光 OLED的原理与区别
基于FPGA的H.264 DCT算法的硬件实现
智慧停车解决方案与结构及发展方向
磁性液位计的工作原理_磁性液位计的维修及保养
nrf24l01收发程序详解
美的空调AWE亮出品牌年轻化头牌 松圈营销玩转IP
中国联通和中国电信正在将2.1GHz频率进行共享
区块链在财富管理方面可以提供帮助吗
如何选择合适的EMI滤波器 EMI滤波器的8个选型参数
PRT脉冲测距技术三大特性及优势
2023CIIE圆满收官!链接全球资源,安富利与您共享“数智”机遇
服装企业“智化”“智造”的发展思路何时能实现?
airpods2功能介绍_airpods2丢了怎么查找
功率放大器应用领域分享:基于液滴微流控的线粒体转移新技术
安防监控市场产值不断攀升 也为光学镜头企业提供了广阔的发展空间
太阳能LED路灯构成及特性说明
华为秋季全场景新品发布会 华为MatePadPro13.2巅峰性能
努比亚Z20工信部入网照片曝光该机采用了前后对称双曲面设计
林肯联手Rivian 发力电动汽车领域