NRF24L01快速上手

本文详细介绍了nRF24L01无线收发器芯片的工作原理、特点和实际操作流程。通过SPI协议与微控制器进行通信,配置寄存器设置参数,实现数据的发送与接收。提供了源码示例,展示了如何初始化IO、设置通信模式以及检查应答信号。实验结果显示,该芯片在指定条件下可以正常工作。
摘要由CSDN通过智能技术生成

NRF24L01简介

nRF24L01是由NORDIC生产的工作在2.4GHz~2.5GHz的ISM 频段的单片无线收发器芯片。无线收发器包括:频率发生器、增强型“SchockBurst”模式控制器、功率放大器、晶体振荡器、调制器和解调器。
最大的优点,就是便宜,且功能强大

实际操作

整体使用标准SPI协议进行读写访问
通过NRF24L01设置内部寄存器来设置参数,最后上电启动即可
其中SPI指令包括:在这里插入图片描述
寄存器地址:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
芯片手册的配置流程在这里插入图片描述

源码分享

将寄存器地址定义,封装为头文件
引脚根据实际情况自定义

#ifndef _API_DEF_
#define _API_DEF_

// Dpin
sbit CSN = P1^3 ;  
sbit CE  = P1^2 ; 
sbit SCK = P1^7 ; 
sbit MOSI= P1^1 ; 
sbit MISO= P1^6 ; 
sbit IRQ = P1^4 ; 

// commands
#define READ_REG    0x00  
#define WRITE_REG   0x20  
#define RD_RX_PLOAD 0x61  
#define WR_TX_PLOAD 0xA0 
#define FLUSH_TX    0xE1 
#define FLUSH_RX    0xE2  
#define REUSE_TX_PL 0xE3 
#define NOP         0xFF  

// registers
#define CONFIG      0x00  
#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  
#define RX_ADDR_P1  0x0B  
#define RX_ADDR_P2  0x0C  
#define RX_ADDR_P3  0x0D  
#define RX_ADDR_P4  0x0E  
#define RX_ADDR_P5  0x0F 
#define TX_ADDR     0x10  
#define RX_PW_P0    0x11 
#define RX_PW_P1    0x12 
#define RX_PW_P2    0x13 
#define RX_PW_P3    0x14 
#define RX_PW_P4    0x15  
#define RX_PW_P5    0x16  
#define FIFO_STATUS 0x17 

#endif   /* _API_DEF_ */

与实际代码

#include<reg52.h>
#include"nRFreg.h"

#define ADDR_LEN   5  // 5字节宽度的发送/接收地址
#define DATA_LEN 4  // 数据通道有效数据宽度(每次发送的字节数)

// 接收用m1,发送机用m2
unsigned char code MyAddr1[ADDR_LEN] = {0x34,0x41,0x11,0x11,0x01};
unsigned char code MyAddr2[ADDR_LEN] = {0x34,0x41,0x10,0x10,0x01}; 

unsigned char RxBuf[DATA_LEN];
unsigned char TxBuf[DATA_LEN];
unsigned char sta ; //此变量用来存储STATUS状态字
#define RX_DR sta^0x40
#define TX_DS sta^0x20
#define MAX_RT sta^0x10


/**************************************************
 init_io()
初始化IO
/**************************************************/
void init_io(void) {
	CE  = 0;        // 待机
	CSN = 1;        // SPI禁止
	SCK = 0;        // SPI时钟置低
	IRQ = 1;        // 中断复位
}
/**************************************************/

/**************************************************
delay_ms()
延迟
/**************************************************/
void delay(unsigned char x) {
	unsigned char y ;
	for ( ; x > 0 ; x-- )
		for ( y = 110 ; y > 0 ; y-- ) ;
}
/**************************************************/

/**************************************************
SPI_RW()
 根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01读出一字节
/**************************************************/
unsigned char SPI_RW(unsigned char byte) {
	unsigned char i;
   	for(i=0; i<8; i++) {
   		MOSI = (byte & 0x80);   // byte最高位输出到MOSI
   		byte <<= 1;             // 低一位移位到最高位
   		SCK = 1;                // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
   		byte |= MISO;       	// 读MISO到byte最低位
   		SCK = 0;            	// SCK置低
   	}
    return byte ;           	// 返回读出的一字节
}
/**************************************************/

/**************************************************
SPI_RW_Reg()
写数据value到reg寄存器
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value) {
	unsigned char status;
  	CSN = 0;                   // CSN置低,开始传输数据
  	status = SPI_RW(reg);      // 选择寄存器,同时返回状态字
  	SPI_RW(value);             // 然后写数据到该寄存器
  	CSN = 1;                   // CSN拉高,结束数据传输
  	return status ;            // 返回状态寄存器
}
/**************************************************/

/**************************************************
SPI_Read()
从reg寄存器读一字节
/**************************************************/
unsigned char SPI_Read(unsigned char reg) {
	unsigned char reg_val;
  	CSN = 0;                    // CSN置低,开始传输数据
  	SPI_RW(reg);                // 选择寄存器
  	reg_val = SPI_RW(0);        // 然后从该寄存器读数据
  	CSN = 1;                    // CSN拉高,结束数据传输
  	return reg_val ;            // 返回寄存器数据
}
/**************************************************/

