完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
硬件平台:STM32F103+NRF24L01
nrf24l01.h #ifndef __NRF24L01_H #define __NRF24L01_H extern Uchar nrfFlag; ////////////////////////////////////////////////////////////////////////////////////////////////////////// //*********************************************NRF24L01************************************* extern Uchar nrfWorkState; extern Uchar g_rf_status; extern Uchar g_rf_rx_buf[0x30]; //#define RX_DR g_rf_status^6 //#define TX_DS g_rf_status^5 //#define MAX_RT g_rf_status^4 #define RX_DR (g_rf_status&0x40) #define TX_DS (g_rf_status&0x20) #define MAX_RT (g_rf_status&0x10) //24L01发送接收数据宽度定义 #define TX_ADR_WIDTH 5 //5字节的地址宽度 #define RX_ADR_WIDTH 5 //5字节的地址宽度 #define TX_PLOAD_WIDTH 6 //32字节的用户数据宽度 #define RX_PLOAD_WIDTH 6 //32字节的用户数据宽度 //Uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址 //Uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 //***************************************NRF24L01寄存器指令******************************************************* #define READ_REG_NRF 0x00 //读配置寄存器,低5位为寄存器地址 #define WRITE_REG_NRF 0x20 //写配置寄存器,低5位为寄存器地址 #define RD_RX_PLOAD 0x61 // 读取接收数据指令 #define WR_TX_PLOAD 0xA0 // 写待发数据指令 #define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 #define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 #define NOP 0xFF // 保留 //*************************************SPI(nRF24L01)寄存器地址**************************************************** #define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 #define EN_AA 0x01 // 自动应答功能设置 #define EN_RXADDR 0x02 // 可用信道设置 #define SETUP_AW 0x03 // 收发地址宽度设置 #define SETUP_RETR 0x04 // 自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 // 发射速率、功耗功能设置 #define STATUS 0x07 // 状态寄存器 #define MAX_TX 0x10 //达到最大发送次数中断 #define TX_OK 0x20 //TX发送完成中断 #define RX_OK 0x40 //接收到数据中断 #define OBSERVE_TX 0x08 // 发送监测功能 #define CD 0x09 // 地址检测 #define RX_ADDR_P0 0x0A // 频道0接收数据地址 #define RX_ADDR_P1 0x0B // 频道1接收数据地址 #define RX_ADDR_P2 0x0C // 频道2接收数据地址 #define RX_ADDR_P3 0x0D // 频道3接收数据地址 #define RX_ADDR_P4 0x0E // 频道4接收数据地址 #define RX_ADDR_P5 0x0F // 频道5接收数据地址 #define TX_ADDR 0x10 // 发送地址寄存器 #define RX_PW_P0 0x11 // 接收频道0接收数据长度 #define RX_PW_P1 0x12 // 接收频道0接收数据长度 #define RX_PW_P2 0x13 // 接收频道0接收数据长度 #define RX_PW_P3 0x14 // 接收频道0接收数据长度 #define RX_PW_P4 0x15 // 接收频道0接收数据长度 #define RX_PW_P5 0x16 // 接收频道0接收数据长度 #define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 //************************************************************************************** ////////////////////////////////////////////////////////////////////////////////////////////////////////// extern void NRF_IRQ_Init(void); extern void NRF24L01_Init(void);//初始化 extern void NRF24L01_RX_Mode(void);//配置为接收模式 extern void NRF24L01_TX_Mode(void);//配置为发送模式 extern Uchar NRF24L01_Write_Buf(Uchar reg, Uchar *pBuf, Uchar Uchars);//写数据区 extern Uchar NRF24L01_Read_Buf(Uchar reg, Uchar *pBuf, Uchar Uchars);//读数据区 extern Uchar NRF24L01_Read_Reg(Uchar reg); //读寄存器 extern Uchar NRF24L01_Write_Reg(Uchar reg, Uchar value);//写寄存器 extern Uchar NRF24L01_Check(void);//检查24L01是否存在 extern Uchar NRF24L01_TxPacket(Uchar *txbuf);//发送一个包的数据 extern Uchar NRF24L01_RxPacket(Uchar *rxbuf);//接收一个包的数据 extern void NRF24L01_CheckRecvData(void); #endif nrf24l01.c Uchar nrfFlag; Uchar nrfWorkState; Uchar g_rf_status; // RF状态寄存器的值 Uchar g_rf_rx_buf[0x30]; Uchar TX_ADDRESS[TX_ADR_WIDTH]={0x01,0x02,0x03,0x04,0xA5}; // 定义RF接收应用地址 Uchar RX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0xA6}; // 定义RF发送工厂地址 Uchar RX_ADDRESS_APP[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0xA6}; // 定义RF接收工厂地址 //SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 extern Uchar NRF24L01_Write_Reg(Uchar reg,Uchar value) { Uchar status; SPISemGet(); //NRF24L01_CSN=0; //使能SPI传输 NRF24L01_CSN_Low(); status =SPI_FLASH_SendByte(reg);//发送寄存器号 SPI_FLASH_SendByte(value); //写入寄存器的值 //NRF24L01_CSN=1; //禁止SPI传输 NRF24L01_CSN_High(); SPISemPut(); return(status); //返回状态值 } //读取SPI寄存器值 //reg:要读的寄存器 extern Uchar NRF24L01_Read_Reg(Uchar reg) { Uchar reg_val; SPISemGet(); NRF24L01_CSN_Low(); //使能SPI传输 SPI_FLASH_SendByte(reg); //发送寄存器号 reg_val=SPI_FLASH_SendByte(0XFF);//读取寄存器内容 NRF24L01_CSN_High(); //禁止SPI传输 SPISemPut(); return(reg_val); //返回状态值 } //在指定位置读出指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 extern Uchar NRF24L01_Read_Buf(Uchar reg,Uchar *pBuf,Uchar len) { Uchar status,Uchar_ctr; NRF24L01_CSN_Low(); //使能SPI传输 status=SPI_FLASH_SendByte(reg);//发送寄存器值(位置),并读取状态值 for(Uchar_ctr=0;Uchar_ctr NRF24L01_CSN_High(); return status; //返回读到的状态值 } //在指定位置写指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 extern Uchar NRF24L01_Write_Buf(Uchar reg, Uchar *pBuf, Uchar len) { Uchar status,Uchar_ctr; NRF24L01_CSN_Low(); //使能SPI传输 status = SPI_FLASH_SendByte(reg);//发送寄存器值(位置),并读取状态值 for(Uchar_ctr=0; Uchar_ctr NRF24L01_CSN_High(); //关闭SPI传输 return status; //返回读到的状态值 } //检测24L01是否存在 //返回值:0,成功;1,失败 extern Uchar NRF24L01_Check(void) { Uchar buf[TX_ADR_WIDTH]; //NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写入5个字节的地址. #ifdef NRF_MODE_SEND NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 #else NRF24L01_Read_Buf(RX_ADDR_P0,buf,5); //读出写入的地址 #endif // DEBUGBUFFER("NRF24L01_Check", buf, 5); #ifdef NRF_MODE_SEND if (Buffercmp(TX_ADDRESS, buf, RX_ADR_WIDTH) == PASSED) #else if (Buffercmp(RX_ADDRESS, buf, RX_ADR_WIDTH) == PASSED) #endif { nrfWorkState = 1; return 1;//检测24L01错误 } nrfWorkState = 0; return 0; //检测到24L01 } //启动NRF24L01发送一次数据 //txbuf:待发送数据首地址 //返回值:发送完成状况 extern Uchar NRF24L01_TxPacket(Uchar *txbuf) { NRF24L01_Write_Reg(FLUSH_TX,0); // 清除TX的FIFO NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节 return 0;//其他原因发送失败 } //启动NRF24L01发送一次数据 //txbuf:待发送数据首地址 //返回值:0,接收完成;其他,错误代码 extern Uchar NRF24L01_RxPacket(Uchar *rxbuf) { Uchar state = 0; state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,state); //清除TX_DS或MAX_RT中断标志 if(state&RX_OK)//接收到数据 { NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//没收到任何数据 } //该函数初始化NRF24L01到RX模式 //设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR //当CE变高后,即进入RX模式,并可以接收数据了 extern void NRF24L01_RX_Mode(void) { NRF24L01_CE_Low(); NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x0f); // 上电, CRC为2 bytes,接收模式,允许RX_DR产生中断 NRF24L01_CE_High(); } //该函数初始化NRF24L01到TX模式 //设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR //PWR_UP,CRC使能 //当CE变高后,即进入RX模式,并可以接收数据了 //CE为高大于10us,则启动发送. extern void NRF24L01_TX_Mode(void) { NRF24L01_CE_Low(); //设置接收包数据长度 NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P0, TX_PLOAD_WIDTH); // PIPE0 接收数据包长度 NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 NRF24L01_CE_High(); } extern void NRF24L01_CheckRecvData(void) { Uchar buf[0x40]; if(NRF24L01_RxPacket(buf)==0)//一旦接收到信息,则显示出来. { DEBUGBUFFER("NRF24L01 RECV", buf, 32); } } |
|
|
|
//初始化24L01的IO口
extern void NRF24L01_Init(void) { #ifdef NRF_MODE_SEND GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = PIN_NRF24L01_IRQ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //IRQ 输入 GPIO_Init(PORT_NRF24L01_IRQ, &GPIO_InitStructure); #else NRF_IRQ_Init(); #endif //NRF24L01_CE=0; //使能24L01 // NRF24L01_CSN=1; //SPI片选取消 NRF24L01_CE_Low(); NRF24L01_CSN_High(); NRF24L01_Write_Buf(WRITE_REG_NRF + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 设置发射地址及长度 NRF24L01_Write_Buf(WRITE_REG_NRF + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 设置接收地址及长度 NRF24L01_Write_Buf(WRITE_REG_NRF + RX_ADDR_P1, RX_ADDRESS_APP, RX_ADR_WIDTH); // 设置接收地址及长度 //SPI_Write_Reg(WRITE_REG + EN_AA, 0x01); // 启动自动应答功能 NRF24L01_Write_Reg(WRITE_REG_NRF+ EN_AA, 0x00); // 关闭自动应答功能 //SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); // PIPE0接收数据 NRF24L01_Write_Reg(WRITE_REG_NRF + EN_RXADDR, 0x03); // PIPE0,PIPE1接收数据 //SPI_Write_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 自动重传10次 NRF24L01_Write_Reg(WRITE_REG_NRF + SETUP_RETR, 0x00); // 禁止重传 NRF24L01_Write_Reg(WRITE_REG_NRF + RF_CH, 40); // RF频率2440MHz //SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x0f); // 发射功率0dBm, 传输速率2Mbps, NRF24L01_Write_Reg(WRITE_REG_NRF + RF_SETUP, 0x27); // 发射功率0dBm, 传输速率250kbps, NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P0, TX_PLOAD_WIDTH); // PIPE0 接收数据包长度 NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P1, TX_PLOAD_WIDTH); // PIPE1 接收数据包长度 } extern void NRF_IRQ_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Connect EXTI Line to GPIO Pin */ GPIO_EXTILineConfig(PORT_SRC_NRF_IRQ, PIN_SRC_NRF_IRQ); /* Configure EXTI line */ EXTI_InitStructure.EXTI_Line = EXTI_LINE_NRF_IRQ; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Enable and set EXTI Interrupt to the highest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXIT_IRQN_NRF_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); EXTI_ClearITPendingBit(EXTI_LINE_NRF_IRQ); // EXTI_GenerateSWInterrupt(EXTI_LINE_PFO); // test } extern void EXTI1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_LINE_NRF_IRQ) != RESET) { EXTI_ClearITPendingBit(EXTI_LINE_NRF_IRQ); if (!nrfFlag) { nrfFlag = 1; } g_rf_status=NRF24L01_Read_Reg(STATUS); // 读出状态值 if(RX_DR){ NRF24L01_Read_Buf(RD_RX_PLOAD,g_rf_rx_buf,RX_PLOAD_WIDTH); // 读出FIFO的数据 NRF24L01_Write_Reg(FLUSH_RX,0); // 清除RX的FIFO } NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x70); // 清除所有中断标志 } } 1.做主机时初始化相关流程 NRF24L01_Init(); NRF24L01_TX_Mode(); 发送数据 u8 recvData[TX_PLOAD_WIDTH]={数据}; NRF24L01_TxPacket(recvData); 2.做从机时初始化相关流程 NRF24L01_Init(); NRF24L01_RX_Mode(); 每收到一次有效数据发生一次中断 g_rf_status=NRF24L01_Read_Reg(STATUS); // 读出状态值 if(RX_DR){ NRF24L01_Read_Buf(RD_RX_PLOAD,g_rf_rx_buf,RX_PLOAD_WIDTH); // 读出FIFO的数据 NRF24L01_Write_Reg(FLUSH_RX,0); // 清除RX的FIFO //DEBUGBUFFER("NRF", g_rf_rx_buf, TX_PLOAD_WIDTH); } NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x70); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1800 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1629 浏览 1 评论
1096 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
735 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1684 浏览 2 评论
1943浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
744浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
578浏览 3评论
601浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
563浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 22:28 , Processed in 0.906418 second(s), Total 80, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号