NRF24L01学习操作教程(二)——NRF实现一对一,一对多通讯

这篇具有很好参考价值的文章主要介绍了NRF24L01学习操作教程(二)——NRF实现一对一,一对多通讯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上篇博客链接:https://blog.csdn.net/DIVIDADA/article/details/130599974?spm=1001.2014.3001.5501


以下单片机例程都是基于STM32 HAL库,在文档末尾,我会提供参考博客和源码程序的链接。

通讯实例与代码实现

在CubeMx中配置单片机时钟、SPI通讯接口、NRF24L01接口等,并生成Keil工程

nrf通过改通道实现一对多,STM32,单片机,学习,stm32

将NRF24L01的驱动程序的.c文件和.h文件添加到工程目录下,重新编译程序

nrf通过改通道实现一对多,STM32,单片机,学习,stm32

nrf24l01实现一对一单向通讯

1.流程分析:

A端:

  • 设置成发送模式(TX_Mode(0))
  • 每隔100ms发送一次数据(NRF24L01_TxPacket())

B端:

  • 设置成接收模式(RX_Mode(0),B端地址设置要同A端一致)
  • 循环判断是否接受到数据(NRF24L01_RxPacket())

2.源码程序

A端:

//....................
uint8_t tx_buf[8];
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    TX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        HAL_Delay(100);
        if(NRF24L01_TxPacket(tx_buf)==0X20)  //NRF24L01模块发送数据并判断是否发送成功
        {
            HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);  //若发送成功,LED电平反转
            tx_buf[0]++;  //若发送成功,tx_buf[0]自增加
        }

    }
    /* USER CODE END 3 */
}

B端:

//....................
uint8_t rx_buf[8];
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    RX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址(同发送模块地址相同)
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        if(NRF24L01_RxPacket(rx_buf)==0X00)  //NRF24L01模块接收数据并判断是否接收成功
        {
            HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);  //若接收成功,LED电平反转
        }

    }
    /* USER CODE END 3 */
}

3.实验结果

在B端程序中进入debug模式,将rx_buf添加到watch窗口中,可以观察到rx_buf[0]值不断增加

nrf通过改通道实现一对多,STM32,单片机,学习,stm32

nrf24l01实现一对一双向通讯

1.流程分析:

A端:

  • 设置成发送模式(TX_Mode(0))
  • 发送一次数据(NRF24L01_TxPacket())
  • 发送完成立马转变成接收模式(RX_Mode(0))
  • 等待接收数据成功(while(READ_NRF24L01_IRQ!=0))
  • 接收数据成功后立马转换发送模式(TX_Mode(0))
  • 进入下一次收发数据,如此循环

B端:

  • 设置成接收模式(RX_Mode(0),B端地址设置要同A端一致)
  • 循环判断是否接受到数据(NRF24L01_RxPacket())
  • 接收到数据成功后立马转换成发送模式(TX_Mode(0))
  • 发送成后立马转换成接收模式(RX_Mode(0)),方便下一次接收

实际上这种双向收发的方式对A、B端的时序要求非常高,通俗点说就是A端处于发送模式并发送数据的时候,B端一定要处于接收模式,否则就是两个哑巴在通讯。所以为了保证通讯的稳定性,需要对上述的通讯流程进行一定的优化,具体优化的地方就是:A端在等待接收数据成功的时候(while(READ_NRF24L01_IRQ!=0)计数等待,若计数值超过阈值,再发送一次,最多发送10次;B端在发送数据时候计数,若计数值超过阈值还未发送成功,立马转变成接收模式。具体实现方法可以见下面的源程序。

经过测试,这种双向收发机制,通讯十分稳定(NICE)

2.源码程序

A端:

//....................
uint8_t tx_buf[8];
uint8_t rx_buf[8];

void NRF_Intercommunication(uint8_t Seq_Nrf,uint8_t *Txbuf, uint8_t *Rxbuf);
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    TX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
		HAL_Delay(100);
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		NRF_Intercommunication(0,tx_buf,rx_buf);  //进行一次双向通讯
    }
    /* USER CODE END 3 */
}
//.........................
void NRF_Intercommunication(uint8_t Seq_Nrf,uint8_t *Txbuf, uint8_t *Rxbuf)
{
	uint8_t j=1;
    uint16_t cnt_01=0,cnt_02=0;
    while(j--)
    {
        TX_Mode(Seq_Nrf);   //设置为发送模式
        NRF24L01_TxPacket(Txbuf);//将数据发送出去
        RX_Mode(Seq_Nrf);               //将数据发送出去后立马转换成接收模式
        while(READ_NRF24L01_IRQ!=0)  //等待接收成功
        {
            if(++cnt_01>0XAFFF)       //如果计数值超过阈值(0XAFFF),则跳出接收等待
                break;
        }

        if(cnt_01>0XAFFF)  //若计数值超过阈值,j赋值1,再次进行一次数据收发
        {
            cnt_01=0;
            if(++cnt_02<10)  //最多重复进行十次数据收发
            {
                j=1;
                continue;
            }
        }
        NRF24L01_RxPacket(Rxbuf);    //读取接收缓存区数据
        cnt_01=0;cnt_02=0;
    }
}

