实现NRF24L01自动对频功能

大家知道这个模块一个只有128个频道,那么代表着同一附近最多只能存在128个设备,不过这个环境中也很难同时存在这样的现象.
如果要制作很多个这样的设备,每个设备需要工作不同频率上,那么就需要每个设备有不同的代码(因为要修改频道)。想想就很可怕。
这也不是一个程序员做的事情。
在网上找了几天也没有找到相关技术,可能是因为商业原因吧,只能自己琢磨实现思路。
最近2天做了一个自动対频的思路,因为代码过多,很多文件都是之前博客编写过的就不上传了。关键是理解思想。


思路:
接收端:
接收端按下按键进入対频模式(在指定的频道上运行)
随机获取频道数
发送频道数给发射端
等待发射端ACK
切换到该频道(随机频道)
进行通信
保存随机频道到内部flash


发射端:
发射端按下按键进入対频模式
接收接收端发来的频道并进行校验
发送接收完毕ACK
切换到该频道(随机频道)
进行通信
保存随机频道到内部flash


整体思路如上诉。


该程序需要用到NRF基本通信功能,随机数功能,flash功能。这些功能前面博客有提到。


开发环境:keil 4
开发语言:C/C++
开发平台:STM32


下面上传代码

dui_pin.h

/*
日期:18-1-18
作者:HES

功能:实现NRF24l01自动对频功能

*/


#ifndef _DUI_PIN_H
#define _DUI_PIN_H
#include "nrf_info.h"
#include "sys.h"
#include "24l01.h"

#define DUI_PIN_LOG 1			//串口日志开关

#define DUI_PIN_CH 00			//对频使用频道

#define NULL 0

#define SEND_ACK 5		//发送的ACK
#define RECV_ACK 5		//接收的ACK

#define	 STEP1 1			//各种对频状态
#define	 STEP2 2
#define	 STEP3 3
#define	 STEP4 4

#define DUI_PIN_ID  99 //对频ID

#define DUI_PIN_FLAG 9	//对频标识

class DUI_PIN:public NRF_INFO		//继承NRF功能
{
	public:
				u8 CH;		//对频频道
				u8 state;	//对频状态
				u8 flash_buf[2];	//用于保存频道数据到falsh
				void RX_start_dui_pin();		//RX对频
				void TX_start_dui_pin();		//TX对频
				void save_ch_flash();				//保存频道到flash
				void read_ch_flash();				//对其flash中频道
};

#endif
dui_pin.c

/*
日期:18-1-18
作者:HES

功能:实现NRF24l01自动对频功能

*/

#include "dui_pin.h"
#include "serial.h" 
#include "delay.h"
#include "time.h"
#include "timer.h"
#include "stdlib.h"
#include "flash.h"


/*
日期:18-1-18
作者:HES

功能:实现接收端自动对频功能

*/
void DUI_PIN::RX_start_dui_pin()
{
	
					u8 num=0;
			#if DUI_PIN_LOG
					printf("<<---进入对频模式--->>\r\n");
			#endif
					NRF24L01_TX_Mode(1,DUI_PIN_CH);
					delay_ms(10);
					
					do
					{
						srand(Timer_Count_Value);	//随机种子Timer_Count_Value是定时器的计数值,
						
						num  = rand() % 128;    //生成0—128内的随机整数,
				#if DUI_PIN_LOG
						printf("<<---生成频道:%d--->>\r\n",num);
				#endif		
						state=STEP1;
					}while(num==DUI_PIN_CH);				//频道等于对频频道,重新获取
					
					while(1)
					{
						state=STEP2;
						NRF24L01_TX_Mode(1,DUI_PIN_CH);
						delay_ms(20);
						send_mes(num,DUI_PIN_FLAG,NULL,NULL,NULL);		//发送随机通道和对频标识
						delay_ms(10);
					
						
#if 1				
						NRF24L01_RX_Mode(1,DUI_PIN_CH);
						delay_ms(20);
						if(recv_mes())
						{
							#if DUI_PIN_LOG
							printf("<<---接收到数据--->>\r\n");
							#endif
							//TX返回ACK
							if(ID==RECV_ACK)
							{		
									CH=num;
									break;
							}
						}
#endif						
							#if DUI_PIN_LOG
						printf("<<---对频中--->>\r\n");
				#endif		
						
					}
				#if DUI_PIN_LOG
						printf("<<---TX接收频道数据完成:%d--->>\r\n",CH);
				#endif
					
					while(1)
					{
						state=STEP3;
						NRF24L01_TX_Mode(1,CH);
						delay_ms(10);
						send_mes(SEND_ACK,NULL,NULL,NULL,NULL);
						delay_ms(10);
						NRF24L01_RX_Mode(1,CH);
						delay_ms(10);
						if(recv_mes())
						{
							//TX返回ACK
							if(ID==RECV_ACK)	
							break;
						}
						#if DUI_PIN_LOG
						printf("<<---频率验证中成:%d--->>\r\n",CH);
						#endif
						
					}
					
				#if DUI_PIN_LOG
						printf("<<---对频完成:%d--->>\r\n",CH);
				#endif
					
					save_ch_flash();
					state=STEP4;
}

