【WCH蓝牙系列芯片】-基于CH592开发板—RF_PHY2.4G带答复回应的收发数据过程
------------------------------------------------------------------------------------------------------------------------------------
一、先看发送端程序修改:
在初始化中,将模式改为LLE_MODE_BASIC基础模式,这样可以切换接收数据和发送数据的状态,设置发射数据的任务事件。


在任务事件中,先发送一遍正确数据,第二次发射一遍错误数据,这样可以达到测试效果
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; }
在接收接收数据模式下,先将接收到的应答数据包拷贝出来,然后设置循环接收应答数据的任务事件

// ========================================== // 处理收到 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)来接收数据。只要包类型和地址匹配,就收下数据


在接收模式中接收数据,将接收到的数据全部拷贝到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();切换模式,重新进入接收模式,等待空中的下一个数据包接收。

浙公网安备 33010602011771号