B端:

//....................
uint8_t tx_buf[8] = {0};
uint8_t rx_buf[8] = {0};
uint8_t Mode=0;//1代表发送模式,0代表接收模式
uint8_t Tx_cnt; //发送次数计数
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    RX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址(同发送模块地址相同)
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
		if(Mode==1)
		{
			Tx_cnt++;
			if(NRF24L01_TxPacket(tx_buf)==0x20)//发送数据成功
			{
                tx_buf[0]++;
                Tx_cnt=0;
				Mode=0;    //转变为接收模式
				RX_Mode(0); //一但发送成功则变成接收模式;
			} 
			
			if(Tx_cnt==3)  //如果连续发送3次都失败,则转换为接收模式
			{
				Tx_cnt=0;
				Mode=0;     //转变为接收模式
				RX_Mode(0);   //一但达到最大发送次数则变成接收模式;
			}
		}
		
		if(Mode==0)
		{
			if(NRF24L01_RxPacket(rx_buf)==0X00)//一旦接收成功则变成发送模式;
			{
				HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
				Mode=1;//转变为发送模式
                TX_Mode(0);
			}
		}

    }
    /* USER CODE END 3 */
}

3.实验结果

在A端程序中进入debug模式,将rx_buf添加到watch窗口中,可以观察到rx_buf[0]值不断增加

nrf通过改通道实现一对多,STM32,单片机,学习,stm32

nrf24l01实现一对多双向通讯

以1对2双向通讯为例,给B端、C端设置不同的地址(Mode(0)和Mode(1)),A端地址设为Mode(0)先与B端进行双向通讯,然后设为Mode(1)先与C端进行双向通讯,如此循环就可实现1对2双向通讯

1.流程分析:

A端:

  • 设置成发送模式,先与B端通讯(TX_Mode(0))
  • 发送一次数据(NRF24L01_TxPacket())
  • 发送完成立马转变成接收模式(RX_Mode(0))
  • 等待接收数据成功(while(READ_NRF24L01_IRQ!=0))
  • 接收数据成功后立马转换发送模式,与C端通讯(TX_Mode(1))
  • 发送一次数据(NRF24L01_TxPacket())
  • 发送完成立马转变成接收模式(RX_Mode(1))
  • 等待接收数据成功(while(READ_NRF24L01_IRQ!=0))
  • 接收数据成功后立马转换发送模式,如此循环与B端、C端通讯

B端:

  • 设置成接收模式(RX_Mode(0),B端地址设置要同A端一致)
  • 循环判断是否接受到数据(NRF24L01_RxPacket())
  • 接收到数据成功后立马转换成发送模式(TX_Mode(0))
  • 发送成后立马转换成接收模式(RX_Mode(0)),方便下一次接收

C端:

  • 设置成接收模式(RX_Mode(1),C端地址设置要同A端一致)
  • 循环判断是否接受到数据(NRF24L01_RxPacket())
  • 接收到数据成功后立马转换成发送模式(TX_Mode(1))
  • 发送成后立马转换成接收模式(RX_Mode(1)),方便下一次接收

2.源码程序

A端:

//....................
uint8_t tx_buf[8];
uint8_t rx_buf[8];

