在EVT的BLE目录下提供了 RF_PHY_HOP 例程,下面来讲述下该例程的运行逻辑:

一.进行RF相关配置的初始化:

void RF_Init(void)
{
    uint8_t    state;
    rfConfig_t rfConfig;

    tmos_memset(&rfConfig, 0, sizeof(rfConfig_t));             // 将 rfConfig 数据清 0
    taskID = TMOS_ProcessEventRegister(RF_ProcessEvent);
    //例程默认的接入地址是一个公共的测试地址,使用此地址可能会出现 CRC 错误较多,建议修改接入地址,如0x71764129修改为0x71764124
    rfConfig.accessAddress = 0x71764129;                       // 禁止使用0x55555555 以及 0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 )
    rfConfig.CRCInit = 0x555555;                               // 设置 CRC 初始值
    rfConfig.Channel = 0;                                      // 默认例程未配置此项,此项为跳频前握手的信道,使用别的信道可以自行配置
    rfConfig.ChannelMap = 0xFFFFFFFF;                          // 设置跳频信道
    rfConfig.LLEMode = LLE_MODE_AUTO;                          // 跳频模式必须使用 Auto 模式否则无法通通讯
    rfConfig.rfStatusCB = RF_2G4StatusCallBack;                // 注册 RF 回调用于获取 RF 状态
    rfConfig.RxMaxlen = 251;                                   // 设置接收数据最大长度
#if (CLK_OSC32K != 0)                                          // 如果使用的是内部低频,建议将心跳间隔设置小一点,如4
    //It is better to choose a shorter heartbeat interval for the internal clock.
    rfConfig.HeartPeriod = 4;
#endif
    state = RF_Config(&rfConfig);
    PRINT("rf 2.4g init: %x\n", state);                        // RF初始化结果,0为成功
//    { // RX mode                                         
//        PRINT("RX mode...\n");
//        tmos_set_event(taskID, SBP_RF_CHANNEL_HOP_RX_EVT);   // 设置 RF 状态为接收,开启接收(执行此任务是还未跳频,只是在握手阶段)
//    }
    RF_Wait_Rx_End();
    { // TX mode
        PRINT("TX mode...\n");                              
        tmos_set_event(taskID, SBP_RF_CHANNEL_HOP_TX_EVT);     //设置 RF 状态为发送,开启发送(执行此任务是还未跳频,只是在握手阶段)
    }
}

 二.发送端握手阶段

    // 开启发送握手包
    if(events & SBP_RF_CHANNEL_HOP_TX_EVT)
    {
        PRINT("\n------------- hop tx...\n");
        if(RF_FrequencyHoppingTx(16))                                         //发送握手包,一次发送16包
        {
            tmos_start_task(taskID, SBP_RF_CHANNEL_HOP_TX_EVT, 100);          //握手失败,62.5ms后再次发送握手包
        }
        else
        {
            tmos_start_task(taskID, SBP_RF_PERIODIC_EVT, 1000);               //握手成功,625ms后开始跳频发送
        }
        return events ^ SBP_RF_CHANNEL_HOP_TX_EVT;
    }

三.接收握手包阶段

    // 开启接收握手包
    if(events & SBP_RF_CHANNEL_HOP_RX_EVT)
    {
        PRINT("hop rx...\n");
        if(RF_FrequencyHoppingRx(200))                                    //开始接收握手包,200ms超时
        {
            tmos_start_task(taskID, SBP_RF_CHANNEL_HOP_RX_EVT, 400);      //未收到握手包,250ms后再次开启接收
        }
        else
        {

            rx_end_flag = FALSE;
            RF_Rx(TX_DATA, 10, 0xFF, 0xFF);                               //握手成功,开启 RF 跳频接收
        }
        return events ^ SBP_RF_CHANNEL_HOP_RX_EVT;
    }

 四.发送端发送数据填充

    if(events & SBP_RF_PERIODIC_EVT)
    {
        RF_Shut();                                            //调用模式前先 SHUT
        TX_DATA[0]--;                                         //将发送数据的首字节-1
        tx_end_flag = FALSE;
        if(!RF_Tx(TX_DATA, 10, 0xFF, 0xFF))                   //发送10字节数据
        {
            RF_Wait_Tx_End();
        }
        tmos_start_task(taskID, SBP_RF_PERIODIC_EVT, 1000);   //625ms后再次发送
        return events ^ SBP_RF_PERIODIC_EVT;
    }

