nrf24l01是适合初学入门的无线模块.docx
- 文档编号:7651407
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:16
- 大小:22.41KB
nrf24l01是适合初学入门的无线模块.docx
《nrf24l01是适合初学入门的无线模块.docx》由会员分享,可在线阅读,更多相关《nrf24l01是适合初学入门的无线模块.docx(16页珍藏版)》请在冰豆网上搜索。
nrf24l01是适合初学入门的无线模块
24l01的多机通信采用频分多子的方法,只需要在接受端对不同的通道配置地址即可。
发送端使用相应的地址作为本机地址。
接受数据时通过读取STATUS中相关位即可得知接收的是哪个通道的数据。
以下仅给出多对一的通信代码。
至于一对多,以及多对多等情况读者可以自行研究了。
只给出相关部分,其他部分请参考前两篇文章
------------------------------------------接受端------------------------------------------------
uintconstADDRESS0[ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//频道0接收地址
uintconstADDRESS1[ADR_WIDTH]={0xc4,0xc3,0xc2,0xc1,0xc0};//频道1接收地址
ucharwho=0xff;
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
voidinit_NRF24L01(void)
{
us(100);
CE=0; //chipenable
CSN=1; //Spidisable
SCK=0; //Spiclocklineinithigh
//SPI_Write_Buf(WRITE_REG+TX_ADDR,ADDRESS0,ADR_WIDTH); //写本地地址
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,ADDRESS0,ADR_WIDTH);//频道0地址
SPI_Write_Buf(WRITE_REG+RX_ADDR_P1,ADDRESS1,ADR_WIDTH);//频道1地址
SPI_RW_Reg(WRITE_REG+EN_AA,0x03); //频道0、1自动应答
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x03); //允许频道0、1
SPI_RW_Reg(WRITE_REG+RF_CH,0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//0接收数据长度
SPI_RW_Reg(WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);//1接收数据长度
SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
}
/******************************************************************************************************/
/*函数:
unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)
/*功能:
数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)
{
unsignedcharrevale=0;
sta=SPI_Read(STATUS);//读取状态寄存其来判断数据接收状况
if(RX_DR) //判断是否接收到数据
{
CE=0;
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
revale=1;
who=sta&0x0e;
who|=0xf0; //通道0:
who==0xf0;通道1:
who==0xf2
}
SPI_RW_Reg(WRITE_REG+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
CSN=0;
SPI_RW(FLUSH_RX);
CSN=1;
returnrevale;
}
voidmain(void)
{
uchari;
ucharRxBuf[TX_PLOAD_WIDTH];
init_NRF24L01();
StartUART();
ms(6000);
while
(1)
{
//如果接收到数据,发往PC
SetRX_Mode();
if(nRF24L01_RxPacket(RxBuf))
{
R_S_Byte(who);
ms(10000);
for(i=0;i { R_S_Byte(RxBuf[i]); ms(10000); } } } } -------------------------------------------发送1---------------------------------------------------- uintconstADDRESS0[ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; 其余与双工通信相同 -------------------------------------------发送2---------------------------------------------------- uintconstADDRESS1[ADR_WIDTH]={0xc4,0xc3,0xc2,0xc1,0xc0};//频道1接收地址 其余与双工通信相同 以上就是简要的代码。 也是重要的地方。 如果发送端要发送数据的话,可能在配置自动应答的接受地址时会遇到一些问题。 (因为是以通道0作为应答通道,而发送模式又必须使得接收发送地址一致,这样给两台发送机发数据就要对0实时配置地址)笔者尝试过配置,没有成功,只好不配置了,都是这样接收端无法接收到自动应答的信号~~ 24l01双向通讯 2010-11-1921: 28 一周的时间过去了,终于搞出来了双向通讯,中间出了点莫名奇妙的情况,导致我迷惘了很久。 上次发的头文件和.c文件有个模式设置的选项。 在做双向通信的时候发现这个有点多余。 所以就删掉了,内容也做了些小改动。 所以就只发修改的部分 ------------------------------------------------------24l01.h------------------------------------------------------------ 这个文件和之前的一样。 只去掉 //模式选择 //#defineRMODE #defineTMODE 这几行 ------------------------------------------------------24l01.c------------------------------------------------------------- 修改了三个地方。 分别是 1、 //**************************************************************************************** /*NRF24L01初始化 /*这里不用设置什么模式,等需要接受或发送数据时指定模式 //***************************************************************************************/ voidinit_NRF24L01(void) { us(100); CE=0; //chipenable CSN=1; //Spidisable SCK=0; //Spiclocklineinithigh SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写本地地址 SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写接收端地址 SPI_RW_Reg(WRITE_REG+EN_AA,0x01); //频道0自动ACK应答允许 SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//允许接收地址只有频道0,如果需要多频道可以参考Page21 SPI_RW_Reg(WRITE_REG+RF_CH,0); // 设置信道工作为2.4GHZ,收发必须一致 SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//设置接收数据长度,本次设置为32字节 SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07); //设置发射速率为1MHZ,发射功率为最大值0dB } 2、 /****************************************************************************************************/ /*函数: voidSetRX_Mode(void) /*功能: 数据接收配置 /****************************************************************************************************/ voidSetRX_Mode(void) { CE=0; SPI_RW_Reg(WRITE_REG+CONFIG,0x0f); //IRQ收发完成中断响应,16位CRC,主接收 CE=1; us(130); } 3、 /*********************************************************************************************************** /*函数: voidnRF24L01_TxPacket(unsignedchar*tx_buf) /*功能: 发送tx_buf中数据 /**********************************************************************************************************/ voidnRF24L01_TxPacket(unsignedchar*tx_buf) { CE=0; //StandByI模式 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,激发数据发送 us(10); } ------------------------------------------------------------------------------------------------------------- 以上就是全部的修改。 这两个文件同样适用于单工通信。 以下给出这次测试用的两个主函数。 为了方便与上次的文章对应。 这里还是以接收,发送区分。 --------------------------------------------------接收-------------------------------------------------------- #include"nrf24l01.h" #include"delay.h" ucharTxBuf[TX_PLOAD_WIDTH]={0x55,0xaa}; //************************************串口初始化********************************************************* voidStartUART(void) { //波特率2400 SCON=0x50; TMOD=0x20; TH1=0xF3; TL1=0xF3; PCON=0x00; TR1=1; } //************************************通过串口将接收到数据发送给PC端************************************** voidR_S_Byte(ucharR_Byte) { SBUF=R_Byte; while(TI==0); //查询法 TI=0; } //************************************主函数************************************************************ voidmain(void) { uchari; ucharRxBuf[TX_PLOAD_WIDTH]; init_NRF24L01(); StartUART(); ms(6000); while (1) { //如果接收到数据,发往PC SetRX_Mode(); if(nRF24L01_RxPacket(RxBuf)) { for(i=0;i { R_S_Byte(RxBuf[i]); } } //发送0x55,0xaa要求发送端发数据 nRF24L01_TxPacket(TxBuf); //SPI_RW_Reg(WRITE_REG+STATUS,0XFF);加上这句后,会出现接收到几组数据后停止了接收的现象,原因未知 ms(130);//这个延时很重要,延时过短,数据包丢失。 //延时过长,减慢速度,甚至无法接收(实验时出现的问题,原因未知) RxBuf[0]=0; RxBuf[1]=0; } } --------------------------------------------------------------------发送--------------------------------------------- include"nrf24l01.h" #include"delay.h" ucharTxBuf[TX_PLOAD_WIDTH]= { 0x01,0x02 }; voidmain() { charRxBuf[TX_PLOAD_WIDTH]={0}; init_NRF24L01(); nRF24L01_TxPacket(TxBuf); ms(6000); while (1) { SetRX_Mode(); if(nRF24L01_RxPacket(RxBuf)) { //将收到的数据发回接收端检验是否正确 //如果设置的数据较长,应使用for循环 TxBuf[0]=RxBuf[0]; TxBuf[1]=RxBuf[1]; nRF24L01_TxPacket(TxBuf); SPI_RW_Reg(WRITE_REG+STATUS,0XFF); ms(90);//这个延时一样很重要 RxBuf[0]=0; RxBuf[1]=0; } } } ------------------------------------------------------------------------------------------------------------- 以上就是这周忙活的东西了,高手不要见笑。 PS: 原先想要使用自动重发功能的,结果发现自动重发的话,传输速率很慢,没有延时的快。 也可能是我自动重发的延时没设置好。 另外最开始几天一直在做中断通信,如果使用IRQ上中断来接受数据,可以明显减轻MCU的负担。 可是我测试了几天下来发现一个无语的结果。 在中断里读出来的STATUS的值是0x00,顿时心灰意冷。 网上有其他人貌似做出来了,可惜我写的跟他们一样也不行啊~~~~,不知道问题在哪。 但有一点是肯定的: 接收到数据时必然引起中断。 过几天继续贴出多机通信的代码。 nrf24l01的51驱动程序 2010-11-1318: 58 随着物联网时代的到来,无线通信技术日趋重要。 nrf24l01是适合初学入门的无线模块。 于是乎我就一头埋进去,苦干一周有余。 发现网上的程序都是抄来抄去的,不甚寒心。 抄也就算了,光抄错的! 后来自己动手研究,完成了SPI接口的操作,继续攻克无线模块,最终无果,只好再找代码。 终于找到了一个可以的。 本来想直接贴出来的,但为了许多和我曾经一样迷茫的同胞可以顺利进入无线领域。 我特意修改代码,整理出nrf24l01.h与nrf24l01.c,一则便于模块化管理,二则,便于使用,便于二次开发。 同时,增加了许多注释。 代码中应该还有许多不足的,甚至多余的东西,后续将会继续发表一篇关于无线模块开发的注意事项。 //---------------------nrf24l01.h---------------------------- #ifndefNRF24L01_H #defineNRF24L01_H #include //模式选择 //#defineRMODE #defineTMODE typedefunsignedcharuchar; typedefunsignedcharuint; //****************************************SPI-IO端口*************************************** sbitCE =P1^0;//3 sbitSCK=P1^1;//5 sbitMISO=P1^2;//7 sbitCSN=P1^5;//4 sbitMOSI=P1^6;//6 sbitIRQ=P1^7;//8 //*****************************************地址、数据长度************************************* #defineTX_ADR_WIDTH 5 //5uintsTXaddresswidth #defineRX_ADR_WIDTH 5 //5uintsRXaddresswidth #defineTX_PLOAD_WIDTH32//20uintsTXpayload #defineRX_PLOAD_WIDTH32//20uintsTXpayload //***************************************NRF24L01寄存器指令******************************************************* #defineREAD_REG 0x00//读寄存器指令 #defineWRITE_REG 0x20//写寄存器指令 #defineRD_RX_PLOAD 0x61//读取接收数据指令 #defineWR_TX_PLOAD 0xA0//写待发数据指令 #defineFLUSH_TX 0xE1//冲洗发送FIFO指令 #defineFLUSH_RX 0xE2//冲洗接收FIFO指令 #defineREUSE_TX_PL 0xE3//定义重复装载数据指令 #defineNOP 0xFF//保留 //*************************************SPI(nRF24L01)寄存器地址**************************************************** #defineCONFIG 0x00//配置收发状态,CRC校验模式以及收发状态响应方式 #defineEN_AA 0x01//自动应答功能设置 #defineEN_RXADDR 0x02//可用信道设置 #defineSETUP_AW 0x03//收发地址宽度设置 #defineSETUP_RETR 0x04//自动重发功能设置 #defineRF_CH 0x05//工作频率设置 #defineRF_SETUP 0x06//发射速率、功耗功能设置 #defineSTATUS 0x07//状态寄存器 #defineOBSERVE_TX 0x08//发送监测功能 #defineCD 0x09//地址检测 #defineRX_ADDR_P0 0x0A//频道0接收数据地址 #defineRX_ADDR_P1 0x0B//频道1接收数据地址 #defineRX_ADDR_P2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- nrf24l01 适合 初学 入门 无线 模块