NRF24L01接收程序(可用)

合集下载

NRF24L01参考程序(包含多个实例)7页word

NRF24L01参考程序(包含多个实例)7页word

(相关人员如觉得本人水平低下,还请见谅)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无线通信模块使用手册一、模块简介该射频模块集成了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的发送与接收程序

N R F24L01的发送与接收程序-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN#include <>#include <>typedef unsigned char uchar;typedef unsigned char uint;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*********************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*********************/uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/**************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/**************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/********************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收CE = 1;inerDelay_us(130); //延时不能太短}/**********************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/***********************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/****************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送 tx_buf中数据/****************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************主函数void main(void){uchar temp =0;init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(6000);P0=0xBF;while(1){nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataLED=0;Delay(10000); //可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}}。

#基于STC89C52的控制NRF24L01的程序,这个是发送程序,改一下,可以作为接收程序。

#基于STC89C52的控制NRF24L01的程序,这个是发送程序,改一下,可以作为接收程序。

这是init.c文件#include "comm.h"#define uchar unsigned char#define uint unsigned intuchar xdata date_time[6];uchar xdata i2c_buf[8];uchar xdata result;uchar xdata re_buf[16];uchar xdata re_cnt;uchar check_sum;uchar flag_init;uchar xdata flag_end;uchar xdata flag_uart_busy;uint r_cnt;uchar flag_ex0_isr;//uchar xdata year ,month ,day0;uchar xdata c_year,c_month,c_day0;uchar xdata tx_buf1[20];uchar xdata tx_buf2[20];uchar xdata tx_buf3[20];uchar xdata tx_buf4[20];uint run_cnt;/*=============================================================================== =* Name : DelayMs( )* Description : delay some times* Input : None* Output : None* Note : None=============================================================================== =*/void init_uart(void){u char i;TMOD|=0x20;T H1=0Xfd;T L1=0Xfd;S CON=0X50;T R1=1;E S=1;I T0 =1; //低电平触发外部中断E X0 =1; //允许外部中断tx_buf1[i]=1;tx_buf2[i]=2;tx_buf3[i]=2;tx_buf4[i]=2;}}/*=============================================================================== =* Name : DelayMs( )* Description : delay some times* Input : None* Output : None* Note : None=============================================================================== =*/////////////////////////////////////////////////////////////////////////////////////////////////void send_one_byte(unsigned char tad ){u char temp;i f(ES==1){E S=0;temp=1;}T I=0;S BUF=tad; //发送数据os_wait2(K_TMO,1);w hile(TI==0);T I=0;f lag_uart_busy=1;i f(temp==1){ES=1;}}/*=============================================================================== =* Name : DelayMs( )* Description : delay some times* Input : None* Output : None* Note : Nonevoid job0(void) // _TASK_ 0{u char temp;u char i;r un_led=0;t emp=0x10;f lag_init =0;i nit_uart();f lag_uart_busy=1;P0 =0xff;r ed_led=1;r un_led=1;i=1;i f(i==2){RX_Mode();TX_Mode();}i nit_io();d elay_ms(550);d elay100();T X_Mode();s end_one_byte(0);f lag_ex0_isr=0;}//--------------------------------------------------- void task1(void) //_task_ 1{u char i;run_cnt++;if(run_cnt>20){run_cnt=0;flag_init=1;for(i=0;i<7;i++){tx_buf1[i]=i2c_buf[6-i];}check_sum=0;for( i=0;i<19;i++){check_sum+= tx_buf1[i];}tx_buf1[19]= check_sum;tx_buf1[i]=i2c_buf[6-i];send_one_byte(i2c_buf[i]);}for(i=0;i<4;i++){send_one_byte(0xff);}send_one_byte(check_sum);}}这是main.c文件#include "comm.h"#define uchar unsigned char#define uint unsigned int//---------------------------------------------------uchar t0_isr_cnt;uint t2_isr_cnt;uchar temp;sbit EXT0= P3^2; //外部中断管脚uchar bdata sta;sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;//---------------------------------------------------void main(void ){// uchar i;j ob0();f lag_end=0;t2_isr_cnt=0;E A=1;// check_sum=0;//------------------------------w hile(1){task1();if(flag_ex0_isr==1){flag_ex0_isr=0;}sta=SPI_Read(STATUS);if(RX_DR==1 || TX_DS==1 || MAX_RT==1){IE0=1; //请求中断send_one_byte(sta);}if(flag_end ==1){red_led=1;re_cnt=0;}}}//---------------------------------------------------//---------------------------------------------------void int_ext0(void ) interrupt 0{r ed_led=0;s ta=SPI_Read(STATUS);i f(RX_DR==1){SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);SPI_RW_Reg(WRITE_REG + STA TUS, sta); //清除中断temp=0x55;}i f(TX_DS==1){SPI_RW_Reg(WRITE_REG + STA TUS, sta); //清除中断temp=0x66;}e lse if(MAX_RT==1){SPI_RW_Reg(FLUSH_TX,0 );SPI_RW_Reg(WRITE_REG + STA TUS, sta); //清除中断temp=0x77;}r ed_led=1;f lag_ex0_isr=1;}//---------------------------------------------------这是nrf2401.c文件#include "comm.h"uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX addressuchar xdata rx_buf[TX_PLOAD_WIDTH];uchar xdata tx_buf[TX_PLOAD_WIDTH];/**************************************************Function: delay100();void delay100(void ){u char x;u char y;f or(x=0;x<100;x++){for(y=0;y<100;y++)_nop_();}}/*************************************************/void delay_ms(unsigned int x){unsigned int i,j;i=0;for(i=0;i<x;i++){j=208;while(j--);}}/**************************************************/void init_io(void){C E =0;C SN=1;S CK=0;}/************************************************** Function: SPI_RW();Description:Writes one byte to nRF24L01, and return the byte readfrom nRF24L01 during write, according to SPI protocol/**************************************************/uchar SPI_RW(uchar byte){u char bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (byte & 0x80); // output 'byte', MSB to MOSIbyte = (byte << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..byte |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again/**************************************************Function: SPI_RW_Reg();Description:Writes value 'value' to register 'reg'/**************************************************/uchar SPI_RW_Reg(BYTE reg, BYTE value){u char status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status byte}/**************************************************//**************************************************Function: SPI_Read();Description:Read one byte from nRF24L01 register, 'reg'/**************************************************/BYTE SPI_Read(BYTE reg){B YTE reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/**************************************************//**************************************************Function: SPI_Read_Buf();Description:Reads 'bytes' #of bytes from register 'reg'Typically used to read RX payload, Rx/Tx address/**************************************************/uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes){u char status,byte_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)p Buf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01/**************************************************Function: SPI_Write_Buf();Description:Writes contents of buffer '*pBuf' to nRF24L01Typically used to write TX payload, Rx/Tx address/**************************************************/uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes){u char status,byte_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status bytefor(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)S PI_RW(*pBuf++);CSN = 1; // Set CSN high againreturn(status); // return nRF24L01 status byte}/**************************************************//**************************************************Function: RX_Mode();Description:This function initializes one nRF24L01 device toRX Mode, set RX address, writes RX payload width,select RF channel, datarate & LNA HCURR.After init, CE is toggled high, which means thatthis device is now ready to receive a datapacket./**************************************************/void RX_Mode(void){C E=0;SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX deviceSPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload widthSPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..CE = 1; // Set CE pin high to enable RX device// This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address // '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps. }Description:This function initializes one nRF24L01 device toTX mode, set TX address, set RX address for auto.ack,fill TX payload, select RF channel, datarate & TX pwr.PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.ToDo: One high pulse(>10us) on CE will now send thispacket and expext an acknowledgment from the RX device./**************************************************/void TX_Mode(void){u char tmp_r=0;C E=0;SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.AckSPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payloadSPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x2a); // 500us + 86us, 10 retrans...SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR //SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..S PI_RW_Reg(WRITE_REG + CONFIG, 0x1e);C E=1;C SN = 0;/*tmp_r= SPI_Read(0);s end_one_byte(tmp_r);t mp_r= SPI_Read(1);s end_one_byte(tmp_r);t mp_r= SPI_Read(2);s end_one_byte(tmp_r);t mp_r= SPI_Read(7);*/t mp_r= SPI_Read(7);i f((tmp_r&0x01)==0x01){SPI_RW_Reg(STATUS,tmp_r);SPI_RW_Reg(FLUSH_TX,0);}C SN = 1;}**************************************************/void nRF24L01_TxPacket(uchar *tx_buf){C E=0;;S PI_RW_Reg(FLUSH_TX, 0x00);SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.AckSPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payloadC E=1;;d elay_ms(1);}这是公共头文件comm.h#include <intrins.h>#include "reg52.h"#include "init.h"#include "api.h"#include "NRF2401.H"//-----------------------------------------------------------------------#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width#define TX_PLOAD_WIDTH 20 // 20 bytes TX payload#define RX_PLOAD_ADDR 0X61 //READ RX BUFFER#define LEFT 1#define RIGHT 0#define TIMER1_EN 0 //0=用来作UART波特率发生器//#define TIMER1_EN 1 //1=用来作定时器sbit run_led= P2^1;sbit red_led= P2^0;sbit CE = P1^4; //dsgsdfgdgsdsbit CSN= P1^2;sbit SCK= P1^0;sbit MOSI= P1^1; //发送sbit MISO= P1^3; //接收sbit IRQ = P3^2; //中断。

stc12单片机SPI的nrf24l01程序

stc12单片机SPI的nrf24l01程序

