CC1101之数据封包格式(Data Packet Format)

本文详细介绍了CC1101射频数据封包的构成,包括序文、同步字、数据长度、接收地址、有效数据和CRC校验位。解释了每个组件的作用及工作原理,特别强调了变长数据模式下的最大数据长度限制和数据处理策略。

CC1101的射频数据封包在发送和接收时,都遵循固定的硬件层格式,大致封包格式图如下图所示:


1、  Preamble bits:CC1101射频数据封包的第一部分:序文,实质上是一连串的010101……,最小长度由CC1101的MDMCFG1.NUM_PREAMBLE寄存器数值设置,单位是:Byte。工作机理是:当控制CC1101进入TX模式后,CC1101将首先发送序文,如果在最小长度的序文发送完之前,有数据写入到TX FIFO,那么在最小长度的序文发送完毕之后,就会不再发送序文,转而发送后面的数据。而如果一直没有数据写入到TX FIFO,那么CC1101将一直发送序文,直到有数据写入到TX FIFO 或控制CC1101退出TX模式。

2、  Sync Word:CC101射频数据封包的第二部分:同步字,用于CC1101接收端进行射频信号同步。其长度是可控的,由MDMCFG2.SYNC_MODE位进行控制,一般可用的是2或4个字节。同步字的具体数值可以通过SYNC0和SYNC1寄存器进行设置。特殊的一个字节的同步字,可通过设置其中一个同步字为:0b10101010,来模仿序文的方式实现。

 前两部分是由CC1101硬件进行调制的。

3、 Length Field:数据长度,在变长的数据模式(PKTCTRL0.LENGTH_CONFIG=1)下,该字节表示的是有效载荷(payload)的数据长度,单位:Byte。注意,有效载荷包括的范围:Address Field+Data Field两部分,其余的包括length Field和后面的CRC、RSSI、LQI部分数据都不算在里面的。在发送时,应该首先往RX FIFO中写入的就是该数据。在接收时,从RX FIFO中读出的第一个字节数据也是该数据。注意:RX FIFO中的LengthField和状态寄存器:RXBYTES(0x3B)表示的数据个数的范围和数值是不一样的。前者是接收到的数据中的有效数据,后者是指RX FIFO中所有的未读取数据,包括LengthField、Address Field、Data Field 、RSSI、CRC_OK+LQI等。在用于判断和读取RXFIFO时应尤为注意。

4、  Address Field:CC1101的芯片硬件接收地址(不同于跑协议时,软件进行判断的目的地地址和源地址),取值范围为:0-255,具体的地址可通过ADDR(0x09)寄存器来进行设置,并通过设置PKTCTRL1.ADR_CHK不为0来进行地址检测使能设置。

5、  Data Field:有效的数据,这是被CC1101接收并放入到RX FIFO中的主要数据,可供软件使用的。接收和使用该部分数据应注意两点:1、变长模式下的最大数据长度由PKT_LENGTH寄存器设置决定,如果该寄存器数值设置过小,将接收不到期望的数据。>=发送的数据长度。2、可以选择在数据末尾添加RSSI和CRC_OK+LOI信息(通过PKTCTRL1.APPEND_STATUS=1来使能),以便进行信号强度检测和CRC校验状况查询。

6、  CRC-16:CRC校验位,位于数据封包的末尾,对从Length Field开始到Data Field结尾为止的所有数据进行CRC校验。该部分数据不用用户操心,CC1101接收并校验完毕之后,会自动移除该数据的,所以该数据对用户也是不可见。CRC校验功能可通过PKTCTRL0.CRC_EN=1来使能,并可通过PKTCTRL1.CRC_AUTOFLUSH位设置来设置CRC校验失败时,对接收数据的处理策略。


要将 PCM 音频封装成 RTP 格式,你需要使用 Java 的音频处理 API。以下是一个简单的示例: ```java import javax.sound.sampled.*; import java.net.*; import java.io.*; public class AudioSender { public static void main(String[] args) throws IOException, LineUnavailableException { // 创建音频输入流 AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); TargetDataLine line = (TargetDataLine)AudioSystem.getLine(info); line.open(format); line.start(); // 创建 RTP 数据报发送套接字 InetAddress address = InetAddress.getByName("192.168.0.1"); int port = 5004; DatagramSocket socket = new DatagramSocket(); // 发送 RTP 数据报 byte[] buffer = new byte[1024]; while (true) { int count = line.read(buffer, 0, buffer.length); byte[] rtpPacket = createRtpPacket(buffer, count); DatagramPacket packet = new DatagramPacket(rtpPacket, rtpPacket.length, address, port); socket.send(packet); } } // 创建 RTP 数据报 private static byte[] createRtpPacket(byte[] data, int length) { byte[] packet = new byte[length + 12]; packet[0] = (byte)128; // 版本号和填充位 packet[1] = (byte)96; // 负载类型 packet[2] = (byte)0; // 序列号高8位 packet[3] = (byte)0; // 序列号低8位 packet[4] = (byte)0; // 时间戳高24位 packet[5] = (byte)0; // 时间戳中间8位 packet[6] = (byte)0; // 时间戳低8位 packet[7] = (byte)0; // SSRC 标识符高8位 packet[8] = (byte)0; // SSRC 标识符低8位 packet[9] = (byte)(length >> 8); // 数据长度高8位 packet[10] = (byte)(length & 0xff); // 数据长度低8位 System.arraycopy(data, 0, packet, 12, length); return packet; } } ``` 这个示例将从默认音频输入设备读取 PCM 音频数据,并将其封装成 RTP 数据报发送到指定的 IP 地址和端口。在创建 RTP 数据报时,需要设置版本号、负载类型、序列号、时间戳、SSRC 标识符和数据长度等信息。你可以根据实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值