51单片机应用之无线通讯模块NRF24L01+

2019-12-02来源: 51hei关键字:51单片机  无线通讯模块  NRF24L01+

本教程关于NRF24L01+的内容十分详细,对于大家的学习和调试及其有帮助

图片1.png

内含详细教程:
0.png0.png0.png0.png0.jpg 



单片机源程序如下:

接下来我们写发送程序:

//**********************************

//   NRF24L01+模块发射程序

//      用8个LED调试

//   Txz001 2012.05.16

//**********************************

#include

typedef unsigned char uchar; //将无符号字节类型重定义为uchar

typedef unsigned int uint;  //将无符号整数类型重定义为Uint

//*********************NRF24L01函数定义****************************

void delayms(uint t);//毫秒延时

void init_NRF24L01(void);   //模块初始化函数

uchar SPI_RW(uchar reg);    //基本SPI读写时序

uchar SPI_Read(uchar reg);  //从寄存器reg读一个字节

void SetRX_Mode(void);      //设置接收模式

uchar SPI_RW_Reg(uchar reg, uchar value);  //向寄存器写一个字节

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); // 从缓冲器读出uchars字节的数据

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); //向缓冲器写进uchars字节的数据

void nRF24L01_TxPacket(uchar * tx_buf); //启动一次发送

uchar nRF24L01_RxPacket(uchar * rx_buf);//读取接收的数据,放入rx_buf数组

//***********NRF24L01模块IO端口定义******************

sbit CE=P1^0;

sbit CSN =P1^1;

sbit SCK =P1^2;

sbit MOSI =P1^3;

sbit MISO =P1^4;

sbit IRQ =P1^5;

//*****************NRF24L01常量**********************

#define TX_ADR_WIDTH    5    //发送地址宽度 5字节

#define RX_ADR_WIDTH    5    //接收地址宽度 5字节

#define TX_PLOAD_WIDTH  32   // 发送数据宽度 32字节

#define RX_PLOAD_WIDTH  32   //接收数据的宽度 32字节

uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0x05}; //本地地址

uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0x05}; //接收地址

//*****************NRF24L01寄存器指令*******************

#define READ_REG        0x00   // 读寄存器指令

#define WRITE_REG       0x20  // 写寄存器指令

#define RD_RX_PLOAD     0x61   // 读取接收数据指令

#define WR_TX_PLOAD     0xA0   // 写待发数据指令

#define FLUSH_TX        0xE1   //清空发送缓冲区

//**************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 delayms(uint t)     //约延时t毫秒

{

  uint i;

  while(t--)

    {

     for(i=0;i<125;i++);

    }        

}

/**********************************************

/*函数:uint SPI_RW(uint uchar)

/*功能:NRF24L01的SPI写时序

/**********************************************/

uchar SPI_RW(uchar uuchar)

{

uchar bit_ctr;

    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 输出8个位

    {

  MOSI = (uuchar & 0x80);     //输出uuhar的最高位

  uuchar = (uuchar << 1);     //左移一位

  SCK = 1;                    // 将时钟线置‘1’

  uuchar |= MISO;             //同时读取STATUS

  SCK = 0;                //然后再将时钟线置‘0’

    }

    return(uuchar);               //返回读取的值

}

/***********************************************

/*函数:uchar SPI_Read(uchar reg)

/*功能:NRF24L01的SPI读取一个字节时序

/***********************************************/

uchar SPI_Read(uchar reg)

{

uchar reg_val;

CSN = 0;             //CSN置'0',允许指令操作

SPI_RW(reg);            //写一条reg指令

reg_val = SPI_RW(0);    //读取reg的值到reg_val

CSN = 1;                //CSN置'1',禁示操作

return(reg_val);        //返回读取的值

}

/***********************************************

/*功能:NRF24L01写一个字节到寄存器函数

/***********************************************/

uchar SPI_RW_Reg(uchar reg, uchar value)

{

uchar status;

  

CSN = 0;                   // CSN置'0',允许操作

status = SPI_RW(reg);      //这指令,并读STATUS

SPI_RW(value);             //写数据值到reg

CSN = 1;                   // CSN置'1',禁止操作

return(status);            // return nRF24L01 status uchar

}

/*****************************************************************

/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)

/*功能: 用于写数据:reg:为寄存器地址,

/*                  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

  SPI_RW(*pBuf++);

CSN = 1;           //关闭SPI

return(status);    //  

}

//******************************************

/*NRF24L01初始化

//******************************************/

void init_NRF24L01(void)

{

  delayms(1);

  CE=0;    //  射频停止工作

  CSN=1;   // 停止寄存器读写

  SCK=0;   //时种信号停止读写

  IRQ=1;//中断复位

  SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      //  频道0自动 ACK应答禁止  

  SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00);      //禁止自动发送

  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,   

  SPI_RW_Reg(WRITE_REG + RF_CH, 1);        //   设置信道工作为2.4GHZ,收发必须一致

  SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节

  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为2MHZ,发射功率为最大值0dB  

}