stc12单片机SPI的nrf24l01程序/////////////////////发送/////////////////////////////// #include <reg52.h>#include <intrins.h>typedef unsigned char uchar;#define uint unsigned int//****************************************IO端口定义***************************************sfr SPCTL = 0xCE;//SPI Control Register SSIG SPEN DORD MSTR CPOL CPHASPR1 SPR0 0000,0100sfr SPSTAT = 0xCD;//SPI Status Register SPIF WCOL - - - -- - 00xx,xxxxsfr SPDAT = 0xCF;sbit CE =P1^0;sbit CSN =P1^1;sbit IRQ =P1^2;sbit led=P1^3;//********************************************************* ********************************* uchar bdata sta;//状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;//*********************************************NRF24L01*************************************#define TX_ADR_WIDTH 5// 5 uints TX address width#define RX_ADR_WIDTH 5// 5 uints RX address width#define TX_PLOAD_WIDTH 32// 32 uints TX payload#define RX_PLOAD_WIDTH 32// 32 uints TX payloaduchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//本地地址uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//接收地址 uchar codeTx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x2 2,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa ,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据 ucharRx_Buf[RX_PLOAD_WIDTH];//接收数据//***************************************NRF24L01寄存器指令*******************************************************#define READ_REG 0x00 // 读寄存器指令 #defineWRITE_REG 0x20 // 写寄存器指令 #define RD_RX_PLOAD 0x61 // 读取接收数据指令 #define WR_TX_PLOAD 0xA0 // 写待发数据指令 #define FLUSH_TX0xE1 // 冲洗发送FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 #define REUSE_TX_PL 0xE3 // 定义重复装载数据指令#define NOP 0xFF // 保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 #define EN_AA 0x01 // 自动应答功能设置 #define EN_RXADDR 0x02 // 可用信道设置#define SETUP_AW 0x03 // 收发地址宽度设置 #defineSETUP_RETR 0x04 // 自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 // 发射速率、功耗功能设置 #define STATUS 0x07 // 状态寄存器 #define OBSERVE_TX 0x08 // 发送监测功能 #defineCD 0x09 // 地址检测 #define RX_ADDR_P0 0x0A // 频道0接收数据地址#defineRX_ADDR_P1 0x0B // 频道1接收数据地址 #defineRX_ADDR_P2 0x0C // 频道2接收数据地址 #defineRX_ADDR_P3 0x0D // 频道3接收数据地址 #defineRX_ADDR_P4 0x0E // 频道4接收数据地址 #defineRX_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栈入栈出状态寄存器设置/******************************************延时函数********************************************************///长延时 void Delay(unsigned int s) { unsigned int i,j;for(i=0;i<1000;i++)for(j=0;j<s;j++); } //短延时 voiddelay_ms(unsigned int x) { unsigned int i,j; i=0;for(i=0;i<x;i++) { j=108; while(j--); } } /************初始化5A spi***************/ void Init_SPI() { SPDAT=0; //初始化数据寄存器 SPSTAT=0XC0; //清除状态寄存器SPCTL=0XD2;//设置为主机模式主频不能超过2M //忽略SS 使能spi MSB SCLK空闲为0 第一个时钟边沿开始采集 spi通信的频率为CUP_CLK/16 } //SPDAT 读写一个字节 //TxData:要写入的字节//返回值:读取到的字节 uchar SPI_ReadWriteByte(uchar TxData){ SPDAT=TxData; //发送一个bytewhile((SPSTAT&0x80)==0); SPSTAT=0XC0; //清除状态寄存器 return SPDAT; //返回收到的数据 } //读取SPI寄存器值 //reg:要读的寄存器 uchar SPI_Read_Reg(uchar reg) { uchar reg_val; CSN = 0; //使能SPI传输SPI_ReadWriteByte(reg); //发送寄存器号reg_val=SPI_ReadWriteByte(0xFF);//读取寄存器内容 CSN = 1;//禁止SPI传输 return(reg_val); //返回状态值 } // 向寄存器REG写一个字节,同时返回状态字节reg寄存器地址 value写入的数据 uchar SPI_RW_Reg (ucharreg,uchar value) { uchar status; CSN=0;status=SPI_ReadWriteByte(reg);//发送寄存器号SPI_ReadWriteByte(value); //写入寄存器的值 CSN=1;return(status); } //写一个数据包 ucharSPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) { ucharstatus,byte_ctr; CSN = 0;status=SPI_ReadWriteByte(reg); for(byte_ctr=0; byte_ctr<bytes;byte_ctr++) SPI_ReadWriteByte(*pBuf++); CSN = 1; return(status); } //读一个数据包 uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) { uchar status,uchar_ctr; CSN = 0;status = SPI_ReadWriteByte(reg);for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr]=SPI_ReadWriteByte(0xFF); CSN = 1; return(status); } /*******************************接 ***** 收 ***** 模 *****式 ***** 代 ***** 码 *************************************//*********************************************************************** *******************************/ /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) /*功能:数据读取后放如rx_buf接收缓冲区中/******************************************************************* ***********************************/ unsigned charnRF24L01_RxPacket(unsigned char* rx_buf) { // unsigned char revale=0; sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况 SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志 if(RX_DR) // 判断是否接收到数据{ SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferSPI_RW_Reg(FLUSH_RX,0xFF);//清除接受FIFO return 1;//读取数据完成标志 } return 0; }/******************************************************************* *********************************/ /*函数:voidRX_Mode(void) /*功能:数据接收配置/******************************************************************* *********************************/ void RX_Mode(void) { CE=0; //SPI_RW_Reg(FLUSH_RX,0x00);//清除接受FIFO //SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack SPI_RW_Reg(WRITE_REG + EN_AA,0x01);//使能自动应答 Enable Auto.Ack:Pipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //连接通道0和地址 Enable Pipe0//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a SPI_RW_Reg(WRITE_REG + RF_CH, 40);//通信频率0~125 设置通信的频率 Select RF channel 40SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节 SPI_RW_Reg(WRITE_REG +RF_SETUP,0X07); //0x07 TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR // 设置TX发射参数,0db增益,2Mbps,低噪声增益开启 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);//配置基本工作模式的参数 CE=1; delay_ms(130); }//************************************串口初始化********************************************************* void StartUART( void ) { //波特率9600 TMOD=0x20;//设置定模式2 TH1=0xFD; TL1=0xFD; SM1=1; //设置串口SCON,为方式1 SM0=0; REN=1; //串行允许 TR1=1; //启动定时器EA=1; //中断 ES=1; //打开串口 }//************************************通过串口将接收到数据发送给PC端 ************************************** voidR_S_Byte(uint R_Byte) { ES=0; SBUF=R_Byte; while(TI==0); TI=0; ES=1; } /************************************主函数************************************************************/ uchar NRF24L01_Check(void) { ucharbuf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; uchar i;SPI_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.SPI_Read_Buf(TX_ADDR,buf,5); //读出写入的地址for(i=0;i<5;i++) if(buf[i]!=0XA5) break; if(i!=5) return 1;//检测24L01错误 return 0; //检测到24L01 } void main() { uint i=0; CE=0; CSN=1; led=0; Init_SPI(); StartUART(); //串口初始while(NRF24L01_Check())//检测不到24L01 { delay_ms(500);delay_ms(500); R_S_Byte(0x11); } //接收模式代码 RX_Mode(); //接受模式 Delay(10);//防止编译警告 while(1){ if(nRF24L01_RxPacket(Rx_Buf)) { for(i=0;i<TX_PLOAD_WIDTH;i++) { R_S_Byte(Rx_Buf[i]); //发送接收到的数据到电脑 } } Delay(10); } }。

nrf24l01发送接收点对点 汇编程序

nrf24l01发送接收点对点 汇编程序

;延时14s子程序
YANSHI1S MOV R7,#250
YANSHI1S1 MOV R6,#250
YANSHI1S2 NOP
NOP
DJNZ R6,YANSHI1S2
DJNZ R2,DUZT1
SETB P1.7 ;CSN变高,完成一次命令
RET
START MOV P1,#0AFH ;模块待机
DJNZ R6,DL0
DJNZ R7,DL1
RET
;将58开始的单或多字节(字节数在R3中)写入芯片
XIENB MOV R0,#58H
CLR P1.7 ;SCN变低
MOV 58H,#21H ;01寄存器
MOV 59H,#03H ;0,1通道允许自动应答
MOV R3,#02H
LCALL XIENB
MOV P1.5,C ;数据送上MOSI线
SETB P1.4 ;数据移入模块
CLR P1.4
SETB P1.6 ;启动发射
MOV R7,#5
DJNZ R7,$
CLR P1.6
MOV R3,#02H
LCALL XIENB
MOV 58H,#2AH ;0A寄存器(通道0)
MOV 59H,#02H ;配置地址
DJNZ R2,XIE1B1
RET
;读芯片状态字 将芯片状态字读到5FH
DUZT MOV R2,#8
SETB P1.5
MOV R0,#70H
XIEXUN LCALL XIE1B
INC R0
DJNZ R3,XIEXUN
SETB P1.7
MOV 58H,#31H ;11寄存器

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序作者:codebaby 文章来源:codebaby 点击数: 1351 更新时间:2011-8-18最近弄了几天的无线模块,玩的是NRF2L01,因为这款无线模块价格便宜,网上也就卖10多块钱!刚开始用51写,“百度一下”发现网上的程序真是百篇一律,你抄我,我抄你。

对比了几个程序之后,发现他们的程序注释也是自相矛盾,看了的唯一收获就是,结合技术资料,对NRF24L01的工作模式和通信过程有了个总体的把握。

用51调了几次没成功,改而用430板子来写。

