STM32F103VE为主控,两个2.4G相互通信

利用STM32,把两个2.4G放在一起进行通信。
前段时间,因为闲暇无事,就玩起了2.4G,利用两个2.4G进行相互通信,我用的2.4G是nRF2401芯片,原理图如下:在这里插入图片描述

下面是主函数代码,头文件在这里省略;
有关2.4G的代码我全部放在了nRF2401.c文件里

int main(void)
 {		 
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	//初始化与LED连接的硬件接口
	Key_Init();
	uart_init(9600);
	SPI_GPIO_Init();
	SPI2_Init();
	NRF24L01_Init();
	 
	printf("nrf24l01 start!\r\n");
	while (NRF24L01_Check())//检测
	{

		printf("nrf24l01 02 failed!\r\n");
	}
	printf("nrf24l01s are ok!\r\n");
	
	NRF24L01_TX_Mode();
	while(NRF24L01_TX_Packet(txbuf)==TX_OK)
	{
		 NRF24L01_RX_Mode();
	}
	
		while(1)
		{	
				Key_Scan();					
				if(mode==0)
				{		
					RX_Mode();
				 }
			  if(mode==1)
				{		
					TX_Mode();									
		    }			
     }
}
 

main.c中交代了两个模式,TX_Mode,和RX_Mode;这两个模式是我在nRF2401.c里进行定义的,主要是分开接收和发送两种模式。

除此之外!!!
在这里需要注意的一点是:(特别注意)
nRF2401在发送和接收信息的时候一定要有空闲时间,不能同时进行,否则会堵塞,信息无法发送,故此我在main.c中初始化之余,加了以下函数防止造成堵塞而无法发送信息:

    NRF24L01_TX_Mode();
	while(NRF24L01_TX_Packet(txbuf)==TX_OK)
	{
		 NRF24L01_RX_Mode();
	}

1,打开NRF24L01_TX_Mode2发送函数
2,判断发送函数是否成功
3,打开NRF24L01_RX_Mode2接收函数
这样就不会造成两个同时打开造成信息堵塞而无法发送信息的情况。

这个情况困扰我很久,一直无法成功发送信息,最后在网上查阅资料的时候看到这个知识点时,才恍然大悟,按照上面这个逻辑,才成功发送信息。

下面是NRF24L01.c文件,这个程序在网上或者视频教学时带的源码里有很多,由于很长所以在此只写和上面有关的一些主要代码,如下:

