news 2026/9/2 21:50:35

沁恒 RISC-V 蓝牙 2.4G RF_PHY 示例说明

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
沁恒 RISC-V 蓝牙 2.4G RF_PHY 示例说明
说明一下沁恒 2.4G RF_PHY 示例 ...... 矜辰所致

前言

在之前我们了解了 蓝牙与 2.4G 的关系 以及学习了沁恒 RISC-V 蓝牙芯片 2.4G 的基础应用,在官方的 EVT 例程里面,还提供了一个名为 RF_PHY 的例程,官方取名为:非标准无线收发例程 。

本文我们主要就是来了解一下这个 RF_PHY 例程以及它的一些实际应用。

沁恒 RISC-V 蓝牙 入门教程专栏目录:
【导航】沁恒 RISC-V 蓝牙 入门教程目录 【快速跳转】
相关博文:
沁恒 RISC-V 蓝牙芯片 2.4G 基础示例说明
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、与 RF_Basic 区别
  • 二、示例测试说明
  • 三、使用说明
    • 3.1 RF_PHY 使用流程
    • 3.2 示例逻辑说明
    • 3.3 参数配置
    • 3.4 包格式 / 收发函数说明
    • 3.5 说明事项
  • 四、常见应用
    • 4.1模拟蓝牙广播
    • 4.2 接收蓝牙广播
    • 4.3 低功耗应用
  • 结语

一、与 RF_Basic 区别

我们之前的讲过 RF_Basic 例程,它是 2.4G 基础模式,自由度更高,想怎么发,发什么,怎么接收,收不收,都可以自由控制,方便用户自行实现各种扩展应用。

本文要讲的 RF_PHY 也是一种 2.4G 收发示例,可以理解为是沁恒自己实现的一套建议的 2.4G 协议,提供底层数据发送接口函数及对收发控制的配置 。

都是 2.4G 例程,实际使用中如何选择例程?

实际使用中需要根据自己的需求选择用哪个例程,RF_PHY 作为沁恒提供的私有协议例程,代码框架和 Ble 应用框架一致,使用 TMOS 管理,如果熟悉了沁恒 Ble 蓝牙的开发,可以很方便的实现应用逻辑,以及低功耗管理,同时也可以和 Ble 同时存在(分时复用)。 而且官方还提供了可跳频收发的 RF_PHY_Hop 例程。

如果 RF_PHY 无法满足应用需求,可以选择自由度更高的 RF_Basic 进行自主开发,当然自由度高意味着需要自己实现的东西更多,大家自己衡量。

二、示例测试说明

示例测试相对来说是简单的,因为是现成的代码,但是我们依然可以通过 BLE 分析仪抓 2.4G 的包,让我们更快的理解如何应用,同时博主会进行一些简单的修改,让大家更加理解这个流程。

示例如下(本文以 CH592 为例,CH58x 是一样的):

与之前的基础示例一样,示例是接收端和发送端一体的,通过注释下面代码切换:

我们在原始示例上不做修改,编译烧录,就是发送端,我们如果通过串口助手观察,它只会停留在开头的打印:

但实际上它还是在周期的发送数据,我们通过 BLE 分析仪可以抓到发送端的数据包,分析仪设置如下(分析仪设置参考示例中的配置,可参考《 沁恒 RISC-V 蓝牙芯片 2.4G 基础示例说明》 一文):

通过看图很好理解,我们有一个发送端,在我们设置的频点周期发送我们设置的数据。这里还可以给大家说明一下,示例中有一个宏定义 :

#defineRF_AUTO_MODE_EXAM1

示例中通过这个宏定义为 0 或者 非 0,可以切换设备的工作模式:

  • 基础模式(发完不需要接收 ACK )
    发完就可以休眠,不保证对面能不能收到。
  • 自动模式(发送完需要接收 ACK 响应)
    自动模式下的发送端:发完会自动进入接收模式,去接收 接收端收到数据以后返回的 ACK 报文。
    自动模式下的接收端:接收完以后会切到发送模式,返回 ACK 。
    (更详细的说明会在下面一个章节 使用说明 里面描述)