在网上查了一些相关的程序,终于成功了。

现在发现其实要写对NRF24L01的基本通信程序并不难,当然要玩转它又是另外一回事了。

我也刚刚才玩会单通道接收发送这个工作模式,其他的工作模式还没玩!还是附上相应的程序供大家学习交流,当然程序可能难免还有疏漏和错误,还望比拼指出!这是NRF24L01的头文件配置程序:#include <msp430x14x.h>//=======================NRF24L01_CE 端口========================================= #define RF24L01_CE_0 P3OUT &=~BIT1#define RF24L01_CE_1 P3OUT |= BIT1//=============================RF24L01_CSN 端口================================== #define RF24L01_CSN_0 P3OUT &=~BIT3#define RF24L01_CSN_1 P3OUT |= BIT3//=============================RF24L01_SCK 端口====================================== #define RF24L01_SCK_0 P3OUT &=~BIT2#define RF24L01_SCK_1 P3OUT |= BIT2//=============================RF24L01_MISO 端口=========================================#define RF24L01_MISO_0 P3OUT &=~BIT0#define RF24L01_MISO_1 P3OUT |= BIT0//============================= RF24L01_MOSI 端口================================ #define RF24L01_MOSI_0 P2OUT &=~BIT6#define RF24L01_MOSI_1 P2OUT |= BIT6//==========================IRQ 状态============================================ #define RF24L01_IRQ_0 P2OUT &=~BIT7#define RF24L01_IRQ_1 P2OUT |= BIT7//==========================NRF24L01地址,接收发送数据长度=============================== =============#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 32 TX payload //这里可以更改你想要发送和接收的数据长度如果是发指令我喜欢越短越好#define RX_PLOAD_WIDTH 32 // 32 uints TX payload//=========================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 NOP1 0xFF // 保留//========================SPI(nRF24L01)寄存器地址===============================#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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//=============================RF24l01状态=====================================char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址//我刚开始学的时候对这个发送和接收地址不是很明白,为什么他要设置成这样,后来才知道这个地址是用户自己定的,也就是说不是每个芯片只有唯一的地址,只要发送和接收端的地址一致就行char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址char sta;char TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; //这个程序要发送的数据void RF24L01_IO_set(void);void ms_delay(void);void InitSys();void Delay(int s);char SPI_RW(char data);char SPI_Read(char reg);char SPI_RW_Reg(char reg, char value);char SPI_Read_Buf(char reg, char *pBuf, char uchars);char SPI_Write_Buf(char reg, char *pBuf, char uchars);void SetRX_Mode(void);char nRF24L01_RxPacket(char* rx_buf);void nRF24L01_TxPacket(char * tx_buf);void init_NRF24L01(void);//===========================RF24L01端口设置========================================== void RF24L01_IO_set(void){P2DIR &= 0x7f; P2DIR |= 0x40; P2SEL&=0x3F; P2IE=P2IE&0x3f;P3DIR &= 0xFE; P3DIR |= 0x0E; P3SEL&=0xF0;}//******************************************************************************//系统初始化打开430XT2晶振//******************************************************************************void InitSys(){unsigned int iq0;_DINT();BCSCTL1 &=~XT2OFF;do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM1+SELS; // MCLK,SMCLK时钟为XT2}//========================延时约5ms============================================= void ms_delay(void){unsigned int i=40000;while (i != 0){i--;}}//========================================长延时================================ void Delay(int s){unsigned int i,j;for(i=0; i<s; i++);for(j=0; j<s; j++);}//****************************************************************************************** //延时函数//****************************************************************************************** void inerDelay_us(char n){for(;n>0;n--);}//============================================================================== //函数:uint SPI_RW(uint uchar)//功能:NRF24L01的SPI写时序//******************************************************************************char SPI_RW(char data){char i,temp=0;for(i=0;i<8;i++) // output 8-bit{if((data & 0x80)==0x80){RF24L01_MOSI_1; // output 'uchar', MSB to MOSI}else{RF24L01_MOSI_0;}data = (data << 1); // shift next bit into MSB..temp<<=1;RF24L01_SCK_1; // Set SCK high..if((P3IN&0x01)==0x01)temp++; // capture current MISO bitRF24L01_SCK_0; // ..then set SCK low again}return(temp); // return read uchar}//*********************************************************************************************** *****//函数:uchar SPI_Read(uchar reg)//功能:NRF24L01的SPI时序//*********************************************************************************************** *****char SPI_Read(char reg){char reg_val;RF24L01_CSN_0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueRF24L01_CSN_1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}//*********************************************************************************************** *****///功能:NRF24L01读写寄存器函数//*********************************************************************************************** *****/char SPI_RW_Reg(char reg, char value){char status1;RF24L01_CSN_0; // CSN low, init SPI transactionstatus1 = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..RF24L01_CSN_1; // CSN high againreturn(status1); // return nRF24L01 status uchar}//*********************************************************************************************** *****///函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数//****************************************************************************************************/char SPI_Read_Buf(char reg, char *pBuf, char chars){char status2,uchar_ctr;RF24L01_CSN_0; // Set CSN low, init SPI tranactionstatus2 = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<chars;uchar_ctr++){pBuf[uchar_ctr] = SPI_RW(0);}RF24L01_CSN_1;return(status2); // return nRF24L01 status uchar}//*********************************************************************************************** **********//函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于写数据reg:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数//*********************************************************************************************** **********/char SPI_Write_Buf(char reg, char *pBuf, char chars){char status1,uchar_ctr;RF24L01_CSN_0; //SPI使能status1 = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<chars; uchar_ctr++){SPI_RW(*pBuf++);}RF24L01_CSN_1; //关闭SPIreturn(status1);}//*********************************************************************************************** *****///函数:void SetRX_Mode(void)//功能:数据接收配置//*********************************************************************************************** *****/void SetRX_Mode(void){RF24L01_CE_0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收RF24L01_CE_1;inerDelay_us(130); //注意不能太小}//*********************************************************************************************** *******///函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)//功能:数据读取后放如rx_buf接收缓冲区中//*********************************************************************************************** *******/char nRF24L01_RxPacket(char* rx_buf){char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(sta&0x40) // 判断是否接收到数据{RF24L01_CE_0 ; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer revale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}//*********************************************************************************************** ************//函数:void nRF24L01_TxPacket(char * tx_buf)//功能:发送tx_buf中数据//*********************************************************************************************** ***********/void nRF24L01_TxPacket(char * tx_buf){RF24L01_CE_0 ; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送RF24L01_CE_1; //置高CE,激发数据发送inerDelay_us(10);}//****************************************************************************************//NRF24L01初始化//***************************************************************************************/void init_NRF24L01(void){inerDelay_us(100);RF24L01_CE_0 ; // chip enableRF24L01_CSN_1; // Spi disableRF24L01_SCK_0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Pa ge21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0E); // IRQ收发完成中断响应,16位CRC ,主接收}}//=============================================================================下面是发送主程序:#include <msp430x14x.h>#include "NRF24L01.h"void main(){WDTCTL = WDTPW + WDTHOLD; //禁止看门狗RF24L01_IO_set();InitSys();init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // 将要发送的数据转移到发送缓冲区while(1){nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器ms_delay();ms_delay();LED1_1;ms_delay();ms_delay();LED1_0;}}下面是接收主程序:将接收到的数据发送到PC 可以通过串口助手来查看接收到数据是否正确#include <msp430x14x.h>#include "NRF24L01.h"char RxBuf[32]={0};//===============================串口初始化=====================================void init_uart0(void){//====================串口工作模式设置========================================U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当CHAR=1时为8位数据//不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置========================================U0TCTL=0x00; //U0TCTL包含串口0发送功能操作U0TCTL +=SSEL0; //波特率发生器选择ACLK//#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。

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

NRF24L01全双工调试程序 自动切换收发模式 可用于实现对讲机
#define RX_ADDR_P1 0x0B //频道1接收数据地址
#define RX_ADDR_P2 0x0C //频道2接收数据地址
#define RX_ADDR_P3 0x0D //频道3接收数据地址
#define R据地址
#define RX_ADDR_P5 0x0F //频道5接收数据地址
函数:uchar SPI_Read(uchar reg)
功能:NRF24L01的SPI时序
#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
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//接收地址
//***************************************NRF24L01寄存器指令**********************************//
#define EN_AA 0x01 //自动应答功能设置
#define EN_RXADDR 0x02 //可用信道设置
#define SETUP_AW 0x03 //收发地址宽度设置
#define SETUP_RETR 0x04 //自动重发功能设置
#define RF_CH 0x05 //工作频率设置
//NRF24L01调试程序,全双工双向通信,即两个模块兼具收发功能,自动高速切换收发模式。

NRF24L01的发送与接收程序

NRF24L01的发送与接收程序