/*****************************************************************************
* 函  数:void NRF24L01_TX_Mode(void)
* 功  能:NRF24L01发送模式配置
* 参  数:无
* 返回值:无
* 备  注:无
*****************************************************************************/
void NRF24L01_TX_Mode(void)
{
	NRF_CE_LOW;
	NRF24L01_Write_Buf(W_REGISTER+TX_ADDR,TX_ADR_WIDTH,(uint8_t *)TX_ADDRESS_Y);//写TX节点地址
	NRF24L01_Write_Buf(W_REGISTER+RX_ADDR_P0,RX_ADR_WIDTH, (uint8_t *) RX_ADDRESS_Y);//写RX节点地址,为了自动使能ACK
	NRF24L01_Write_Reg(W_REGISTER+EN_AA, 0x01);//使能通道0自动应答
	NRF24L01_Write_Reg(W_REGISTER+EN_RXADDR, 0x01);//使能通道0接收地址
	NRF24L01_Write_Reg(W_REGISTER+SETUP_PETR, 0x1a);//设置自动重发间隔时间:500us+86us,最大重大次数:10次
	NRF24L01_Write_Reg(W_REGISTER+RF_CH, 40);//设置通道为40
	NRF24L01_Write_Reg(W_REGISTER+RF_SETUP, 0x0f);//设置发射参数:0dB增益;2Mnps;低噪声增益开启
	NRF24L01_Write_Reg(W_REGISTER+NRF24L01_CONFIG,0x0e);//基本参数:PWR_UP;EN_CRC;16BIT_CRC;发送模式;开启所有中断
	NRF_CE_HIGH;//NRF_CE为高,10us后启动发送数据
	delay_us(12);
}
/*****************************************************************************
* 函  数:void NRF24L01_TX_Mode(void)
* 功  能:NRF24L01发送模式配置
* 参  数:无
* 返回值:无
* 备  注:无
*****************************************************************************/
void NRF24L01_RX_Mode(void)
{
	NRF_CE_LOW;
	NRF24L01_Write_Buf(W_REGISTER+RX_ADDR_P0, RX_ADR_WIDTH, (uint8_t *) RX_ADDRESS_X);//写RX地址节点
	NRF24L01_Write_Reg(W_REGISTER+EN_AA,0x01);//使能通道0自动应答
	NRF24L01_Write_Reg(W_REGISTER+EN_RXADDR,0x01);//使能通道0接收地址
	NRF24L01_Write_Reg(W_REGISTER+RF_CH, 40);//设置RF通信频率
	NRF24L01_Write_Reg(W_REGISTER+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0有效数据宽度
	NRF24L01_Write_Reg(W_REGISTER+RF_SETUP, 0x0f);//设置TX发射参数:0db增益,2Mbps,低噪声增益开启
	NRF24L01_Write_Reg(W_REGISTER+NRF24L01_CONFIG, 0x0f);//基本参数:PWR_UP;EN_CRC;16BIT_CRC;接收模式;开启所有中断
	NRF_CE_HIGH;//CE为高,进入接收模式
}

/*****************************************************************************
* 函  数:uint8_t NRF24L01_TX_Packet(uint8_t *txbuf)
* 功  能:NRF24L01发送一次数据
* 参  数:*txbuf:等待发送数据的首地址
* 返回值:MAX_TX:最大重发次数;TX_OK:发送完成;0xFF:发送失败
* 备  注:无
*****************************************************************************/
uint8_t NRF24L01_TX_Packet(uint8_t *txbuf)
{
	uint8_t ret;

	NRF_CE_LOW;
	NRF24L01_Write_Buf(W_TX_PAYLOAD, TX_PLOAD_WIDTH, txbuf);//写数据到txbuf,32字节
	NRF_CE_HIGH;//启动发送
	while (NRF_IRQ_STATUS);//等待发送完成
	ret = NRF24L01_Read_Reg(NRF24L01_STATUS);//读取状态寄存器的值
	NRF24L01_Write_Reg(W_REGISTER+NRF24L01_STATUS, ret);//清除TX_DS or MAX_RT的中断标志
	if(ret&MAX_TX)//达到最大重发次数
		{
			NRF24L01_Write_Reg(FLUSH_TX, 0XFF);//清除TX FIFO	寄存器
			return MAX_TX;
	}
	if(ret&TX_OK)	//发送完成
		{
			
			return TX_OK;
	}
	return 0xFF;//发送失败
	
}

/*****************************************************************************
* 函  数:uint8_t NRF24L01_RX_Packet(uint8_t *rxbuf)
* 功  能:NRF24L01接收一次数据
* 参  数:*rxbuf:等待接收数据的首地址
* 返回值:0:接收成功;1:接收数据失败
* 备  注:无
*****************************************************************************/
uint8_t NRF24L01_RX_Packet(uint8_t *rxbuf)
{
	uint8_t ret;


	NRF_CE_HIGH;
	while(NRF_IRQ_STATUS);
	NRF_CE_LOW;

	ret = NRF24L01_Read_Reg(NRF24L01_STATUS);//读取状态寄存器的值
	NRF24L01_Write_Reg(W_REGISTER+NRF24L01_STATUS, ret);//清除TX_DS or MAX_RT的中断标志
	if(ret&RX_OK)//接收到数据
		{
			NRF24L01_Read_Buf(R_RX_PAYLOAD,RX_PLOAD_WIDTH,rxbuf);//读取数据
			NRF24L01_Write_Reg(FLUSH_RX,0xFF);//清除RX FIFO寄存器
			return 0;
	}
	return 1;//没有接收到数据
}

这里主要是一些源码,无多大改动;

下面是我自己加的TX_Mode,和RX_Mode函数

void TX_Mode(void)
{
	uint8_t ret,i;
	delay_ms(500);
	NRF24L01_TX_Mode();					
	while(NRF24L01_TX_Packet(txbuf)==TX_OK)
	{											
		printf("nrf1 send is sucessed!\r\n");
		printf("\r\n");
		for(i=0;i<5;i++)
		{
			 printf("nrf1 send data is %d \r\n",txbuf[i]);
		}			
		delay_ms(500);	 //延时300ms	
		mode=0;
		LED2=~LED2;
		break;							
	}
}

void RX_Mode(void)
{
	uint8_t ret,i;
	delay_ms(500);	
	NRF24L01_RX_Mode();
	while(NRF24L01_RX_Packet(rxbuf)==0)
	 {												
			ret = NRF24L01_RX_Packet2(rxbuf);
			for(i=0;i<5;i++)
			{
			   printf("nrf2 recieve data is %d \r\n",rxbuf[i]);
			}
			printf("nrf recieves data sucessed!\r\n");
			if(text_buf[4]==8)
			{
				delay_ms(500);	 //延时300ms
				mode=1;
				LED1=~LED1;
			}
			break;
	 }
}

其中主函数里的mode=0/1的值就是从这里来的

在这两个函数最后判断是否接收完数据,我利用的是直接判断的数组的最后一位text_buf[4]的值,其中我对数组的定义如下:


const uint8_t TX_ADDRESS_X[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};//发送端地址
const uint8_t RX_ADDRESS_X[RX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};//接收端地址

const uint8_t TX_ADDRESS_Y[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x02};//发送端地址
const uint8_t RX_ADDRESS_Y[RX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x02};//接收端地址

extern uint8_t txbuf[5]={5,2,3,4,9};
extern uint8_t rxbuf[5]={0,0,0,0,0};

extern int mode=0;
extern uint8_t text_buf[5]={0,0,0,0,0};

发送数组里的最后一位是9所以我这里直接判断最后一位数组的值来确定是否接收完全。

缺点:
在这里我判断数据是否接收完成的放法是不够严谨的,无法保证数据准确性
改进:
后面可以用协议的方式来保证数据的准确性。

以上为个人观点以及从网上借鉴而来,如有不足及错误,希望多多指教。

程序员的道路任重而道远,诸君努力,哈哈哈哈


                           >  人生苦短,我用keil5. 
                           | 
                    __\--__|____
       ||=======OOOOO[/007__|
               _____\_______|/---.
             /___mingrisoft.com___|
             \@@@@@@@@@@@@@@@@@@@0/

              ~~~~~~~~~~~~~~~~~~~~~
''


  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值