NRF24L01无线模块C语言程序

合集下载

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册一、模块简介该射频模块集成了NORDIC公司生产的无线射频芯片nRF24L01:1.支持2.4GHz的全球开放ISM频段,最大发射功率为0dBm2.2Mbps,传输速率高3.功耗低,等待模式时电流消耗仅22uA4.多频点(125个),满足多点通信及跳频通信需求5.在空旷场地,有效通信距离:25m(外置天线)、10m(PCB天线)6.工作原理简介:发射数据时,首先将nRF24L01配置为发射模式,接着把地址TX_ADDR和数据TX_PLD 按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号。

如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从发送堆栈中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC_CNT)达到上限,MAX_RT置高,TX_PLD不会被清除;MAX_RT或TX_DS置高时,使IRQ变低,以便通知MCU。

最后发射成功时,若CE为低,则nRF24L01进入待机模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入待机模式2。

接收数据时,首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。

当接收方检测到有效的地址和CRC时,就将数据包存储在接收堆栈中,同时中断标志位RX_DR置高,IRQ变低,以便通知MCU去取数据。

若此时自动应答开启,接收方则同时进入发射状态回传应答信号。

最后接收成功时,若CE变低,则nRF24L01进入空闲模式1。

三、模块引脚说明四、模块与AT89S52单片机接口电路注:上图为示意连接,可根据自己实际需求进行更改;使用AT89S52MCU模块时,请将Nrf24L01通讯模块每个端口(MOSI、SCK、CSN和CE)接4.7K的排阻上拉到VCC增强其驱动能力(如下图:)。

基于nRF24L01的无线通信模块设计

基于nRF24L01的无线通信模块设计

1前言 (2)2总体方案设计 (3) (3)图2.1无线通信模块框图 (3)3单元模块设计 (4)3.1 nRF24L01的简单介绍 (4)3.2 STC89C52的简单介绍 (6)3.3 LCD1602的简单介绍 (7)3.4 其它的器件 (8)3.5 各单元模块的联系 (8)4软件设计 (9)5系统调试 (10)5.1主要问题及分析 (10)5.2调试工具 (10)6系统功能、指标参数 (11)6.1系统能实现的功能 (11)6.2系统指标参数测试 (11)6.3系统的指标功能及参数分析 (11)7结论 (12)8总结与体会 (13)9参考文献 (14)10附录 (15)10.1相关设计图 (15) (15) (16)图10.2无线收发模块电路原理总图 (16)图10.3正5V电源模块图 (16)10.2相关的程序 (20)1前言本次我们三人小组设计的是无线通信模块,根据设计要求我们选择了无线收发模块nRF24L01、单片机STC89C52、LCD1602和键盘模块等作为本次设计的硬件需求。

首先我们与老师一起讨论了一些设计的相关事宜和设计思路。

接下来我们一起画好了模拟电路图,在老师的帮助下我们对电路图进行了补充和完善。

完成这些基本工作后,在老师和同学的帮助下我们买回了自己所需的元器件。

接着我们变分工完成了元器件的焊接连接和程序的编写,然后便是模块的上电调试,设计的答辩和设计报告的完善。

我们本次之所以会选择无线通信模块的设计,是我们觉得无线通信技术是现代社会中一门很重要的技术,我们掌握好了这门技术对以后我们的工作生活都有很大的帮助。

我们本次设计的无线通信模块虽然只是我们的一次小小的体验,但我们都知道无线通信在我们现在所处的信息时代是多么的重要,如今我们生活的方方面面无不与无线通信息息相关。

我们所熟悉的手机、电脑、电视等等都与无线通信有着直接的联系。

甚至在某些高端领域方面无线通信技术能反映一个国家的科技水平和综合国力。

NRF24L01全双工调试程序 自动切换收发模式 可用于实现对讲机