#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//**************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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 // 保留//*************************************SPI(nRF24L01)寄存器地址#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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//*****************************************************************************void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uint SPI_RW(uint uchar);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uint SPI_RW_Reg(uchar reg, uchar value);uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/******************************************************************************/*延时函数void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//*****************************************************************************/*NRF24L01初始化//*****************************************************************************/void init_NRF24L01(void){inerDelay_us(100);CE=0; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收}/******************************************************************************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************************************************************************uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{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; // ..then set SCK low again}return(uchar); // return read uchar}/******************************************************************************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/******************************************************************************uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*****************************************************************************//*功能:NRF24L01读写寄存器函数/*****************************************************************************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*****************************************************************************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*****************************************************************************/uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/******************************************************************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/*****************************************************************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/*****************************************************************************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/*****************************************************************************/void SetRX_Mode(void){CE=0;// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1;inerDelay_us(130);}/*****************************************************************************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/*****************************************************************************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/******************************************************************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送 tx_buf中数据/*****************************************************************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************串口初始化void StartUART( void ){ //波特率4800SCON = 0x50;TMOD = 0x20;TH1 = 0xFA;TL1 = 0xFA;PCON = 0x00;TR1 = 1;}//************************************通过串口将接收到数据发送给PC端void R_S_Byte(uchar R_Byte){SBUF = R_Byte;while( TI == 0 ); //查询法TI = 0;}//************************************主函数void main(void){uchar i,temp;uchar RxBuf[32];init_NRF24L01() ;StartUART();Delay(6000);while(1){SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)){LED=0;temp++;for(i=0;i<32;i++){R_S_Byte(RxBuf[i]);Delay(600);}}LED=1;Delay(600);}}#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//***********************************发送缓冲区uchar TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; ////*********************************************NRF24L01*********************** #define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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 // 保留//*************************************SPI(nRF24L01)寄存器地址#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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//*****************************************************************************void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uint SPI_RW(uint uchar);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uint SPI_RW_Reg(uchar reg, uchar value);uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/******************************************************************************/*延时函数/*****************************************************************************/void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//*****************************************************************************/*NRF24L01初始化//****************/void init_NRF24L01(void){inerDelay_us(100);CE=0; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/**************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************/uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSI uchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/********************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication... SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*******************//*功能:NRF24L01读写寄存器函数/*********************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*********************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*********************/uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/**************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/**************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/********************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收inerDelay_us(130); //延时不能太短}/**********************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/***********************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/****************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送 tx_buf中数据/****************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************主函数void main(void){uchar temp =0;init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(6000);P0=0xBF;{nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer data LED=0;Delay(10000); //可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}}。

NRF24L01的发送与接收程序

NRF24L01的发送与接收程序

#include <> #include <>typedef unsigned char uchar;typedef unsigned char uint;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1; // CSN high again/* 函数: uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) /* 功能 : 用于读数据,reg :为寄存器地址,pBuf :为待读出数据地址, uchars :读出数据的个数******************* uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranaction return(status); }// return nRF24L01 status ucharstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/**************************/* 函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/* 功能: 用于写数据:为寄存器地址,pBuf :为待写入数据地址,uchars :写入数据的个数/**************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI 使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; // 关闭SPIreturn(status); ///********************//* 函数:void SetRX_Mode(void)/* 功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); 接收CE = 1;inerDelay_us(130); // 延时不能太短}/**********************//* 函数: unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/* 功能:数据读取后放如 rx_buf 接收缓冲区中/***********************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI 使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload frombuffer// IRQ 收发完成中断响应, 16 位 CRC,主 FIFOSPI_RW_Reg(WRITE_REG+STATUS,sta); // 接收到数据后RX_DR,TX_DS,MAX_P都置高为1 通过写1 来清楚中断标志return revale;}/****************************/* 函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/* 功能:发送tx_buf 中数据/****************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //StandBy I 模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据// SPI_RW_Reg(WRITE_REG + CONFIG, OxOe); // IRQ 收发完成中断响应,16 位CRC 主发送CE=1; //置高CE激发数据发送inerDelay_us(1O);}//************************************ void main(void){uchar temp =O;init_NRF24LO1() ;nRF24LO1_TxPacket(TxBuf);Delay(6OOO);PO=OxBF;主函数// Transmit Tx buffer datawhile(1)nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataLED=0;Delay(10000); // 可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}。

ATmega16— nrf24l01接收程序

ATmega16—  nrf24l01接收程序

/** nrf24l01_jieshou.c** Created: 2015/4/4 11:53:11* Author: LOVE*//************************************************************************/ /* 常用头文件及宏定义*/ /************************************************************************/#include <avr/io.h>#include <util/delay.h> //延时文件#include <avr/sleep.h> //睡眠文件#include <avr/interrupt.h> //中断文件#include <avr/eeprom.h> //eeprom#define BIT(x) (1<<(x))#define uchar unsigned char#define uint unsigned int/************************************************************************/ /* USART程序*/ /************************************************************************//* 引脚说明*/ /* PD0 RXD PD 1 PXD */void chushihua_usart(){UCSRB|=BIT(TXEN);UCSRC|=BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0);//8位UBRRH=0;UBRRL=25;//19.2K波特率}void write_char_usart(char shuju){while(!(UCSRA&BIT(UDRE)));UDR=shuju;}void write_string_usart(char *str){while(*str!='\0'){write_char_usart(*str);str++;}}/************************************************************************/ /* NRF24L01 */ /************************************************************************/// PA0 CE PA1 CSN PA2 SCK PA3 MOSI PA4 MISO PA5 IQR#define DDR_NRF2401 DDRA#define PORT_NRF2401 PORTA#define PIN_NRF2401 PINA#define CE_H PORT_NRF2401|=BIT(0)#define CE_L PORT_NRF2401&=~BIT(0)#define CSN_H PORT_NRF2401|=BIT(1)#define CSN_L PORT_NRF2401&=~BIT(1)#define SCK PORT_NRF2401|=BIT(2),PORT_NRF2401&=~BIT(2)#define MOSI_H PORT_NRF2401|=BIT(3)#define MOSI_L PORT_NRF2401&=~BIT(3)#define MISO_PIN (PIN_NRF2401&BIT(4))#define IQR_PIN (PIN_NRF2401&BIT(5))char a[3]={0};char read_peizhi(char dizhi){CSN_L;char i;for (i=0;i<8;i++){if (dizhi&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}dizhi=0;for (i=0;i<8;i++){_delay_us(10);if (MISO_PIN){dizhi+=BIT(7-i);}SCK;}CSN_H;return dizhi;}void write_peizhi(char dizhi,char shuju) {char i;CSN_L;dizhi+=BIT(5);for (i=0;i<8;i++){if (dizhi&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}for (i=0;i<8;i++){if (shuju&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}CSN_H;}void read_shuju(uchar n){uchar i,j;CSN_L;for (i=0;i<8;i++){if (0x61&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}for (j=0;j<n;j++){a[j]=0;for (i=0;i<8;i++){_delay_us(10);if (MISO_PIN){a[j]+=BIT(7-i);}SCK;}}CSN_H;}void write_shuju(char shuju) {char i;CSN_L;for (i=0;i<8;i++){if (0xa0&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}for (i=0;i<8;i++){if (shuju&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}CSN_H;}void qingchu_tx(){char i;CSN_L;for (i=0;i<8;i++){if (0xe1&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}CSN_H;}void qingchu_rx(){char i;CSN_L;for (i=0;i<8;i++){if (0xe2&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}CSN_H;}char read_zhuangtai(){CSN_L;char i,zhuangtai=0;MOSI_H;for (i=0;i<8;i++){SCK;_delay_us(40);if (MISO_PIN){zhuangtai+=BIT(7-i);}}CSN_H;return zhuangtai;}void read_dizhi(char dizhi,char *shuju,char zijie) {CSN_L;char i,j;for (i=0;i<8;i++){if (dizhi&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}shuju+=zijie;for (j=0;j<zijie;j++){shuju--;*shuju=0;for (i=0;i<8;i++){_delay_us(10);if (MISO_PIN){*shuju+=BIT(7-i);}SCK;}}CSN_H;}void write_dizhi(char dizhi,char *shuju,char zijie) {char i,j;CSN_L;dizhi+=BIT(5);for (i=0;i<8;i++){if (dizhi&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}shuju+=zijie;for (j=0;j<zijie;j++){shuju--;for (i=0;i<8;i++){if (*shuju&BIT(7-i)){MOSI_H;}else{MOSI_L;}SCK;}}CSN_H;}void chushihua_nrf2401(){DDR_NRF2401|=BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(5);DDR_NRF2401&=~(BIT(4)|BIT(5));PORT_NRF2401|=BIT(4)|BIT(5);CSN_H;CE_L;char dizhi[5]={'l','o','v','e',0x01};write_peizhi(0,0x0b);write_peizhi(0x02,1);write_dizhi(0x0a,dizhi,5);//接收地址love01dizhi[4]=0x02;write_dizhi(0x10,dizhi,5);//发送地址love02write_peizhi(0x11,0x03);//接收数据宽度3CE_H;}/************************************************************************/ /* 中断*/ /************************************************************************/void chushihua_int0(){MCUCR|=BIT(ISC01);GICR|=BIT(INT0);DDRD&=~BIT(2);PORTD|=BIT(2);sei();}ISR(INT0_vect){uchar zhuangtai,i,j;zhuangtai=read_peizhi(0x07);write_string_usart("状态");for (i=0;i<8;i++){if (zhuangtai&BIT(7-i)){write_char_usart('1');}else{write_char_usart('0');}}if (zhuangtai&BIT(6)){read_shuju(3);for (j=0;j<3;j++){write_string_usart(" | 数据");write_char_usart(j+'0');write_char_usart(' ');for (i=0;i<8;i++){if (a[j]&BIT(7-i)){write_char_usart('1');}else{write_char_usart('0');}}}write_peizhi(0x07,BIT(6));zhuangtai=read_peizhi(0x07);write_string_usart(" | 状态");for (i=0;i<8;i++){if (zhuangtai&BIT(7-i)){write_char_usart('1');}else{write_char_usart('0');}}}write_char_usart(0x0d);write_char_usart(0x0a);}/************************************************************************/ /* 主函数*/ /************************************************************************/int main(){chushihua_usart();chushihua_nrf2401();chushihua_int0();while(1){}}。

