完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
原子忘了将一句话,我来补充:无线模块内部有寄存器地址,读取寄存器的时候,地址就是手册的地址。写寄存器的时候,地址第6位要或1也就是(地址值或0x20)原子的程序写的很清晰,我没接触过这模块,也没看手册,现在明白了。我说AAAAA和1AAAAA是怎么回事呢。
http://www.openedv.com/posts/list/6363.htm http://www.openedv.com/posts/list/6369.htm http://www.openedv.com/posts/list/6391.htm NRF24L01+程序.rar (10.58 MB ) KEIL4中文完美版.zip (32.14 MB ) |
|
相关推荐
29个回答
|
|
|
|
|
|
谢谢分享
|
|
|
|
无线模块的地址从0x00开始往后排,大部分寄存器8位。(76543210)用spi方式读取。比如读取0x00寄存器:先spi写寄存器地址0x00,后写0xff(0xff对无线模块是空命令,利用的是sck时钟的电平跳变读出0x00地址的数据)如果要写寄存器,地址的二进制的第6位要为1(无线为了区分读地址还是写地址)0010 0000是0x20这就是为何原子的程序(设置无线寄存器地址要加上0x20的原因)
例如:无线模块24L01寄存器0x05,是设置nRF24L01的工作频率(bit7不用,bit6~0工作频率值)。就要写(0x05加0x20等于0x25)后设置(例:NRF24L01_Write_Reg((0x05+0x20),0x7f)//工作频率设置0111 1111 基础很重要,当时没看手册,光看原子的程序,看得很纠结,看了手册后,就很快明白程序为何这样写了。 |
|
|
|
|
|
|
|
发射地址const u8 TX_ADDRESS [TX_ADR_WIDTH]={0x00,0xc2,0xc2,0xc2,0xc2}; //发送地址(地址要和接收通道地址一致) 接收地址const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0x00,0xc2,0xc2,0xc2,0xc2}; //接收0通道地址(地址随便改,但必须和发射地址一致) const u8 RX_ADDRESS1[RX_ADR_WIDTH]={0x01,0xc2,0xc2,0xc2,0xc2}; //接收1通道地址0xc2是被锁死的,只能改0x01 const u8 RX_ADDRESS2[RX_ADR_WIDTH]={0x02,0xc2,0xc2,0xc2,0xc2,}; //接收2通道地址 写的时候是低位先写,所以只要写1次 const u8 RX_ADDRESS3[RX_ADR_WIDTH]={0x03,0xc2,0xc2,0xc2,0xc2,}; //接收3通道地址 const u8 RX_ADDRESS4[RX_ADR_WIDTH]={0x04,0xc2,0xc2,0xc2,0xc2,}; //接收4通道地址 const u8 RX_ADDRESS5[RX_ADR_WIDTH]={0x05,0xc2,0xc2,0xc2,0xc2}; //接收5通道地址 注:红底字的值可以随意改,黑底字 的值被锁死了。 要想通讯:条件:1 接收地址和发射地址必须一致 2 无线模块0x05寄存器的值必须一致(发射/接收这2模块) 3 无线模块从0x00寄存器往后的(各个bit位的功能)去看下手册 |
|
|
|
学习了
|
|
|
|
24L01和24L01+差不多,写地址的时候要注意,并不是高位写到低位,而是低位先写出,通道2345的高位被锁成和0通道一样,所以2345写地址只能写一次,这个就是写的低位的地址。
|
|
|
|
楼主正解,很有心!
|
|
|
|
顶一下
|
|
|
|
顶一下
|
|
|
|
我想两个模块通信,51接收,stm32发射, 我已经把它都设置成一样的配置了,stm32总是进入:MAX_TX 最大重发次数。 我的package是4不是32,两边都改了。 给你看下配置: 51: unchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址 void NRFSetRXMode() { CE=0; NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址 NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答 NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/ NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式 CE = 1; Delay(5);//保持10us秒以上 } STM32: const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址 const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址 void NRF24L01_TX_Mode(void) { NRF24L01_CE_L; NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 NRF24L01_Write_Buf(WRITE_REG_NRF+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK NRF24L01_Write_Reg(WRITE_REG_NRF+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG_NRF+EN_RXADDR,0x01); //使能通道0的接收地址 // NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_RETR,0x0a); NRF24L01_Write_Reg(WRITE_REG_NRF+RF_CH,40); //设置RF通道为40 // NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x07); NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x0e); //配置基本工作模式的参数WR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 NRF24L01_CE_H;//CE为高,10us后启动发送 } 帮忙看下吧,谢了,调了几天没调出来,收发设置函数,与读写都没问题,32和32板子可以正常通信,51和51板子可以正常通信。 |
|
|
|
我看了你的程序,我想说的是,你发射机加个10秒的延时试试。(因为发射机发射后必须收到接受机应答,才能确定发射成功。)发射机发射,如果接收机运行慢,又开始下一轮发射,这样发射永远失败。 |
|
|
|
哥们实验了还是不行。 int main(void) { u8 tmp_buf[4]={0x31,0x32,0x33,0x34}; // u8 tmp_buf[33]; u8 key,mode; u16 t=0; System_Initialize(); if(!NRF24L01_Check()) { printf("NRF24L01_Check OK"); delay_ms(200); NRF24L01_TX_Mode(); mode=' ';//从空格键开始 while(1) { if(NRF24L01_TxPacket(tmp_buf)==TX_OK) { printf("Send Complete"); }else { printf("Send Failed"); }; delay_ms(10000); } } else printf("NRF24L01_Check Failed"); } 这是main函数。 发送还是原封不动用的战舰板子的: unsigned char NRF24L01_TxPacket(unsigned char *txbuf) { u8 sta; SPI2_SetSpeed(SPI_BaudRatePrescaler_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) NRF24L01_CE_L; NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节 NRF24L01_CE_H;//启动发送 while(NRF24L01_IRQ_In!=0);//等待发送完成 sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&MAX_TX)//达到最大重发次数 { NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; } if(sta&TX_OK)//发送完成 { return TX_OK; } return 0xff;//其他原因发送失败 } 单步调试发现每次运行结果都是:MAX_TX 达到了最大重发次数。 你说的延时我在main中那样写对么 另51中的读取数据: unchar NRFRevDate(unchar *RevDate) { unchar RevFlags=0; sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器 if(RX_DR) // 判断是否接收到数据 { CE=0; //SPI使能 NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WITDH);// 从RXFIFO读取数据 RevFlags=1; //读取数据完成标志 } NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标 return(RevFlags); } |
|
|
|
楼主帮忙一起想想办法吧
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对了,51和STM32是用一个keil么?我之前的编译不了51的,只能STM32 --------------------------------- 不一样,keil版本不一样的,一个用于51 另一个用于arm |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2573 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2367 浏览 5 评论
3216 浏览 3 评论
2841 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2795 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
673浏览 1评论
911浏览 0评论
1032浏览 0评论
675浏览 0评论
507浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 04:31 , Processed in 1.473391 second(s), Total 119, Slave 101 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号