NRF24L01全双工调试程序 自动切换收发模式 可用于实现对讲机
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit P30 = P3^0;
sbit P31 = P3^1;
sbit P32 = P3^2;
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);//设置发射速率为2MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c);//IRQ引脚不显示中断掉电模式1~16CRC校验
ucharbdata sta;
sbitRX_DR=sta^6;
sbitTX_DS=sta^5;
sbitMAX_RT=sta^4;
//********************************NRF24L01初始化******************************************//
void init_NRF24L01()
{
delayus(100);
CE=0; //片选使能
CSN=1; // SPI使能
SCK=0; // SPI时钟拉低
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //写接收端地址

NRF24L01接收程序_ATMEGA16

NRF24L01接收程序_ATMEGA16

参考网上资源 ------------------------------------------------------------------------------*///----------------------------------------------------------------------------//--------------------------------NRF24L01 接口定义-------------------------------//-----------------------------------------------------------------------------#include<iom16v.h> #define uint unsigned int #define uchar unsigned char //#define NRF24L01_MISO #define Hign_24L01_MISO #define Low_24L01_MISO #define Read_24L01_MISO //#define NRF24L01_MOSI #define Hign_24L01_MOSI #define Low_24L01_MOSI #define Read_24L01_MOSI //#define NRF24L01_SCK #define Hign_24L01_SCK #define Low_24L01_SCK #define Read_24L01_SCK //#define NRF24L01_CSN #define Low_24L01_CSN #define Hign_24L01_CSN //#define NRF24L01_CE #define Hign_24L01_CE #define Low_24L01_CE #define Read_24L01_CE //#define #define #define #define PB4 //输入 0 PORTB |= (1 << PB4) PORTB &= ~(1 << PB4) PINB & (1 << PB4) PB3 //输出 1 PORTB |= (1 << PB3) PORTB &= ~(1 << PB3) PINB & (1 << PB3) PB5 //输出 1 PORTB |= (1 << PB5) PORTB &= ~(1 << PB5) PINB & (1 << PB5); PB2 //输出 1 PORTB &= ~(1 << PB2) PORTB |= (1 << PB2) PB1 //输出 1 PORTB |= (1 << PB1) PORTB &= ~(1 << PB1) PINB & (1 << PB1)

NRF24L01参考程序28包含多个实例

NRF24L01参考程序28包含多个实例

(相关人员如觉得本人水平低下,还请见谅)Nrf24L01的使用程序和使用方法和简单操作:功能:无线对发程序。

两个模块a,b,实现按下一个按键,会在对方的数码管上显示3或4,在本机上显示1,2。

当一个模块,比如a模块。

当两个按键按下其中一个,则会在另一个模块b上显示数字3,4(具体根据按下哪个按键)。

以上功能描述,B模块按键按下,如同a模块一样的功能,不做系统性描述了。

下面给出程序中几个地方的解释:#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 // 保留类似这种的描述,可以等同于READ_REG =0x00;这个是经过实际程序测试出来的,比如以下程序:#include<reg51.h>#define k 0xfevoid main(){P1=k;}则会出现此类结果:MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0;此处为spi的核心,是spi协议的编程,其中uchar |= MISO; 表示uchar |= MISO | uchar; MOSI = (uchar & 0x80);其中0x80是1000 0000,与上uchar,这种&,是按位与,故可以从uchar提取出一个电平给mosi。

关于NRF24l01的调试

关于NRF24l01的调试

NRF24l01的调试过程与方法小结心得体会:最近老板给了几块nrf24l01模块我,初次上手难免走了许多的弯路,经过近一周的时间的不断调试,模块之间终于可以相互收发数据了。

这样下来终于松了一口气。

其间的各种辛苦与艰辛难于言表。

上网大致看了一下,网上基于51的调试比较多,但是我们实验室用的是DSP2812,由于nrf24l01是SPI接口,2812上刚好有SPI的接口,这样貌似给使用带来了方便,但是51之类的芯片虽然没有SPI口,但是例程也最多,关于他的讨论比较多。

最开始我的想法也比较混乱,想直接用SPI来调试,把底层函数稍微修改了一下,发现并没有结果,这个东西就像一个黑匣子一样,即看不见也摸不着,后来我慢慢改变了思路。

既然网上基于IO口模拟的SPI的例程最多,我决定另外走一条路,先用2812的IO 口模拟SPI再用自带的SPI口去调试。

这样一来我就有了两条可以走的路。

第一条:底层SPI时序用IO口模拟去写。

第二条:底层直接用2812的SPI去操作。

虽然这样一来,路好走了一点,有各类的程序可以参考,但是这样带来最大的一个问题,这也是后来我才发现的,nrf24l01的最大读写速率是有限制的,2812在150M运行时很显然是太大了一点,由于nrf24l01对时序的要求很高,端口的读写速率和时序都有严格的要求,所以我们才看到,在网上一般是15M左右的单片机来模拟IO口,没有谁用150M的DSP来模拟IO口的,当然既然确定了这样的方法后来也发现了问题,我还是继续走下去了。

很重要的一点是系统的时钟频率。

当然时序的要求也很高,这也就是为什么,网上说这个模块不好调试的原因,既然是调试,当然我们既然是调试,肯定有一个思路和方法。

那么方法是什么呢?开始的时候我是一股脑将发送和接收的程序都写进去,然后啥现象也没有,然后就傻眼了。

在网上看了看,于是有了一点思路。

方法是将发送和接收的调试分开来调试,以读取nrf24l01内部的寄存器为手段,先调试发送方,发送方调试没有问题以后,让发送方不断的发送数据,然后再来调试接收方,直到接收方也没有问题,再接着望下面去做。

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册一、模块简介该射频模块集成了NORDIC公司生产的无线射频芯片nRF24L01:1.支持2.4GHz的全球开放ISM频段,最大发射功率为0dBm2.2Mbps,传输速率高3.功耗低,等待模式时电流消耗仅22uA4.多频点(125个),满足多点通信及跳频通信需求5.在空旷场地,有效通信距离:25m(外置天线)、10m(PCB天线)6.工作原理简介:发射数据时,首先将nRF24L01配置为发射模式,接着把地址TX_ADDR和数据TX_PLD 按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号。

如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从发送堆栈中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC_CNT)达到上限,MAX_RT置高,TX_PLD不会被清除;MAX_RT或TX_DS置高时,使IRQ变低,以便通知MCU。