NRF24L01接收程序

NRF24L01接收程序

/*************************************************头文件:NRF24L01.h**文件名: NRF24L01.c**创建人: 动车组**日期: 2012-8-21•**功能描述:用NRF24L01发送一定字节数的数据或者接收数据**占用资源:四位控制SPI总线的IO线和1位NRF24L01模式控制引脚** 占用一个中段***********************************************/#include"nrf24l01.h"uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar code RX_ADDRESS_0[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//为了应答接收设备,接收通道0地址和发送地址相同//uchar code RX_ADDRESS_1[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道1地址//通道1-5最有最低字节不一样//uchar code RX_ADDRESS_2[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道2地址//且写地址的时候是低字节先写//uchar code RX_ADDRESS_3[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道3地址//uchar code RX_ADDRESS_4[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道4地址//uchar code RX_ADDRESS_5[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道5地址bit RX_OK = 0; //接收数据完成标志,在中断中置位bit TX_OK = 1; //数据发送完毕标志,在中断置位由于第一次要可以发送所以初值为1bit MAX_RT_OK=0; //发送次数超过设置的次数的标志在中断置位uchar bdata sta = 0x00; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/************************************以下是SPI的读写函数*********************************************//****************************************************************************** **********************/*函数:uchar SPI_RW(uchar date)/*功能:SPI一个字节写时序/****************************************************************************** **********************/uchar SPI_RW(uchar byte){SCK = 0;for(i=0; i<8; i++) // 循环8次{MOSI = (byte & 0x80); // byte最高位输出到MOSIbyte <<= 1; // 低一位移位到最高位SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据byte |= MISO; // 读MISO到byte最低位SCK = 0; // SCK置低}return(byte); // 返回读出的一字节}/****************************************************************************** **********************/*函数:uchar SPI_Read(uchar reg)/*功能:SPI 从reg中读出一个字节时序/****************************************************************************** **********************/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); // 返回寄存器数据}/****************************************************************************** **********************//*功能:SPI 在reg中写入数据value函数/****************************************************************************** **********************/void SPI_RW_Reg(uchar reg, uchar value){CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字SPI_RW(value); // 然后写数据到该寄存器CSN = 1; // CSN拉高,结束数据传输}/****************************************************************************** **********************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于SPI连读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出/****************************************************************************** **********************/void SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar i;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<bytes; i++)pBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出CSN = 1; // CSN拉高,结束数据传输}/****************************************************************************** ***************************/*函数:uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于SPI连写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************************** ***************************/void SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar i;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<bytes; i++)SPI_RW(pBuf[i]); // 逐个字节写入nRF24L01CSN = 1; // CSN拉高,结束数据传输}/*************************以下是nrf24l01的应用层函数*******************************************/void nrf_delay(){uint a=130*10;while(a--);}/*************************************************************************** NRF24L01初始化/**************************************************************************/ void init_NRF24L01(void){CE=0; // 待机// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // 配置寄存器设置为接收模式SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 通道0自动ACK应答允许0x01SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有通道0,如果需要多频道可以参考Page21 0x01// SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03); // 收发地址宽度设置为5个字节SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a); // 等待250+86us 重发10次SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS_0, RX_ADR_WIDTH); // 为了应答接收设备,接收通道0地址和发送地址相同SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地发送地址SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节EX1=1; //开外部中断1IT1=1; //下降沿触发EA=1; //开总中断}/***************************************************************************/*设置模式:b为0时是发送模式为1时是接收模式*//**************************************************************************/ void Set_Mode(char b){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e+b); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1; // 模式转换要等待130Usnrf_delay();}/****************************************************************************** *****************************/*函数:bit nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据返回1数据发送/****************************************************************************** ****************************/bit nRF24L01_TxPacket(uchar * tx_buf){bit val=0;if(TX_OK){TX_OK=0;CE=0; //StandBy I模式SPI_RW_Reg(WRITE_REG+STATUS,sta); //发送完数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志// CSN = 0; // CSN置低,开始传输数据// SPI_RW(FLUSH_TX);//数据成功发送到了接收端,此时状态寄存器的TX_DS位置高并把数据从TX FIFO中清除掉//所以这里就不要再清除TX FIFO了// CSN = 1; // CSN置低,开始传输数据SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送val = 1;}else if(MAX_RT_OK){MAX_RT_OK=0;SPI_RW_Reg(WRITE_REG+STATUS,sta); //发送完数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志CSN = 0; // CSN置低,开始传输数据SPI_RW(FLUSH_TX); //MAX_RT位置高,不清除TX FIFO 中的数据所以这里要清除TX FIFOCSN = 1;TX_OK=1;}return val;}/****************************************************************************** ************************//*函数:bit nRF24L01_RxPacket(uchar* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/****************************************************************************** ************************/bit nRF24L01_RxPacket(uchar* rx_buf){bit revale=0;if(RX_OK) // 判断是否接收到数据{RX_OK=0; //接收数据标志清零CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferSPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志CSN = 0; // CSN置低,开始传输数据SPI_RW(FLUSH_RX); //用于清空FIFO !!CSN = 1; // CSN置低,开始传输数据revale =1; //读取数据完成标志Set_Mode(1); //重新设置为接收模式}return revale;}/*NRF24L01 IRQ引脚产生的中断函数*/void Int_1() interrupt 2{sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) //接收到数据了RX_OK=1;if(TX_DS) //数据发送完毕TX_OK=1;if(MAX_RT)MAX_RT_OK=1;}/**************************************************//*************************************************文件名: NRF24L01.h**创建人: 动车组**日期: 2012-8-21•**功能描述:用NRF24L01发送一定字节数的数据或者接收数据**占用资源:四位控制SPI总线的IO线和1位NRF24L01模式控制引脚** 占用一个中段***********************************************/#ifndef __NRF24L01_H__#define __NRF24L01_H__#include <REG52.H>#define uint unsigned int#define uchar unsigned char//********************SPI 引脚号********************************sbit M ISO=P1^6; // 7 主入从出sbit SCK =P1^7; // 5 SPI 时钟由主机产生sbit CSN =P3^7; // 4 SPI使能为1时SPI禁止sbit MOSI=P1^5; // 6 主出从入//********************NRF24L01引脚*********************sbit CE =P3^6;sbit IRQ =P3^3; //中断引脚#define TX_PLOAD_WIDTH 32 // 发送字节数在这里设置发送和接收要一样#define RX_PLOAD_WIDTH 32 // 接收字节数在这里设置void init_NRF24L01(void); //NRF24L01初始化已经中断初始化了void Set_Mode(char b);///*设置模式:b为0时是发送模式为1时是接收模式*/bit nRF24L01_TxPacket(uchar * tx_buf);//发送tx_buf中数据返回1数据发送bit nRF24L01_RxPacket(uchar* rx_buf) ;//返回1时数据读取后放如rx_buf接收缓冲区中否则没有数据#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width//***************************************NRF24L01寄存器指令**********************************#define READ_REG 0x00 // 读寄存器指令/**************************************************000A AAAA 读配置寄存器;AAAAA 指出读操作的寄存器地址**************************************************/#define WRITE_REG 0x20 // 写寄存器指令/****************************************************************************** **************001A AAAA 写配置寄存器;AAAAA 指出写操作的寄存器地址只有在掉电模式和待机模式下可操作******************************************************************************* **************/#define RD_RX_PLOAD 0x61 // 读取接收数据指令/****************************************************************************** **************0110 0001 读RX有效数据;1-32字节,读操作全部从字节0开始,当读RX有效数据完成后FIFO寄存器中有效数据被清除;应用于接收模式下******************************************************************************* **************/#define WR_TX_PLOAD 0xA0 // 写待发数据指令/****************************************************************************** ***************1010 0000 写TX有效数据,1-32字节写操作,从字节0开始;应用于发射模式下/****************************************************************************** ***************/#define FLUSH_TX 0xE1 // 冲洗发送FIFO指令/****************************************************************************** ***************1110 0001 清除TX FIFO 寄存器,应用于发射模式下*********************************************************************************************/#define FLUSH_RX 0xE2 // 冲洗接收FIFO指令/****************************************************************************** ***************1110 0010 清除RX FIFO 寄存器;应用于接收模式下.在传输应答信号过程中不应执行此指令,也就是说若传输应答信号过程中执行此指令的话,将使得应答信号不能被完整的传输******************************************************************************* **************/#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令/****************************************************************************** ***************1110 0011 重新使用上一包有效数据,当CE为高过程中数据包被不断的重新发射在发射数据包过程中必须禁止数据包重利用功能******************************************************************************* **************/#define NOP 0xFF // 保留/****************************************************************************** ***************1111 1111 空操作,可以用来读状态寄存器******************************************************************************* **************///*************************************SPI(nRF24L01)寄存器地址*******************************#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式/****************************************************************************** ***************寄存器位复位值类型描述reserved 7 0 R/W 默认为0MASK_RX_DR 6 0 R/W 可屏蔽中断RX_RD,1:IRQ引脚不显示RX_RD中断;0:RX_RD中断产生时IRQ引脚电平为低MASK_TX_DS 5 0 R/W 可屏蔽中断TX_DS,1:IRQ引脚不显示TX_DS中断;0:TX_DS中断产生时IRQ引脚电平为低MASK_MAX_RT 4 0 R/W 可屏蔽中断MAX_RT,1:IRQ引脚不显示TX_DS 中断;0:MAX_RT中断产生时IRQ引脚电平为低EN_CRC 3 1 R/W CRC使能.如果EN_AA中任意一位为高,则EN_CRC强迫为高CRCO 2 0 R/W CRC 模式:‘0’-8 位CRC 校验;‘1’-16 位CRC 校验PWR_UP 1 0 R/W 1:上电;0:掉电PRIM_RX 0 0 R/W 1:接收模式0:发射模式******************************************************************************* **************/#define EN_AA 0x01 // 自动应答功能设置此功能禁止后可与nRF2401 通讯/****************************************************************************** ***************位7:6保留(00) 位5:0(11 1111):数据通道5-0自动应答允许******************************************************************************* **************/#define EN_RXADDR 0x02 // 可用信道设置接收地址允许/****************************************************************************** ***************位7:6保留(00) 位5:0(00 0011):接收数据通道5-0允许******************************************************************************* **************/#define SETUP_AW 0x03 // 收发地址宽度设置/****************************************************************************** ***************位7:2保留(0000 00) 位1:0(11):接收/发射地址宽度00:无效;01:三字节;10:四字节;11:五字节******************************************************************************* **************/#define SETUP_RETR 0x04 // 自动重发功能设置/****************************************************************************** ***************位7:4(0000) 自动重发延时= ((位7:4)+1)*250+86us延时时间是指一包数据发送完成到下一包数据开始发射之间的时间间隔位3:0(0011):自动重发计数自动重发(位3:0)次例如复位值是自动重发3次******************************************************************************* **************/#define RF_CH 0x05 // 工作频率设置/****************************************************************************** ***************位7保留(0) 位6:0(000 0010):设置nRF24L01 工作通道频率******************************************************************************* **************/#define RF_SETUP 0x06 // 射频寄存器/****************************************************************************** ***************位7:5保留(000) 位4(0):PLL_LOCK 允许;仅应用于测试模式位3(1): 数据传输率:‘0’–1Mbps ‘1’2 Mbps位2:1保留(11) 发射功率:00-18dBm 01-12dBm 10-6dBm 11 0dBm 位0(1) 低噪声放大器增益******************************************************************************* **************/#define STATUS 0x07 // 状态寄存器/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7 0 R/W 默认为0RX_DR 6 0 R/W 接收数据中断,当接收到有效数据后置一,写‘1’清除中断TX_DS 5 0 R/W 数据发送完成中断,当数据发送完成后产生中断.如果工作在自动应答模式下,只有当接收到应答信号后此位置一,写‘1’清除中断MAX_RT 4 0 R/W 达到最多次重发中断,写‘1’清除中断如果MAX_RT中断产生,则必须清除后系统才能进行通讯RX_P_NO 3:1 111 R 接收数据通道号000-101:数据通道号110:未使用111:RX FIFO 寄存器为空TX_FULL 0 0 R TX_FIFO寄存器满标志1:TX FIFO 寄存器满0: TX FIFO 寄存器未满,有可用空间******************************************************************************* **************/#define OBSERVE_TX 0x08 // 发送监测功能/****************************************************************************** ***************寄存器位复位值类型描述PLOS_CNT 7:4 0000 R 数据包丢失计数器,当写RF_CH 寄存器时此寄存器复位,当丢失15个数据包后此寄存器重启ARC_CNT 3:0 0000 R 重发计数器,发送新数据包时此寄存器复位******************************************************************************* **************/#define CD 0x09 // 地址检测载波检测/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7:1 000000 RCD 0 0 R 载波检测******************************************************************************* **************/#define RX_ADDR_P0 0x0A // 频道0接收数据地址/****************************************************************************** ***************寄存器位复位值类型描述RX_ADDR_P0 39:0 0xE7E7E7E7E7 R/W 数据通道0接收地址最大长度5个字节先写低字节所写字节数量由SETUP_AW设定******************************************************************************* **************/#define RX_ADDR_P1 0x0B // 频道1接收数据地址 (0xC2C2C2C2C2)#define RX_ADDR_P2 0x0C // 频道2接收数据地址 (0xC2C2C2C2C3)#define RX_ADDR_P3 0x0D // 频道3接收数据地址 (0xC2C2C2C2C4)#define RX_ADDR_P4 0x0E // 频道4接收数据地址 (0xC2C2C2C2C5)#define RX_ADDR_P5 0x0F // 频道5接收数据地址 (0xC2C2C2C2C6)#define TX_ADDR 0x10 // 发送地址寄存器先写低字节,在增强型ShockBurstTM模式下RX_ADDR_P0与此地址相等#define RX_PW_P0 0x11 // 接收频道0接收数据长度位7:6保留(00);(位5:0)个字节有效数据宽度(00 0000)#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栈入栈出状态寄存器设置/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7 0 R/W 默认为0TX_REUSE 6 0 R 若TX_REUSE=1,则当CE位高电平状态时,不断发送上一数据包TX_REUSE 通过SPI 指令REUSE_TX_PL 设置通过W_TX_PALOAD或FLUSH_TX 复位TX_FULL 5 0 R TX FIFO 寄存器满标志1:TX FIFO 寄存器满0: TX FIFO 寄存器未满有可用空间TX_EMPTY 4 1 R TX FIFO 寄存器空标志1:TX FIFO 寄存器空0: TX FIFO 寄存器非空Reserved 3:2 00 R/W 墨认为00RX_FULL 1 0 R RX FIFO 寄存器满标志1:RX FIFO 寄存器满0: RX FIFO 寄存器未满有可用空间RX_EMPTY 0 1 R RX FIFO 寄存器空标志1:RX FIFO 寄存器空0: RX FIFO 寄存器非空******************************************************************************* **************/#endif/****************************/#include <REG52.H>#include"C_Ko.h"#include"nrf24l01.h"#define uchar unsigned char#define uint unsigned intvoid main(){uchar tab[32];uchar i;UA TR_Init(); //串口初始化init_NRF24L01(); //NRF24L01初始化已经中断初始化了Set_Mode(1); //为1时是接收模式*/while(1){if(nRF24L01_RxPacket(tab)){for(i=0;i<32;i++){Uatr_Print_Char(tab[i]);Uatr_Prints("\t\n");}}}}/***********串口程序在这里!/view/5282ded1195f312b3169a5a0.html?st=1 ***************/。