我们观察到默认为自动模式的,所以我们发送端应该是每次发送完数据以后,会去接收数据,但是目前我们并没有接收端,设备会在回调函数RF_2G4StatusCallBack中进入TX_MODE_RX_TIMEOUT状态,我们可以在这里做个简单的测试:

这样的话,没有接收端,我们应该可以看到我们发射端周期打印 test 数据,如下图所示:

刚才的是额外的测试,我们再用一个设备,把代码里面 TX mode 部分注销掉, RX mode 部分放出来,烧录以后,两个设备一起观察:

同时我们的 BLE 分析仪也可以抓到 ACK 消息:

上面就是示例使用自动模式收发的效果展示,如果了解了自动模式,基础模式就太简单了,这里不多余测试,下面我们就来说说收发函数的使用相关以及示例的一个逻辑流程。

三、使用说明

基于 RF_PHY 示例介绍一下 2.4G 私有协议的使用步骤以及一些注意事项。

3.1 RF_PHY 使用流程

要使用 RF_PHY 首先在初始化的时候需要调用RF_RoleInit()

CH59x_BLEInit();HAL_Init();RF_RoleInit();

然后就是RF_Config配置,配置根据示例来进行即可,下文也会有详细说明。

RF_Config(&rf_Config);

配置完成以后就可以根据自己的应用逻辑进行收发。

发送/接收端 完成/失败/超时等状态都会返回到回调函数,后续操作都可以在回调函数中处理,但是需要注意,回调函数为中断回调,需要快进快出,不要在这个回调函数中调用 RF 接收或者发送 API ,可以参考示例,修改标志位,使用 TMOS 事件方式调用自己需要的操作。

TMOS 的使用请参考博主之前的博文:沁恒微 蓝牙 芯片 TMOS 使用

回调函数在初始化的时候注册:

rf_Config.rfStatusCB=RF_2G4StatusCallBack;//...state=RF_Config(&rf_Config);

回调函数中使用 TMOS 创建需要后续进行的事件:

