Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
NRF24L01
STM32
5
NRF24与裸机版本驱动通信
发布于 2021-01-18 21:17:58 浏览:917
订阅该版
现在有一个项目需求,使用NRF24L01进行一对多通信,多点发送端采用正点原子的NRF24L01驱动,节点一的代码如下``` #include "24l01.h" #include "spi.h" #include "board.h" const u8 TX_ADDRESS0[TX_ADR_WIDTH]={0xAB,0xB6,0xB5,0xB4,0xB3}; //发送地址 const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0xAB,0xB6,0xB5,0xB4,0xB3}; //接收地址 //初始化24L01的IO口 void NRF24L01_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC,GPIO_Pin_4); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); SPI1_Init(); //初始化SPI SPI_Cmd(SPI1, DISABLE); // SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //选择了串行时钟的稳态:时钟悬空低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第一个时钟沿 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 NRF24L01_CE=0; //使能24L01 NRF24L01_CSN=1; //SPI片选取消 } //检测24L01是否存在 //返回值:0,成功;1,失败 u8 NRF24L01_Check(void) { u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i; SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 for(i=0;i<5;i++)if(buf[i]!=0XA5)break; if(i!=5)return 1;//检测24L01错误 return 0; //检测到24L01 } //SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 u8 NRF24L01_Write_Reg(u8 reg,u8 value) { u8 status; NRF24L01_CSN=0; //使能SPI传输 status =SPI1_ReadWriteByte(reg);//发送寄存器号 SPI1_ReadWriteByte(value); //写入寄存器的值 NRF24L01_CSN=1; //禁止SPI传输 return(status); //返回状态值 } //读取SPI寄存器值 //reg:要读的寄存器 u8 NRF24L01_Read_Reg(u8 reg) { u8 reg_val; NRF24L01_CSN = 0; //使能SPI传输 SPI1_ReadWriteByte(reg); //发送寄存器号 reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容 NRF24L01_CSN = 1; //禁止SPI传输 return(reg_val); //返回状态值 } //在指定位置读出指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len) { u8 status,u8_ctr; NRF24L01_CSN = 0; //使能SPI传输 status=SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0;u8_ctr
#include "nrf24l01.h" /* Exported types --------------------------------------------------------------------------*/ /* Exported constants ----------------------------------------------------------------------*/ /* Exported macro --------------------------------------------------------------------------*/ ///<命令映射 #define NRF24CMD_R_REG 0x00 // 读寄存器 #define NRF24CMD_W_REG 0x20 // 写寄存器 #define NRF24CMD_R_RX_PAYLOAD 0x61 // 读接收缓冲区 #define NRF24CMD_W_TX_PAYLOAD 0xA0 // 写发送缓冲区 #define NRF24CMD_FLUSH_TX 0xE1 // 清空发送FIFO #define NRF24CMD_FLUSH_RX 0xE2 // 清空接收FIFO #define NRF24CMD_REUSE_TX_PL 0xE3 // PTX模式下使用,重装载发送缓冲区 #define NRF24CMD_ACTIVATE 0x50 // 使能命令,后接数据 0x73 #define NRF24CMD_R_RX_PL_WID 0x60 // 读顶层接收FIFO大小 #define NRF24CMD_W_ACK_PAYLOAD 0xA8 // RX模式下使用,写应答发送缓冲区 ///<寄存器映射 #define NRF24REG_CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 #define NRF24REG_EN_AA 0x01 // 自动应答功能设置 #define NRF24REG_EN_RXADDR 0x02 // 可用信道设置 #define NRF24REG_SETUP_AW 0x03 // 收发地址宽度设置 #define NRF24REG_SETUP_RETR 0x04 // 自动重发功能设置 #define NRF24REG_RF_CH 0x05 // 工作频率设置 #define NRF24REG_RF_SETUP 0x06 // 发射速率、功耗功能设置 #define NRF24REG_STATUS 0x07 // 状态寄存器 #define NRF24REG_OBSERVE_TX 0x08 // 发送监测功能 #define NRF24REG_RPD 0x09 // 接收功率检测 #define NRF24REG_RX_ADDR_P0 0x0A // 频道0接收数据地址 #define NRF24REG_RX_ADDR_P1 0x0B // 频道1接收数据地址 #define NRF24REG_RX_ADDR_P2 0x0C // 频道2接收数据地址 #define NRF24REG_RX_ADDR_P3 0x0D // 频道3接收数据地址 #define NRF24REG_RX_ADDR_P4 0x0E // 频道4接收数据地址 #define NRF24REG_RX_ADDR_P5 0x0F // 频道5接收数据地址 #define NRF24REG_TX_ADDR 0x10 // 发送地址寄存器 #define NRF24REG_RX_PW_P0 0x11 // 接收频道0接收数据长度 #define NRF24REG_RX_PW_P1 0x12 // 接收频道1接收数据长度 #define NRF24REG_RX_PW_P2 0x13 // 接收频道2接收数据长度 #define NRF24REG_RX_PW_P3 0x14 // 接收频道3接收数据长度 #define NRF24REG_RX_PW_P4 0x15 // 接收频道4接收数据长度 #define NRF24REG_RX_PW_P5 0x16 // 接收频道5接收数据长度 #define NRF24REG_FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 #define NRF24REG_DYNPD 0x1C // 动态数据包长度 #define NRF24REG_FEATURE 0x1D // 特点寄存器 ///<寄存器功能位掩码部分映射 //CONFIG #define NRF24BITMASK_RX_DR ((uint8_t)(1<<6)) // 接收完成中断使能位 #define NRF24BITMASK_TX_DS ((uint8_t)(1<<5)) // 发送完成中断使能位 #define NRF24BITMASK_MAX_RT ((uint8_t)(1<<4)) // 达最大重发次数中断使能位 #define NRF24BITMASK_EN_CRC ((uint8_t)(1<<3)) // CRC使能位 #define NRF24BITMASK_CRCO ((uint8_t)(1<<2)) // CRC编码方式 (1B or 2B) #define NRF24BITMASK_PWR_UP ((uint8_t)(1<<1)) // 上(掉)电 #define NRF24BITMASK_PRIM_RX ((uint8_t)(1)) // PR(T)X //SETUP_AW #define NRF24BITMASK_AW ((uint8_t)(0x03)) // RX/TX地址宽度 //SETUP_RETR #define NRF24BITMASK_ARD ((uint8_t)(0xF0)) // 重发延时 #define NRF24BITMASK_ARC ((uint8_t)(0x0F)) // 重发最大次数 //RF_CH #define NRF24BITMASK_RF_CH ((uint8_t)(0x7F)) // 射频频道 //RF_SETUP #define NRF24BITMASK_RF_DR ((uint8_t)(1<<3)) // 空中速率 #define NRF24BITMASK_RF_PWR ((uint8_t)(0x06)) // 发射功率 //STATUS #define NRF24BITMASK_RX_DR ((uint8_t)(1<<6)) // 接收完成标志位 #define NRF24BITMASK_TX_DS ((uint8_t)(1<<5)) // 发送完成标志位 #define NRF24BITMASK_MAX_RT ((uint8_t)(1<<4)) // 最大重发次数标志位 #define NRF24BITMASK_RX_P_NO ((uint8_t)(0x0E)) // RX_FIFO状态标志区位 #define NRF24BITMASK_TX_FULL ((uint8_t)(1)) // TX_FIFO满标志位 //OBSERVE_TX #define NRF24BITMASK_PLOS_CNT ((uint8_t)(0xF0)) // 丢包计数 #define NRF24BITMASK_ARC_CNT ((uint8_t)(0x0F)) // 重发计数 //CD #define NRF24BITMASK_CD ((uint8_t)(1)) // 载波检测标志位 //通用掩码,RX_PW_P[0::5] 掩码相同 #define NRF24BITMASK_RX_PW_P_ ((uint8_t)(0x3F)) // 数据管道RX-Payload中的字节数 //FIFO_STATUS #define NRF24BITMASK_TX_REUSE ((uint8_t)(1<<6)) // #define NRF24BITMASK_TX_FULL2 ((uint8_t)(1<<5)) // #define NRF24BITMASK_TX_EMPTY ((uint8_t)(1<<4)) // #define NRF24BITMASK_RX_RXFULL ((uint8_t)(1<<1)) // #define NRF24BITMASK_RX_EMPTY ((uint8_t)(1)) // //FEATURE #define NRF24BITMASK_EN_DPL ((uint8_t)(1<<2)) // 动态长度使能位 #define NRF24BITMASK_EN_ACK_PAY ((uint8_t)(1<<1)) // Payload with ACK 使能位 #define NRF24BITMASK_EN_DYN_ACK ((uint8_t)(1)) // W_TX_PAYLOAD_NOACK 命令使能位 //通用掩码,适用于多个寄存器: EN_AA, EN_RXADDR, DYNPD #define NRF24BITMASK_PIPE_0 ((uint8_t)(1)) // #define NRF24BITMASK_PIPE_1 ((uint8_t)(1<<1)) // #define NRF24BITMASK_PIPE_2 ((uint8_t)(1<<2)) // #define NRF24BITMASK_PIPE_3 ((uint8_t)(1<<3)) // #define NRF24BITMASK_PIPE_4 ((uint8_t)(1<<4)) // #define NRF24BITMASK_PIPE_5 ((uint8_t)(1<<5)) // /* Exported variables ----------------------------------------------------------------------*/ static uint16_t l_error_count = 0; extern hal_nrf24l01_port_t hal_nrf24l01_port; /* Exported functions ----------------------------------------------------------------------*/ static uint8_t _read_reg(uint8_t reg) { uint8_t temp, rtmp = 0; temp = NRF24CMD_R_REG | reg; hal_nrf24l01_port.send_then_recv(&temp, 1, &rtmp, 1); return rtmp; } static void _write_reg(uint8_t reg, uint8_t data) { uint8_t temp[2]; temp[0] = NRF24CMD_W_REG | reg; temp[1] = data; hal_nrf24l01_port.write(&temp[0], 2); } /** * @brief 置位寄存器的部分位 * @param[in] reg: 寄存器地址 * @param[in] mask: 位掩码. eg: 0x81 标识置位第七位和第零位 */ static void _set_reg_bits(uint8_t reg, uint8_t mask) { uint8_t temp; temp = _read_reg(reg); temp |= mask; _write_reg(reg, temp); } static void _reset_reg_bits(uint8_t reg, uint8_t mask) { uint8_t temp; temp = _read_reg(reg); temp &= ~mask; _write_reg(reg, temp); } static void _write_reg_bits(uint8_t reg, uint8_t mask, uint8_t value) { uint8_t temp, tidx; for (tidx = 0; tidx < 8; tidx++) { if (mask & (1 << tidx)) break; } temp = ~mask & _read_reg(reg); temp |= mask & (value << tidx); _write_reg(reg, temp); } static void send_activate_command(void) { uint8_t temp[2] = { NRF24CMD_ACTIVATE, 0x73}; hal_nrf24l01_port.write(temp, 2); } static void set_address_width5(void) { _write_reg(NRF24REG_SETUP_AW, 0x03); } static void set_tx_rp0_address5(void) { uint8_t temp; uint8_t rp0_addr[5] = {0xAB,0xB6,0xB5,0xB4,0xB3}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P0; hal_nrf24l01_port.send_then_send(&temp, 1, rp0_addr, 5); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P0,32); } static void set_tx_rp1_address5(void) { uint8_t temp; uint8_t rp1_addr[5] = {0xF1,0xB6,0xB5,0xB4,0xB3}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P1; hal_nrf24l01_port.send_then_send(&temp, 1, rp1_addr, 5); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P1,32); } static void set_tx_rp2_address5(void) { uint8_t temp; uint8_t rp2_addr[1] = {0xA3}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P2; hal_nrf24l01_port.send_then_send(&temp, 1, rp2_addr, 1); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P2,32); } static void set_tx_rp3_address5(void) { uint8_t temp; uint8_t rp3_addr[1] = {0xA3}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P3; hal_nrf24l01_port.send_then_send(&temp, 1, rp3_addr, 1); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P3,32); } static void set_tx_rp4_address5(void) { uint8_t temp; uint8_t rp4_addr[1] = {0x0F}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P4; hal_nrf24l01_port.send_then_send(&temp, 1, rp4_addr, 1); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P4,32); } static void set_tx_rp5_address5(void) { uint8_t temp; uint8_t rp5_addr[1] = {0x05}; temp = NRF24CMD_W_REG | NRF24REG_RX_ADDR_P5; hal_nrf24l01_port.send_then_send(&temp, 1, rp5_addr, 1); _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P5,32); } void nrf24l01_multichannel(void) { set_tx_rp1_address5(); set_tx_rp2_address5(); set_tx_rp3_address5(); set_tx_rp4_address5(); set_tx_rp5_address5(); _set_reg_bits(NRF24REG_EN_AA, 0x3f); _set_reg_bits(NRF24REG_EN_RXADDR, 0x3f); _set_reg_bits(NRF24CMD_W_REG+NRF24REG_RF_CH,40); //设置RF频率,发射频率=2.4G+40=2.44G _set_reg_bits(NRF24CMD_W_REG+NRF24REG_RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 _set_reg_bits(NRF24CMD_W_REG+NRF24REG_CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 } ////该函数初始化NRF24L01到RX模式 ////设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR ////当CE变高后,即进入RX模式,并可以接收数据了 //void NRF24L01_RX_Mode(void) //{ // hal_nrf24l01_port.reset_ce(); // // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P0,5);//选择通道0的有效数据宽度 // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P1,5); // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P2,5); // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P3,5); // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P4,5); // _write_reg(NRF24CMD_W_REG+NRF24REG_RX_ADDR_P5,5); // _write_reg(NRF24CMD_R_REG + NRF24REG_EN_AA,0x3f); //使能通道0的自动应答 // _write_reg(NRF24CMD_R_REG + NRF24REG_EN_RXADDR,0x3f); //使能通道0的接收地址 // _write_reg(NRF24CMD_R_REG + NRF24REG_RF_CH,40); //设置RF频率,发射频率=2.4G+40=2.44G // _write_reg(NRF24CMD_R_REG + NRF24REG_RX_PW_P0,5); //选择通道0的有效数据宽度 // _write_reg(NRF24CMD_R_REG + NRF24REG_RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 // _write_reg(NRF24CMD_R_REG + NRF24REG_CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 // hal_nrf24l01_port.set_ce(); //CE为高,进入接收模式 //} static void set_rf_channel(uint8_t channel) { _write_reg(NRF24REG_RF_CH, channel & 0x7F); } static void set_air_data_rate(nrf24_adr_et adr) { if (adr == ADR_1Mbps) { _reset_reg_bits(NRF24REG_RF_SETUP, NRF24BITMASK_RF_DR); } else if (adr == ADR_2Mbps) { _set_reg_bits(NRF24REG_RF_SETUP, NRF24BITMASK_RF_DR); } } static void set_rf_power(nrf24_power_et pa) { if ((pa == RF_POWER_0dBm) || (pa == RF_POWER_N6dBm) || (pa == RF_POWER_N12dBm) || (pa == RF_POWER_N18dBm)) { _write_reg_bits(NRF24REG_RF_SETUP, NRF24BITMASK_RF_PWR, pa); } } static void _set_auto_retransmit_delay(uint8_t ard) { _write_reg_bits(NRF24REG_SETUP_RETR, NRF24BITMASK_ARD, ard); } static void _set_auto_retransmit_count(uint8_t arc) { _write_reg_bits(NRF24REG_SETUP_RETR, NRF24BITMASK_ARC, arc); } static void set_crc(nrf24_crc_et crc) { if (crc == CRC_0_BYTE) { _reset_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_EN_CRC); } else { if (crc == CRC_1_BYTE) { _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_EN_CRC); _reset_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_CRCO); } else if (crc == CRC_2_BYTE) { _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_EN_CRC); _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_CRCO); } } } static void set_esb_param(nrf24_esb_t *pt) { // avoid ARD equals 250us if (pt->ard == 0) pt->ard += 1; _set_auto_retransmit_delay(pt->ard); _set_auto_retransmit_count(pt->arc); } // bit: RX_DR, TX_DS, MAX_RT static void reset_status(uint8_t bitmask) { bitmask |= _read_reg(NRF24REG_STATUS); _write_reg(NRF24REG_STATUS, bitmask); } static void reset_observe_tx(void) { _write_reg(NRF24REG_OBSERVE_TX, 0); } //[note] the NRF24CMD_R_RX_PL_WID command doesn't work?! static uint8_t get_top_rxfifo_width(void) { uint8_t temp = NRF24CMD_R_RX_PL_WID; hal_nrf24l01_port.send_then_recv(&temp, 1, &temp, 1); return temp; } // [note] enable activate-command befor enable_dpl // pipe range: 0 ~ 5 // will also enable ENAA_PX to static void enable_dpl_and_ackpayload(uint8_t pipe) { if (pipe > 5) return; _set_reg_bits(NRF24REG_FEATURE, NRF24BITMASK_EN_ACK_PAY); _set_reg_bits(NRF24REG_FEATURE, NRF24BITMASK_EN_DPL); _set_reg_bits(NRF24REG_DYNPD, 0x3f); } static void enabled_irq(uint8_t bitmask) { if (!((bitmask == NRF24BITMASK_RX_DR) || (bitmask == NRF24BITMASK_TX_DS) || (bitmask == NRF24BITMASK_MAX_RT))) return; _reset_reg_bits(NRF24REG_CONFIG, bitmask); } static void disable_irq(uint8_t bitmask) { if (!((bitmask == NRF24BITMASK_RX_DR) || (bitmask == NRF24BITMASK_TX_DS) || (bitmask == NRF24BITMASK_MAX_RT))) return; _set_reg_bits(NRF24REG_CONFIG, bitmask); } static void write_tx_payload(const uint8_t *pb, uint8_t len) { uint8_t temp = NRF24CMD_W_TX_PAYLOAD; hal_nrf24l01_port.send_then_send(&temp, 1, pb, len); } static void write_ack_payload(uint8_t pipe, const uint8_t *pb, uint8_t len) { uint8_t temp; if (pipe > 5) return; temp = NRF24CMD_W_ACK_PAYLOAD | pipe; hal_nrf24l01_port.send_then_send(&temp, 1, pb, len); } /* 读取接收缓冲区数据 */ static void read_rxpayload(uint8_t *pb, uint8_t len) { uint8_t tcmd; if ((len > 32) || (len == 0)) return; tcmd = NRF24CMD_R_RX_PAYLOAD; hal_nrf24l01_port.send_then_recv(&tcmd, 1, pb, len); } static void flush_tx_fifo(void) { uint8_t temp = NRF24CMD_FLUSH_TX; hal_nrf24l01_port.write(&temp, 1); } static void flush_rx_fifo(void) { uint8_t temp = NRF24CMD_FLUSH_RX; hal_nrf24l01_port.write(&temp, 1); } // note: will clear the error-counter uint16_t nrf24_get_errcnt(void) { uint16_t temp = l_error_count; l_error_count = 0; return temp; } void nrf24_power_up(void) { _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PWR_UP); } void nrf24_power_down(void) { _reset_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PWR_UP); } /** * @brief PTX(ROLE) run * @param[in] pb_tx: pointer of tx-buffer * @param[out] pb_rx: pointer of rx-buffer * @param tlen: size of pb_tx (by bytes) * @return Zero indicates sent complete but no data received; * Negative number indicates error; * Other indicates the number of bytes of received data, and indicates that sent is complete * * @attention Send data and then received data */ int nrf24_ptx_run(uint8_t *pb_rx, const uint8_t *pb_tx, uint8_t tlen) { uint8_t sta, trycnt = 0, rlen = 0; if (tlen > 32) return -6; write_tx_payload(pb_tx, tlen); hal_nrf24l01_port.set_ce(); do { sta = _read_reg(NRF24REG_STATUS); if (sta & NRF24BITMASK_MAX_RT) { // send failed; try again reset_status(NRF24BITMASK_MAX_RT); if (++trycnt > 6) { hal_nrf24l01_port.reset_ce(); flush_tx_fifo(); reset_status(NRF24BITMASK_MAX_RT); l_error_count++; return -1; } } } while (!(sta & NRF24BITMASK_TX_DS)); reset_status(NRF24BITMASK_TX_DS); if (sta & NRF24BITMASK_RX_DR) { reset_status(NRF24BITMASK_RX_DR); rlen = get_top_rxfifo_width(); read_rxpayload(pb_rx, rlen); } hal_nrf24l01_port.reset_ce(); return rlen; } /** * @brief PRX(ROLE) cycle * @param[out] pb_rx: pointer of rx-buffer * @param[in] pb_tx: pointer of tx-buffer * @param tlen: size of pb_tx (by bytes) * @return Zero indicates no data received; * Negative number indicates error; * Other indicates the number of bytes of received data, and indicates that sent is complete * * @attention Receive data and then send data */ int nrf24_prx_cycle(uint8_t *pb_rx, const uint8_t *pb_tx, uint8_t tlen) { uint8_t sta, rlen = 0; sta = _read_reg(NRF24REG_FIFO_STATUS); if (!(sta & NRF24BITMASK_RX_EMPTY)) { rlen = get_top_rxfifo_width(); read_rxpayload(pb_rx, rlen); // flush_rx_fifo(); if ((tlen > 0) && (tlen <= 32)) { write_ack_payload(0, pb_tx, tlen); } } return rlen; } void nrf24_prx_write_txbuffer(const uint8_t *pb, uint8_t len) { if (len > 32) return; write_ack_payload(0, pb, len); } /** * Please refer to nrf24_ptx_run */ int nrf24_irq_ptx_run(uint8_t *pb_rx, const uint8_t *pb_tx, uint8_t tlen, void (*waitirq)(void)) { int rlen = 0; uint8_t sta; if (tlen > 32) return -6; write_tx_payload(pb_tx, tlen); hal_nrf24l01_port.set_ce(); (*waitirq)(); sta = _read_reg(NRF24REG_STATUS); if (sta & NRF24BITMASK_TX_DS) { reset_status(NRF24BITMASK_TX_DS); if (sta & NRF24BITMASK_RX_DR) { reset_status(NRF24BITMASK_RX_DR); rlen = get_top_rxfifo_width(); read_rxpayload(pb_rx, rlen); } } else if (sta & NRF24BITMASK_MAX_RT) { hal_nrf24l01_port.reset_ce(); flush_tx_fifo(); reset_status(NRF24BITMASK_MAX_RT); l_error_count++; rlen = -1; } else { // shouldn't run to here rlen = -2; } hal_nrf24l01_port.reset_ce(); return rlen; } /** * Please refer to nrf24_prx_cycle */ int nrf24_irq_prx_run(uint8_t *pb_rx, const uint8_t *pb_tx, uint8_t tlen, void (*waitirq)(void)) { int rlen = 0; (*waitirq)(); reset_status(NRF24BITMASK_RX_DR | NRF24BITMASK_TX_DS); rlen = nrf24_prx_cycle(pb_rx, pb_tx, tlen); return rlen; } void nrf24_default_param(nrf24_cfg_t *pt) { pt->power = RF_POWER_0dBm; pt->esb.ard = 1; // 自动重发延时(1+1)*250 = 500us pt->esb.arc = 10; // 自动重发计数up to 10 times pt->crc = CRC_2_BYTE; // crc; fcs is two bytes pt->adr = ADR_2Mbps; // air data rate 1Mbps pt->channel = 40; // rf channel 6 pt->address[4] = 0x12; // address is 0x123456789A pt->address[3] = 0x34; pt->address[2] = 0x56; pt->address[1] = 0x78; pt->address[0] = 0x9A; } /** * @return success returns 0; failure returns negative number */ int nrf24_init(nrf24_cfg_t *pt) { if ((pt->role != ROLE_PTX) && (pt->role != ROLE_PRX)) { rt_kprintf("[nrf24-warning]: unknown ROLE\r\n"); _reset_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PWR_UP); return -1; } hal_nrf24l01_port.init(pt->ud); send_activate_command(); // it doesn't work? enable_dpl_and_ackpayload(5); set_address_width5(); set_tx_rp0_address5(); nrf24l01_multichannel(); set_rf_power(pt->power); set_rf_channel(pt->channel); set_air_data_rate(pt->adr); set_crc(pt->crc); set_esb_param(&pt->esb); if (pt->use_irq) { //enable all irq enabled_irq(NRF24BITMASK_RX_DR | NRF24BITMASK_TX_DS | NRF24BITMASK_MAX_RT); } else { //disable all irq disable_irq(NRF24BITMASK_RX_DR | NRF24BITMASK_TX_DS | NRF24BITMASK_MAX_RT); } flush_rx_fifo(); flush_tx_fifo(); reset_status(NRF24BITMASK_RX_DR | NRF24BITMASK_TX_DS | NRF24BITMASK_MAX_RT); reset_observe_tx(); if (pt->role == ROLE_PTX) { _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PWR_UP); _reset_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PRIM_RX); } else if (pt->role == ROLE_PRX) { _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PWR_UP); _set_reg_bits(NRF24REG_CONFIG, NRF24BITMASK_PRIM_RX); hal_nrf24l01_port.set_ce(); } else { // never run to here ; } return 0; } uint8_t rx_pipe_num_choose(void) { uint8_t rlen; uint16_t pipe_state; pipe_state = _read_reg(NRF24REG_STATUS); // rt_kprintf("%d\r\n", pipe_state); _write_reg(NRF24REG_STATUS, pipe_state); /* 清除TX_DS或MAX_RT中断标志 */ if (pipe_state & 0x40)//接收到数据 { hal_nrf24l01_port.reset_ce(); switch (pipe_state & 0x0E) { case 0x00: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P0, rlen); break; case 0x02: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P1, rlen); break; case 0x04: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P2, rlen); break; case 0x06: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P3, rlen); break; case 0x08: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P4, rlen); break; case 0x0A: rlen = get_top_rxfifo_width(); read_rxpayload(RxBuf_P5, rlen); break; } flush_rx_fifo(); hal_nrf24l01_port.set_ce(); return 0; } return 1;//没收到任何数据 } #if defined(NRF24_USING_INFO_REPORT) void _nrf24_report_config_reg(uint8_t data) { if (data & NRF24BITMASK_PRIM_RX) rt_kprintf("PRX mode\r\n"); else rt_kprintf("PTX mode\r\n"); if (data & NRF24BITMASK_EN_CRC) { rt_kprintf("crc opened. FCS: "); if (data & NRF24BITMASK_CRCO) rt_kprintf("2bytes\r\n"); else rt_kprintf("1byte\r\n"); } else rt_kprintf("crc closed\r\n"); if (!(data & (NRF24BITMASK_RX_DR | NRF24BITMASK_TX_DS | NRF24BITMASK_MAX_RT))) { if (!(data & NRF24BITMASK_RX_DR)) rt_kprintf("RX irq; "); if (!(data & NRF24BITMASK_TX_DS)) rt_kprintf("TX irq; "); if (!(data & NRF24BITMASK_MAX_RT)) rt_kprintf("MAX_RT irq; "); rt_kprintf("opened\r\n"); } else { rt_kprintf("all irq closed\r\n"); } if (data & NRF24BITMASK_PWR_UP) rt_kprintf("power up now\r\n"); else rt_kprintf("power down now\r\n"); } void _nrf24_report_enaa_reg(uint8_t data) { if (!(data & 0x3F)) { rt_kprintf("all pipe AA closed"); return; } if (data & NRF24BITMASK_PIPE_0) rt_kprintf("pipe0 "); if (data & NRF24BITMASK_PIPE_1) rt_kprintf("pipe1 "); if (data & NRF24BITMASK_PIPE_2) rt_kprintf("pipe2 "); if (data & NRF24BITMASK_PIPE_3) rt_kprintf("pipe3 "); if (data & NRF24BITMASK_PIPE_4) rt_kprintf("pipe4 "); if (data & NRF24BITMASK_PIPE_5) rt_kprintf("pipe5 "); rt_kprintf("AA opened\r\n"); } void _nrf24_report_enrxaddr_reg(uint8_t data) { if (!(data & 0x3F)) { rt_kprintf("all rx-pipe closed"); return; } if (data & NRF24BITMASK_PIPE_0) rt_kprintf("rx-pipe0 "); if (data & NRF24BITMASK_PIPE_1) rt_kprintf("rx-pipe1 "); if (data & NRF24BITMASK_PIPE_2) rt_kprintf("rx-pipe2 "); if (data & NRF24BITMASK_PIPE_3) rt_kprintf("rx-pipe3 "); if (data & NRF24BITMASK_PIPE_4) rt_kprintf("rx-pipe4 "); if (data & NRF24BITMASK_PIPE_5) rt_kprintf("rx-pipe5 "); rt_kprintf(" opened\r\n"); } void _nrf24_report_setupaw_reg(uint8_t data) { rt_kprintf("rx/tx address field width: "); switch (data & 0x3) { case 0: rt_kprintf("illegal\r\n"); break; case 1: rt_kprintf("3bytes\r\n"); break; case 2: rt_kprintf("4bytes\r\n"); break; case 3: rt_kprintf("5bytes\r\n"); break; } } void _nrf24_report_setupretr_reg(uint8_t data) { rt_kprintf("auto retransmit delay: %dus\r\n", (((data & 0xF0) >> 4) + 1) * 250); rt_kprintf("auto retransmit count: up to %d\r\n", (data & 0x0F)); } void _nrf24_report_rfch_reg(uint8_t data) { rt_kprintf("rf channel: %d\r\n", data & 0x7F); } void _nrf24_report_rfsetup_reg(uint8_t data) { rt_kprintf("air data rate: "); if (data & NRF24BITMASK_RF_DR) rt_kprintf("2Mbps\r\n"); else rt_kprintf("1Mbsp\r\n"); rt_kprintf("rf power: "); switch ((data & NRF24BITMASK_RF_PWR) >> 1) { case 0: rt_kprintf("-18dBm\r\n"); break; case 1: rt_kprintf("-12dBm\r\n"); break; case 2: rt_kprintf("-6dBm\r\n"); break; case 3: rt_kprintf("0dBm\r\n"); break; } } void _nrf24_report_status_reg(uint8_t data) { rt_kprintf("status: "); if (data & NRF24BITMASK_RX_DR) rt_kprintf("new rx data; "); if (data & NRF24BITMASK_TX_DS) rt_kprintf("last tx ok; "); if (data & NRF24BITMASK_MAX_RT) rt_kprintf("max-rt error exist; "); if (data & NRF24BITMASK_TX_FULL) rt_kprintf("tx-fifo is full; "); else rt_kprintf("tx-fifo is not full; "); data = (data & NRF24BITMASK_RX_P_NO) >> 1; if (data > 5) { if (data == 7) rt_kprintf("rx-fifo empty; "); else rt_kprintf("rx-fifo not used?; "); } else { rt_kprintf("rx-fifo pipe: %d; ", data); } rt_kprintf("\r\n"); } void _nrf24_report_observetx_reg(uint8_t data) { rt_kprintf("lost packets count: %d\r\n", (data & NRF24BITMASK_PLOS_CNT) >> 4); rt_kprintf("retransmitted packets count: %d\r\n", data & NRF24BITMASK_ARC_CNT); } void _nrf24_report_fifostatus_reg(uint8_t data) { if (data & NRF24BITMASK_TX_REUSE) rt_kprintf("tx-reuse opened\r\n"); if (data & NRF24BITMASK_TX_FULL2) rt_kprintf("tx-fifo full\r\n"); else if (data & NRF24BITMASK_TX_EMPTY) rt_kprintf("tx-fifo empty\r\n"); else rt_kprintf("tx-fifo has some data\r\n"); if (data & NRF24BITMASK_RX_RXFULL) rt_kprintf("rx-fifo full\r\n"); else if (data & NRF24BITMASK_RX_EMPTY) rt_kprintf("rx-fifo empty\r\n"); else rt_kprintf("rx-fifo has some data\r\n"); } void _nrf24_report_dynpd_reg(uint8_t data) { rt_kprintf("dynamic payload length enabled (pipe): "); if (!(data & 0x3F)) { rt_kprintf("none\r\n"); return; } if (data & NRF24BITMASK_PIPE_0) rt_kprintf("pipe0; "); if (data & NRF24BITMASK_PIPE_1) rt_kprintf("pipe1; "); if (data & NRF24BITMASK_PIPE_2) rt_kprintf("pipe2; "); if (data & NRF24BITMASK_PIPE_3) rt_kprintf("pipe3; "); if (data & NRF24BITMASK_PIPE_4) rt_kprintf("pipe4; "); if (data & NRF24BITMASK_PIPE_5) rt_kprintf("pipe5; "); rt_kprintf("\r\n"); } void _nrf24_report_feature_reg(uint8_t data) { rt_kprintf("feature enabled conditions: "); if (data & NRF24BITMASK_EN_DPL) rt_kprintf("dynamic payload length; "); if (data & NRF24BITMASK_EN_ACK_PAY) rt_kprintf("payload with ack; "); if (data & NRF24BITMASK_EN_DYN_ACK) rt_kprintf("W_TX_PAYLOAD_NOACK command; "); rt_kprintf("\r\n"); } void nrf24_report(void) { _nrf24_report_config_reg(_read_reg(NRF24REG_CONFIG)); _nrf24_report_enaa_reg(_read_reg(NRF24REG_EN_AA)); _nrf24_report_enrxaddr_reg(_read_reg(NRF24REG_EN_RXADDR)); _nrf24_report_setupaw_reg(_read_reg(NRF24REG_SETUP_AW)); _nrf24_report_setupretr_reg(_read_reg(NRF24REG_SETUP_RETR)); _nrf24_report_rfch_reg(_read_reg(NRF24REG_RF_CH)); _nrf24_report_rfsetup_reg(_read_reg(NRF24REG_RF_SETUP)); _nrf24_report_status_reg(_read_reg(NRF24REG_STATUS)); _nrf24_report_observetx_reg(_read_reg(NRF24REG_OBSERVE_TX)); _nrf24_report_fifostatus_reg(_read_reg(NRF24REG_FIFO_STATUS)); _nrf24_report_dynpd_reg(_read_reg(NRF24REG_DYNPD)); _nrf24_report_feature_reg(_read_reg(NRF24REG_FEATURE)); } #endif // NRF24_USING_INFO_REPORT #ifdef NRF24_USING_SHELL_CMD #include
static void nrf24(int argc, char **argv) { if (argc < 2) { rt_kprintf("USAGE: nrf24 [OPTION]\r\n"); rt_kprintf("[OPTION]:\r\n"); rt_kprintf(" init [spiDevice]\r\n"); rt_kprintf(" portinit [spiDevice]\r\n"); rt_kprintf(" readreg [regAddr]\r\n"); rt_kprintf(" writereg [regAddr] [data]\r\n"); #ifdef NRF24_USING_INFO_REPORT rt_kprintf(" report\r\n"); #endif // NRF24_USING_INFO_REPORT return; } #ifdef NRF24_USING_INFO_REPORT if (!rt_strcmp(argv[1], "report")) { nrf24_report(); } #endif // NRF24_USING_INFO_REPORT if (argc < 3) { return; } if (!rt_strcmp(argv[1], "readreg")) { uint8_t reg = atoi(argv[2]); rt_kprintf("reg:0x%x val: 0x%x\n", reg, _read_reg(reg)); } if (!rt_strcmp(argv[1], "init")) { nrf24_cfg_t nrf24; nrf24_default_param(&nrf24); nrf24.role = ROLE_PRX; nrf24.ud = argv[2]; nrf24_init(&nrf24); } else if (!rt_strcmp(argv[1], "portinit")) { hal_nrf24l01_port.init(argv[2]); } if (argc < 4) { return; } if (!rt_strcmp(argv[1], "writereg")) { if (!rt_strcmp(argv[1], "writereg")) { uint8_t reg = atoi(argv[2]); uint8_t data = atoi(argv[3]); _write_reg(reg, data); } } } MSH_CMD_EXPORT(nrf24, nrf24l01); #endif // NRF24_USING_SHELL_CMD ``` ``` `
查看更多
1
个回答
默认排序
按发布时间排序
RiceChen
认证专家
2021-01-19
内核/软件架构/开源
你想表达什么内容,直接完整版,有软件包,可以参考 ![image.png](https://oss-club.rt-thread.org/uploads/20210119/7d6858bebc17cc602ddde5b5acd7e324.png)
撰写答案
登录
注册新账号
关注者
0
被浏览
917
关于作者
曾恺昀
这家伙很懒,什么也没写!
提问
5
回答
0
被采纳
0
关注TA
发私信
相关问题
1
裸机工程移植 RT-Thread
2
Keil MDK 移植 RT-Thread Nano
3
移植 Nano,rt_thread_mdelay()延迟时间不对
4
裸机工程移植 RT-Thread内核
5
关于利用0x68000000作为扩展sram?
6
STM32F413 SD 卡写入速度提升方法
7
STM32 RTC 闹钟
8
http_ota 提示no memory
9
studio中怎么把PB3 和PA15引脚设置为普通IO口使用?
10
求一份基于RTT系统封装好的STM32F1系列的FLASH操作程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用
2
Rt-thread中OTA下载后,bootloader不搬程序
3
ulog 日志 LOG_HEX 输出时间改为本地日期时间
4
在RT-Thread Studio中构建前执行python命令
5
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
xiaorui
1
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部