NRF24L01多路通讯调试成功的关键--附程序文件

NRF24L01多路通讯调试成功的关键--附程序文件

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(); //初始化模块uchar TX_packet(uchar *tx_buf); //返回值判断是否成功uchar RX_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(uchar dat) // SPI读写指令{uchar i;for(i=0;i<8;i++){SCK = 0;MOSI = (dat&0x80);dat <<= 1;SCK = 1;dat |= MISO;}SCK = 0;return dat;}uchar NRF24L01_read_reg(uchar reg) //读某个寄存器的状态{uchar value;CSN=0; //拉低CSN,允许操作SPI_RW(reg); //写寄存器指令value = SPI_RW(0); //读寄存器值CSN=1; //拉高CSN,禁止操作return value; //返回寄存器状态}uchar NRF24L01_write_reg(uchar reg,uchar value) //写向某个寄存器写指令,并读出状态{uchar status;CSN=0; //拉低CSN,允许操作status = SPI_RW(reg); //写寄存器指令,并读出寄存器状态SPI_RW(value); //写寄存器值CSN=1; //拉高CSN,禁止操作return status; //返回寄存器之前的值}uchar NRF24L01_read_buf(uchar reg,uchar *pbuf,uchar n){uchar i,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(uchar reg,uchar *pbuf,uchar n){uchar i,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,次数15NRF24L01_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,发送功率最大值0dbNRF24L01_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;}uchar TX_packet(uchar *tx_buf){uchar tx_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);}uchar RX_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; //读取数据完成标志置1NRF24L01_write_reg(WRITE_REG + STATUS,0xff); //清除中断标志位}CE = 1;return revalue;//返回读取数据完成标志}。

NRF24L01功能使用文档

NRF24L01功能使用文档

NRF24L01功能使用文档一、NRF24L01的功能特点:1.双向通信:NRF24L01可以同时作为发送器和接收器,实现双向通信。

这意味着可以用它构建各种无线传感器网络。

2. 高速数据传输:NRF24L01的最大数据传输速率为2Mbps,这使得它可以用于高速数据传输的应用场景,如视频传输。

3.高可靠性:NRF24L01具有自动重复传输和错误检测功能。

当传输数据时,NRF24L01会自动重复发送数据,并在接收端检测错误。

这提高了数据传输的可靠性。

4.小尺寸和低功耗:NRF24L01的尺寸小,只有20针的QFN封装,适用于各种空间受限的应用场景。

同时,它的工作电压范围广,只需1.9-3.6V,功耗低。

5.多通道:NRF24L01支持多达125个通道,这使得它可以与其他无线设备同时工作,避免干扰。

二、NRF24L01的使用方法:1. 引脚连接:首先,将NRF24L01的引脚连接到主控制器(如Arduino)上。

连接时需要注意引脚的对应关系,如CE(引脚1)连接到主控制器的数字引脚9上,CSN(引脚2)连接到数字引脚10上,SCK (引脚3)连接到数字引脚13上,等等。

2.配置寄存器:NRF24L01有多个寄存器,用于配置各种参数。

可以通过SPI接口向这些寄存器写入数据来配置NRF24L01、例如,可以通过写入到寄存器地址0x00的数据来配置NRF24L01的发射功率、数据传输速率、等等。

3.发送数据:在发送数据之前,需要将NRF24L01设置为发送模式。

首先,将CE置高,然后向TXFIFO寄存器中写入数据。

NRF24L01会自动将数据传输给接收器,并等待接收器的确认。

4.接收数据:在接收数据之前,需要将NRF24L01设置为接收模式。

