[其它] arduino驱动nRF24L01+数据发不出去

[复制链接]
 楼主| feiyinglala 发表于 2022-6-11 02:14 | 显示全部楼层 |阅读模式
本帖最后由 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
14.jpg 13.jpg
整体思路: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寄存器配置状态
    延时循环计数

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

  13. 循环第1次
  14. EN_AA:0
  15. EN_RXADDR:0
  16. SETUP_RETR:0
  17. CONFIG:3E
  18. 发送前STATUS:E
  19. 发送前FIFO_STATUS:1
  20. 心跳还在
源代码如下:
1.主程序
  1. void loop() {
  2.   Serial.print( "循环第" );
  3.   Serial.print(i, HEX );
  4.   Serial.println("次");
  5. /***********1.读取EN_AA等寄存器的配置值*******************/  
  6.   Mirf.readRegister(EN_AA,&temp[0],1); //读取寄存器配置值
  7.   Serial.print( "EN_AA:" );
  8.   Serial.println( temp[0], HEX );
  9.   
  10.   Mirf.readRegister(EN_RXADDR,&temp[0],1); //读取寄存器配置值
  11.   Serial.print( "EN_RXADDR:" );
  12.   Serial.println( temp[0], HEX );

  13.   Mirf.readRegister(SETUP_RETR,&temp[0],1); //读取寄存器配置值
  14.   Serial.print( "SETUP_RETR:" );
  15.   Serial.println( temp[0], HEX );
  16.   
  17.   Mirf.readRegister(CONFIG,&temp[0],1); //读取寄存器配置值
  18.   Serial.print( "CONFIG:" );
  19.   Serial.println( temp[0], HEX );
  20. /***********2.读取STATUS等寄存器的初始值*******************/   
  21.   //Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
  22.   temp[0] = Mirf.getStatus();
  23.   Serial.print( "发送前STATUS:" );
  24.   Serial.println( temp[0], HEX );
  25.   
  26.   Mirf.readRegister(FIFO_STATUS,&temp[0],1); //读取寄存器配置值
  27.   Serial.print( "发送前FIFO_STATUS:" );
  28.   Serial.println( temp[0], HEX );
  29. /**************3.发送数据*******************/
  30. Mirf.send(PC_Buf);                //发送指令,发送32字节数据
  31.   //while(Mirf.isSending()) delay(20);         //直到发送成功(TX_DS为1),退出循环 20220529卡死
  32. /***********4.读取STATUS等寄存器的初始值*******************/
  33.   Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
  34.   Serial.print( "发送后STATUS:" );
  35.   Serial.println( temp[0], HEX );

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

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

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

  9.     // Initialize spi module
  10.     spi->begin();        //启动SPI
  11. }


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

  17.         // Set RF channel
  18.         configRegister(RF_CH,channel);        //待核实
  19.         
  20.     // Set length of incoming payload
  21.         configRegister(RX_PW_P0, payload);                //数据包长度
  22.         configRegister(RX_PW_P1, payload);

  23.     // Start receiver
  24.     powerUpRx();                                        //默认为接收态
  25.     flushRx();        //不知用途
  26. }
  1. void Nrf24l::setRADDR(uint8_t * adr)         
  2. // Sets the receiving address        设置接收地址
  3. {
  4.         ceLow();
  5.         writeRegister(RX_ADDR_P1,adr,mirf_ADDR_LEN);
  6.         ceHi();
  7. }

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

  14.         writeRegister(RX_ADDR_P0,adr,mirf_ADDR_LEN);
  15.         writeRegister(TX_ADDR,adr,mirf_ADDR_LEN);
  16. }
  17. void Nrf24l::send(uint8_t * value)
  18. {
  19.     uint8_t status,f_status;
  20.     status = getStatus();

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

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

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

  67. //20220529编写 待验证^^^^^^
  68. }

源码.rar

7.1 KB, 下载次数: 2

 楼主| 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接口就行了。这个怎么判断的发布出去?
gaochy1126 发表于 2022-12-29 20:12 | 显示全部楼层
你可以参考网上的代码,这个驱动nRF24L01不是很难的。        
 楼主| feiyinglala 发表于 2022-12-30 11:40 | 显示全部楼层
gaochy1126 发表于 2022-12-29 20:12
你可以参考网上的代码,这个驱动nRF24L01不是很难的。

谢谢版主支持,后来发现不是代码问题,是电压问题,我单独搞了个小班子,用1117给nRF单独供电就可以正常工作了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

224

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

21

主题

224

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部