void NRF_Intercommunication(uint8_t Seq_Nrf,uint8_t *Txbuf, uint8_t *Rxbuf);
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    TX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        for(int i=0;i<2;i++)
        {
            HAL_Delay(100);
            HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
            NRF_Intercommunication(i,tx_buf,rx_buf);  //与B端、C端各进行一次双向通讯
        }
    }
    /* USER CODE END 3 */
}
//.........................
void NRF_Intercommunication(uint8_t Seq_Nrf,uint8_t *Txbuf, uint8_t *Rxbuf)
{
	uint8_t j=1;
    uint16_t cnt_01=0,cnt_02=0;
    while(j--)
    {
        TX_Mode(Seq_Nrf);   //设置为发送模式
        NRF24L01_TxPacket(Txbuf);//将数据发送出去
        RX_Mode(Seq_Nrf);               //将数据发送出去后立马转换成接收模式
        while(READ_NRF24L01_IRQ!=0)  //等待接收成功
        {
            if(++cnt_01>0XAFFF)       //如果计数值超过阈值(0XAFFF),则跳出接收等待
                break;
        }

        if(cnt_01>0XAFFF)  //若计数值超过阈值,j赋值1,再次进行一次数据收发
        {
            cnt_01=0;
            if(++cnt_02<10)  //最多重复进行十次数据收发
            {
                j=1;
                continue;
            }
        }
        NRF24L01_RxPacket(Rxbuf);    //读取接收缓存区数据
        cnt_01=0;cnt_02=0;
    }
}

B端:

//....................
uint8_t tx_buf[8] = {0};
uint8_t rx_buf[8] = {0};
uint8_t Mode=0;//1代表发送模式,0代表接收模式
uint8_t Tx_cnt; //发送次数计数
//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    RX_Mode(0);  //将NRF24L01模块设置为发送模式,传入参数0设置地址(同发送模块地址相同)
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
		if(Mode==1)
		{
			Tx_cnt++;
			if(NRF24L01_TxPacket(tx_buf)==0x20)//发送数据成功
			{
                tx_buf[0]++;
                Tx_cnt=0;
				Mode=0;    //转变为接收模式
				RX_Mode(0); //一但发送成功则变成接收模式;
			} 
			
			if(Tx_cnt==3)  //如果连续发送3次都失败,则转换为接收模式
			{
				Tx_cnt=0;
				Mode=0;     //转变为接收模式
				RX_Mode(0);   //一但达到最大发送次数则变成接收模式;
			}
		}
		
		if(Mode==0)
		{
			if(NRF24L01_RxPacket(rx_buf)==0X00)//一旦接收成功则变成发送模式;
			{
				HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
				Mode=1;//转变为发送模式
                TX_Mode(0);
			}
		}

    }
    /* USER CODE END 3 */
}

C端:

C端代码除了地址设置与B端不同外,其余均相同

//....................

//....................
int main(void)
{
    //...................
    NRF24L01_Init(); //NRF24L01初始化
    while(NRF24L01_Check());  //检测NRF24L01模块是否在位
    RX_Mode(1);  //将NRF24L01模块设置为发送模式,传入参数1设置地址(同发送模块地址相同)
    //....................
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
		if(Mode==1)
		{
            //....................
            RX_Mode(1);
            
		}
		if(Mode==0)
		{
        	//....................
            TX_Mode(1);
		}
    }
    /* USER CODE END 3 */
}

3.实验结果

同样通过debug模式,可以观察到接收数据。

总结

以上内容详细介绍了,使用NRF24L01实现1对1单向通讯、1对1双向通讯、1对多双向通讯;想要程序源码的可以进我的github仓库自取:https://github.com/HaoJosephWen/Code-of-blog,或评论区留下邮箱。

参考博客

NRF24L01 的双向通信_nrf24l01怎么配对_努力学习cs的博客-CSDN博客

NRF24L01一对多通信方法_noting_to_talk的博客-CSDN博客

nrf24l01中文资料_工作原理_教程_程序 – 瑞生网 (rationmcu.com)

新手如何快速搞通NRF24L01通信 – 瑞生网 (rationmcu.com)文章来源地址https://www.toymoban.com/news/detail-791726.html