首先,将CE置高,然后等待数据的接收。

一旦接收到数据,可以从RXFIFO寄存器中读取数据。

5.错误处理:当数据传输过程中出现错误时,NRF24L01会自动重复发送数据。

NRF24L01无线收发的ARM程序

NRF24L01无线收发的ARM程序

#include "systemInit.h"#include "buzzer.h"#include "uartGetPut.h"#include <stdio.h>#include <string.h>typedef unsigned char uchar;typedef unsigned char uint;//*-----------定义KEY------------------------#define KEY_PERIPH SYSCTL_PERIPH_GPIOG#define KEY_PORT GPIO_PORTG_BASE#define KEY_PIN GPIO_PIN_5void buzzer00(){unsigned int x;buzzerInit(); // 蜂鸣器初始化for(x=6666;x>6333;x--){buzzerSound(x);SysCtlDelay(1 * (TheSysClock / 6000));}for(x=6333;x<6666;x++){buzzerSound(x);SysCtlDelay(1 * (TheSysClock / 3000));}//GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, 0x00);buzzerQuiet();}/*void buzzer11(){buzzer00();buzzer00();buzzer00();buzzerSound(200);SysCtlDelay(100 * (TheSysClock / 3000));buzzerQuiet();}void buzzer1(){unsigned int x;buzzerInit(); // 蜂鸣器初始化for(x=1333;x>888;x--){buzzerSound(x);SysCtlDelay(1 * (TheSysClock / 6000));}for(x=888;x<1333;x++){buzzerSound(x);SysCtlDelay(1 * (TheSysClock / 3000));}//GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, 0x00);buzzerQuiet();}*///-----------临时--------------------------*///------------NRF24L01 端口定义--------------------输出型-----------------------#define CE_PERIPH SYSCTL_PERIPH_GPIOA#define CE_PORT GPIO_PORTA_BASE#define CE_PIN GPIO_PIN_3 //sbit CE =P1^1; //PA3#define MOSI_PERIPH SYSCTL_PERIPH_GPIOA#define MOSI_PORT GPIO_PORTA_BASE#define MOSI_PIN GPIO_PIN_1 //sbit MOSI =P1^4; //PA1#define SCK_PERIPH SYSCTL_PERIPH_GPIOA#define SCK_PORT GPIO_PORTA_BASE#define SCK_PIN GPIO_PIN_2 //sbit SCK =P1^3; //PA2#define CSN_PERIPH SYSCTL_PERIPH_GPIOA#define CSN_PORT GPIO_PORTA_BASE#define CSN_PIN GPIO_PIN_4 //sbit CSN =P1^2; //PA4//------------nrf905状态标志-----------------读入型--------------------------#define MISO_PERIPH SYSCTL_PERIPH_GPIOA //sbit MISO =P1^5; //PA0#define MISO_PORT GPIO_PORTA_BASE#define MISO_PIN GPIO_PIN_0#define IRQ_PERIPH SYSCTL_PERIPH_GPIOG#define IRQ_PORT GPIO_PORTG_BASE#define IRQ_PIN GPIO_PIN_4 //sbit IRQ =P1^6; //PG4/************************************按键***************************************************sbit KEY1=P3^6;sbit KEY2=P3^7;************************************数码管位选*********************************************sbit led3=P2^0;sbit led2=P2^1;sbit led1=P2^2;sbit led0=P2^3;************************************蜂明器***************************************************sbit B ELL=P3^4;***********************************数码管0-9编码*******************************************uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9段码*********************************************NRF24L01************************ *************/#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 20 // 20 uints TX payload //打包长度#define RX_PLOAD_WIDTH 20 // 20 uints TX payloaduchar TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************NRF24L01寄存器指令*******************************************************//SPI指令#define READ_REG 0x00 // 读寄存器指令000AAAAA AAAAA指出读操作的寄存器地址#define WRITE_REG 0x20 // 写寄存器指令001AAAAA AAAAA指出写操作的寄存器地址,只能在掉电或待机模式下操作#define RD_RX_PLOAD 0x61 // 读取接收数据指令01100001 读RX有效数据,1~32字节。

NRF24L01无线模块收发程序(实测成功多图)

NRF24L01无线模块收发程序(实测成功多图)

NRF24L01无线模块收发程序(实测成功多图)本模块是NRF24L01无线传输模块,用于无线传输数据,距离不远,一般只是能够满足小距离的传输,目测是4-5m,价格一般是4元左右,可以方便的买到。

51最小系统学习板就可以,当时是用了两块学习板,一块用于发送,一块用于接收。

小车也是比较容易购到的,四个端口控制两个电机,两个控制一个电机,当两个端口高低电平不同时电机就会转动,即为赋值1和0是电机转动,赋值可以用单片机作用,当然这是小车启动部分,前进后退左转右转就是你赋值0和1的顺序问题了。

整体思路是用发射端的按键控制小车,即为按键按下就前进,再按其他按键实现其他功能,本次程序是在用NRF24L01发射数据在接收端用1602显示的基础上改变。

