CH585 RF_Basic例程讲解<含单向和双向发送>

CH585_RF基础通讯例程见下图路径:

1、RF初始化参数配置

/*******************************************************************************
 * @fn      RFRole_Init
 *
 * @brief   RF应用层初始化
 *
 * @param   None.
 *
 * @return  None.
 */
void RFRole_Init(void)
{
    rfTaskID = TMOS_ProcessEventRegister( RFRole_ProcessEvent );
    {
        rfRoleConfig_t conf ={0};

        conf.TxPower = LL_TX_POWEER_4_DBM;//配置初始发射功率
        conf.rfProcessCB = RF_ProcessCallBack;//注册RF中断回调
        conf.processMask = RF_STATE_RX|RF_STATE_RX_CRCERR|RF_STATE_TX_FINISH|RF_STATE_TIMEOUT;//配置RF中断事件
        RFRole_BasicInit( &conf );//RF初始化
    }
    {
        gParm.accessAddress = 0x71762345;//配置默认通信地址
        gParm.crcInit = 0x555555;//初始化CRC校验和,一般不做修改
        // 配置PHY类型
        gParm.properties = LLE_MODE_PHY_2M;//配置2M模式
        // 配置重传间隔,发送次数大于1时有效,和TxParam.sendCount配合使用
        gParm.sendInterval = 1999*2;
        // 配置发送稳定时间
        gParm.sendTime = 10*2;//gParm.sendTime可在程序中任意时刻修改,不会耗时,注意点:↓↓↓↓↓
    //①不包含跳频操作,即调用发送接口时频点保持不变,该值配置时在此例程中不建议低于6*2,即6us,实际需按照下文第5点进行调整;
    //②如果此次发送有频点修改,该值配置时最低必须至少是60*2,即60us,如低于这个时间会导致频点切换不稳定,出现接收端收不到数据问题;
RFRole_SetParam( &gParm ); } }

 

2、发送方和接收方参数配置

    // TX相关参数,全局变量
    {
        gTxParam.accessAddress = gParm.accessAddress;//配置初始通信地址
        gTxParam.crcInit = gParm.crcInit;//配置初始化CRC校验和
        gTxParam.properties = gParm.properties;//配置通信模式
        gTxParam.sendCount = 1;//配置重传间隔,发送次数大于1时有效,0和1都代表只发一次,无重传
        gTxParam.txDMA = (uint32_t)TxBuf;//TxDMA配置
    }
    // RX相关参数,全局变量
    {
        gRxParam.accessAddress = gParm.accessAddress;//配置初始通信地址
        gRxParam.crcInit = gParm.crcInit;//配置CRC校验初始值
        gRxParam.properties = gParm.properties;//配置通信模式
        gRxParam.rxDMA = (uint32_t)RxBuf;//RxDMA配置
gRxParam.rxMaxLen = TEST_DATA_LEN;//接收方需配置,虽说接收方接收没有配置超时时间,但是如果在Rx状态下接收到的有效数据长度大于所配置的rxMaxLen,会有概率返回接收超时,原因是不能错过下一次接收窗口,从而影响接收下一包数据
} PFIC_EnableIRQ( BLEB_IRQn ); PFIC_EnableIRQ( BLEL_IRQn );//使能BLE中断,中断方式接收 PRINT("rf role init.id=%d\n",rfTaskID);

  

3、定时器中断配置,演示发送方发送数据,为了不影响RF接收数据的响应时间,配置了中断嵌套,允许其他中断打断

    TMR0_TimerInit( GetSysClock() / RF_DEVICE_PERIDOC );//4k速率发送,250us进一次中断
    TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 开启中断
    PFIC_SetPriority( TMR0_IRQn, 0x80 );
    PFIC_EnableIRQ(TMR0_IRQn);

 

4、定时器中断函数

