打印
[其它]

arduino驱动nRF24L01+数据发不出去

[复制链接]
2585|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 feiyinglala 于 2022-6-11 02:39 编辑

目的:借鉴Mirf库,使用arduino驱动nRF模块,通过串口监视工作状态

特别说明:我将模块配置为了无需ACK的单发状态(EN_AA/EN_RXADDR/SETUP_RETR均配置为0x00)
现象问题:寄存器配置显示正确,数据也加载到FIFO中了,但就是发不出去(STATUS=0E,FIFO_STATUS=0X01)串口通信正常,模块是正常的(换到STM32驱动就可以发出去)

引脚关系: CE -> 8  // * CSN -> 7 // * SCK -> 13  * MOSI -> 11 * MISO -> 12 * IRQ  -> 2

整体思路:nRF初始化默认配置为接收状态,在接到电脑通过串口发送的命令后启动发送
setup():
    串口和定时器初始化
    Mirf.init,配置CE和CSN引脚
    Mirf.config 配置为接收模式--清空FIFO接收区
loop():
    读取当前EN_AA / EN_RXADDR / SETUP_RETR / CONFIG寄存器配置状态和STATUS、FIFO_STATUS寄存器状态
    Mirf.send   检验是否在发送状态---配置为发送模式---清空FIFO发送区---CE置高发送
    读取发送后STATUS、FIFO_STATUS寄存器配置状态
    延时循环计数

串口接收到的信息
Starting wireless...
Wireless initialized!
循环第0次
EN_AA:1
EN_RXADDR:1
SETUP_RETR:3
CONFIG:1F
发送前STATUS:E
发送前FIFO_STATUS:11
Mirf中send函数段:status=E
发送后STATUS:E
发送后FIFO_STATUS1:1