下面是程序源码(有好几个文件,分别创建)1.//////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////2.#include3.4.#include5.6.#include'1602.h'7.#include'delay.h'8.#include 'nrf24l01.h'9.#define uint unsigned int10.#define uchar unsigned char11.uint Weight_Shiwu=1234;12.unsigned char KeyScan(void);//键盘扫描13.// unsigned char KeyScan(void);//键盘扫描14.15.//#define KeyPort P016.sbit KEY1 = P0^0;17.sbit KEY2 = P0^1;18.sbit KEY3 = P0^2;19.sbit KEY4 = P0^3;20.sbit KEY5 = P0^4;21.void main()22.{23.// char TxDate[4];24.// LCD_Init(); //初始化液晶屏25.// LCD_Clear(); //清屏26.// NRF24L01Int(); //初始化LCD160227.// LCD_Write_String(4,0,'welcome');28.while(1)29.{30.KeyScan();31.32.}33.}34.35.36.37.38.unsigned char KeyScan(void)39.{40./******************************************************** /42.{43.if(!KEY1) //如果检测到低电平,说明按键按下44.{45.DelayMs(10); //延时去抖,一般10-20ms46.if(!KEY1) //再次确认按键是否按下,没有按下则退出47.{48.while(!KEY1);//如果确认按下按键等待按键释放,没有则退出49.{50.TxDate[0] = 1;//向左转51.TxDate[1] = 0;52.TxDate[2] = 1;53.TxDate[3] = 1;54.NRFSetTxMode(TxDate);//发送数据·55.while(CheckACK()); //检测是否发送完毕56.}57.}58.}59./******************************************************** /60.else if(!KEY2) //如果检测到低电平,说明按键按下61.{62.DelayMs(10); //延时去抖,一般10-20ms63.if(!KEY2) //再次确认按键是否按下,没有按下则退出64.{65.while(!KEY2);//如果确认按下按键等待按键释放,没有则退出66.{67.TxDate[0] = 1;//向右转69.TxDate[2] = 1;70.TxDate[3] = 0;71.NRFSetTxMode(TxDate);//发送数据72.while(CheckACK()); //检测是否发送完毕73.}74.}75.}76./******************************************************** /77.else if(!KEY3) //如果检测到低电平,说明按键按下78.{79.DelayMs(10); //延时去抖,一般10-20ms80.if(!KEY3) //再次确认按键是否按下,没有按下则退出81.{82.while(!KEY3);//如果确认按下按键等待按键释放,没有则退出83.{84.TxDate[0] = 1;//前进85.TxDate[1] = 0;86.TxDate[2] = 1;87.TxDate[3] = 0;88.NRFSetTxMode(TxDate);//发送数据89.while(CheckACK()); //检测是否发送完毕90.}91.}92.}93./******************************************************** /94.else if(!KEY4) //如果检测到低电平,说明按键按下96.DelayMs(10); //延时去抖,一般10-20ms97.if(!KEY4) //再次确认按键是否按下,没有按下则退出98.{99.while(!KEY4);//如果确认按下按键等待按键释放,没有则退出100.{101.TxDate[0] = 0;//后退102.TxDate[1] = 1;103.TxDate[2] = 0;104.TxDate[3] = 1;105.NRFSetTxMode(TxDate);//发送数据106.while(CheckACK()); //检测是否发送完毕107.}108.}109.}110.else if(!KEY5)111.{112.DelayMs(10);113.if(!KEY5)114.{115.while(!KEY5)116.{117.TxDate[0] = 1;118.TxDate[1] = 1;119.TxDate[2] = 1;120.TxDate[3] = 1;121.NRFSetTxMode(TxDate);122.while(CheckACK());123.}125.}126.}127.}1.//////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////2.#include3.4.#include5.6.#include'1602.h'7.#include'delay.h'8.#include 'nrf24l01.h'9.#define uint unsigned int10.#define uchar unsigned char11.uint Weight;12.sbit a = P2^0;13.sbit b = P2^1;14.sbit c = P2^2;15.sbit d = P2^3;16.void main()17.{18.LCD_Init(); //初始化液晶屏19.LCD_Clear(); //清屏20.*(RevTempDate+4)=*\0*;21.NRF24L01Int();22.while(1)23.{25.NRFSetRXMode();//设置为接收模式26.GetDate();//开始接受数;27.//Weight=RevTempDate[0]*1000+RevTempDate[1]*100+RevTemp Date[2]*10+RevTempDate[3];28.LCD_Write_Char(7,0,RevTempDate[0]+0x30);29.LCD_Write_Char(8,0,RevTempDate[1]+0x30);30.LCD_Write_Char(9,0,RevTempDate[2]+0x30);31.LCD_Write_Char(10,0,RevTempDate[3]+0x30);32. a = RevTempDate[0];//根据接受数据来设置高低电平(目测仅限传输1.0两种数值)33. b = RevTempDate[1];34. c = RevTempDate[2];35. d = RevTempDate[3];36.}37.}38.39.///////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////1.#include2.3.#include 'nrf24l01.h'4.#define uchar unsigned char5.#define uint unsigned int6.sbit IRQ =P1^2;//输入7.sbit MISO =P1^3; //输入8.sbit MOSI =P1^1;//输出9.sbit SCLK =P1^4;//输出10.sbit CE =P1^5;//输出11.sbit CSN =P1^0;//输出12.uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址13./*****************状态标志*****************************************/14.uchar bdata sta; //状态标志15.sbit RX_DR=sta^6;16.sbit TX_DS=sta^5;17.sbit MAX_RT=sta^4;18./*****************SPI时序函数******************************************/19.uchar NRFSPI(uchar date)20.{21.uchar i;22.for(i=0;i<8;i++)>23.{24.if(date&0x80)25.MOSI=1;26.else27.MOSI=0; // byte最高位输出到MOSI28.date<=1;>29.SCLK=1;30.if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据31.date|=0x01; // 读MISO到byte最低位32.SCLK=0; // SCK置低33.}34.return(date); // 返回读出的一字节35.}36./**********************NRF24L01初始化函数*******************************/37.void NRF24L01Int()38.{39.DDelay(2);//让系统什么都不干40.CE=0; //待机模式141.CSN=1;42.SCLK=0;43.IRQ=1;44.}45./*****************SPI读寄存器一字节函数*********************************/46.uchar NRFReadReg(uchar RegAddr)47.{48.uchar BackDate;49.CSN=0;//启动时序50.NRFSPI(RegAddr);//写寄存器地址51.BackDate=NRFSPI(0x00);//写入读寄存器指令52.CSN=1;53.return(BackDate); //返回状态54.}55./*****************SPI写寄存器一字节函数*********************************/56.uchar NRFWriteReg(uchar RegAddr,uchar date)57.{58.uchar BackDate;59.CSN=0;//启动时序60.BackDate=NRFSPI(RegAddr);//写入地址61.NRFSPI(date);//写入值62.CSN=1;63.return(BackDate);64.}65./*****************SPI读取RXFIFO寄存器的值********************************/66.uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen)67.{ //寄存器地址//读取数据存放变量//读取数据长度//用于接收68.uchar BackDate,i;69.CSN=0;//启动时序70.BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址71.for(i=0;i72.{73.RxDate[i]=NRFSPI(0);74.}75.CSN=1;76.return(BackDate);77.}78./*****************SPI写入TXFIFO寄存器的值**********************************/79.uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen)80.{ //寄存器地址//写入数据存放变量//读取数据长度//用于发送81.uchar BackDate,i;82.CSN=0;83.BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址84.for(i=0;i85.{86.NRFSPI(*TxDate++);87.}88.CSN=1;89.return(BackDate);90.}91./*****************NRF设置为发送模式并发送数据******************************/92.void NRFSetTxMode(uchar *TxDate)93.{//发送模式94.CE=0;95.NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_A DDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度96.NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同97.NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WIT DH);//写入数据98./******下面有关寄存器配置**************/99.NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答100.NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0101.NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次102.NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40103.NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益104.NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电105.CE=1;106.DDelay(5);//保持10us秒以上107.}108./*****************NRF设置为接收模式并接收数据******************************/109.//主要接收模式110.void NRFSetRXMode()111.{112.CE=0;113.NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址114.NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答115.NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0116.NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40117.NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WIT DH); // 接收通道0选择和发送通道相同有效数据宽度118.NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/119.NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式120.CE = 1;121.DDelay(5);//保持10us秒以上122.}123./****************************检测应答信号******************************/124.uchar CheckACK()125.{ //用于发射126.sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器127.if(TX_DS||MAX_RT) //发送完毕中断128.{129.NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志130.CSN=0;131.NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果大家记住!!132.CSN=1;133.return(0);134.}135.else136.return(1);137.}138./******************判断是否接收收到数据,接到就从RX 取出*********************/139.//用于接收模式140.uchar NRFRevDate(uchar *RevDate)141.{142.uchar RevFlags=0;143.sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器144.if(RX_DR) // 判断是否接收到数据145.{146.CE=0; //SPI使能147.NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WI TDH);// 从RXFIFO读取数据148.RevFlags=1; //读取数据完成标志149.}150.NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标151.return(RevFlags);152.}153.void DDelay(uint t)154.{155.uint x,y;156.for(x=t;x>0;x--)157.for(y=110;y>0;y--);158.}159.///////////////////////////////////////////////////////////// ///////////////////////////////////////////1.#include 'delay.h'2./*------------------------------------------------延时函数,含有输入参数 unsigned char t,无返回值4.unsigned char 是定义无符号字符变量,其值的范围是5.0~255 这里使用晶振12M,精确延时请使用汇编,大致延时6.长度如下 T=tx2+5 uS7.------------------------------------------------*/8.void DelayUs2x(unsigned char t)9.{10.while(--t);11.}12./*------------------------------------------------13.mS延时函数,含有输入参数 unsigned char t,无返回值14.unsigned char 是定义无符号字符变量,其值的范围是15.0~255 这里使用晶振12M,精确延时请使用汇编16.------------------------------------------------*/17.void DelayMs(unsigned char t)18.{19.20.while(t--)21.{22.//大致延时1mS23.DelayUs2x(245);24.DelayUs2x(245);25.26.}27.}28.///////////////////////////////////////////////////////////// //////////////////////////////1.下面是接收的NRF24L01的程序。

nRF24L01接收和发送的问题

nRF24L01接收和发送的问题

24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根本不知道是发的问题还是收的问题,不隐晦的说,我当时也是没理清调试思路才浪费了大半天时间看着模块干瞪眼。

正确的方法应该是先调试发送方,能保证发送正确,再去调接收,这样就可以有针对性的解决问题。

至于怎么去调发送方,先说下发送方的工作流程:•配置寄存器使芯片工作于发送模式后拉高CE端至少10us•读状态寄存器ST ATUS•判断是否是发送完成标志位置位•清标志•清数据缓冲网上的程序我也看过,大多都是成品,发送方发送-等应答-(自动重发)-触发中断。

可是这样的流程就已经把接收方给牵涉进来了,就是说一定要接收方正确收到数据并且回送应答信号之后发送方才能触发中断,结束一次完整的发送。

可是这跟我们的初衷不相符,我们想单独调试发送,完全抛开接收,这样就要去配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。

SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RX ADDR, 0x00); // 失能接收通道0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发(注:以下贴出的寄存器描述由于中文资料上有一个错误,故贴出原版英文资料)有了以上这三个配置,发送方的流程就变成了发送-触发中断。

这样就抛开了接收方,可以专心去调试发送,可是怎么样才知道发送是否成功呢,要用到另外两个寄存器,ST ATUS和FIFO_ST AT US。

这样就很清晰了,我们可以通过读取ST ATUS的值来判断是哪个事件触发了中断,寄存器4、5、6位分别对应自动重发完成中断,数据发送完成中断,数据接收完成中断。

也就是说,在之前的配置下,如果数据成功发送,那么ST ATUS的值应该为0x2e。

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

////************************************接收程序******************************************************//#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;//****************************************NRF24L01端口定义***************************************sbit M ISO =P1^5;sbit M OSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//***************************************************************************** **************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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 // 保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#d efine FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//***************************************************************************** *********void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uchar SPI_RW(uchar num);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uchar SPI_RW_Reg(uchar reg, uchar value);uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时*****************************************void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//***************************************************************************** *************uchar bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/****************************************************************************** ************/*延时函数/****************************************************************************** ************/void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//***************************************************************************** ***********/*NRF24L01初始化//***************************************************************************** **********/void init_NRF24L01(void){inerDelay_us(100);CE=0; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收}/****************************************************************************** **********************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/****************************************************************************** **********************/uchar SPI_RW(uchar num){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (num & 0x80); // output 'uchar', MSB to MOSInum = (num << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..num |= MISO; // capture current M ISO bitSCK = 0; // ..then set SCK low again}return(num); // return read uchar}/****************************************************************************** **********************//*功能:NRF24L01读写寄存器函数/****************************************************************************** **********************/uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/****************************************************************************** **********************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/****************************************************************************** **********************/uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uchar status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/****************************************************************************** ***************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************************** ***************************/uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uchar status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/****************************************************************************** **********************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/****************************************************************************** **********************/void SetRX_Mode(void){CE=0;// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1;inerDelay_us(130);}/****************************************************************************** ************************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/******************************************************************************************************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;while(IRQ!=0);CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志SPI_RW_Reg(WRITE_REG+STATUS,0XFF);return revale;}//************************************串口初始化*********************************************************void StartUART( void ){ //波特率4800SCON = 0x50;TMOD = 0x20;TH1 = 0xFA;TL1 = 0xFA;PCON = 0x00;TR1 = 1;}//************************************通过串口将接收到数据发送给PC端**************************************void R_S_Byte(uchar R_Byte){SBUF = R_Byte;while( TI == 0 ); //查询法TI = 0;}//************************************主函数************************************************************void main(void){uchar i,temp;uchar RxBuf[32];init_NRF24L01() ;StartUART();Delay(6000);while(1){SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)){temp++;for(i=0;i<32;i++){R_S_Byte(RxBuf[i]);Delay(600);}}Delay(600);}}。

相关文档
最新文档