/**************************************************
SPI_Read_Buf()
从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址
/**************************************************/
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char * pBuf, unsigned char bytes) {
	unsigned char status, i;
  	CSN = 0;                    // CSN置低,开始传输数据
  	status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
  	for(i=0; i<bytes; i++)
    	pBuf[i] = SPI_RW(0);    // 逐个字节从nRF24L01读出
  	CSN = 1;                    // CSN拉高,结束数据传输
  	return status ;             // 返回状态寄存器
}
/**************************************************/

/**************************************************
SPI_Write_Buf()
把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
/**************************************************/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char * pBuf, unsigned char bytes) {
	unsigned char status, i;
  	CSN = 0;                    // CSN置低,开始传输数据
  	status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
  	for(i=0; i<bytes; i++)
    	SPI_RW(pBuf[i]);        // 逐个字节写入nRF24L01
  	CSN = 1;                    // CSN拉高,结束数据传输
  	return status ;             // 返回状态寄存器
}
/**************************************************/

/**************************************************
RX_Mode()
这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void RX_Mode(void) {
	CE = 0;
  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       // 自动应答
	SPI_RW_Reg(WRITE_REG + SETUP_AW , 0x03 ) ; //地址宽度
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);            // 选择射频通道0x40
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);      // 数据传输率,发射功率,低噪声放大器增益
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, MyAddr1, ADDR_LEN);  // 接收设备通道0地址设置为
  	SPI_RW_Reg(WRITE_REG + RX_PW_P0, DATA_LEN);  // 接收通道宽度设置 ( 4 )
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);      //接收数据通道0允许
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);       // CRC使能,16位CRC校验,上电,接收模式
  	CE = 1;                                 // 拉高CE启动接收设备
}
/**************************************************/

/**************************************************
TX_Mode()
 这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
130us后启动发射.注意,数据发送结束后,发送模块自动转入接收模式等待应答信号。
/**************************************************/


void TX_Mode(unsigned char * BUF , unsigned char * ToAddr , unsigned char CH ) {
	CE = 0;
  	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);  // 自动重发
	SPI_RW_Reg(WRITE_REG + SETUP_AW , 0x03 ) ; //地址宽度
  	SPI_RW_Reg(WRITE_REG + RF_CH, CH);         // 选择射频通道0x40
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);      // 数据传输率,发射功率,低噪声放大器增益
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x02);      // 上电
  	SPI_Write_Buf(WRITE_REG + TX_ADDR, ToAddr, ADDR_LEN);     // 写入发送的通道地址
  	SPI_Write_Buf(WR_TX_PLOAD, BUF, DATA_LEN); // 将数据(BUF)写入TF FIFO
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // CRC使能,16位CRC校验,上电
	CE = 1;
}
/**************************************************/

/**************************************************
Check_ACK()
检查接收设备有无接收到数据包,
/*************************************************/
unsigned char Check_ACK(void) { // 收到应答信号返回0,反之 ; clear为1,不重发数据,为0相反
	while(IRQ);  //默认情况下(当前情况就是默认),发送/接收数据之后IRQ位会置0
	sta = SPI_RW(NOP);                    // 返回状态寄存器
	if(MAX_RT) { // 如果触发重发次数溢出
		SPI_RW_Reg(WRITE_REG + STATUS, sta) ;  // 清除TX_DS和MAX_RT中断标志
		SPI_RW(FLUSH_TX) ;
		return 1 ;
	}
	if(TX_DS) { 
		SPI_RW_Reg(WRITE_REG + STATUS, sta) ;
		return 0 ;
	}	
}
/**************************************************/


int i = 1 ;
/**************
//接收方
void main(void) {
	
	P2 = 0xff ;
	init_io();	
	RX_Mode();	

	while (!IRQ) {
		SPI_Read_Buf(RD_RX_PLOAD, RxBuf, DATA_LEN);
		P2 = RxBuf[0] ;
		sta = SPI_RW(NOP) ;
		SPI_RW_Reg( WRITE_REG + STATUS , sta ) ;
		
		while (1) {
			i %= 4 ;
			i += 1 ;
			delay(1000);delay(1000);delay(1000);
			P2 = RxBuf[i] ;
		}
	}
}
/**************/



/**************
//发送---------------------------------------------------------------
void main(void) {
	
	init_io() ;
	RX_Mode();
	
	TxBuf[3] = 0x09 ;
	TxBuf[2] = 0x01+2 ;
	TxBuf[1] = 0x01+1 ;
	TxBuf[0] = 0xc0 ;
	
	delay(10) ;
	TX_Mode( TxBuf , MyAddr1 , 40 ) ;
	while (1) ;
}
/**************/

测试

试验机参数:
接收机:STC89C52RC + NRF24L01
发送机:STC89C52 + NRF24L01 + 电源(NRF24L01工作与3.0~3.7v)
在这里插入图片描述

可以正常使用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值