完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
参照野火STM32程序调试NRF24L01成功,颇获喜感
nRF24L01是一款工作在2.4~2.5GHz世界通用ISM频段的单片无线收发器芯片。无线收发器包括:频率发生器、增强型SchockBurstTM模式控制器、功率放大器、警惕振荡器、调制器、解调器。输出功率、频道选择和协议的设置可以通过SPI接口进行设置。 模块外形图如下图所示: PCB和引脚示意图如下图所示: 电路图如图所示: VDD电压范围为1.9V~3.6V,我使用的是3.3V,与单片机的通信接口类型为SPI,读写时序如下图所示: 与开发板硬件连接如下: * 硬件连接:----------------------------—----| | PA5-SPI1-SCK : NRF -SCK | | PA6-SPI1-MISO : NRF -MISO | | PA7-SPI1-MOSI : NRF -MOSI | | PA4 : NRF -CE | * | PA3 : NRF -CSN | | PA2 : NRF -IRQ | * ------------------------------------------- 引脚配置如下: /*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能 GPIO_Init(GPIOA, &GPIO_InitStructure); /*配置SPI_NRF_SPI的CE引脚,GPIOA^4和SPI_NRF_SPI的 CSN 引脚: NSS GPIOC^4*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /*配置SPI_NRF_SPI的IRQ引脚,GPIOA^2*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); SPI配置如下: SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据大小8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟极性,空闲时为低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第1个边沿有效,上升沿为采样时刻 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分频,9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); /* Enable SPI1 */ SPI_Cmd(SPI1, ENABLE); 配置进入接收模式: void NRF_RX_Mode(void) { NRF_CE_LOW(); SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通信频率 SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,0db增益,1Mbps,低噪声增益开启 SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 NRF_CE_HIGH(); /*CE拉高,进入接收模式*/ delay_ms(100); //CE拉高一段时间 } 配置进入发射模式: void NRF_TX_Mode(void) { NRF_CE_LOW(); SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址; SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK; SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答; SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址; SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次; SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道为CHANAL; SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,0db增益,1Mbps,低噪声增益开启; SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断; /*CE拉高,进入发送模式*/ NRF_CE_HIGH(); delay_ms(100); //CE要拉高一段时间才进入发送模式 } NRF24L01的开机自检: u8 NRF_Check(void) { u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2}; u8 buf1[5]; u8 i; SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5); /*写入5个字节的地址. */ SPI_NRF_ReadBuf(TX_ADDR,buf1,5); /*读出写入的地址 */ for(i=0;i<5;i++) /*比较*/ { if(buf1!=0xC2) break; } if(i==5) return SUCCESS ; //MCU与NRF成功连接 else return ERROR ; //MCU与NRF不正常连接 } 数据发送: u8 NRF_Tx_Dat(u8 *txb) { u8 state; NRF_CE_LOW(); /*ce为低,进入待机模式1*/ SPI_NRF_WriteBuf(WR_TX_PLOAD,txb,TX_PLOAD_WIDTH); /*写数据到TX BUF 最大 32个字节*/ NRF_CE_HIGH(); /*CE为高,txb非空,发送数据包 */ while(NRF_Read_IRQ()!=0); /*等待发送完成中断 */ state = SPI_NRF_ReadReg(STATUS); /*读取状态寄存器的值 */ SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); /*清除TX_DS或MAX_RT中断标志*/ SPI_NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器 /*判断中断类型*/ if(state&MAX_RT) //达到最大重发次数 return MAX_RT; else if(state&TX_DS) //发送完成 return TX_DS; else return ERROR; //其他原因发送失败 } 数据接收,可放在主函数里循环检测,也可更换为中断模式检测: u8 NRF_Rx_Dat(u8 *rxb) { u8 state; NRF_CE_HIGH(); //进入接收状态 /*等待接收中断*/ //while(NRF_Read_IRQ()!=0);/// NRF_CE_LOW(); //进入待机状态 state = SPI_NRF_ReadReg(STATUS); /*读取status寄存器的值*/ if(state&RX_DR) /*判断是否接收到数据*/ //接收到数据 { SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);/* 清除中断标志*/ SPI_NRF_ReadBuf(RD_RX_PLOAD,rxb,RX_PLOAD_WIDTH);//读取数据 // SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 return RX_DR; }else return ERROR; //没收到任何数据 } 主循环任务程序如下: void nrf_task(void *pdata) { while(NRF_Check()!=SUCCESS){ delay_ms(100); } NRF_TX_Mode();//主动请求连接 nrf_Txbuf[0]='H'; nrf_Txbuf[1]='E'; nrf_Txbuf[2]='L'; nrf_Txbuf[3]='L'; nrf_Txbuf[4]='0'; do { status = NRF_Tx_Dat(nrf_Txbuf); }while((status != TX_DS)&(status != MAX_RT));//发送成功或者到达最大重发次数 if(status == MAX_RT) { USART1_printf( USART1,"Connection Failedrn"); } memset(nrf_Txbuf,0,sizeof(nrf_Txbuf)); NRF_RX_Mode();//配置为接收模式 while(1) { /*等待接收数据*/ status = NRF_Rx_Dat(nrf_Rxbuf); /*判断接收状态*/ if(status == RX_DR)//接收到数据中断标志 { U***_SendData((char*)nrf_Rxbuf,strlen((char*)nrf_Rxbuf));//通过USB转发 } if(0 != strlen((char*)nrf_Txbuf))//发送缓冲不为空 { NRF_TX_Mode();//主动请求连接 do { status = NRF_Tx_Dat(nrf_Txbuf); delay_ms(10); }while((status != TX_DS)&(status != MAX_RT));//发送成功或者到达最大重发次数 memset(nrf_Txbuf,0,sizeof(nrf_Txbuf)); NRF_RX_Mode();//配置为接收模式 } delay_ms(100); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1784 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1088 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
729 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
734浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
559浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 19:57 , Processed in 0.805096 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号