五.接收端 ack 数据填充

    if(events & SBP_RF_RF_RX_EVT)
    {
        uint8_t state;
        RF_Shut();                                        //在调用模式前先 SHUT
        TX_DATA[0]++;                                     //将回复的ack数据首字节+1
        rx_end_flag = FALSE;
        state = RF_Rx(TX_DATA, 10, 0xFF, 0xFF);           //配置成接收状态并填充回复的ack数据
        return events ^ SBP_RF_RF_RX_EVT;
    }

六.回调函数获取数据

void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
{
    switch(sta)
    {
        case TX_MODE_TX_FINISH:                                        //发送完成
        {
            break;
        }
        case TX_MODE_TX_FAIL:                                          //发送失败
        {
            tx_end_flag = TRUE;
            break;
        }
        case TX_MODE_RX_DATA:                                          //发送端收到ack数据
        {
            tx_end_flag = TRUE;
            if (crc == 0) {
                uint8_t i;

                PRINT("tx recv,rssi:%d\n", (int8_t)rxBuf[0]);
                PRINT("len:%d-", rxBuf[1]);

                for (i = 0; i < rxBuf[1]; i++) {
                    PRINT("%x ", rxBuf[i + 2]);
                }
                PRINT("\n");
            } else {
                if (crc & (1<<0)) {
                    PRINT("crc error\n");
                }

                if (crc & (1<<1)) {
                    PRINT("match type error\n");
                }
            }
            break;
        }
        case TX_MODE_RX_TIMEOUT: // Timeout is about 200us               //发送端接收超时
        {
            tx_end_flag = TRUE;
            break;
        }
        case TX_MODE_HOP_SHUT:                                           //发送端 HOP 跳频断开
        {
            tx_end_flag = TRUE;
            PRINT("TX_MODE_HOP_SHUT...\n");
            tmos_set_event(taskID, SBP_RF_CHANNEL_HOP_TX_EVT);           //重新开始发送握手包
            break;
        }

        case RX_MODE_RX_DATA:                                            //接收端接收的数据
        {
            if (crc == 0) {
                uint8_t i;

                RF_Wait_Rx_End();
                PRINT("rx recv, rssi: %d\n", (int8_t)rxBuf[0]);
                PRINT("len:%d-", rxBuf[1]);
                
                for (i = 0; i < rxBuf[1]; i++) {
                    PRINT("%x ", rxBuf[i + 2]);
                }
                PRINT("\n");
            } else {
                if (crc & (1<<0)) {
                    PRINT("crc error\n");
                }

                if (crc & (1<<1)) {
                    PRINT("match type error\n");
                }
            }
            tmos_set_event(taskID, SBP_RF_RF_RX_EVT);                     //接收到数据后再次开启接收
            break;
        }
        case RX_MODE_TX_FINISH:                                           //接收端回复ack结束
        {
            rx_end_flag = TRUE;
            break;
        }
        case RX_MODE_TX_FAIL:                                             //接收端回复ack失败
        {
            rx_end_flag = TRUE;
            break;
        }
        case RX_MODE_HOP_SHUT:                                            //接收端 HOP 跳频断开
        {
            PRINT("RX_MODE_HOP_SHUT...\n");
            rx_end_flag = TRUE;
            tmos_set_event(taskID, SBP_RF_CHANNEL_HOP_RX_EVT);            //开启接收握手包
            break;
        }
    }
}

七.开发注意点:

1.RF跳频例程和蓝牙主从通信类似,默认是开启配对绑定的,如A和B建立跳频通信后会存在对方的mac地址,此时若有另一对C和D是不可以和A和B之间通信的,将配对绑定信息删除后可以进行通信,只要有一方没有配对绑定信息即可。

若不想配对绑定可以通过此宏配置:#ifndef BLE_SNV
#define BLE_SNV                             TRUE   //TRUE开启,FALSE关闭
#endif

删除配对绑定接口:RF_BondingErase();

posted on 2025-12-31 15:22  WCH蓝牙应用分享  阅读(0)  评论(0)    收藏  举报