循环第1次
EN_AA:0
EN_RXADDR:0
SETUP_RETR:0
CONFIG:3E
发送前STATUS:E
发送前FIFO_STATUS:1
心跳还在
源代码如下:
1.主程序
void loop() {
  Serial.print( "循环第" );
  Serial.print(i, HEX );
  Serial.println("次");
/***********1.读取EN_AA等寄存器的配置值*******************/  
  Mirf.readRegister(EN_AA,&temp[0],1); //读取寄存器配置值
  Serial.print( "EN_AA:" );
  Serial.println( temp[0], HEX );
  
  Mirf.readRegister(EN_RXADDR,&temp[0],1); //读取寄存器配置值
  Serial.print( "EN_RXADDR:" );
  Serial.println( temp[0], HEX );

  Mirf.readRegister(SETUP_RETR,&temp[0],1); //读取寄存器配置值
  Serial.print( "SETUP_RETR:" );
  Serial.println( temp[0], HEX );
  
  Mirf.readRegister(CONFIG,&temp[0],1); //读取寄存器配置值
  Serial.print( "CONFIG:" );
  Serial.println( temp[0], HEX );
/***********2.读取STATUS等寄存器的初始值*******************/   
  //Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
  temp[0] = Mirf.getStatus();
  Serial.print( "发送前STATUS:" );
  Serial.println( temp[0], HEX );
  
  Mirf.readRegister(FIFO_STATUS,&temp[0],1); //读取寄存器配置值
  Serial.print( "发送前FIFO_STATUS:" );
  Serial.println( temp[0], HEX );
/**************3.发送数据*******************/
Mirf.send(PC_Buf);                //发送指令,发送32字节数据
  //while(Mirf.isSending()) delay(20);         //直到发送成功(TX_DS为1),退出循环 20220529卡死
/***********4.读取STATUS等寄存器的初始值*******************/
  Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
  Serial.print( "发送后STATUS:" );
  Serial.println( temp[0], HEX );

  Mirf.readRegister(FIFO_STATUS,&temp[0],1); //读取寄存器配置值
  Serial.print( "发送后FIFO_STATUS1:" );
  Serial.println( temp[0], HEX );

//Mirf.writeRegister(STATUS,0xff,1);   //改造为清除状态寄存器
  delay(1000*i); if(i<5)i++;        //此行为节奏控制,后续可删除
2.Mirf.CPP[改造后]
void Nrf24l::init() 
// Initializes pins to communicate with the MiRF module
// Should be called in the early initializing phase at startup.
{   
    pinMode(cePin,OUTPUT);        //CE配置为输出
    pinMode(csnPin,OUTPUT);        //CSN配置为输出

    ceLow();        //默认配置为低,待机1:无数据传输
    csnHi();        //默认配置为高,片选禁用

    // Initialize spi module
    spi->begin();        //启动SPI
}


void Nrf24l::config() //改造为默认保持收         
// Sets the important registers in the MiRF module and powers the module
// in receiving mode
// NB: channel and payload must be set now.
{

        // Set RF channel
        configRegister(RF_CH,channel);        //待核实
        
    // Set length of incoming payload
        configRegister(RX_PW_P0, payload);                //数据包长度
        configRegister(RX_PW_P1, payload);

    // Start receiver
    powerUpRx();                                        //默认为接收态
    flushRx();        //不知用途
}
void Nrf24l::setRADDR(uint8_t * adr)         
// Sets the receiving address        设置接收地址
{
        ceLow();
        writeRegister(RX_ADDR_P1,adr,mirf_ADDR_LEN);
        ceHi();
}

void Nrf24l::setTADDR(uint8_t * adr)
// Sets the transmitting address        设置发送地址
{
        /*
         * RX_ADDR_P0 must be set to the sending addr for auto ack to work.
         */

        writeRegister(RX_ADDR_P0,adr,mirf_ADDR_LEN);
        writeRegister(TX_ADDR,adr,mirf_ADDR_LEN);
}
void Nrf24l::send(uint8_t * value)
{
    uint8_t status,f_status;
    status = getStatus();

    while (PTX) {                //PTX标志为1(发送态时),判断是否完成处于发送中
            status = getStatus();
                //status第4、5位任何一位置位,就表明完成了上次发送
            if((status & (1 << TX_DS))){//((1 << TX_DS)  | (1 << MAX_RT)))){        //数据发送完成中断 或 达到最大重发
                    PTX = 0;        //标志状态回归接收态
                    break;
            }//Serial.print( "当前:PTX=1,异常" );        //20220607因TX_DS未变,导致始终输出
    }                  // Wait until last paket is send
        
        ceLow();                                        //StandBy I模式        
        powerUpTx();                               // Set to transmitter mode , Power up
        
        csnLow();                    // Pull down chip select
    spi->transfer(FLUSH_TX);     // Write cmd to flush tx fifo
    csnHi();                    // Pull up chip select
        delayMicroseconds(50);                 //延时至少保持5us   

        //装填数据
        csnLow();                    // Pull down chip select        片选有效
        spi->transfer( W_TX_PAYLOAD ); // Write cmd to write payload
        transmitSync(value,payload);   // 【关键动作发送】Write payload
        csnHi();                    // CSN拉高结束向FIFO写数据
        //置高发射
        ceHi();                     // Start transmission
        delayMicroseconds(130);

        //串口监控代码
        status=getStatus();
        Serial.print( "Mirf中send函数段:status=" );
        Serial.println(status, HEX );
}
void Nrf24l::powerUpTx(){
        PTX = 1;
//20220529编写 待验证
csnHi();                    // Pull up chip select
setTADDR(Tx_addr);                        //写发送端地址TX_ADDR 和接收端地址RX_ADDR_P0
setRADDR(Rx_addr);                        //写接收端RX_ADDR_P1地址(CE电平拉低写地址后变高)
//RX_ADDR_P0
writeRegister(RX_ADDR_P0,Rx_addr,mirf_ADDR_LEN);
writeRegister(TX_ADDR,Tx_addr,mirf_ADDR_LEN);
configRegister(EN_AA,0x00);                //自动应答ACK禁止
configRegister(EN_RXADDR,0x00); //[发送专用]允许接收地址只有频道0         
configRegister(SETUP_RETR,0x00);        //[调试]自动重发禁用
configRegister(RF_CH,channel);        //Set RF channel
configRegister(RF_SETUP,0x0f);                //设置发射速率2MHz,发射功率为最大值0dB
// Set length of incoming payload
configRegister(RX_PW_P0, payload);
configRegister(CONFIG, 0x3e);//, mirf_CONFIG | ( (1<<PWR_UP) | (0<<PRIM_RX) ) );        

//20220529编写 待验证^^^^^^
}

源码.rar

7.1 KB

使用特权

评论回复

相关帖子

沙发
feiyinglala|  楼主 | 2022-6-14 02:27 | 只看该作者
我现在怀疑,是CE端口电平太高导致工作异常,nRF模块VCC端口是3.3V,但是CE直连arduino的D8引脚,测得高电平电压为4.7V,是不是该用个分压电路。

使用特权

评论回复
板凳
feiyinglala|  楼主 | 2022-7-14 20:36 | 只看该作者
问题解决了,是电压问题,我单独用万用板焊了一个3.3V芯片给nRF供电就好了

使用特权

评论回复
地板
gaochy1126| | 2022-12-29 20:12 | 只看该作者
驱动nRF24L01,只需要使用spi接口就行了。这个怎么判断的发布出去?

使用特权

评论回复
5
gaochy1126| | 2022-12-29 20:12 | 只看该作者
你可以参考网上的代码,这个驱动nRF24L01不是很难的。        

使用特权

评论回复
6
feiyinglala|  楼主 | 2022-12-30 11:40 | 只看该作者
gaochy1126 发表于 2022-12-29 20:12
你可以参考网上的代码,这个驱动nRF24L01不是很难的。

谢谢版主支持,后来发现不是代码问题,是电压问题,我单独搞了个小班子,用1117给nRF单独供电就可以正常工作了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

210

帖子

1

粉丝