




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
说实话,对于一个初次调试这个模块的同学,想要找一个直接可用的程序不好找,同时是找到的片段程序很多又是木有注释的,我们(菜鸟)没有很好的理解芯片资料的能力,看着都是一头雾水。在这儿,我贴出发送和接收两部分,希望可以让学习者轻松一点理解和掌握其操作流程。同时声明一下,下面的程序不是我写的,但是99%的注释是我写的,对于掌握的人来说,不需要这样多的注释,我是面对需要学习的人而写的。这样也算是我对电子技术给我的乐趣的回馈。在没有和程序作者取得联系的情况下我修改一部分且直接贴上百度,希望见谅,我们都是希望这对大家的学习有所帮助!注释的位置需要调整一下哦以下是发送端程序:#include<reg52.h>#include<intrins.h>#defineMODE0//MODE=1时为发送代码 MODE=0时为接收代码typedefunsignedcharuchar;//************************************************IO端口定义*****************sbitMISO=P2^3;sbitMOSI=P2^2;sbitSCK=P2^1;sbitCE=P2^5;sbitCSN=P2^0;sbitIRQ=P3^2;sbitled=P1^2;//*****************************************************************************ucharbdatasta;//状态标志sbitRX_DR=sta^6;sbitTX_DS=sta^5;sbitMAX_RT=sta^4;********************************κ∣oCO^ICd***********************************************#defineTX_ADR_WIDTH#defineRX_ADR_WIDTH#defineTX_PLOAD_WIDTH#defineRX_PLOAD_WIDTH5//5uintsTXaddresswidth5//5uintsRXaddresswidth32//32uintsTXpayload32//32uintsTXpayloaducharconstTX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//本地地址ucharconstRX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址ucharcodeTx_Buf[TX_PLOAD_WIDTH]{0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据UCharRx_Buf[RX_PLOAD_WIDTH];//接收数据//*********NRF24L01寄存器指令*******************************************************#defineREAD_REG#defineWRITE_REG#defineRD_RX_PLOAD#defineWR_TX_PLOAD#defineFLUSH_TX#defineFLUSH_RX#defineREUSE_TX_PL#defineNOP0x00//读寄存器指令0x20//写寄存器指令0x61//读取接收数据指令0xA0//写待发数据指令0xE1//冲洗发送FIFO指令0xE2//冲洗接收FIFO指令0xE3//定义重复装载数据指令0xFF//保留//***SPI(nRF24L01)寄存器地址****************************************************#defineCONFIG 0x00〃配置收发状态,CRC校验模式以及收发状态响应方式#defineEN_AA 0x01//自动应答功能设置0x02//可用信道设置#defineEN_RXADDR#defineSETUP_AW0x03//收发地址宽度设置#defineSETUP_RETR0x04//自动重发功能设置#defineRF_CH0x05//工作频率设置#defineRF_SETUP0x06//发射速率、功耗功能设置#defineSTATUS0x07//状态寄存器#defineOBSERVE_TX0x08//发送监测功能#defineCD0x09//地址检测#defineRX_ADDR_P00x0A//频道0接收数据地址#defineRX_ADDR_P10x0B//频道1接收数据地址#defineRX_ADDR_P20x0C//频道2接收数据地址#defineRX_ADDR_P30x0D//频道3接收数据地址#defineRX_ADDR_P40x0E//频道4接收数据地址#defineRX_ADDR_P50x0F//频道5接收数据地址#defineTX_ADDR0x10//发送地址寄存器#defineRX_PW_P00x11//接收频道0接收数据长度#defineRX_PW_P10x12//接收频道0接收数据长度#defineRX_PW_P20x13//接收频道0接收数据长度#defineRX_PW_P30x14//接收频道0接收数据长度#defineRX_PW_P40x15//接收频道0接收数据长度#defineRX_PW_P50x16//接收频道0接收数据长度#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置/******************************************延时函数********************************************/voidDelay(unsignedints) //长延时{unsignedinti,j;for(i=0;i<1000;i++)for(j=0;j<s;j++);}voiddelay_ms(unsignedintx) //短延时{unsignedinti,j;i=0;for(i=0;i<x;i++){j=108;;while(j--);}}/************************************IO口模拟SPI总线代码************************************************/UCharSPLRW(UCharbyte) //SPI边发送边接收,这儿写法值得学习,减少形参{UCharbit_Ctr;for(bit_Ctr=0;bit_Ctr<8;bit_Ctr++){MOSI=(byte&0x80); //取最高位发送byte=(byte<<1); //不断地填补到最高位SCK=1;byteI=MISO; 〃把接收到的数据一位一位的补充到byte中去,这样就不需要多定义变量//led=MISO;Delay(150);SCK=0;}return(byte);//byte就是从机的答复}//***********************************通过spi通讯的方式对模块进行写操作****************************************************ucharSPI_RW_Reg(ucharreg,ucharvalue)//向寄存器REG写一个字节,同时返回状态字节,这里关系到模块的操作,//你要给模块发送命令,然后它回复你表示收到了指令,然后执行你的指令{ucharstatus;CSN=0;status=SPLRW(reg); Hteg就是我们按照资料给模块的指令,SPLRW(reg)的return值就是模块的答复,也就是告诉单片机它现在的状态,它要干什么。SPLRW(Value); 〃Value就是我们需要传输的内容,这里就是给它发送我们要它发送东西的指令,接着我们就把要发送的东西给它。CSN=1;return(status); 〃之所以要return一个StatUS,是因为我们要知道模块有没有发送了}//***********************************通过spi通讯方式将模块收到的数据读取到单片机******************************************UCharSPLRead(UCharreg) 〃这里的reg和上面的reg不一样,他们在不同的作用域,所以不会有什么干扰,就是看起来会乱{uCharreg_Val;CSN=0;SPI_RW(reg);reg_Val=SPI_RW(0);//0是什么指令呢?到上面看一下,哦,,原来是读寄存器指令,返回来的自然是寄存器里面存下来已经接收到的值CSN=1;return(reg_val); //将模块接收到的值返回给单片机老大}//***********************************告诉模块写信人和收信人的地址的函数*********************************************************ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes){ucharstatus,byte_ctr;CSN=0;//SetCSNlow,initSPItranaction这不用说了,看时序图status=SPI_RW(reg);//Selectregistertowritetoandreadstatusbyte告诉模块我准备发送东西for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)//thenwriteallbyteinbuffer(*pBuf)告诉模块我要发送东西SPI_RW(*pBuf++); //每发出去指针就后移一位,这写法值得学习CSN=1;//SetCSNhighagain 这不用说了,看时序图return(status);//returnnRF24L01statusbyte看看模块的状态,知道它是否发送了还是在偷懒}/*******************************发*****∏⅛*****送*****模*****式*****代*****码*************************************/VoidTX_Mode(Void)〃开始我也不习惯TX是发送的意思,总得习惯的,大家都一样
是模块设置,写什么指令,要模块怎样怎样{CE=0;SPLRW_Reg(FLUSHJX,0x00);//FLUSH_TX是冲洗发送FIFO数据缓存器的意思,FIFO
是英文FirstInFirstOUt的缩写,是一种先进先出的数据缓存器,最好百度一下面就SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//WritesTX_AddresstonRF24L01复杂,其实就是告诉模块发送地址和发送地址位宽,看上面的定义//也就是我告诉邮递员你要把信送到哪儿去,这是地址。SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//RX_Addr0sameasTX_AdrforAuto.Ack把写信和收信的地址配对好。SPI_RW_Reg(WRITE_REG+EN_AA,0x01);//EnableAuto.Ack:Pipe0使能自动回复通道0我要你模块有自动回复的功能,同样是对模块写指令SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);//EnablePipe0告诉模块通过那个通道传送信息,0X01没搞懂SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a);//500us+86us,10retrans...1a开启自动重发功能SPI_RW_Reg(WRITE_REG+RF_CH,40);//SelectRFchannel40 设置工作频率为40hzSPI_RW_Reg(WRITE_REG+RF_SETUP,0x07 ); //TX_PWR:0dBm,Datarate:1Mbps,LNA:HCURR发射速率、功耗功能设置SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//设置接收数据长度,本次设置为2字节SPLRW_Reg(WRTE_REG +CONFIG,0x0e); 〃配置收发状态,CRC校验模式以及收发状态响应方式CE=1;delay_ms(100);//设置完毕,说白了就是模块的初始化}//************************************上面对模块初始化好了,那么这个函数就是发送数据啦!****************************************voidTransmit(unsignedchar*tx_buf){CE=0;//StandByI模式SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//装载接收端地址SPLRW_Reg(FLUSH_TX,0x00);//FLUSH_TX是冲洗发送FIFO数据缓存器的意思,上面出现过,但是还是讲一下SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);//终于,我们等的就是这一刻,告诉模块我们要发送的数据和数据位宽〃WR_TX_PLOAD是写发送数据的指令,Tx_Buf是数组名,也是指针,TX_PLOAD_WIDTH是数据宽度SPLRW_Reg(WRITE_REG+CONFIG,0x0e);//IRQ收发完成中断响应,16位CRC,主发送//CRC是循环冗余码校验这是模块的工作,我们要他这样做,谁叫他有这功能CE=1;〃置高CE,激发数据发送delay_ms(150);}***********************************数啦主函到//*voidmain(void){CE=0;SCK=0;CSN=1; //设置模块为发送模式P1=0x00;TX_Mode(); //初始化模块使之做好发送工作//SPI_RW_Reg(FLUSH_RX,0x00);while(1){Transmit(Tx_Buf);//传送数据Delay(10);sta=SPI_Read(READ_REG+STATUS);//读出模块的状态,我要知道其是否成功发送了,看下面吧if(TX_DS){PI=Sta;〃8位LED显示当前STATUS状态发送中断应使bit5=1灯灭Delay(100);SPI_RW_Reg(WRITE_REG+STATUS,Sta);//不懂}if(MAX_RT)//如果发送超时{P1=0x0f;〃发送超时时8位LED灯bit4=1灯灭Delay(150);SPI_RW_Reg(WRITE_REG+STATUS,Sta); //不懂}}}以下是接收端程序:#include<reg52.h>#include<intrins.h>#defineMODE0//MODE=1时为发送代码 MODE=0时为接收代码typedefunsignedcharuchar;//*******************************************************************************IO端口定义sbitMISO=P2^3;sbitMOSI=P2^2;sbitSCK=P2^1;sbitCE=P2^5;sbitCSN=P2^0;sbitIRQ=P3^2;sbitled=P1^2;sbitled1=P3^0;sbitled2=P3^1;sbitled3=P3^6;sbitled4=P3^7;//******************************************************************************************ucharbdatasta;//状态标志sbitRX_DR=sta^6;sbitTX_DS=sta^5;sbitMAX_RT=sta^4;//*********************************NRF24L01*************************************************#defineTX_ADR_WIDTH#defineRX_ADR_WIDTH#defineTX_PLOAD_WIDTH#defineRX_PLOAD_WIDTH5//5uintsTXaddresswidth5//5uintsRXaddresswidth32//32uintsTXpayload32//32uintsTXpayloaducharconstTX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//本地地址ucharconstRX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址ucharcodeTx_Buf[TX_PLOAD_WIDTH ]{0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据UCharRx_Buf[RX_PLOAD_WIDTH];//接收数据//***************************************NRF24L01寄存器指令*******************************************************#defineREAD_REG#defineWRITE_REG#defineRD_RX_PLOAD#defineWR_TX_PLOAD#defineFLUSH_TX#defineFLUSH_RX#defineREUSE_TX_PL#defineNOP0x00//读寄存器指令0x20//写寄存器指令0x61//读取接收数据指令0xA0//写待发数据指令0xE1//冲洗发送FIFO指令0xE2//冲洗接收FIFO指令0xE3//定义重复装载数据指令0xFF//保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#defineCONFIG#defineEN_AA#defineEN_RXADDR#defineSETUP_AW#defineSETUP_RETR#defineRF_CH#defineRF_SETUP0X00//配置收发状态,CRC校验模式以及收发状态响应方式0x01//自动应答功能设置0x02//可用信道设置0x03//收发地址宽度设置0x04//自动重发功能设置0x05//工作频率设置0x06//发射速率、功耗功能设置#defineSTATUS0x07//状态寄存器#defineOBSERVE_TX0x08//发送监测功能#defineCD0x09//地址检测#defineRX_ADDR_P00x0A//频道0接收数据地址#defineRX_ADDR_P10x0B//频道1接收数据地址#defineRX_ADDR_P20x0C//频道2接收数据地址#defineRX_ADDR_P30x0D//频道3接收数据地址#defineRX_ADDR_P40x0E//频道4接收数据地址#defineRX_ADDR_P50x0F//频道5接收数据地址#defineTX_ADDR0x10//发送地址寄存器#defineRX_PW_P00x11//接收频道0接收数据长度#defineRX_PW_P10x12//接收频道0接收数据长度#defineRX_PW_P20x13//接收频道0接收数据长度#defineRX_PW_P30x14//接收频道0接收数据长度#defineRX_PW_P40x15//接收频道0接收数据长度#defineRX_PW_P50x16//接收频道0接收数据长度#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置****************************************函延时数/**********************************************/voidDelay(unsignedints) //长延时{unsignedinti,j;for(i=0;i<1000;i++)for(j=0;j<s;j++);}voiddelay_ms(unsignedintx) //短延时{unsignedinti,j;i=0;for(i=0;i<x;i++){j=108;;while(j--);}}/************************************IO口模拟SPI总线代码************************************************/UCharSPLRW(UCharbyte) //SPI边发送边接收,这儿写法值得学习,减少形参{UCharbit_Ctr;for(bit_Ctr=0;bit_Ctr<8;bit_Ctr++){MOSI=(byte&0x80); //取最高位发送byte=(byte<<1); //不断地填补到最高位SCK=1;byteI=MISO; 〃把接收到的数据一位一位的补充到byte中去,这样就不需要多定义变量//led=MISO;Delay(150);SCK=0;}return(byte);//byte就是从机的答复}//***********************************通过spi通讯的方式对模块进行写操作****************************************************ucharSPI_RW_Reg(ucharreg,ucharvalue)//向寄存器REG写一个字节,同时返回状态字节,这里关系到模块的操作,//你要给模块发送命令,然后它回复你表示收到了指令,然后执行你的指令{ucharstatus;CSN=0;status=SPLRW(reg); 〃reg就是我们按照资料给模块的指令,SPLRW(reg)的return值就是模块的答复,也就是告诉单片机它现在的状态,它要干什么。SPLRW(ValUe); 〃ValUe就是我们需要传输的内容,这里就是给它发送我们要它发送东西的指令,接着我们就把要发送的东西给它。CSN=1;return(status); 〃之所以要return一个StatUS,是因为我们要知道模块有没有发送了}//***********************************通过spi通讯方式将模块收到的数据读取到单片机******************************************ucharSPLRead(UCharreg) 〃这里的reg和上面的reg不一样,他们在不同的作用域,所以不会有什么干扰,就是看起来会乱{uCharreg_Val;CSN=0;SPI_RW(reg);reg_Val=SPI_RW(0); //0是什么指令呢?到上面看一下,哦,,原来是读寄存器指令,返回来的自然是寄存器里面存下来已经接收到的值CSN=1;return(reg_Val);//将模块接收到的值返回给单片机老大//***********************************告诉模块写信人和收信人的地址的函数*********************************************************ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes){ucharstatus,byte_ctr;CSN=0;//SetCSNlow,initSPItranaction这不用说了,看时序图status=SPI_RW(reg);//Selectregistertowritetoandreadstatusbyte告诉模块我准备发送东西for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)//thenwriteallbyteinbuffer(*pBuf)告诉模块我要发送东西SPI_RW(*pBuf++); //每发出去指针就后移一位,这写法值得学习CSN=1;//SetCSNhighagain 这不用说了,看时序图return(status);//returnnRF24L01statusbyte看看模块的状态,知道它是否发送了还是在偷懒}接收模式代/********************************************************码*************************************/ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)//读数据函数{unsignedcharstatus,uchar_ctr;CSN=0;//SetCSNlow,initSPItranaction不用讲,看时序图status=SPI_RW(reg);//Selectregistertowritetoandreadstatusuchar写指令for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr]=SPI_RW(0);//逐位读出数据CSN=1;return(status);//returnnRF24L01statusuchar看状态,知道有模块有没有工作****************************************************************************************************//***函数:unsignedCharnRF24L01_RxPacket(UnSignedchar*rx_buf)/***功能:数据读取后放在rx_buf接收缓冲区中/******************************************************************************************************/unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf) //我们要用上面的函数把接收到的数据读出来{unsignedcharrevale=0;sta=SPI_Read(STATUS);//读取状态寄存其来判断数据接收状况if(RX_DR)//判断是否接收到数据{//CE=0;//SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);//readreceivepayloadfromRX_FIFObuffer和发送程序一样,一个是指令,一个是指针,一个是宽度revale=1;//读取数据完成标志//Delay(100);}SPI_RW_Reg(WRITE_REG+STATUS,sta);//接收到数据后RX_DR,TX_DS,MAX_PT都置
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 濮阳科技职业学院《大数据统计模型实验》2023-2024学年第二学期期末试卷
- 喀什大学《数字影像工程》2023-2024学年第二学期期末试卷
- 安徽工业经济职业技术学院《流行音乐经典作品分析(2)》2023-2024学年第二学期期末试卷
- 公章的管理制度
- 公司章程中内控的内容
- 公共交通线路调整管理制度
- 工程施工队每周进度计划表格
- 页岩砖砌体施工方案
- 【2025年二手房行业资讯:深圳周录1812套再创新高】
- 江西省上饶市2024-2025学年高二上学期1月期末英语试题【含答案】
- GB/T 12618.4-2006开口型平圆头抽芯铆钉51级
- 红金大气商务风领导欢迎会PPT通用模板
- 学前教育学00383-历年真题-试卷
- 淡马锡模式解读汇总课件
- 2022年郑州卫生健康职业学院单招职业适应性测试笔试试题及答案解析
- 穴位贴敷技术操作流程图及评分标准
- 湖北省黄冈市基层诊所医疗机构卫生院社区卫生服务中心村卫生室地址信息
- 个人有关事项报告表(全)
- 角膜上皮损伤-临床诊治专家共识-课件
- 电力排管检验批
- 毕业论文-楼道节能灯的设计与实现
评论
0/150
提交评论