caseRX_MODE_TX_FAIL:{#if(RF_AUTO_MODE_EXAM)rx_end_flag=TRUE;tmos_set_event(taskID,SBP_RF_RF_RX_EVT);#endifbreak;}

与 RF_PHY 有关的 API 函数在库函数CH59xBLE_LIB.h中 :

函数详细注释大家自行查看 EVT :externbStatus_tRF_RoleInit(void);externbStatus_tRF_Config(rfConfig_t*pConfig);externbStatus_tRF_Rx(uint8_t*txBuf,uint8_ttxLen,uint8_tpktRxType,uint8_tpktTxType);externbStatus_tRF_Tx(uint8_t*txBuf,uint8_ttxLen,uint8_tpktTxType,uint8_tpktRxType);//shut down,stop tx/rx mode.externbStatus_tRF_Shut(void);// rf mode set radio channel/frequency.externvoidRF_SetChannel(uint32_tchannel);//rf mode set radio frequency and whitening channel index//note: LLEMode bit6 set 1externbStatus_tRF_SetFrequency(uint32_tfrequency,uint8_tch);

3.2 示例逻辑说明

与 RF_Basic 定时器里面发送不一样,RF_PHY 示例使用的 TMOS 事件进行周期发送,并且 Auto 模式发送完成以后设备会自动进入接收状态,无需应用层干预。

下面使用两个流程图来说明一下示例的流程。

首先是 RF_PHY 发送端(Auto 模式):

然后是 RF_PHY 接收端(加入了是否为 Auto 模式判断):

3.3 参数配置

参数配置 就是一个结构体成员rfConfig_t,里面有一些在讲 RF_Basic 的时候都讲过,这里我们直接在上一张图片说明,如下:

Channel 和 Frequency 说明

在配置中既有 Channel ,又有 Frequency ,其中使用哪个与 LLEMode 的 BIT6 有关:

  • 当 LLEMode 的 BIT6 为 1 的时候,表示选择 Frequency 作为通讯频点,精确到 1KHz 。
  • 当 LLEMode 的 BIT6 为 0 的时候,表示选择 Channel 作为通讯频点,此时的 Channel 对于蓝牙规范的 0~ 39 信道,2MHz 一个信道。

另外,关于跳频详细点的说明如下图:

参数的配置大家可参考文章,上图来自此文章:https://www.cnblogs.com/JayWellsBlog/p/18302685

3.4 包格式 / 收发函数说明

先了解一下 RF_PHY 的数据包格式,如下:

然后看一下发送函数官方解释如下:

/** * @brief tx mode. * * @param txBuf - tx mode tx data * @param txLen - tx mode tx length(0-251) * @param pktTxType - tx mode tx package type * broadcast type(0xFF):received by all matching types; * others:only received by matching type * @param pktRxType - tx mode rx package type(auto mode) * broadcast type(0xFF):receive all matching types, * others:receive match type or broadcast type * * @return 0 - success. 1-access address error 2-busy */externbStatus_tRF_Tx(uint8_t*txBuf,uint8_ttxLen,uint8_tpktTxType,uint8_tpktRxType);

对于发送函数:

  1. 第一个参数是 发送端 发送的数据;
  2. 第二个参数是 发送端 发送的长度:
  3. 第三个参数是 发送端 发送的包头,当为 0XFF 的时候表示我是广播状态,谁都可以收;
  4. 第四个参数是 发送端 接收的包头,就是表示发送端在自动模式下面想要接收的 ACK 的包头,如果 ACK 返回的报文,包头不是自己设定的,就不接收,0XFF 表示接收所有包头的 ACK 。
bStatus_tRF_Rx(uint8_t*txBuf,uint8_ttxLen,uint8_tpktRxType,uint8_tpktTxType);

同理,对于接收函数:

  1. 第一个参数是 接收端 准备要发送的数据;
    在 Auto 模式下面,接收端必须在接收到数据之前把 ACK 数据准备好,射频模块一旦收到一包 CRC 正确的数据,硬件自动把 FIFO 里的这段数据作为 ACK 回发出去;CPU 根本来不及再临时准备。
    所以这个数据是准备要回复的 ACK 数据。
  2. 第二个参数是 接收端 发送的长度(ACK 的长度):
  3. 第三个参数是 接收端 想要接收的包头,当为 0XFF 的时候表示我什么包都想收;其他时候只收和我设置的一样的包头。
  4. 第四个参数是 接收端 回 ACK 发送的包头。
  5. 调用了接收函数,芯片就会进入接收状态,只要不是人为的停止或者进入休眠,那么芯片就一直在接收状态,一直在等待着报文的到来。

对于收发函数,我们可以通过简单的修改看一下实际效果。

首先改一下发送函数,发送包头改成 0xAA,想要接收的包头改成 0XBB:

if(!RF_Tx(TX_DATA,10,0xAA,0xBB))

我们通过分析仪抓到的发送包如下:

然后我们如果接收端不做任何修改,RF_Rx 后两个参数为 0xFF 0XFF,可接收任意包头的消息,回的 ACK 包头为 0xFF,我们可以推测出这个现象,就是接收端可以收到发送端的数据,但是发送端收不到 ACK 数据(因为发送端限制了 ACK 只收 包头为 0XBB 的数据)。

测试的现象如下图,在示例基础上加了发送端接收 ACK 超时打印(接收端可以接收,发射端无法收到 ACK):

在上面修改发射端的前提下,如果我们想收发正常,我们可以把接收端的,参数改成 0xFF 0xBB,或者 0xAA, 0XBB:

state=RF_Rx(TX_DATA,10,0xFF,0xBB);

测试效果如下:

OK,通过这个测试我们可以更加理解收发函数,能让我们在后面应用合理恰当的使用这两个函数。

3.5 说明事项

一些使用中需要注意的事项说明(持续更新):

  • 自动模式下面需要提前准备好 ACK 的数据,就是上面收发函数说明章节彩色字体提到的。

  • 调用接收函数以后,只要没有进入休眠,芯片处于持续接收的状态,只要没有接收到数据,它会一直处于接收状态。它是一种状态,并不是一个瞬时的动作。

  • 在示例里面有两个等待函数:
    RF_Wait_Tx_End手动模式等待发送完成,自动模式等待发送-接收完成
    RF_Wait_Rx_End自动模式等待应答发送完成
    都是等待接近 5ms 左右的时间,此时可以做一些应用层面的事情,实际上我简单测试,不加这个等待也是可以的,这个看大家实际使用中的处理,通过功耗仪器可以看到这个等待时间:

  • 关于低功耗
    因为使用 TMOS 管理,我们可以和蓝牙一样,定义HAL_SLEEP= 1,让 TMOS 自动管理休眠。
    示例开启睡眠的测试效果如下:

四、常见应用

通过上面介绍,我们应该对 RF_PHY 有了全面的认识,这里列举几个常见应用示例,示例列举的时候就不做过多的分析说明了,不懂的小伙伴得好好看看前文咯。

4.1模拟蓝牙广播

我们在 RF_PHY 示例基础上进行简单的修改(自己找到代码中对应的点去修改):

#defineRF_AUTO_MODE_EXAM0uint8_tTX_DATA[]={0x11,0x22,0x33,0x44,0x55,0x66,//MAC 地址0x05,0x09,'Q','Z','H'//广播名字};if(events&SBP_RF_PERIODIC_EVT){RF_Shut();tx_end_flag=FALSE;RF_Tx(TX_DATA,sizeof(TX_DATA),0x02,0xFF);tmos_start_task(taskID,SBP_RF_PERIODIC_EVT,1000);returnevents^SBP_RF_PERIODIC_EVT;}voidRF_Init(void){uint8_tstate;rfConfig_trf_Config;tmos_memset(&rf_Config,0,sizeof(rfConfig_t));taskID=TMOS_ProcessEventRegister(RF_ProcessEvent);rf_Config.accessAddress=0x8E89BED6;// 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 )rf_Config.CRCInit=0x555555;rf_Config.Channel=37;rf_Config.Frequency=2402000;#if(RF_AUTO_MODE_EXAM)rf_Config.LLEMode=LLE_MODE_AUTO;#elserf_Config.LLEMode=LLE_MODE_BASIC;// 使能 LLE_MODE_EX_CHANNEL 表示 选择 rf_Config.Frequency 作为通信频点#endifrf_Config.rfStatusCB=RF_2G4StatusCallBack;rf_Config.RxMaxlen=251;state=RF_Config(&rf_Config);PRINT("rf 2.4g init: %x\n",state);//...

就可以得到一个名称为 ”QZH“ ,MAC地址为66:55:44:33:22:11 的 蓝牙广播设备,通过 BLE 调试助手扫描结果如图:

4.2 接收蓝牙广播

接收的设置和发送初始化设置一样,只是接收的数据处理是在 中断回调函数的RX_MODE_RX_DATA中处理的。 这里给大家推荐一篇实现接收蓝牙广播的文章,大家自行参考:

https://www.cnblogs.com/good-fs/p/19813022

4.3 低功耗应用

低功耗和 BLE 一样,定义宏定义HAL_SLEEP= 1,交给 TMOS 管理,没有任务执行的时候自动进入休眠:

对于发送端来说,什么时候发,都是应用层自主控制的,所以发送端的低功耗使能低功耗宏定义,就已经能做到低功耗了,示例使能低功耗后发送端的测试效果如下(就是上文说明事项里面关于低功耗提到的):

可以看到博主测试的芯片,休眠电流在 2.2uA 左右,实际平均功耗主要看发送频率,和 BLE 是一样的,当然示例里面应该还可以去掉 4.5ms 的延时进一步降低平均功耗。

接收端低功耗

对于接收端低功耗,因为他并不知道数据什么时候会来,但是为了低功耗又不能一直开着接收,所以在实际应用中,一般的实现方式就是一段时间内开启一次接收窗口。

打个比方,每1秒钟,开启 50ms 的接收,这样就可以保证低功耗。

但是采用这种方式,对发送端也是有要求的,每次发送,不可能是发送完一包或者2包就停止,为了保证通信的稳定性,发送端每次连续发送的时间,应该是需要大于 1 秒钟,保证接收端能够收到数据。

当然要注意,上面是提供的一个实际应用的处理思路。其中接收端的时间窗口与唤醒时间,发送端的持续发送时间都需要结合实际的环境,包长度,等细节进行合理调整。

结语

本文我们说明了一下 RF_PHY 例程以及实际场合下的一些应用示例,大家在使用的时候可以根据自己的实际需求选择使用 RF_PHY 还是 RF_Basic 例程进行扩展开发。

好了,本文就到这里。谢谢大家!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 21:48:25

用VC打造自己的串口调试工具ComTest:从底层通信到协议解析

简介:ComTest串口调试工具是基于VC编写的完整串口通信工程,面向硬件开发、嵌入式系统调试及物联网设备测试等场景,解决RS-232标准下串口通信中数据接收、发送与稳定性检查的实际问题。压缩包为RAR格式,共18个文件,以h头…

作者头像 李华
网站建设 2026/9/2 21:48:14

天猫精灵CC10实测:从配网到智能家居联动的完整指南

带屏智能音箱用过不少,但把“睡前陪伴”这件事做到体验完整的,天猫精灵 CC10 算一个。它不只是一个能回答问题的语音助手,而是一个放在床头柜上的家庭信息屏:晚上睡觉前听播客、设闹钟、关灯、调空调,白天还能拿来追剧…

作者头像 李华
网站建设 2026/9/2 21:47:47

带屏智能音箱的实用价值:从睡前助眠到智能家居场景联动

最近几年,「带屏智能音箱到底是不是伪需求」这个问题,一直在数码爱好者圈子里反复被讨论。有人说它是“买前觉得多余,买后离不开”的床头神器;也有人觉得它就是一块变大了的智能音箱屏幕,新鲜感过了就吃灰。抛开争论不…

作者头像 李华
网站建设 2026/9/2 21:43:33

天猫精灵技能开发实战:从零构建“欧皇之堡”语音应用

立秋刚过,朋友圈满屏都是“秋天的第一杯奶茶”。不过咱们程序员要玩就玩点不一样的——别人喝奶茶,我们来写一个“秋天的第一个堡堡”!这篇文章要分享的不是奶茶,而是天猫精灵上的一个智能语音技能——“欧皇之堡”的完整开发实战…

作者头像 李华
网站建设 2026/9/2 21:43:00

Python实现新闻资讯聚合系统:RSS抓取、智能去重与实时推送实战

ABC晚间新闻类资讯聚合系统开发实战:RSS抓取、去重分类与实时推送如果你做过新闻资讯类 App、天气预警小程序或者企业内部情报监控系统,大概率会被同一件事折磨过:信源太多、格式太乱、重复内容太多、时效性又强。尤其是“晚间新闻”这类多主…

作者头像 李华
网站建设 2026/9/2 21:40:36

格聂牧场高海拔徒步攻略:天气、装备与安全准备指南

之前看过不少格聂牧场和格聂神山方向的徒步视频,画面里是夏季草甸、花海、雪山和成群的牦牛,确实很让人心动。但真正到自己准备出发时,才会发现这类高海拔徒步路线和城市周边爬山完全是两码事。尤其是看到“花海视频为2026年7月30日&#xff…

作者头像 李华