最后发射成功时,若CE为低,则nRF24L01进入待机模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入待机模式2。

接收数据时,首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。

当接收方检测到有效的地址和CRC时,就将数据包存储在接收堆栈中,同时中断标志位RX_DR置高,IRQ变低,以便通知MCU去取数据。

若此时自动应答开启,接收方则同时进入发射状态回传应答信号。

最后接收成功时,若CE变低,则nRF24L01进入空闲模式1。

三、模块引脚说明1 / 197 NC 空 8 CSN 芯片片选信号 I 9 CE 工作模式选择I 10+5V电源四、模块与AT89S52单片机接口电路注:上图为示意连接,可根据自己实际需求进行更改;使用AT89S52MCU 模块时,请将Nrf24L01通讯模块每个端口(MOSI 、SCK 、CSN 和CE )接4.7K 的排阻上拉到VCC 增强其驱动能力(如下图:)。

STM8的SPI口NRF24L01例程

STM8的SPI口NRF24L01例程

//定时器初值*定时器分频*系统分频/16MHZ=定时时

//250*8*2/16mhz=250us
TIM4_IER |= 0x01;
//- - - - - - - UIE(Enable TIM4 OVR interrupt)
TIM4_CR1 |= 0x81; //ARPE - - - OPM URS UDIS CE_PINN
//Configure TIM3 prescaler = 8192
TIM3_CR1 |= 0x81;
//*/
//------------------------------//
TIM4_PSCR = 0x03;
//PSC[2:0] [1.2.4.8.16.32.64.128]
TIM4_ARR = 0xfA;
//BIT[2:0] Configure TIM2 prescaler =1 //ARPE - - - OPM URS UDIS CE_PINN
// TIM3 CC1 control LED Blinking //Output mode PWM2.
//CC polarity low,enable PWM output
/////////////////////////////////////////////
//
/////////////////////////////////////////////
delay_time(u16 i)
{ u16 j;
for(j=0;j<i;++j)
{ while(!f_250us)
TIM3_ARRH = 0x03; TIM3_ARRL = 0xff;
//自动从装载寄存器,先装高字节
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

NRF24L01无线模块C语言程序 24MHz晶振 #include #include #include #include #include #include

#define U8 unsigned char #define U16 unsigned int

#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节 #define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节 #define TX_DATA_WITDH 1//发送数据宽度1个字节 #define RX_DATA_WITDH 1//接收数据宽度1个字节

#define R_REGISTER 0x00//读取配置寄存器 #define W_REGISTER 0x20//写配置寄存器 #define R_RX_PAYLOAD 0x61//读取RX有效数据 #define W_TX_PAYLOAD 0xa0//写TX有效数据 #define FLUSH_TX 0xe1//清除TXFIFO寄存器 #define FLUSH_RX 0xe2//清除RXFIFO寄存器 #define REUSE_TX_PL 0xe3//重新使用上一包有效数据 #define NOP 0xff//空操作

#define CONFIG 0x00//配置寄存器 #define EN_AA 0x01//使能自动应答 #define EN_RXADDR 0x02//接收通道使能0-5个通道 #define SETUP_AW 0x03//设置数据通道地址宽度3-5 #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//P0通道数据宽度设置 #define RX_PW_P1 0x12//P1通道数据宽度设置 #define RX_PW_P2 0x13//P2通道数据宽度设置 #define RX_PW_P3 0x14//P3通道数据宽度设置 #define RX_PW_P4 0x15//P4通道数据宽度设置 #define RX_PW_P5 0x16//P5通道数据宽度设置 #define FIFO_STATUS 0x17//FIFO状态寄存器

//NRF24L01 U8 NRFACK(); U8 NRFSPI(U8 date); U8 NRFReadReg(U8 RegAddr); U8 NRFWriteReg(U8 RegAddr,U8 date); U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen); U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen); U8 NRFRevDate(U8 *RevDate); void NRFSetTxMode(U8 *TxDate); void NRF24L01Int(); void NRFSetRXMode(); U8 CheckACK(); void Delay(U16 t); U8 bdata sta;

//main void Delay_10ms(U16 del);

bit CE=P1^4; //RX/TX模式选择端 sbit IRQ=P1^1; //可屏蔽中断端 sbit CSN=P1^6; //SPI片选端//就是SS sbit MOSI=P1^0; //SPI主机输出从机输入端1 sbit MISO=P1^2; //SPI主机输入从机输出端 sbit SCLK=P1^3; //SPI时钟端

U8 code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址

U8 bdata sta; //状态标志 sbit RX_DR=sta^6; sbit TX_DS=sta^5; sbit MAX_RT=sta^4;

void Delay(U16 t) { U16 x,y; for(x=t;x>0;x--) for(y=110;y>0;y--); }

U8 NRFSPI(U8 date) {

U8 i; for(i=0;i<8;i++) // 循环8次 { if(date&0x80) MOSI=1; else MOSI=0; // byte最高位输出到MOSI date<<=1; // 低一位移位到最高位 SCLK=1; if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据, 同时从MISO输出1位数据 date|=0x01; // 读MISO到byte最低位 SCLK=0; // SCK置低 } return(date); // 返回读出的一字节 }

void NRF24L01Int() { Delay(2);//让系统什么都不干 CE=0; //待机模式1 CSN=1; SCLK=0; IRQ=1; }

U8 NRFReadReg(U8 RegAddr) { U8 BackDate; CSN=0;//启动时序 NRFSPI(RegAddr);//写寄存器地址 BackDate=NRFSPI(0x00);//写入读寄存器指令 CSN=1; return(BackDate); //返回状态 } U8 NRFWriteReg(U8 RegAddr,U8 date) { U8 BackDate; CSN=0;//启动时序 BackDate=NRFSPI(RegAddr);//写入地址 NRFSPI(date);//写入值 CSN=1; return(BackDate); }

U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen) { //寄存器地址//读取数据存放变量//读取数据长度//用于接收 U8 BackDate,i; CSN=0;//启动时序 BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址 for(i=0;i { RxDate[i]=NRFSPI(0); } CSN=1; return(BackDate); }

U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen) { //寄存器地址//写入数据存放变量//读取数据长度//用于发送 U8 BackDate,i; CSN=0; BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址 for(i=0;i { NRFSPI(*TxDate++); } CSN=1; return(BackDate); }

void NRFSetTxMode(U8 *TxDate) {//发送模式 CE=0; NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度 NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同 NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据 NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答 NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益 NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电 CE=1; Delay(5);//保持10us秒以上 }

//主要接收模式 void NRFSetRXMode() { CE=0; NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址 NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答 NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/ NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式 CE = 1; Delay(5);//保持10us秒以上 }

U8 CheckACK() { //用于发射 sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器 if(TX_DS||MAX_RT) //发送完毕中断 {

相关文档
最新文档