完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
NRF24L01
NRF24L01是工作在2.4~2.5GHz世界通用ISM频段的单片机无线收发芯片。
[tr]管脚功能[/tr]
NRF24L01集成了所有高速链路层的自动应答、自动重发、数据包识别等操作,无需MCU介入。 在接收模式下,NRF24L01可同时接收6个不同通道的数据,每个通道使用不同的地址。芯片可通过STATUS寄存器的RX_P_NO来获取接收数据的通道号。接收时芯片还会通过PID(数据包识别)来判断是否与上一个数据相同,CRC检测数据的完整性,并进行自动应答。接收完毕芯片触发中断RX_DR,数据存储在RX_FIFO中。 在发送模式下,在将打包完的数据发送后,芯片将等待接收端的应答信号,若有则触发中断TX_DS并清除TX_FIFO;若无则自动重发,重发次数大于重发计数器ARC_CNT是,STATUS状态寄存器的MAX_RT置“1”,不清除TX_FIFO的数据。 数据长度,NRF24L01的发送数据长度最长32字节,其支持静态和动态1两种模式。在静态模式中,我们通过RX_PW_Px寄存器来接收数据长度,该模式下发送数据长度必须于设定值相同,若要更改数据长度需要操作相关寄存器。在动态模式中,我们需要先设置FEATURE和DYNPD寄存器来开启,在接收端可使用命令R_RX_PL_WID来获取数据长度。 NRF24L01的6个通道地址有一定的规则,其中只有数据通道0可配置40位地址。而数据通道1~5则是32位共用地址+各自地址。 需要注意:由于芯片要求,在向寄存器写入地址信息时是低字节先写;在配置数据通道2~5,由于仅最后一位可配置,因此定义仅需与设置最后一位即可。 const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x77,0x35,0xF9,0xD3,0xE7}; //发送地址(本机)const u8 RX0_ADDRESS[RX_ADR_WIDTH]={0x77,0x35,0xF9,0xD3,0xE7}; //接收地址0调试思路 SPI通信 NRF24L01使用SPI通信,驱动它的第一步就是通信部分的,将底层通讯部分的程序封装后,后续的寄存器操作等都是可以跨平台移植的。而SPI的通讯又可以分为模拟和硬件两种实现方式,模拟即通过软件操作GPIO来实现SPI通讯协议,这个方法由于时序是软件操作,对单片机工作频率有限定,更改工作频率可能回导致不可用。硬件即使用单片机内部的片上外设,这个相对更加稳定,但其管脚固定,且有些单片机并没有硬件的SPI外设。两种方法需要根据实际情况选择,这里展示STC15和STM32的硬件SPI下的使用方法 STC15 u8 SPIx_ReadWriteByte(u8 byte) { u8 d_read,d_send=byte; SPDAT = d_send;//发送数据 while(!(SPSTAT&SPIF)) //等待数据发送完毕 ; SPSTAT = SPIF|WCOL; //清除状态位 d_read = SPDAT; return d_read; } STM32 uint8_t SPIx_ReadWriteByte(SPI_HandleTypeDef* hspi,uint8_t byte) { uint8_t d_read,d_send=byte; if(HAL_SPI_TransmitReceive(hspi,&d_send,&d_read,1,0xFF)!=HAL_OK) { d_read=0xFF; } return d_read; } 动态长度 数据的动态长度必须对下图两个寄存器进行操作 NRF24L01_Write_Reg(NRF_WRITE_REG+DYNPD,0x3F); //开启6通道DPL NRF24L01_Write_Reg(NRF_WRITE_REG+FEATURE,0x04|0x02);//开启DPL和ACK 在接受端想要获取数据长度便需要发送相关命令,而不是读取RX_PL_Px寄存器中的值 uint8_t NRF24L01_SendSring(uint8_t *txbuf,uint8_t length) { uint8_t sta,i; uint8_t tx_buffer[32];//发送数据缓存 tx_buffer[0]=length-1;//发送数据的首位为数据长度,sizeof求得长度包括了‘ ’ for(i=0;i tx_buffer[i+1] = txbuf;//将待发送数据放到数据长度后,组成一个完整需要发送的数据 } SPI1_SetSpeed(SPI_BAUDRATEPRESCALER_16); //spi速度为6.75Mhz(24L01的最大SPI时钟为10Mhz) NRF24L01_CE_LOW(); NRF24L01_Write_Reg(FLUSH_TX,0xff); NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,length);//写数据到TX BUF 32个字节 NRF24L01_CE_HIGH();//启动发送 while(NRF24L01_IRQ_PIN_READ()!=0);//等待发送完成 sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(NRF_WRITE_REG+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;//其他原因发送失败 } 文中若有错误,欢迎各位在评论区指正,共同学习! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1752 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1611 浏览 1 评论
1052 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1666 浏览 2 评论
1926浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
711浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
560浏览 3评论
583浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 13:33 , Processed in 1.008668 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号