沁恒 RISC-V 蓝牙芯片 2.4G 基础示例说明

复制代码
说明一下沁恒 2.4G RF_Basic  示例  ...... 矜辰所致

前言

在我们使用蓝牙芯片的时候,2.4G 与 蓝牙使用的是同一套射频硬件,有时候遇到一些不同的应用场合:比如要求延迟极低(8K回报率键鼠),MCU 资源占用要尽可能小(节约内存空间),或是需要高度自定义通信逻辑。 这时我们可以不运行完整蓝牙协议栈,直接操控底层射频硬件,使用私有 2.4G 来实现无线通信功能。

沁恒提供了 2.4GRF 的库,在 EVT 中提供了几个 2.4G 的例程。

本文我们来看看其中 RF 基础例程 RF_basic 。

我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • [一、 基础介绍](#一、 基础介绍)
    • [1.1 私有2.4G 与蓝牙比较](#1.1 私有2.4G 与蓝牙比较)
    • [1.2 推荐使用场景](#1.2 推荐使用场景)
  • [二、 例程说明](#二、 例程说明)
    • [2.1 测试效果](#2.1 测试效果)
      • [2.1.1 无应答收发](#2.1.1 无应答收发)
      • [2.1.2 应答收发](#2.1.2 应答收发)
    • [2.2 例程分析(BLE 分析仪)](#2.2 例程分析(BLE 分析仪))
      • [2.2.1 代码解析](#2.2.1 代码解析)
      • [2.2.2 分析仪抓包解析](#2.2.2 分析仪抓包解析)
      • [2.2.3 数据格式说明](#2.2.3 数据格式说明)
  • 三、一些使用说明
  • 四、典型应用
    • [4.1 模拟蓝牙广播](#4.1 模拟蓝牙广播)
    • [4.2 接收蓝牙广播](#4.2 接收蓝牙广播)
  • 结语

一、 基础介绍

1.1 私有2.4G 与蓝牙比较

2.4G 与 蓝牙基本区别,我们用一个表格简单介绍,不太熟悉的小伙伴依旧可以去问 AI,这些基础的概念介绍 AI 还是靠谱的 。

对比项 私有 2.4G(裸 RF) BLE 蓝牙
通信延迟 可达几百 μs,时序完全可控 连接间隔最小 7.5ms,广播间隔最小 20ms,受协议栈约束
MCU 资源 Flash/RAM 占用极小,几百字节 RAM 即可工作 协议栈开销大,需几 KB~十几 KB RAM、数十上百 KB Flash
协议自由度 极高:信道、包长、同步字、ACK、重传全部自定义 严格遵循 Core Spec,PDU、GATT、广播参数被规范限制
跳频策略 可自己实现,也可固定单信道 广播态 :固定 37/38/39 信道; 连接态:强制自适应跳频
数据包开销 头部开销少,有效载荷占比高(可达 90%+) 存在 PDU、MIC(加密时)、ATT 等固定协议开销
设备兼容性 仅自家收发设备互通,无法直连手机/平板 原生支持手机/电脑/平板,标准设备互相兼容
系统兼容性 无 OS 兼容问题,行为完全由代码决定 iOS/安卓扫描限制、GATT 缓存、连接参数被主机拒绝等
设备发现与配对 全部需要自己手写实现 协议栈自带广播扫描、配对、绑定、加密(AES-CCM)
休眠低功耗 休眠唤醒逻辑全部自行开发 协议栈内置成熟的广播/连接休眠机制
抗干扰能力 固定信道易受 Wi-Fi/微波炉干扰,需自行处理 AFH 跳频自动避开干扰信道,抗干扰能力更强
开发周期 长:射频、时序、协议、加密全部自己搭 短:调用协议栈 API 即可,生态成熟
认证成本 无需BQB认证,成本低 需 BQB 认证(费用较高),否则不能打蓝牙商标
传输速率 自定义,可做到很高(如 2Mbps+)或很低 标准速率:1M / 2M / 500K / 125K(LE Coded)

1.2 推荐使用场景

选私有 2.4G:

  • 追求极低延迟(8K 鼠标、游戏手柄、模型遥控)
  • MCU 资源极其紧张(几 KB Flash 都嫌多)
  • 需要高度自定义包格式、收发时序、重传、ACK 策略
  • 设备间点对点/多点组网,不需要对接手机/电脑
  • 需要固定信道做射频测试或特定场景通信
  • 不想交 BQB 认证费,快速出货

选 BLE:

  • 需要设备直连手机、平板、电脑,不想配 Dongle
  • 需要现成配对、安全加密、设备发现,不想手写上层逻辑
  • 使用标准 HID、电池、心率等 GATT Profile,追求跨厂商互通
  • 需要快速开发上市,利用成熟协议栈
  • 对抗 Wi-Fi 干扰有要求,需要 AFH 跳频

二、 例程说明

本文以 CH585 为例说明,例程位置如下:

RF_Basic 为 2.4G 库中的基础模式,提供 RF 收发接口函数,相关参数配置接口,便于扩展各种应用,可依据此模式进行自主开发。

2.1 测试效果

在示例 RF_basic.c 文件最上面,有一些宏定义, 通过宏定义可以配置为基础收发,带 ACK 的收发等不同模式 。

2.1.1 无应答收发

我们做基本测试是需要烧录 2 个设备,一个作为发送端,一个作为接收端 ,默认是无应答收发,我们只需要例程里面注意下面两个宏定义,分别烧录2个设备即可测试,如下图:

两个设备通过串口都可以看到 Debug 信息,分别会打印接收到的包数,与发送的包数,这个示例的串口波特率为 921600 ,如下图:

2.1.2 应答收发

只需要把宏定义 WAIT_ACK 改为 1 ,测试效果如下,打印的数据依然和上面一样:每秒发送的包数,每秒接收的包数,收到报文的 RSSI 值 ,因为发送端需要接收 ACK ,接收端需要发送 ACK ,所以两端都有收发:

c 复制代码
#define  WAIT_ACK         1               // 是否使能ACK

别看感觉好多错误,这是每秒的数据,每秒发将近 4000 条报文,丢几条也算是正常的。

上面是示例展示的使用效果,对于示例其实也是很简单的,因为官方提供给了我们库,我们只需要学会配置和函数的使用,就可以进行 2.4G 收发的应用了,我们下面来说明一下。

2.2 例程分析(BLE 分析仪)

2.2.1 代码解析

对于 2.4G 通信,有 5 项核心配置:

  • accessAddress :接入地址
  • crcInit :CRC 校验种子
  • frequency :载波频点
  • PHY 速率
  • Whitening :数据白化开关

上面的 5 项参数一致是 PHY 层通信的必要条件。

这里推荐一篇大佬的文章,文章对 RF_basic 主要代码做了详细的注释:

https://www.cnblogs.com/azou/p/18776980

代码解析参考上面文章,使用流程大家直接去看示例,因为逻辑很简单,一些注意事项与不同应用示例的应用在下文也会有说明,示例中有一个 wchrf.h 头文件,里面就是官方提供的 2.4G 库的头文件。我们主要来说明 3 个结构体:rfRoleParam_trfipTx_trfipRx_t 实际上官方注释已经很清晰了 ,这里用表格解释一下 。

首先是 rfRoleParam_t 代表着链路层的基础配置,定义了通信双方共享的物理层参数 :

字段 类型 说明
accessAddress uint32_t 接入地址,32 位 PHY 层地址。用于区分不同链路,收发双方必须一致,比如蓝牙广播的固定接入地址为 0x8E89BED6
crcInit uint32_t CRC 初始值,收发双方需一致,用于数据完整性校验。
frequency uint32_t 射频频率 ,范围 2400000~2483500 kHz(即 2.4~2.4835 GHz)。 示例中直接使用通道也可以定义 0~39 (如果使用0~39赋值就是按照蓝牙通道分布对应的频段进行收发的,通道0就是 2404MHz,示例赋值为16:2438MHz)
properties uint32_t 属性位域: • bit0 : 数据白化开关(0=开启,1=关闭) • bit1 : 等待 ACK 模式(0=不等待,1=等待 ACK) • bit4-5: 速率选择(00=1Mbps,01=2Mbps)
rxMaxLen uint16_t 接收数据最大长度,防止缓冲区溢出。
sendInterval uint16_t 重发间隔,单位 N×0.5μs。用于自动重传机制。
sendTime uint16_t Rx→Tx 切换时间,计算公式:(N×0.5μs) + 24μs。控制从接收状态切换到发送状态的延迟。
mapCheckCount uint8_t 信道质量检测阈值,默认 2。连续丢包达到该次数时判定信道质量差,可触发跳频。

rfipTx_t 配置发送端的行为,负责确定这次发送怎么发 :

字段 类型 说明
accessAddress uint32_t 同上,接入地址。
crcInit uint32_t 同上,CRC 初始值。
frequency uint32_t 同上,射频频率。
properties uint32_t 属性位域(比 rfRoleParam_t 多了 bit2): • bit0 : 白化开关 • bit1 : 等待 ACK(发送后是否等待接收方回 ACK) • bit2 : 白化信道来源选择(0=自动/默认,1=使用 whiteChannel 字段) • bit4-5: 速率(00=1M,01=2M)
txDMA uint32_t 发送 DMA 地址,指向待发送数据的内存地址,硬件直接 DMA 取数发送。
whiteChannel uint8_t 白化信道索引 ,当 properties bit2=1 时生效,用于指定数据白化算法的信道参数。
sendTime uint8_t Rx→Tx 切换时间,公式同上:(N×0.5μs) + 24μs。注意这里类型是 uint8_t,范围比 rfRoleParam_t 中的小。
sendCount uint16_t 重发次数 。如果开启 ACK 模式,发送未收到 ACK 时会自动重传,最多重发 sendCount 次。

rfipRx_t 配置接收端的行为,负责确定这次接收怎么收 :

字段 类型 说明
accessAddress uint32_t 同上。
crcInit uint32_t 同上。
frequency uint32_t 同上。
properties uint32_t 属性位域: • bit0 : 白化开关 • bit1 : 发送 ACK(收到数据后是否自动回复 ACK) • bit4-5 : 速率(00=1M,01=2M)
rxDMA uint32_t 接收 DMA 地址,指向接收缓冲区,硬件收到数据后通过 DMA 直接写入。
whiteChannel uint8_t 白化信道索引,配合数据白化使用。
rxMaxLen uint16_t 接收数据最大长度。
timeOut uint16_t 接收超时时间,0=无超时;非 0 时单位为 N×0.5μs。用于等待数据时的超时退出。

2.2.2 分析仪抓包解析

为了更加直观的展示 2.4G 的效果,我们可以通过蓝牙协议分析仪抓包看一下结果,分析仪的设置如下图 :

这里再说明一下虽然结构体 成员frequency 注释为 rf frequency (2400000kHz-2483500kHz) ,但是我们可以使用蓝牙频段(0~ 39)作为参数测试,使用(0~39)频段以蓝牙频段为准(37 为 2402 MHz) ,使用沁恒的分析仪目前直接选择通道即可,目前沁恒的分析仪也只能抓处于这些频段的 2.4G 包,如果使用其他的 2.4G 分析仪,需要注意一下使用此方式设置的通道对应的频段。

分析仪抓取的数据如下:

通过分析仪基本上数据怎配置,发出来的效果是怎样的都很直观,也没必要过多赘述 。

2.2.3 数据格式说明

上面的抓包结果我们已经可以看出来一些格式,对于完整的报文格式应该是如下图所示:

我们只需要设置好接入地址,然后应用中设定好自己需要的 PDU,第一个字节包头实际上可以自定义,0~ 0xFF 随意定义,第二个字节长度就比较关键,因为写了多少(长度不包括前面 包头+长度本身 两个字节),那么后面发出的数据就会多少个字节。

三、一些使用说明

  • 要达到 8K 的速率(125us 一次数据),每包的数据是有限制的。计算这个的理论基础就是:

    2M PHY:单 bit 时间 0.5μs,每个字节就是 4μs 。

    所以除了用户数据,还有前导码 2B(8μs),接入地址 4B(16μs),CRC 3B(12μs),这些就固定消耗 36μs,还需要减去硬件准备需要的时间(这里按照 5μs 算,具体以实际芯片为准),对于8K来说,还剩余 125 - 36 - 5 = 84 μs ,所以我们的 Payload 最大字节数:84 ÷ 4 = 21 字节(估算,具体以实际芯片为准)。

  • 2.4G 基础模式一次报文用户数据最大有效长度为 251, PDU 为 253 ,除去前面的包头和长度2个字节。

  • 示例中使用的是定时器 125us 一次发送,每秒 8000 条数据,实际极限数据比这个还要快一点(注意要是同等长度的数据报文),个人测试可以达到 1W条每秒(约 100 us 一条数据,数据内容长度和示例一致的情况,实际上这个测试是为了说明下面一条,告知大家怎么连续发送数据):

  • 如何连续发送数据

    就是上一条极限测试数据是怎么测试出来的,就是关闭定时器周期发送,在 RF 回调函数 RF_ProcessCallBack 中的发送完成状态里面调用发送(连续发送模式下面沁恒蓝牙分析仪抓取数据个人感觉有点异常,不影响本文说明,这里也不讨论),如下:

c 复制代码
__HIGH_CODE
void RF_ProcessCallBack( rfRole_States_t sta,uint8_t id  )
//省略......
    if( sta&RF_STATE_TX_FINISH )
    {
#if( WAIT_ACK )
        rf_rx_start( );
#endif
        gTxCount ++;
        TxBuf[0] = 0x55;
        TxBuf[1] = TEST_DATA_LEN;
        TxBuf[2]++;
        TxBuf[3] = gRssi;
        rf_tx_start( TxBuf );
    }
  • 2.4G 发送调制波数据,根据示例方式,用户可以任意设定数据(只有第二个字节长度位置有要求,它的数据决定了后面的数据长度,其他位置都数据都可以自定义)。
    发送单载波,直接调用RFIP_SingleChannel( uint8_t ch );
  • rf_tx_start 函数中,先调用了RFIP_SetTxStart( ); 函数,然后才是RFIP_SetTxParm( &gTxParam ); ,并不是写错了,是因为这里的RFIP_SetTxStart并不是立即发送的意思,它只是状态先切换到发送,最后配置都好了以后底层会自动发送。具体在上面代码解析章节推荐博文里面有提到:
  • 新的型号 CH587 有 4M 的PHY ,为了满足更快的需求,587 的 RF_Basic 在 4M 模式下面第一个字节就是长度数据(节约一个字节),这个后续有应用再来详细补充。

四、典型应用

推荐记录一些 2.4 G 的典型应用。

4.1 模拟蓝牙广播

在很多简单只需要广播,不需要连接的 Ble 简单应用中,我们可以使用 2.4G 方式实现,从而节约芯片资源(Ble 协议栈是比较大的),比如典型的 Beacon 设备。

首先我们之前讲过 BLE 广播包格式如下:

更多详细说明可参考博主之前的文章:

BLE 蓝牙空中报文格式与解析(广播包)

我们在 RF_Basic 示例基础上进行简单的修改,修改的地方如下,意思看注释:

c 复制代码
//把频点改成蓝牙广播频点 37 38 39 都可以
#define  TEST_FREQUENCY   37              // 通信频点
//把接入地址改成和蓝牙广播一致
gParm.accessAddress = 0x8E89BED6;
//使用 1M PHY,对应1个字节前导码
gParm.properties = LLE_MODE_PHY_1M;
//把发送频率放低一点,1S钟4次,这个根据实际需求来
TMR0_TimerInit( GetSysClock() / 4 );

最后就是修改广播数据了,我们通过上面推荐文章可以知道 Header 是如何解析的:

所以我们可以得知 TxBuf[0] 决定广播类型和 MAC 地址类型,TxBuf[1] 决定数据长度:

长度后面需要跟着 6 个字节的 MAC 地址,是需要计算进长度的,然后后面就按照 Ble 广播的「AD Structure」格式填写我们需要的数据,所以最终我们可以在 RF_Basic 示例中断中把数据定义为如下:

c 复制代码
__INTERRUPT
__HIGH_CODE
void TMR0_IRQHandler(void) // TMR0 定时中断
{
    if(TMR0_GetITFlag(TMR0_3_IT_CYC_END))
    {
        TMR0_ClearITFlag(TMR0_3_IT_CYC_END); // 清除中断标志
        // 初始化发送的数据
        //广播类型
        TxBuf[0] = 0x02;
        //数据长度(MAC地址长度+数据长度)
        TxBuf[1] =0x0B;
        //mac地址
        TxBuf[2] = 0x11;
        TxBuf[3] = 0x22;
        TxBuf[4] = 0x33;
        TxBuf[5] = 0x44;
        TxBuf[6] = 0x55;
        TxBuf[7] = 0x66;
        //广播数据
        TxBuf[8] = 0x05;
        TxBuf[9] = 0x09;
        TxBuf[10] = 'Q';
        TxBuf[11] = 'Z';
        TxBuf[12] = 'H';
        rf_tx_start( TxBuf );
    }
}

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

4.2 接收蓝牙广播

接收蓝牙广播博主没有实测过,因为暂时并没有遇到此类需求,这里只推荐一个前辈的文章给大家参考:

(手动防检测)https://www.cnblogs.com/gscw/p/18959562

结语

本文主要介绍说明了一下沁恒蓝牙芯片的 2.4G 基础示例 RF_Basic ,总的来说,RF_Basic 示例展示了RF 收发接口函数,相关参数配置接口的使用,用户可以根据自己的实际需求扩展各种应用。

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

相关推荐
zzc9211 年前
路由器最大传输速率测试
5g·wifi·2.4g·802.11n·双频并发·802.11ac·ac1200
zzc9211 年前
手机(电脑)与音响的蓝牙通信
智能手机·电脑·蓝牙·2.4g·ble·嗅探
daisy.skye1 年前
WIFI的SSID超长,隐藏,重复 (2.4G和5G差异)
5g·wifi·2.4g·频率·热点
清风徐来辽3 年前
Android 蓝牙广播
蓝牙广播
宇凡微3 年前
宇凡微2.4g遥控船开发方案,采用合封芯片
电脑·2.4g