到了这里,关于NRF24L01学习操作教程(二)——NRF实现一对一,一对多通讯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32模拟SPI控制NRF24L01发送和接收

    NRF24L01是一款2.4Ghz ISM频段无线收发芯片。NRF24L01模块可视为无需配对和连接型的WIFI或蓝牙模块。NRF24L01可工作于1发6收工作模式。一个NRF24L01模块工作于发送模式时,每次根据设定的接收端地址发送射频信号和数据;一个NRF24L01模块工作于接收模式时,可以接收来自1~6个发送端

    2024年02月08日
    浏览(47)
  • 基于江科大STM32利用NRF24L01向电脑发送 汉字、字符、数字、浮点数。

    最近在使用stm32单片机时,有一个需求,就是通过NRF24L01向电脑发送数据,学习了部分教程后,发现目前分享的程序里基本只能发送简单的16进制数,并不能发送汉字、字符、数字、浮点数等,于是在其基础上进行改进,目前可以实现发送汉字、字符、数字、浮点数,需要源码

    2024年04月10日
    浏览(44)
  • 基于STM32的NRF24L01 2.4G通讯模块的驱动实验(HAL库)

    前言: 本文为手把手教学 NRF24L01 2.4G 通讯模块的驱动实验,本教程的  MCU  采用 STM32F103ZET6 与 STM32F103C8T6 ,彼此进行互相通讯。通过  CubeMX 软件配置  SPI  协议驱动 NRF24L01 2.4G 通讯模块( HAL库 )。 NRF24L01 2.4G 是嵌入式较为常见的模块,希望这篇博文能给读者朋友的工程项目

    2024年02月16日
    浏览(43)
  • STM32在使用NRF24L01中PC(电脑)连接无显示数据以及出现error的解决办法

    1.1 问题情况 在使用 正点原子 的代码中有以下这样一段代码: 我们可以看到,这里调用了 NRF24L01 的自检函数 ,用于判断自检是否通过,当自检不通过时,在LCD上就会显示 NRF24L01 Error 1.2 解决办法 其实这个问题是 引脚冲突的问题 ,我们可以在正点原子提供的原理图(这里我

    2024年01月23日
    浏览(56)
  • STM32F103C8T6实验代码之NRF24L01P 多发一收

    NRF24L01P射频芯片,比NRF24L01具有更高的可靠性,更多的功 率等级,以及更远的传输距离和更低的功率。此外还内置RFX2401功放芯片, 内建LNA,接收灵敏度 提高10dBm,工作在2.4GHz~2.5GHz的ISM频段。 电压:最小值=1.9V;典型值=3.0V;最大值=3.6V; 如果要接入5V,需要使用电阻进行分压

    2024年02月06日
    浏览(50)
  • STM32F103C8T6与2.4G无线模块NRF24L01连接

    最近使用到了这个2.4G无线模块NRF24L01,比蓝牙好用,需要同时使用两个来用,它长这样: 使用它需要代码支持,因此我在耗费了一些精力后,从网上东拼西凑了一些代码,修修补补后使它能够正常运行, 注意:我只测试了两个2.4G无线模块NRF24L01的连接。 下图是2.4G无线模块

    2024年02月12日
    浏览(46)
  • stm32驱动NRF24L01_原理+代码解析

    目录 概念 废话篇(24L01简介) 引脚分配 工作模式 通信地址理解(个人疑难点) 原理分析 寄存器赏析 寄存器操作指令  配置寄存器(CONFIG,位置:0X00)  自动应答使能寄存器(EN_AA,0X01) RX地址使能寄存器(EN_RXADDR,0X02)  自动重发设置寄存器(SETUP_RETR,0X04)  射频频

    2024年01月18日
    浏览(45)
  • nRF51822 入门必备教程(一篇搞定nRF51)

    部署PC端开发环境 nRFgo Studio v1.14或更高版本 Keil MDK-ARM Lite v4.54或更高版本 J-Link Software v4.52b或更高版本 下载手机端app IOS系统:进入App Store并搜索“ nRFToolbox ” Android系统(4.3或更高):下载nRFToolbox,解压后安装即可 注意:蓝牙4.0和传统蓝牙的开发方法不同,首先需要手机支持蓝

    2024年02月04日
    浏览(44)
  • 通过一个实际例子说明Django中的数据库操作方法OneToOneField()的用法【数据表“一对一”关系】

    当我们在Django中定义一个模型时,可以使用 OneToOneField 来建立一个一对一的关系。这种关系表示两个模型之间的一种特殊关联,其中一个模型的实例只能与另一个模型的实例关联。 让我们以一个简单的示例来说明 OneToOneField 的用法。假设我们正在构建一个简单的博客应用,其

    2024年02月13日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包