NRFL多通道通信.docx
《NRFL多通道通信.docx》由会员分享,可在线阅读,更多相关《NRFL多通道通信.docx(17页珍藏版)》请在冰豆网上搜索。
NRFL多通道通信
无线抢答系统
本系统用到4个NRF24L01模块,最多可以加到7个NRF24L01(其中一个用作主机另外的六个用作从机)。
显示用的是诺基亚的5110,MCU用的是52单片机。
经亲测发送和接收都很好。
废话不多说,在此给上原理图加程序。
附上成品图
阅读NRF24L01那部分代码请结合nrf24L01中文资料中的寄存器介绍结合起来一起看,能使你理解的更透彻。
在此附上NRF24L01芯片的寄存器的作用和地址图片(下图的截图是在“nrf24L01中文资料”中截的图需要更完整的“nrf24L01中文资料”请自己XX搜索下载)
主机代码
可下载到开发板上也可以自己做一个可以串口通信的最小系统或者去掉主机代码中的串口通信部分下载到上图做的板中(记得修改引脚)
#include<>
#include<>
typedefunsignedcharuchar;
typedefunsignedcharuint;
/*****************NRF24L01端口定义*****************************************/
sbitMISO=P0^4;
sbitMOSI=P0^3;
sbitSCK=P0^2;
sbitCE=P0^0;
sbitCSN=P0^1;
sbitIRQ=P0^5;
/*************LCD5110I/O定义***********************************************/
sbitLCD_RST=P1^4;
sbitLCD_CE=P1^3;
sbitLCD_DC=P1^2;
sbitLCD_SCLK=P1^0;
sbitLCD_Din=P1^1;
/******************按键****************************************************/
sbitKEY1=P3^6;
sbitKEY2=P3^7;
/******************发光二极管*********************************************/
sbitled1=P1^6;
sbitled2=P1^7;
/******************NRF24L01地址宏定义*************************************/
#defineTX_ADR_WIDTH5)右移一位,准备传送下一个数据
SCK=1;)设置SCK为高
uchar|=MISO;thensetSCKlowagain)拉低SCK时钟产生下降沿,从MSOI送出数据,在下一次SCK为高时读入MISO
}
return(uchar);.)CSN拉低,启动SPI通信
NRF24L01_SPI_RW(reg);)设置读取的寄存器
reg_val=NRF24L01_SPI_RW(0);thenreadregistervalue)读出寄存器中的数据
CSN=1;andwritevaluetoit..)向选择的寄存器中写入数据
CSN=1;)右移一位,准备传送下一个数据
SCK=1;)设置SCK为高
uchar|=MISO;thensetSCKlowagain)拉低SCK时钟产生下降沿,从MSOI送出数据,在下一次SCK为高时读入MISO
}
return(uchar);.)CSN拉低,启动SPI通信
NRF24L01_SPI_RW(reg);)设置读取的寄存器
reg_val=NRF24L01_SPI_RW(0);thenreadregistervalue)读出寄存器中的数据
CSN=1;andwritevaluetoit..)向选择的寄存器中写入数据
CSN=1;//(CSNhighagain)CSN拉高,终止SPI通信
return(status);//(returnnRF24L01statusuchar)返回2401reg寄存器的状态
}
/****************************************************************************************************/
/*函数:
uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)
/*功能:
用于读数据,reg:
为寄存器地址,pBuf:
为待读出数据地址,uchars:
读出数据的个数
/****************************************************************************************************/
uintNRF24L01_SPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)
{
uintstatus,uchar_ctr;
CSN=0;//SetCSNlow,initSPItranaction
status=NRF24L01_SPI_RW(reg);//Selectregistertowritetoandreadstatusuchar
for(uchar_ctr=0;uchar_ctrpBuf[uchar_ctr]=NRF24L01_SPI_RW(0);//
CSN=1;
return(status);//returnnRF24L01statusuchar
}
/*********************************************************************************************************
/*函数:
uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)
/*功能:
用于写数据,reg:
为寄存器地址,pBuf:
为待写入数据地址,uchars:
写入数据的个数
/*********************************************************************************************************/
uintNRF24L01_SPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)
{
uintstatus,uchar_ctr;
CSN=0;//SPI使能
status=NRF24L01_SPI_RW(reg);
for(uchar_ctr=0;uchar_ctrNRF24L01_SPI_RW(*pBuf++);//指向下一个数据
CSN=1;//关闭SPI
return(status);//返回24L01的状态
}
/****************************************************************************************************/
/*函数:
voidSetRX_Mode(void)
/*功能:
数据接收配置
/****************************************************************************************************/
voidNRF24L01_SetRX_Mode(void)
{
CE=0;//片选使能
NRF24L01_SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);//IRQ收发完成中断响应,16位CRC,主接收
CE=1;//片选失能
inerDelay_us(130);
}
/******************************************************************************************************/
/*函数:
unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)
/*功能:
数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
unsignedcharNRF24L01_RxPacket(unsignedchar*rx_buf)
{
unsignedcharrevale=0;
NRF24L01_SetRX_Mode();
Delay(1000);
sta=NRF24L01_SPI_Read(STATUS);//读取状态寄存其来判断数据接收状?
if(RX_DR)//判断是否接收到数据
{
CE=0;//SPI使能
NRF24L01_SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);//(readreceivepayloadfromRX_FIFObuffer)从接收缓冲器中读出数据
revale=1;//读取数据完成标志
led2=0;//二极管显示接没接收到数据
}
NRF24L01_SPI_RW_Reg(WRITE_REG+STATUS,sta);//接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清除中断标志
CSN=0;
NRF24L01_SPI_RW(FLUSH_RX);//用于清空FIFO!
!
关键!
!
防止接收先前的数据!
CSN=1;
Delay(100);
led2=1;
returnrevale;
}
/***********************************************************************************************************
/*函数:
voidnRF24L01_TxPacket(unsignedchar*tx_buf)
/*功能:
发送tx_buf中数据
/**********************************************************************************************************/
voidNRF24L01_TxPacket(unsignedchar*tx_buf)
{
CE=0;//(StandByI模式)待机I模式
CSN=0;
NRF24L01_SPI_RW(FLUSH_TX);//用于清空FIFO!
!
关键!
!
防止发送先前的数据!
CSN=1;
NRF24L01_SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//装载接收端地址0
NRF24L01_SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);//装载数据
NRF24L01_SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);//IRQ收发完成中断响应,16位CRC,主发送
CE=1;//置高CE,激发数据发送
inerDelay_us(10);
}
/****************************************************************************************************/
voidmain()
{
unsignedcharTxBuf[TX_PLOAD_WIDTH]={0};//定义发送的数据数组
unsignedcharRxBuf[RX_PLOAD_WIDTH]={0};//定义接收数据的数组
unsignedchartf=0;//模式标志
LCD_init();//5110的初始化
LCD_clear();//5110的清屏函数
NRF24L01_init();//NRF24L01的初始化
LCD_write_english_string(3*6,0,"acceptor");//字符串显示
while
(1)
{
while
(1)
{
NRF24L01_RxPacket(RxBuf);
Delay(1000);
LCD_write_english_string(3*6,1,RxBuf);
if(KEY2==0)
{//去抖延时
Delay(30);
if(KEY2==0)
{
TxBuf[0]=0;//抢答模式
led1=0;
Delay(120);
led1=1;
Delay(120);
NRF24L01_TxPacket(TxBuf);
while(!
KEY2);
}
}
if(KEY4==0)
{
Delay(30);//去抖延时
if(KEY4==0)
{while(!
KEY4);break;}
}
}
TxBuf[0]=0;
TxBuf[1]=0;
LCD_write_english_string(2*6,1,"jurymode");
LCD_write_english_string(2*6,2,"grade:
");
LCD_write_english_char(8*6,2,'0');
while
(1)
{
if(KEY1==0)
{
Delay(30);//去抖延时
if(KEY1==0)
{
TxBuf[1]=TxBuf[1]+1;
if(TxBuf[1]==11)
TxBuf[1]=0;
LCD_write_english_char(8*6,2,TxBuf[1]+0x30);
LCD_write_english_char(9*6,2,'');
if(TxBuf[1]==10)
{
LCD_write_english_char(8*6,2,'1');
LCD_write_english_char(9*6,2,'0');
}
led1=0;
Delay(120);
led1=1;
Delay(120);
while(!
KEY1);
}
}
if(KEY2==0)
{
Delay(30);//去抖延时
if(KEY2==0)
{
TxBuf[0]=1;//评委模式
NRF24L01_TxPacket(TxBuf);
led1=0;
Delay(120);
led1=1;
Delay(120);
while(!
KEY2);
}
}
if(KEY3==0)
{
Delay(30);//去抖延时
if(KEY3==0)
{
if(TxBuf[1]==0)
{TxBuf[1]=10;}
else
{TxBuf[1]=TxBuf[1]-1;}
LCD_write_english_char(8*6,2,TxBuf[1]+0x30);
LCD_write_english_char(9*6,2,'');
if(TxBuf[1]==10)
{
LCD_write_english_char(8*6,2,'1');
LCD_write_english_char(9*6,2,'0');
}
led1=0;
Delay(120);
led1=1;
Delay(120);
while(!
KEY3);
}
}
if(KEY4==0)
{
Delay(30);//去抖延时
if(KEY4==0)
{while(!
KEY4);break;}
}
}
LCD_write_english_string(2*6,1,"");
LCD_write_english_string(2*6,2,"");
TxBuf[0]=0;
TxBuf[1]=0;
}
}
/**********************************************************************************
修改日:
2013/9/25
称号:
起点学校:
桂林电子科技大学
本人现在正在写上位机的串口通信软件有什么意见的可以一起交流
**********************************************************************************/