/*
日期:18-1-18
作者:HES

功能:实现发送端自动对频功能

*/

void DUI_PIN::TX_start_dui_pin()
{
					u8 n=0;
					u8 num=0;
			#if DUI_PIN_LOG
					printf("<<---进入对频模式--->>\r\n");
			#endif
					NRF24L01_RX_Mode(1,DUI_PIN_CH);
					delay_ms(10);
					
				
						state=STEP1;
					
					
					while(1)
					{
						state=STEP2;
						NRF24L01_RX_Mode(1,DUI_PIN_CH);
						delay_ms(20);
						if(recv_mes())
						{
							
							if(TX_voltage!=DUI_PIN_FLAG)continue;		//接收到不是对频标识则继续等待
							
							#if DUI_PIN_LOG
							printf("<<---接收到对频数据--->>\r\n");
							#endif	
							
							//TX返回ACK
							
									CH=ID;
									NRF24L01_TX_Mode(1,DUI_PIN_CH);
									delay_ms(20);
									n=10;
									while(n--!=1)												//发送10次ACK
									{
										send_mes(RECV_ACK,NULL,NULL,NULL,NULL);		
										delay_ms(100);
									}
									break;
							}
							#if DUI_PIN_LOG
							printf("<<---对频中--->>\r\n");
							#endif	
						}
						
					
				#if DUI_PIN_LOG
						printf("<<---TX接收频道数据完成:%d--->>\r\n",CH);
				#endif
					
					while(1)
					{
						state=STEP3;
						NRF24L01_RX_Mode(1,CH);
						delay_ms(20);
						if(recv_mes())
						{
							//TX返回ACK
							if(ID==RECV_ACK)	
							break;
						}
					#if DUI_PIN_LOG
						printf("<<---频率验证:%d--->>\r\n",CH);
					#endif
					}
					
									NRF24L01_TX_Mode(1,CH);
									delay_ms(20);
									n=10;
									while(n--!=1)
									{
										send_mes(RECV_ACK,NULL,NULL,NULL,NULL);
										delay_ms(20);
									}
					
				#if DUI_PIN_LOG
						printf("<<---对频完成:%d--->>\r\n",CH);
				#endif
					
				save_ch_flash();
									
				state=STEP4;					
					
}
/*
日期:18-1-18
作者:HES

功能:实现保存频道到内部flash

*/
void DUI_PIN::save_ch_flash()
{
	flash_buf[0]=CH;
	flash_buf[1]=1;
	
	FLASH_WriteByte(ADDR,flash_buf,2);
	
}
/*
日期:18-1-18
作者:HES

功能:实现读取内部flash中频道

*/
void DUI_PIN::read_ch_flash()
{
	
	FLASH_ReadByte(ADDR,flash_buf,2);
	
	CH=flash_buf[0];
	
}
主函数测试:

	接收端主函数调用测试:

	DUI_PIN dui_pin //定义功能对象

	main()
	{
		/*
			之前一定要初始化NRF基本通信功能,随机数功能,flash功能。三大板块功能

		 */
		dui_pin.RX_start_dui_pin();
		printf("RX対频完成\r\n");
	}

	发射端主函数调用测试:

	DUI_PIN dui_pin //定义功能对象

	main()
	{
		/*
			之前一定要初始化NRF基本通信功能,随机数功能,flash功能。三大板块功能

		 */
		dui_pin.TX_start_dui_pin();
		printf("TX対频完成\r\n");
	}
接收端效果:

<<---对频中--->>
<<---对频中--->>
<<---对频中--->>
<<---接收到数据--->>
<<---TX接收频道数据完成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---频率验证中成:95--->>
<<---对频完成:95--->>





猜你喜欢

转载自blog.csdn.net/hes_c/article/details/79112358
今日推荐