This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC1101:接收数据有时良好、有时糟糕

Guru**** 2414260 points
Other Parts Discussed in Thread: CC1101, CC2500, CC1100

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1059110/cc1101-receive-data-sometimes-good-sometimes-bad

器件型号:CC1101
主题中讨论的其他器件: CC2500CC1100

如何发生以下情况以及如何提高数据发送和接收的成功率 ?

  1. #ifdef DATARATE_250kbps
    static const uint8_t CC1101InitData[ INIT_NUM ][ 2 ]=
    {
    //0x29:CHP_RDYn 0x2E:3-高阻 0x0F:CRC_OK
    { CC1101_IOCFG2, 0x0F}, // IOCFG2 GDO2 Default is CHP_RDYn.0x29
    { CC1101_IOCFG1, 0x2E }, // IOCFG1 GDO1 Default is 3-state
    { CC1101_IOCFG0, 0x06 }, // IOCFG0 GDO0 output pin configuration.0x06
    { CC1101_FIFOTHR, 0x0E }, // FIFOTHR RXFIFO and TXFIFO thresholds.
    { CC1101_SYNC1, 0XD3 },
    { CC1101_SYNC0, 0X91 },
    { CC1101_PKTLEN, 0xFF }, // PKTLEN Packet length.
    { CC1101_PKTCTRL1, 0x04 }, // PKTCTRL1数据包自动控制.状态字节开启/地址检查
    { CC1101_PKTCTRL0, 0x45 }, // PKTCTRL0数据包自动控制. CRC开启/可变长度
    //ADDR
    //CHANNR
    { CC1101_FSCTRL1, 0x0C }, // FSCTRL1 频率合成器控制 sensitivity:0x0c current consumption:0x12
    { CC1101_FSCTRL0, 0x00 }, // FSCTRL0 频率合成器控制
    { CC1101_FREQ2, 0x10 }, // FREQ2 Frequency control word, high byte
    { CC1101_FREQ1, 0x44 }, // FREQ1 Frequency control word, middle byte.
    { CC1101_FREQ0, 0xEC }, // FREQ0 Frequency control word, low byte.
    
    { CC1101_MDMCFG4, 0x2D }, // MDMCFG4 Modem configuration.
    { CC1101_MDMCFG3, 0x3B }, // MDMCFG3 Modem 速率
    { CC1101_MDMCFG2, 0x13 }, // MDMCFG2 Modem DC 阻断滤波器. sensitivity:0x13 current consumption:0x93
    { CC1101_MDMCFG1, 0x22 }, // MDMCFG1 Modem 调制格式/MC/ 4bytes前导
    { CC1101_MDMCFG0, 0xF8 }, // MDMCFG0 Modem 信道频率间隔
    
    { CC1101_DEVIATN, 0x62 }, // DEVIATN Modem deviation setting (when FSK modulation is enabled).
    //MCSM2 0X07
    //MCSM1 0X30
    { CC1101_MCSM0, 0x18 }, // MCSM0 Main Radio Control State Machine configuration.
    { CC1101_FOCCFG, 0x1D }, // FOCCFG 频率偏移补偿配置
    { CC1101_BSCFG, 0x1C }, // BSCFG 位同步配置
    { CC1101_AGCCTRL2, 0xC7 }, // AGCCTRL2 AGC control.
    { CC1101_AGCCTRL1, 0x00 }, // AGCCTRL1 AGC control.
    { CC1101_AGCCTRL0, 0xB0 }, // AGCCTRL0 AGC control.
    //WOREVT1 0X87
    //WOREVT0 0X6B
    //WORCTRL 0XFB
    { CC1101_FREND1, 0xB6 }, // FREND1 Front end RX configuration.
    { CC1101_FREND0, 0x10 }, // FREND0 Front end TX configuration.
    { CC1101_FSCAL3, 0xEA }, // FSCAL3 Frequency synthesizer calibration.
    { CC1101_FSCAL2, 0x2A }, // FSCAL2 Frequency synthesizer calibration.
    { CC1101_FSCAL1, 0x00 }, // FSCAL1 Frequency synthesizer calibration.
    { CC1101_FSCAL0, 0x1F }, // FSCAL0 Frequency synthesizer calibration.
    //RCCCTRL1 0X41
    //RCCCTRL0 0X00
    //FSTEST 0X59
    //PTEST 0X7F
    //AGCTEST 0X3F
    { CC1101_TEST2, 0x88 },
    { CC1101_TEST1, 0x31 },
    { CC1101_TEST0, 0x0B }, // TEST0 // TEST0 Various test settings.//TEST0 0X0B
    };
    #endi
  2. void CC1101_RX_MODE(uint8_t type)
    {
      RESET_GDO0;
      RESET_GDO2;
      reset_rxData();
      reset_txData();
    
      CC1101_Write_Cmd(CC1101_SIDLE );
    
      //delay_ms(1);
      CC1101_Write_Cmd( CC1101_SFRX );
      CC1101_Write_Cmd( CC1101_SFTX );
    	CC1101_Write_Reg(CC1101_PKTLEN,0xff);//
      CC1101_Write_Reg(CC1101_IOCFG2,0x07);  //CRC_OK
      CC1101_Write_Reg(CC1101_PKTCTRL0,0x45);//可变长度
      //ADR_CHK:Address check, no broadcast
      CC1101_Write_Reg(CC1101_PKTCTRL1,0x0D);
        
    	CC1101_Write_Reg(CC1101_MCSM0,0x18);// When going from IDLE to RX or TX (or FSTXON)
      CC1101_Write_Reg(CC1101_IOCFG0,0x06); //收到同步字置位,数据包末尾\地址校验失败\RXFIFO溢出时取消置位
      //WOR, RX_TIME是百分比,退出WOR,RX_TIME就必须一直持续到packet结束
      CC1101_Write_Reg(CC1101_MCSM2,0x07);//RX_TIME:Until end of packet
    }
    
    
    
  3. void CC1101_WOR_Init( void )
    {
      //CC1101_Write_Cmd(CC1101_SIDLE );
      //提前配置I/O,输出状态不正常
      //与 RX FIFO 相关:达到或超出 RX FIFO 阈值填充 RX FIFO 时置位,或到达数据包结尾时置位
      
      //CC1101_Write_Reg(CC1101_WOREVT1,0x87);//Event0高8位  1000ms
      //CC1101_Write_Reg(CC1101_WOREVT0,0x6A);//Event0低8位
      
      CC1101_Write_Reg(CC1101_MCSM0,0x38);// 每第四次当从 RX 或 TX 返回空闲时自动进行校准
      CC1101_Write_Reg(CC1101_MCSM2,0x10);//RX_RSSI=1(便于快速休眠)  1000ms*0.391%
      
      uint16_t sl_p;
      if(WOR_short){
        sl_p =50;
      }else {
        sl_p =1000;
      }
      sl_p = (uint16_t)(sl_p*(34.666));//26000/750
      CC1101_Write_Reg(CC1101_WOREVT1,sl_p>>8);//Event0高8位  1000ms
      CC1101_Write_Reg(CC1101_WOREVT0,sl_p);//Event0低8位
      
      //WORCTRL.EVENT1  t1=EVENT1*750/26M 16 (0.444 – 0.462 ms)
      //CC1101_Write_Reg(CC1101_WORCTRL,0x48);// 事件 1 工作暂停前事件 0 后  WOR_RES==0 1LSB周期 (27μs – 31μs)
      CC1101_Write_Reg(CC1101_WORCTRL,0x08);// 事件 1 工作暂停前事件 0 后  WOR_RES==0 1LSB周期 (27μs – 31μs)
      //Event0 计算公式:34666约为1s  t0=WOREVT*(2^(5*WOR_RES))*750/26M  8.8uA平均功耗
      delay_us(3000);
      //CC1101_Write_Reg(CC1101_WORCTRL,0x30);
      uint8_t calib1 = CC1101_Read_Status(RCCTRL1_STATUS);
      uint8_t calib0 = CC1101_Read_Status(RCCTRL0_STATUS);
      CC1101_Write_Reg(CC1101_RCCTRL1, calib1);
      CC1101_Write_Reg(CC1101_RCCTRL0, calib0);
      
      CC1101_Write_Reg(CC1101_IOCFG0,0x25);  //0x25  WOR ENVT1
      //CC1101_Write_Cmd(CC1101_SIDLE );
      CC1101_Write_Cmd(CC1101_SWORRST );    //Resets the real time clock
      CC1101_Write_Cmd(CC1101_SWOR);         // Starts Wake-on-Radi
      //CC1101_Write_Cmd(CC1101_SPWD);
    }
  4. MCU:STM32L496  SPI:4MHz TSP:1us  
  5.  例如:#define CC1101_SET_CSn_LOW CC_CS_0;DELAY_us (2);
    #define CC1101_SET_CSn_HIGH DELAY_us (2);CC_CS_1;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    图1和2:  

    不是很清楚这些图实际上显示了什么。 根据该图、我想它是3个节点向收集器发送数据、收集器在接收到数据时发送一个 ACK。 在某些情况下、未接收到 ACK。  

    为了便于调试:只使用一个 RX 和一个 TX 单元。 此外、将 LNA_PD/PA_PD 信号置于引脚上(请参阅 CC1101数据表中的表41)。 代码片段表示使用了 WOR、并将这些信号路由出去将显示 TX 端发送时 RX 是否实际监听。 验证时序。 有关  详细信息、另请参阅 www.ti.com/.../swra126。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     failures

    重新传输故障:

    重新传输 成功:”

    为什么这种情况总是发生?

    如何提高重传的成功率?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能描述一下这些图上发生了什么情况吗? 图中显示了一些 GDO 信号、但不清楚实际显示了哪些信号。 您能否编写一份描述图解显示内容的文本?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我参考《应用手册 N049》“用于 CC1100/CC2500和 MSP430示例和函数库的软件用户指南”  

    page13;title:接收任意长度的数据包。

     屏幕截图显示了 GDO0_CFG 和 GDO2_CFG。 我需要 通过 无限 模式传输3000字节的数据。在  我的应用中,

    GDO0_CFG:6 (0x06)
    当发送/接收到 SYNC 字时置为有效、并在数据包末尾取消置为有效。 在 RX 中、该引脚还将
    当数据包因地址或最大长度过滤而被丢弃或当对讲机进入时置位
    RXFIFO_OVERflow 状态。 在 TX 中、如果 TX FIFO 下溢、引脚将失效。
    GDO2_CFG:6 (0x00)
    关联到 RX FIFO:当 RX FIFO 被填满或超过 RX FIFO 阈值时置为有效。 当 RX FIFO 失效时
    低于同一阈值。

    如 图9使用逻辑分析仪捕获 RX 场景所示、此时 ISR:数据包完成中断。 设置数据包接收标志。

    读取 寄存器“RXBYTES” 并 返回“NUM_RXBYTES” 为0。  因此整个数据包 传输 失败

    uint8_t CC1101_Get_RxCounter( void )
    {
      static uint8_t RX_bytes;
      RX_bytes = CC1101_Read_Status( CC1101_RXBYTES );
      rxData.rx_fifo = ( RX_bytes & BYTES_IN_RXFIFO );	
      return (RX_bytes & BYTES_FLOW);
    }
    
    uint8_t CC1101_GDO0_ISR(void)
    {
      //----------------------- TX MODE -----------------------
      if(Radio_mode ==TX_MODE ) //send mode
      {
        if(txData.txmode == PKG_INFINITE)//发送后续TX FIFO
        {
          txData.lastpkg = FALSE;
          CC1101_RX_Mode(RX_MODE,INFINITE);
        }else{
          if(txData.packetSentFlag == TRUE){ //单次发送完成后回自动切换RX模式
            txData.packetSentFlag = FALSE;
            Radio_mode = RX_MODE;
            //CC1101_Write_Cmd(CC1101_SRX);
            CC1101_check_RX();//CC1101_RX_Mode(RX_MODE,VARIABLE);//
          }else{
            CC1101_Tx(I_p.para[1]);
          }
        }
        return 0;
      }
      else if(Radio_mode> TX_MODE )//0or2 receive mode
      {
        if(GDO0 == GPIO_PIN_RESET)//下降沿  End of Packet
        {
          //sync_GDO0_task();
          if(txData.packetSentFlag == TRUE){ //单次发送完成后回自动切换RX模式
            txData.packetSentFlag = FALSE;
            return 0;
          }
          if(CC1101_Get_RxCounter( )){//超时或者溢出
            CC1101_Write_Cmd( CC1101_SFRX );
            return 0x11;
          }
          if(rxData.rx_fifo == 0){
            return 0x12;
          }
          else//收到数据包
          {
            if(rxData.pktFormat == VARIABLE)
              return CC1101_Rx_Packet(rxData.buf);
            else
              return CC1101_Rx_Packet(Udp);
          }
        }
      }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="66607" URL"~/support/wireless-connectivity/sub-GHz 组/sub-1GHz/f/sub-1GHz 论坛/1059110/CC1101-receive-data-mage-mage-mage-mage-mage-dad/3919487#3919487"]为便于调试:仅使用一个 RX 和一个 TX 单元。 此外、将 LNA_PD/PA_PD 信号置于引脚上(请参阅 CC1101数据表中的表41)。 代码片段表示使用了 WOR、并将这些信号路由出去将显示 TX 端发送时 RX 是否实际监听。 验证时序。 有关  详细信息、另请参阅 www.ti.com/.../swra126。  [/报价]

    您是否尝试执行此操作、是否可以确认您是否正在使用 WOR?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试执行 LNA_PD/PA_PD  单路输出。我将提供新信息。但问题与 WOR 有关?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在您在第一个帖子中发布的代码中、您有一个名为 CC1101_WOR_Init 的函数。 我假设您使用无线电唤醒?  

    我提出 WOR 和 LNA_PD/PA_PD 信号的原因是、使用 WOR 时的典型误差是当您认为芯片不在 RX 中时。 通过监控 PD 信号、可以很容易地看出当主器件处于 TX (或其他方式)时从器件是否处于 RX 中

    如果这与 WOR 设置相关、调试的另一种方法是使用正常 RX (而不是 WOR)、并查看您是否看到相同的问题。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如上图所示、接收器 RX 模式 LNA_PD 始终处于高电平

    我已经在无限模式下实现了极长数据的发送和接收、但成功率不够高、并且重传通常会失败。 从屏幕截图中可以看到、我首先在 WOR 模式下唤醒了 slaver 设备、然后主设备将在从设备接收到命令后启动命令以请求数据并发送数据。 该流程已正确执行、但最后一个数据包中可能会出现错误、导致数据包验证失败。 我观察到 LNA_PD/ PA_PD RX TX 都处于正确状态、但 NUM_RXBYTES 仍然为0。 此时、我读取 RX FIFO 中的数据。 RX FIFO 中有数据、但长度通常比实际的少几个字节。 我认为出现异常是正常的、但我无法理解为什么重复重传仍然失败。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不确定这是否包含在线程中:这是否仅在您有多个从器件时发生?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    通信失败是随机的、但我重复了几次。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我询问您是否只在多个从器件上看到此情况的原因:由于您得到 NUM_RXBYTES = 0、这可能表示您未正确接收数据。 如果您有多个从器件、它们可能同时处于 TX 中并损坏数据。  

    不同的想法:  

    代码表示您使用的是 STM32。 我们已经看到 FAST MCU 的情况、由于时序问题可能会发生奇怪的错误。

    您是否使用示波器监控 SPI 接口、以检查其是否符合 CC1101数据表中的"四线制串行配置和数据接口"? 最重要的是"当 CSn 被拉低时、MCU 必须等到 CC1101、所以引脚变为低电平、然后才能开始传输标头字节。"

    当我看到两个定义 #define CC1101_SET_CSn_LOW CC_CS_0;Delay_us (2)时、我开始考虑它;
    在代码中#define CC1101_SET_CSn_HIGH DELAY_us (2);CC_CS_1。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为您所说 的是"代码表示您正在使用 STM32。 我们已经看到 FAST MCU 的情况、由于时序问题、可能会发生奇怪的错误。" 当我降低 SPI 速率并增加 TSP 时、重新传输成功率显著增加。 进行了大量测试。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好。TRE。

    我找到了本文档  SWRA147B《设计手册 DN010 采用 CC1101的近端接收》第5页4.2时序。

    我认为解决方案在哪里。但我不理解如何做到。像这样吗?

    /**
    * @brief :CC1101连续写寄存器
    * @param :
    * @Addr:地址
    * @pWriteBuff:写入的数据串首地址
    * @WriteSize:写入的数据个数
    * @note  :无
    * @retval:无
    */
    void CC1101_Write_Multi_Reg( uint8_t Addr, uint8_t *pWriteBuff, uint8_t WriteSize )
    {	
      if(WriteSize)
      {
        CC1101_SET_CSN_LOW();
        SPI_READ_WRITE_BYTR( Addr | WRITE_BURST );	//连续写命令 及首地址
        HAL_SPI_Transmit(&hspi2, pWriteBuff, WriteSize, 0xff);
        delay_us(100);//250kbps  100> (72+10)
        CC1101_SET_CSN_HIGH();
      }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在详细介绍实施方案之前:如果增加节点和/或移除天线之间的距离、您是否会看到改进? 您在接收到的数据包上看到了哪些 RSSI?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果您的 RSSI 为-40dBm、则不会出现饱和问题、因为饱和限制约为-15dBm。 如果这是根本原因、那么在 RSSI 水平较低而 RSSI 水平较高时、您应该看到的问题较少?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    void CC1101_Write_Multi_Reg( uint8_t Addr, uint8_t *pWriteBuff, uint8_t WriteSize )
    {	
      if(WriteSize)
      {
        CC1101_SET_CSN_LOW();
        SPI_READ_WRITE_BYTR( Addr | WRITE_BURST );	//连续写命令 及首地址
        HAL_SPI_Transmit(&hspi2, pWriteBuff, WriteSize, 0xff);
        delay_us(100);//250kbps  100> (72+10)
        CC1101_SET_CSN_HIGH();
      }
    }

    上图中延迟的增加确实显著提高了在无限模式下大型数据包的成功率、接近100%。

    由于我使用逻辑分析仪、主设备和从设备之间的距离非常近、小于30cm。因此、当我增加 TX 功率时、RSSI 会增加一点、但故障会增加。

    我认为我的硬件设计中存在缺陷。 可以帮我看一下吗?我可以将其发送到您的电子邮件地址吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    由于单元已关闭、因此在调试时、您似乎会遇到饱和问题。 但是、在系统部署时、您是否会遇到饱和问题? 如果没有、我建议您移除其中一个装置上的天线以降低 RSSI、这可能比编写自定义 SW 更容易。  

    您似乎没有等待它变低?  

    我将检查延迟。  

    对于硬件、最简单的方法是通过 https://www.ti.com/tool/SIMPLELINK-SUB1GHZ-DESIGN-REVIEWS 申请审核、 我会在您提交文件后从系统中收到一封邮件。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="248535" url="~/support/wireless-connectivity/sub-1GHz-group/sub-1GHz/f/sub-1GHz-forum/1059110/CC1101-receive-data-mage-gow-mage-mage-mage-mage-dad/3962097#3962097"]图中的延迟增加会显著提高100%/quote 数据包的成功率,这会使上述数据包的成功率接近100%。]

    不应要求在此处添加延迟。  

    --

    根据此主题中迄今收到的信息、我仍然对问题所在的位置有疑问。

    最好采取几个步骤:

    -硬件:

    • 您是否验证了传导性能? 您的硬件的性能与数据表中所述的性能相当。
    • 您是否验证了辐射性能? 天线是否已调谐?

    -软件

    • 您是否已检查 SPI 通信/接口的实现是否符合数据表中规定的要求。 一个典型的细节就是等待这样做。 正如我提到过的、使用快速 MCU、您可能会面临在设置或类似值之前读取值的风险

    -协议

    • 目前您正在使用带有 WOR 和多个节点的3000字节数据包。 要了解重新传输的原因、应简化系统
    • 从1个主器件、1个从器件开始。 使用30字节数据包。 使用30字节数据包有几个用途:它大大简化了软件、因为您不需要两个不同的中断来处理3000字节。 而较短数据包的误码风险较低。 使用点对点通信而不是多个节点消除了节点之间定时的要求。
    • 当它按预期工作时、仍然使用1个主器件、1个从器件、但使用300字节数据包。 然后、您使用与3000字节相同的逻辑/中断、但出错的几率较低。

    您是否需要在一个数据包中发送3000个字节、或者是否能够在多个数据包上将其拆分? 发送此长数据包时、在空中出现位错误的概率很大。