__INTERRUPT
__HIGH_CODE
void TMR0_IRQHandler(void) // TMR0 定时中断
{
    if(TMR0_GetITFlag(TMR0_3_IT_CYC_END))
    {
        TMR0_ClearITFlag(TMR0_3_IT_CYC_END); // 清除中断标志
        // 初始化发送的数据
        #define TEST_DATA_LEN 4
        TxBuf[0] = 0x55;//帧头,数据自定义
        TxBuf[1] = TEST_DATA_LEN;//数据长度,不包含第一字节和第二字节,用于告知底层数据包整体长度
        //TxBuf长度=2+TEST_DATA_LEN
        TxBuf[2]++;
        TxBuf[3] = gRssi;//RSSI是通过其他地方赋值过来的,不代表这个字节固定代表RSSI
        TxBuf[4] = 0;
        TxBuf[5] = 0;
        rf_tx_start( TxBuf );//启动DMA发送
    }
}

 

 

5、RF发送函数

 

/**
 * @brief   rf发送数据子程序
 *
 * @param   pBuf - 发送的DMA地址
 *
 * @return  None.
 */
__HIGH_CODE
void rf_tx_start( uint8_t *pBuf )
{
    RFIP_SetTxStart( );//配置寄存器启动发送,需要一定时间,在此期间可以配置下面的频点和数据准备
    // 配置发送的频点
    gTxParam.frequency = TEST_FREQUENCY;//配置频点
    // 发送的DMA地址
    gTxParam.txDMA = (uint32_t)pBuf;
//    gTxParam.accessAddress = gParm.accessAddress; // 发送同步字
//    gTxParam.sendCount = 1;  // 发送次数
    RFIP_SetTxParm( &gTxParam );//启动发送
}

 

6、配置Rx通信频点,配置Rx接收窗口时间

/**
 * @brief   rf接收数据子程序
 *
 * @param   None.
 *
 * @return  None.
 */
__HIGH_CODE
void rf_rx_start( void )
{
    // 配置发送的频点
    gRxParam.frequency = TEST_FREQUENCY;
    // 配置接收的超时时间,0则无超时
    gRxParam.timeOut = 80;//单位1us,库注释有误,单位并非0.5us
    //RF发送完切至Rx等待应答时,极限时间为24us+sendtime+(2字节前导码+4字节接入地址+3字节CRC)*4us=60+sendtime,单位us
    //建议配置超时时间至少为80us,如果代码处理还有耗时,建议再加上一些余量
//    gRxParam.accessAddress = gParm.accessAddress; // 接收同步字
    RFIP_SetRx( &gRxParam );//启动接收,打开接收窗口
}

 

7、发送结束后,会间隔一定时间,在中断里收到此次发送的状态回调,

如果发送成功,则进入RF_STATE_TX_FINISH中断,切换至接收态,打开接收窗口,在打开接收窗口后,根据主动配置的超时时间:

①如果超时,进入RF_STATE_TIMEOUT中断,选择丢包还是重传,重传需主动调用rf_tx_start再次发送

②如果在接收窗口期间内正确接收到了数据包,则进入RF_STATE_RX,用户可选择主动下发下一包数据

/*******************************************************************************
 * @fn      RF_ProcessCallBack
 *
 * @brief   rf中断处理程序
 *
 * @param   sta - 中断状态.
 *          id - 保留
 *
 * @return  None.
 */
__HIGH_CODE
void RF_ProcessCallBack( rfRole_States_t sta,uint8_t id  )
{
    if( sta&RF_STATE_RX )//要么收到数据进RF_STATE_RX,要么没收到数据进入RF_STATE_TIMEOUT,二者进其一
    {
        rf_rx_process_data();//接收成功,获取完整数据
    }

    if( sta&RF_STATE_RX_CRCERR )//如果收到对方回复的数据后,校验结果与CRC不符会进入该中断
    {
        PRINT("nak@crc\n");
    }

    if( sta&RF_STATE_TX_FINISH )//底层发送成功后,会将发送成功状态通过此中断函数报上来
    {
#if( WAIT_ACK )
        rf_rx_start( );//发送结束,转为Rx接收,打开接收窗口,等待对方收到数据前导码后回复应答数据
#endif
        gTxCount ++;//可统计每秒钟发送成功的数据包数量
    }

    if( sta&RF_STATE_TIMEOUT )//在打开接收窗口后,超过配置的gRxParam.timeOut时,进入接收超时中断
    {
        //此处可配置重传
        PRINT("timeout\n");
        //如果超时,在这里重新发送
    }
}

 

posted @ 2025-03-17 15:34  oTvTo  阅读(137)  评论(0)    收藏  举报