【WCH蓝牙系列芯片】-基于CH592开发板—RF_PHY2.4G带答复回应的收发数据过程

------------------------------------------------------------------------------------------------------------------------------------ 

  在CH592芯片基础上,可以只跑2.4GRF_PHY程序,这一部分在例程中也有体现,这次在RF_PHY非标准无线收发例程中进行修改,修成带判断数据接收是否正确的应答机制的收发数据过程。这样在发送端如果给接收端一直发送数据,如何发送的数据不是接收端想要的数据,就可以不做回应,但是发送数据是接收端想要的数据,就得发送数据作为应答包发给发送端。

一、先看发送端程序修改:

  在初始化中,将模式改为LLE_MODE_BASIC基础模式,这样可以切换接收数据和发送数据的状态,设置发射数据的任务事件。

image

image

在任务事件中,先发送一遍正确数据,第二次发射一遍错误数据,这样可以达到测试效果

if(events & SBP_RF_PERIODIC_EVT)
    {
        static uint8_t send_count = 0;
        const uint8_t target_data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; // 正确数据
        const uint8_t wrong_data[10]  = {0, 2, 3, 4, 5, 6, 7, 8, 9, 0}; // 错误数据

        RF_Shut();
        tx_end_flag = FALSE;

        // 交替发送正确和错误数据,测试效果
        if(send_count == 0) {
            tmos_memcpy(TX_DATA, target_data, 10);
            PRINT("\n[TX] Sending Correct Data...\n");
        } else {
            tmos_memcpy(TX_DATA, wrong_data, 10);
            PRINT("\n[TX] Sending Wrong Data...\n");
        }
        send_count = !send_count;

        //发射数据
        if(!RF_Tx(TX_DATA, 10, 0xFF, 0xFF)) {
            RF_Wait_Tx_End(); // 阻塞等待发射完成
        }

        //发射完毕,立刻切换为接收模式,重新等待 RX 端的应答!
        RF_Shut();
        RF_Rx(txRecvBuf, 10, 0xFF, 0xFF);

        //开启一个 10ms 的超时定时器
        // 给 RX 端留出 10 毫秒的时间去运行代码和发回执
        tmos_start_task(taskID, SBP_RF_TX_ACK_TIMEOUT_EVT, 16);

        //重新启动 5000ms 后的下一次发送
        tmos_start_task(taskID, SBP_RF_PERIODIC_EVT, 1600*5);

        return events ^ SBP_RF_PERIODIC_EVT;
    }

在接收接收数据模式下,先将接收到的应答数据包拷贝出来,然后设置循环接收应答数据的任务事件

image

    // ==========================================
    // 处理收到 RX 应答的事件
    // ==========================================
    if(events & SBP_RF_TX_ACK_RECV_EVT)
    {
        uint8_t i; // 定义循环变量
        // 成功收到了 RX 端的回包,停止超时定时器!
        tmos_stop_task(taskID, SBP_RF_TX_ACK_TIMEOUT_EVT);
        RF_Shut(); // 收到应答了,关闭射频模块省电了
        PRINT("[TX] >>> RX Match SUCCESS! ACK Data: ");
        // 使用 for 循环将 txRecvBuf 里的 10 个字节全部打印出来
        for (i = 0; i < 10; i++)
        {
            PRINT("%02x ", txRecvBuf[i]);
        }
        PRINT("\n"); // 打印完换行

        return events ^ SBP_RF_TX_ACK_RECV_EVT;
    }

  二、接收端程序处理:

  在RF_Init初始中,还是把模式改为LLE_MODE_BASIC,方便收发数据切换,然后直接调用RF_Rx(rx_mode_tx_data, 10, 0xFF, 0xFF)来接收数据。只要包类型和地址匹配,就收下数据

image

image

  在接收模式中接收数据,将接收到的数据全部拷贝到tempRxBuf中,然后进行SBP_RF_RF_RX_EVT任务事件,进行数据的判断。

    if(events & SBP_RF_RF_RX_EVT)
    {
        uint8_t state;
        RF_Shut(); // 必须先关闭当前 RF 状态
    // 匹配目标数据
    uint8_t target[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

    // 判断数据是否匹配
    if (tmos_memcmp(tempRxBuf, target, 10))
    {
        uint8_t i; // 声明循环变量
        // ==========================================
        // 匹配成功:主动发送应答包给 TX
        // ==========================================
        PRINT("Match OK! Sending ACK to TX...\n");
        //将匹配成功的接收数据完整打印出来
        PRINT("Matched Data: ");
        for(i = 0; i < 10; i++)
        {
            PRINT("%02x ", tempRxBuf[i]);
        }
        PRINT("\n");
        tx_end_flag = FALSE;

        //  ackData 就是回给 TX 端的数据
        if(!RF_Tx(ackData, 10, 0xFF, 0xFF))
        {
            RF_Wait_Tx_End(); // 阻塞等待发送完成
        }
        // 发送完成后,清空 tempRxBuf 防止下次误判
        tmos_memset(tempRxBuf, 0, 10);
    }
    else
    {
        // ==========================================
        // 匹配失败:什么都不做
        // ==========================================
        PRINT("Match Failed! Keep silent.\n");
    }
    //无论刚才发没发应答,最后都必须重新开启接收!
    RF_Shut(); // 切换模式前先 Shut
    // 重新进入接收模式,等待空中的下一个数据包
    state = RF_Rx(rx_mode_tx_data, 10, 0xFF, 0xFF);
    PRINT("Restart RX listening, state = %x\n", state);
    return events ^ SBP_RF_RF_RX_EVT;
}

  通过对比目标的数据,如果匹配成功,就发送应答数据给发送端(TX),如果匹配失败之后,就什么都不操作,输一个日志打印。这一轮结束之后,就直接调用 RF_Shut();切换模式,重新进入接收模式,等待空中的下一个数据包接收。

image

  可以通过串口打印可以看到,如果成功匹配到发送的目标数据,接收端就会收到应答数据,如果匹配不成功,那就会出现超时状态,不会有应答状态。

 

 

 

posted on 2026-04-30 22:40  凡仕  阅读(23)  评论(0)    收藏  举报