• 使用C语言+USRP B210从零开始实现无线通信(3) DASK差分幅度键控调制


    上一篇文章中,已经生成了一串封装好的二进制数据包。如果我们有声卡,或者有SDR终端,则可以着手让数据播放/发射出去了。

    1. 数据的调制

    0,1是一个离散的值,而声卡的声强,SDR(如USRP B210)TX口的无线电磁波的功率,都是一个模拟的、连续的值。要用这种模拟量表示数字量,需要引入调制技术。当然,在接收方,也需要把声强或者感应电压转化为01, 此类过程叫做解调。调制与解调是专门的一门子学科,里面的理论背景很深,而且很多算法与衔接的纠错技术是一体化设计的,在这里很难搞深入了。

    但一切复杂的事物,总有简单的一面。在最初的有线电传时代,曾经直接用摩尔斯类似的滴滴声表示01,或者用有无声音表示01. 这个实验里,我们使用前后两个时刻声音大小的起伏表示01.

    2. 差分幅度键控

    差分幅度键控是使用前后两个时刻的电压的大小关系表示0或者1. 如果V0 > V1,则表示1,否则表示0. 这种调制方式被古老的飞机ADS-B收发机采用。在没有噪声的情况下,前后两个时刻必然有一个时刻有电平,另一个时刻无电平。但因为存在噪声,绝对的0V或者0mW的测量值是不可能达到的,因此主要采用比较大小的方法,而不是比较绝对的门限。

    如,序列 0 1 1 0 ,表示为DASK波形,生成的各个时刻的理论值是这样的:

    时刻:时刻0时刻1时刻2时刻3时刻4时刻5时刻6时刻7
    功率:0mW3mW3mW0mW3mW0mW0mW3mW

    Signal
    不过,到了实验现场,还有一些因素需要考虑。AD/DA(数字-模拟,模拟-数字)过程中主要注意以下几个小问题。

    2.1 带通限制

    有过《信号系统》背景知识的同学肯定知道,上述冲击波形的频谱是很宽的。经过SDR器件后,带宽一般都会限定在一定的范围内。即使实验中不考虑成型滤波的问题主动地降低带宽,硬件本身的通道滤波带来的影响也很可观。这种限制带来的特点直观上就是这些陡峭的冲击值变成了类似SINC函数的曲线。

    带限

    2.2 直流分量

    由于SDR器件默认的波形是交流的,均值位于0mv处。我们产生的波形,如果只含有0,3这种正值,就会产生直流分量。为了避免这种问题,使用0,3,-3这样的值,来产生均值为0的波形。

    0sig

    2.3 选择调制速率

    时刻0,时刻1间隔多少合适呢?这取决于器件的性能,以及计算机的性能。间隔越短,1秒能发送的数据越多,当然对器件的要求也更高。一般的SDR、声卡都有采样率的限制。比如声卡的采样率是9600Hz,则1秒内,最多只能传输9600个功率值。USRP B210可以传输56M个采样点,但是要考虑接收方的处理压力。

    一秒能够传输的状态个数,单位是波特,Bd。选择调制速率,不但要考虑发射通道的能力,更要考虑接收处理的压力。在接收处理时,由于接收通道的时间轴和发射通道不是同步的,因此,在A/D时,选择的时刻很可能和咱们发射波形的时刻是错开的。如果用很低的速率来采样,如果运气不好,采集到的就是如下蓝色的位置:

    在这里插入图片描述所以,一般都会采用比调制速率高的倍数采样率,比如4倍、5倍、15倍等, 得到类似下图的波形:
    4倍
    要保证主能量峰值上要有3-4个采样点为佳。这样,选择一个调制速率M,还要保证N倍的速率要能够满足接收方的处理计算极限K。

    M N < K MN < K MN<K

    所以,调制速率不能设置的太大。

    3 C语言实现调制

    在发射时,理论上可以直接使用发射速率M发射,用接收速率 MN接收。但是,由于M,MN这两个速率具有的公因数不同,导致SDR设备可能无法确切的工作在其中某些速率上。如M=300KHz,最接近的工作点为266.66666KHz,会造成困扰。在本次实验里,接收、发射都使用确切的、相同的采样率;在发射时,使用倍率补零的方式变相降低调制速率。

    同时,为了有效限制带宽,采用汉明窗取代冲击进行成型,效果也很好,代码如下:

    		        static const short hamm[15] = {2560, 4018, 8102,14004,20556,26458,30542,32000,30542,26458,20556,14004, 8102, 4018, 2560};
    				static const short phe[4][2] = {{1,1},{-1,1},{-1,-1},{1,-1}};
    				tag_tx_plain plan;
    				plan.tmstmp.frag = 0;
    				plan.tmstmp.sec = 0;
    				plan.length_left = packagedta.size() * 2 * 15;
    				std::vector<short> signal;
    				for (int i=0;i<packagedta.size();++i)
    				{
    					const short ni = phe[i % 4][0];
    					const short nq = phe[i % 4][1];
    					if (packagedta[i])
    					{
    						//1:15
    						for (int j=0;j<15;++j)
    						{
    							signal.push_back(hamm[j]*ni);
    							signal.push_back(hamm[j]*nq);
    						}
    						for (int j=0;j<15;++j)
    						{
    							signal.push_back(0);
    							signal.push_back(0);
    						}
    					}
    					else
    					{
    						for (int j=0;j<15;++j)
    						{
    							signal.push_back(0);
    							signal.push_back(0);
    						}
    						for (int j=0;j<15;++j)
    						{
    							signal.push_back(hamm[j]*ni);
    							signal.push_back(hamm[j]*nq);
    						}
    					}
    				}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    HammSpectrum

    4. 相关代码

    相关代码和工程参考gitcode.

  • 相关阅读:
    03大数据技术之Hadoop(HDFS)
    Vue.js 计算属性的基本使用,复杂使用 ,set 和 get,计算属性与methods的对比 和 计算属性与侦听器
    【矩阵论】1.准备知识(下)
    AI Agent新对决:LangGraph与AutoGen的技术角力
    英伟达禁售?FlashAttention助力LLM推理速度提8倍
    AD360荣获2023 Fortress奖:卓越的身份验证和身份管理解决方案
    进程初识
    设计模式学习笔记 - 桥接模式
    C++自学精简教程 目录(必读)
    【React学习】—React简介(一)
  • 原文地址:https://blog.csdn.net/goldenhawking/article/details/126753729