/******************************************************

/*函数: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 + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址  

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,激发数据发送

delayms(1);

}


//************************************

//              主函数

//************************************

void main()

{

  uchar  TxBuf[32];

  uchar status;  //定义一个变量用来装读取到的STATUS数值

  init_NRF24L01();//NRF24L01初始化

  SPI_RW_Reg(WRITE_REG+STATUS,0XFF);   //清状态寄存器

  status=SPI_Read(STATUS); //读取状态

  P0=~status;//P0口显示读取的状态

  delayms(4000);//显示延时4秒,以便从容看清楚

  P0=0xff;//清除显示

  delayms(600);

TxBuf[0]=1; //我们设置个初值1在想要

[1] [2]
关键字:51单片机  无线通讯模块  NRF24L01+ 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481662.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于STC15w104单片机的人体红外报警
下一篇:基于51单片机的nrf24l01无线的接收和发射程序

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

数据的加密传输——单片机上实现TEA加密解密算法
各位大侠在做数据传输时,有没有考虑过把数据加密起来进行传输,若在串口或者无线中把所要传的数据加密起来,岂不是增加了通信的安全性。常用的加密解密算法比如DES、RSA等,受限于单片机的内存和运算速度,实现起来比较困难,但一种叫TEA的加密算法特别适合单片机使用。TEA(Tiny Encryption Algorithm)是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。目前我只知道QQ一直用的是16轮TEA。我之前做过一个数字的无线对讲机,把语音数据加密后
发表于 2019-12-11
单片机+ULN2003A步进电机控制系统(正反转+加减速)
51单片机步进电机的正反转。加减速控制电路原理图如下:仿真原理图如下 单片机源程序如下:#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit RS = P2^4;//1602数据/命令选择端(H:数据寄存器L:指令寄存器) sbit RW = P2^5;//1602读/写选择端 sbit E  = P2^6;//1602使能信号端sbit key1=P3^0;//用户按键sbit key2
发表于 2019-12-11
单片机+ULN2003A步进电机控制系统(正反转+加减速)
单片机自行车测速系统+源程序+proteus仿真
自行车测速系统仿真原理图如下单片机源程序如下:#include "d:c51reg51.h"#include "d:c51intrins.h"sbit LCM_RS=P3^0;sbit LCM_RW=P3^1;sbit LCM_EN=P3^7;#define BUSY                  0x80              //常量定义#define DATAPORT       
发表于 2019-12-11
单片机自行车测速系统+源程序+proteus仿真
简单做的基于51单片机的数码管时钟
看看抽屉的材料,就想做做东西玩玩。本来想做99码表的,结果按键开关不够,就改成了时钟。话不多说,直接上图。最小系统 显示模块 最后效果 仿真原理图如下(proteus仿真工程文件可到本帖附件中下载) 单片机源程序如下:/**********************************************************************************实验名   :数码管动态显示*实验效果        :8位数码管显示数字12345678*注意   : 每位数码管显示之间延迟时间
发表于 2019-12-11
简单做的基于51单片机的数码管时钟
MFRC522电路原理图与单片机测试程序
MFRC522电路原理图: 天线部分: 单片机+MFRC522测试源程序如下:/**********************RC522实验开发板例程*************************  CPU:STC89C52RC*  晶振:11.0592MHZ******************************************************************///实验目的:/*-----------------------------------------------  名称:MF RC522  内容:通过标准程序静态显示字符 
发表于 2019-12-11
MFRC522电路原理图与单片机测试程序
采用高性能XMEGAl28单片机实现便携式电解质分析仪的设计
电解质分析仪可测定生物标本如血清、血浆、全血及稀释尿液中的值钾(K)、钠(Na)、氯(C1)、钙(Ca)、PH值等,并通过计算提供标准化离子钙(nCa)、总钙(TCa),在临床上具有较重要的意义。自80年代汽巴康宁,奥林巴斯等国外产品进入中国后,国产电解质分析仪迅速跟进,并研制出一批性能较高的产品。近几年随着一些突发事件的发生(如:汶川大地震),对便携式医疗仪器的需求大大增加,便携式电解质分析仪就是其中之一。这里提出一款采用ATMEL公司推出的高性能XMEGAl28单片机为核心器件设计的由电池供电的便携式电解质分析仪,可以满足野外使用需求。1 XMEGA简介XMEGA是8位AVR微处理器的强劲性能升级版本。XMEGA采用第二代
发表于 2019-12-11
采用高性能XMEGAl28单片机实现便携式电解质分析仪的设计
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved