400-007-3336
usrp_support@tnm-corad.com.cn

GNU Radio介绍

什么是GNU Radio?

        GNU Radio是一个完全开源的软件无线电结构平台,它可以用来设计和仿真,也可以用来连接真实的无线电系统。GNU Radio是一个高度模块化,采用流图类形式的软件架构平台,它本身提供了许多模块库,使用者可以很快速的使用这些模块来建立关于信号处理的流程。

为什么要用GNU Radio?

        从前,在开发无线通信设备时,工程师必须开发一种特定的信号级检测电路,设计一个特定的集成电路,该芯片将能够解码或编码。软件无线电(SDR)采用模块化处理,处理无线电信号的算法在计算机上实现。 

        你当然可以用你的电脑连接无线设备在一个程序中你从头开始编写算法。但这就变得很麻烦:为什么你要重新执行一个标准的滤波器?为什么你要关心如何在不同的处理模块之间移动数据?用高度优化的方法,而不用自己写不是最好的吗?你如何让你的程序在多核架构上很好地扩展,而且在嵌入式设备上运行得很好? 

        进入GNU Radio:框架致力于编写计算机信号处理中的应用。GNU Radio包易于使用且可重用的模块功能,提供良好的可扩展性,还提供了一个广泛的标准算法库,适用于各种不同的通用平台。平台本身提供了大量的实例,供使用者参考。

信号处理流程

关于信号的一些原理 

        首先设备接收到的是模拟信号,电脑不能识别和处理,我们必须转化成数字信号。经过ADC转化成数字信号后,我们的电脑就能识别,可以对数据进行处理,比如数字滤波,调制解调,信号识别等。

 模块化流程化的数字信号处理 

        为了对数字信号进行处理,我们必须首先考虑信号处理的步骤(滤波、调制解调、分析,检测),然后我们调用相关的模块,用流程图的方式连接起来就组成了一个无线通信系统。最简单的一个实例如下:

        当一个应用被创建时,一个完整的模块化的流程图就建立起来了。这个在GNU Radio就叫流程图。下面是一个多个模块组成的流程图:

        GNU Radio是一个利用这些信号处理模块创建流程图的软件架构平台,这些组成了GNU Radio各种应用。

        作为一个GNU Radio的使用者,你可以使用这些GNU Radio提供的信号处理模块,也可以把它们嵌入到你自己的更加复杂的信号处理流程图中,而不用关心这些数据如何在这些模块之间流动,一旦你的程序连接好,它们会自动进行。

        GNU Radio包括了大量的常用模块,这里列出了一些仅供参考:

信号产生模块:

Constant Source

Noise Source

Signal Source

...

调制解调模块:

AM Demod

Continuous Phase Modulation

PSK Mod / Demod

...

仪器模块

Constellation Sink

Frequency Sink

Time Sink

...

信道模块

Channel Model

Fading Model

Dynamic Channel Model

...

滤波器模块

Band Pass / Reject Filter

Low / High Pass Filter

IIR Filter

...

信号分析模块

FFT

Log Power FFT

Goertzel {{collapse(Resamplers)

...

        使用这些模块,许多标准的任务,如同步,测量和可视化,可以通过只连接适当的模块到您的信号处理流程图就可以实现。此外,你可以自己写信号处理模块,把现有的块与一些提供新的智能功能,连同一些逻辑实现。或您可以开发自己的模块,对输入数据和输出数据进行控制。因此,GNU Radio是一个信号处理块和开发者互动的发展框架。它有一个广泛的标准库的块,并且有很多系统可供开发人员参考。




第一次使用USRP

        请根据你购买的设备在 1,2,3,4 点中选择相应的方法配置你的计算机和设备。然后再根据 5,6 项测试软件环境和设备。


1 USRP 网络接口系列(USRP N200,USRP N210,USRP 2)

            主机网络设置:USRP 网络接口系列初始 IP 地址为 192.168.10.2 。需要把 PC 机的 IP 设置为与 USRP 在同一网络。

1.1 左键单击桌面右上角的网络连接图标,然后选择下拉菜单的“编辑连接..”选项打开“网络连接”窗口。


1.2 在“有线”选项卡中点击“添加”,设置网络连接名称为任意名称(以 usrp为例),并在“设备 MAC 地址”下拉菜单中选择将用于连接 USRP 的网卡:


1.3 点击“IPv4 设置”选项卡,点击添加按钮,输入 IP 地址: 192.168.10.1,子网掩码:255.255.255.0。完成后保存设置。


1.4 给 USRP 供电,并用网线连接 USRP 和 PC。在 PC 机桌面右上角左键单击网络连接图标,在下拉菜单中选择 usrp 连接。


1.5 在终端运行:uhd_find_devices,看 PC 机是否已经连接上 USRP:


1.6 给 USRP 烧写固件(一般在第一次使用或更新 UHD 时需要做这一步):sudo usrp_n2xx_simple_net_burner


到此,整个 UHD+GNU Radio 平台就算搭建好了。

2 USRP B100 和 B110

        给 USRP 供电,并用配套的 USB 连接线连接 USRP 和 PC 机。由于每次运行程序,UHD 会自动给 USRP 装载固件和 FPGA 镜像,该系列不需要进行特别设置。


3 USRP B210 和 B200

提示:

1) B200 不需要额外供电,所以 Ettus 没有提供电源适配器;

2) B210 在 1 收 1 发情况下,也不需要电源,双收双发情况下才需要外接电源适配器。为了方便烧写固件和 FPGA 镜像,先不使用电源适配器,等烧写完成后,在有需要的情况下再接上电源。

用配套的 USB 连接线连接 USRP 和计算机。在终端运行 

uhd_usrp_probe

烧写完 firmwa 后,很可能没继续烧写 FPGA 镜像,显示 No devices found, 如下图所示:


这时候将 USRP 的 USB 连接线从计算机上拔出来,再马上插回去,重新运行 uhd_usrp_probe


这时可以正常烧写固件和 FPGA 镜像了。

4 X310 和 X300

X3x0 提供了多种连接方式到计算机。

1) 千兆网口 将 X3x0 配套的万兆网转千兆网适配器(SFP Adapter for 1GigE)接在 X3x0 的 port 0 万兆网口,如下图所示。


        该网口默认 IP 地址是 192.168.10.2,用配套的网线连接 X3x0 到计算机的千兆网口。计算机对应网口的 IP 地址配置为 192.168.10.1,具体配置方式和 1.1,1.2,1.3 一致。然后按照 1.4,1.5 检测计算机是否能找到 USRP 设备。

        接下来运行 uhd_usrp_probe,可以查看设备详细信息。如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.10.2

如下图所示

烧写完毕后重启设备即可。


2)万兆网口 将万兆网卡安装到计算的 PCI-E 插槽,然后将万兆网线一端连接到万兆网卡中的任意一个网口(Ettus 提供的万兆网卡有 2 个网口,计算机能够识别为 2 张网卡),万兆网线的另外一段连接到 X3x0 的 port 1 万兆网口:


给设备供电,并且按下 X3x0 的电源开关,这时计算机能够识别到有新的网络,编辑该网络:将网络连接名称修改为容易识别的名称,然后修改 MTU 为 9000。


接下点击“IPv4 设置”选项卡,修改网卡 IP 地址为 192.168.40.1(因为X3x0 的 port 1 网卡默认 IP 地址为 192.168.40.2),保持设置。


重启 X3x0 设备,运行 uhd_find_devices,查看设备是否能被计算机识别。然后运行 uhd_usrp_probe,查看设备详细信息,如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.40.2

如下图所示

烧写完毕后重启设备即可。


3)PCI-E 连接卡(PCI‐Express Connectivity Kit 或者 ExpressCard PCIe Interface Kit) 将 PCI‐Express Connectivity Kit 中的板卡安装到计算机的 PCI-E插槽,(如果是笔记本用的 ExpressCard PCIe Interface Kit,将扩展卡连接到笔记本相应接口),用配套的连接线连接板卡和 X310 面板的 pcie x4 接口:


为了在 linux 系统中使用 PCIE 连接卡,需要在计算机中安装 NI USRP RIO kernelmodules。安装步骤如下:

A. 到 http://files.ettus.com/binaries/niusrprio/niusrprio-installer.tar.gz 下载安装软件压缩包;

B. 解压tar zxf niusrprio-installer.tar.gz


C. 安装:

sudo niusrprio-installer/INSTALL

所有安装提示都选择 y,安装脚本将会下载安装所有需要的文件。

D. NI USRP RIO kernel modules 使用方法:

打开 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie start

关闭 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie stop

查询状态:

sudo /usr/local/bin/niusrprio_pcie status

使用 PCI-E 接口卡连接 X3x0 时,不能热拔插。拔出连接线或者关闭 X3x0 之前,需要关闭 PCI-E 接口卡:sudo /usr/local/bin/niusrprio_pcie stop

安装完 NI USRP RIO kernel modules 后,运行sudo /usr/local/bin/niusrprio_pcie start

打开 PCI-E 接口卡,然后检查 X3x0 是否与计算机连接:uhd_find_devices。然后运行 uhd_usrp_probe 查看设备详细信息。如果

提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --resource=rio0


GNU Radio流程图编程

开始了解GRC

        我们已经知道GNU Radio是一个各种信号处理模块的“容器”。在这里,我们将从一个简单的例子讲起,展示如何使用GNU Radio Companion(GRC).我们需要清楚的是,GRC是允许我们创建Python文件图形的,不过流程图的方式更加简化了GNU Radio的使用。

        首先我们来看一下GNU Radio Companion的界面。它包括4个区域:模块库、工具栏、函数输出窗口和工作区域。

        学会一个东西最好的方法就是亲自尝试,想到一个问题,然后自己找出答案。大家可以首先在界面摸索,打开GRC的方式,在终端输入命令:

gnuradio-companion


找到自己需要的模块

        在右边的模块库里面有各种不同类型的信号处理模块,包括了GNU Radio的标准模块和我们初始化的模块。怎样快速的找到我们自己需要的模块呢?假设我们需要一个产生信号的模块,我们可以看到有一个叫做Waveform Generator的类型,打开就可以看到各种产生信号的模块了。那么假设我们需要一个展示波形图,但是又不确定哪种模块是效果最好的,又怎么办呢?我们在上一章节知道,有一个叫sink的类型,但是右边并没有发现sink的类型。这个时候我们就需要使用搜索的功能了,按Ctrl+f,或者点击搜索按钮,然后输入模块的关键字sink,我们可以看到很多关于sink的模块了:

现在让我们添加一个叫QT GUI Time Sink的模块。我们可以通过双击或拖动的方式。

修改模块的参数

        工作区域里面包含各种信号处理模块和变量。我们双击打开模块,设置它的参数属性。如下图:

        在不同的应用系统中,我们可能需要修改这些默认的参数。我们把原来的名字去掉,可以看到ID字样编程蓝色。这种颜色表明信息已经被修改,但是还没有保存。我们再尝试一下修改windows size为300,300,单击OK。然后我们可以看到尺寸的改变。然后,我们看到documentation:

        看用颜色标记的字段,我们知道ID用来确定python文件名字和相关类的名字。

        然后,我们删除掉ID里面的字符串,看到最底下出现了红色的报错信息,同时,ID也变成了红色,这样我们能够很方便的确定错误的所在。

        为了方便,我们取ID的名字为”tutorial_two_1”,同时将Generate Options改成”QT GUI”,因为我们采用的是QT GUI sink,而不是WX GUI sink,在最新版的GNU Radio,默认的是QT GUI.GRC是一个图形化的界面,它是基于python环境的。所以当我们执行一个流程图时,实际上我们真的运行的是一个python程序。ID是用来命名python文件名,与GRC文件保存在同样的路径下。默认情况下,ID是top_block,所以它创建一个为top_block.py的文件。更改ID使我们可以更改保存的文件名,以更好进行文件管理。

        这个GRC-Python连接另一个结果是,Python可以控制GRC的参数属性。事实上,所有的输入框属性或变量,我们使用时被解释为Python。这意味着我们可以使用Python调用设置属性,如调用NumPy或其他GNU Radio功能。这方面的一个常见用途是称为filter.firdes滤波器设计工具从GNU Radio建立我们的滤波器抽头。

        注意的另一个关键是接口不同的颜色。这些实际上对应于不同的数据类型,我们将在本教程后面稍后覆盖。


第一个信号流程图

        现在我们了解如何找到块,如何将它们添加到工作区,以及如何编辑块属性,我们尝试建立一个将信号输出到示波器的流程图,注意模块之间的数据类型的匹配:

        注意到有一个叫throttle block的模块:在本教程后面的更详细的解释是什么。现在,可以了解的是这个模块确保流程图不消耗100%的CPU周期,不然你的电脑可能反应不过来。

        在此之前,我们先来看一下工具栏。

        这里主要是一些流程图软件执行的一些命令,如新建,打开,保存等。让我们开始我们的流程图,我们给它取名叫做tutorial_two。这里有几个重要的工具,Generate flowgraph,excute flowgraph,分别是产生GRC,和运行GRC。在help里面的type,我们可以看到每种数据类型对应的颜色。


关于Generate Options设置

        Generate Options有两种常用的设置QT GUI和WX GUI。最常见的错误就是设置的Generate Options与实际我们用的不匹配。具体来讲,就是我们Generate Options设置的是QT GUI,但是我们构造的流程图却是WX GUI我们会的到如下的报错信息:

        反过来的话,也会得到类似的报错信息。所以,我们必须首先确定自己选用的是QT GUI还是WX GUI。


查看输出

        让我们点击Execute按钮启动程序,我们可以看到如下的波形:

        这是一个复数类型的波形。我们简单化一些,选用别的数据类型。关掉程序,我们打开Help-Type,可以看到如下的数据类型的代表颜色:

        在这里,我们基本上可以找到所有的数据类型。我们看到我们的流程图的接口是蓝色的,很明显这是32位浮点型组成复数形式,现在我们可以解释刚才输出有两个波形的情况了,Time Sink输入一个复数,然后输出它的实部和虚部。现在,我们尝试修改以下信号源的数据类型,将其改为浮点型,然后我们看到它的接口编程橘黄色的,当我们把它和Throttle Block连接时,看到有红色的报错,我们点击工具栏的红色的横杆,可以看到具体的报错信息:

        报错信息显示,数据长度不匹配。这是由于我们的数据类型不匹配的原因。GNU Radio不允许不同的数据类型之间直接连接。我们把所有的模块都改成浮点型的,然后再次运行,可以看到如下的波形:

        现在我们可以看到,只有一个波形输出了,我们可以尝试用鼠标放大或者缩小。


使用GNU Radio Companion

        现在我们已经能够创建自己的流图了,我们进一步的来学习一些GNU Radio Companion有关知识。

关于Throttle Block

        首先,我们来讨论下Throttle Block,之前在我们的流图有用到过。下图是添加Throttle 模块和不添加Throttle 模块的CPU的使用率对比:

        我们可以看到,当流图没有连接硬件也没有连接Throttle 的时候,CPU基本是满负载运行的。在一个流图中我们只需要一个Throttle 就可以了,不管它是有几个输入输出。我们可以认为Throttle 起到限速的作用,设置高的速率,流图执行快,设置低的速率流图执行慢。打个比方,比如我们设置Throttle 为1e6,另一个设置1e3,我们可以看到CPU在1e6的情况下比1e3占用更多的资源。当有硬件连接的时候,我们不需要Throttle 模块,因为硬件本身已经对速率有了限制。

关于采样率

        我们已经知道硬件需要设定特定的采样率来实现某些特定的功能,现在我们来自己创建一个GRC,来看看不同的采样率之间有什么区别:

根据上图配置好参数:

QT GUI Chooser模块设置3个采样速率,ID改为samp_rate

所有的source模块的Sampling Rate改为samp_rate

音频模块改为48e3

所有的sink模块的sampling rate改为audio_rate

        在这里,我们可以看到没有Throttle 模块,这是因为这里有音频硬件。点击运行,设置sample rate为48e3,可以听到熟悉的电话的拨号音,再看一下fft,确实有两个分别为440Hz和350Hz的频段。

        尝试下,当改变sampling rate比audio sampling低的时候,看能否还能听到拨号音。再尝试下,当改变sampling rate比audio sampling高的时候,看能否还能听到拨号音。正常的话,应该听不到拨号音,因为声卡的速率和我们采样的速率不匹配。所以,任何时候,都应该设置正确的采样率。


瀑布图

        现在来看一个由probe,soundcard以及QT Sink模块组成的正弦信号瀑布图:

        请参考上图设置好参数,另外,必须注意的是Audio Sink的Sample Rate。设置好后,点击运行,可以看到:


总结

        现在我们应该知道流图的基本原理,能有找到自己需要的信号处理模块,正确的设置采样率。如何发现并定位错误,怎样设置相应的数据类型,用户可以自己动手,多多尝试,这样就能够比较快的上手GRC了。

GNU Radio与硬件

使用UHD Blocks

        这里我们采用的是Ettus USRP B200,使用的驱动是UHD,所以我们可以在gr-uhd找到我们需要的source和sink模块。为了使用UHD Blocks,首先的必须装好UHD。用户可以在嘉兆科技的官网找到相应的安装方法。如果是直接从源代码编译安装的,安装成功后,在GNU Radio Companion中会发现UHD的相关模块。

发射一个QPSK信号

        首先我们利用现有的模块建立一个流图。然后,通过移掉相关模块来实现QPSK的发射。流图如下:

        运行结果如下:

        然后,我们移除一些和添加一些模块,来连接发射一个真实的信号。由于是真实的无线信道,所以移除noise和add模块。因为有硬件限制速率,所以也不再需要Throttle block。转变成真实的无线系统是很容易的,我们在UHD Sink里找到UHD USRP Sink模块,然后添加到刚才的流图的最后的输出当中,当做流图的信号发射模块。

配置UHD Sink参数

        GNU Radio支持变量模块,用户可以通过修改变量模块的值,来改变整个流图的值,而不用去依次修改,这是非常方便的。复制和粘贴你的samp_rate变量模块两次,分别来控制中心频率和增益。我们设置的中心频率和增益必须是你所使用的硬件设备支持的,不同的设备支持的频段可能是不同的。这里,我们设置中心频率为2.421GHz,增益设置为30dB,这是这个设备支持的发射增益的1/3。

        现在,可以利用新的变量模块来调整UHD里面的参数了。打开UHD USRP Sink,你会看到一个参数列表,这里有许多的参数我们需要调整。向下滚动到列表的底部,相应地设置以下属性:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz: freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

        需要特别注意的一点是任何大于1的值都会引起削波,这意味着振幅被“截断”在1。总的来说,必须设置幅度小雨1。在这个例子中,我们将添加乘0.5乘法器的输出,以确保处于正确的幅度。现在,流图如下:

        如果你执行你的图,你会看到通常的初始化和GUI启动除,而不是一切都被模拟,你实际上是发送你的QPSK信号。如果我们看一下分析仪上的频谱,你应该能够清楚地看到你选择的频率的信号。如果你看不到,仔细检查一下你的参数,也试着修改下增益。

可以看到,跟我们设置是符合的,这说明我们已经成功的发射了QPSK信号。

创建一个FM接收机

        在这一节中,我们将建立一个工作调频收音机接收器,你可以使用它收听你当地调频广播电台。


创建一个软件频谱分析仪

        一个基本的但是却非常有用的是你可以利用GNU Radio创建一个实时的频谱分析的fft,这是一个用软件实现的无线电频谱分析仪,利用它用户能够验证你的硬件是否工作正常,在这里,我们可以利用它来确定我们所在地区的广播电台的频段,以便我们可以调谐到相应的频段。

        现在我们来创建一个流图。找到UHD USRP Source和QT GUI Sink模块。之前我们用固定的中心频率和增益,现在来把它变成实时可调的。找到QT GUI Range模块,添加两个这样的模块到流图中。设置相应的参数,这里使用的是USRP B200:

QT GUI Range 1:

ID: freq

Label: freq

Default Value: 1e9

Start: 70e6

Stop: 6e9

Step: 10e6


QT GUI Range 2:

ID: gain

Label: gain

Default Value: 0

Start: 0

Stop: 74

Step: 1

        尝试修改你的samp_rate,会发现一些有意思的东西。这里设置的是32MSps.现在来设置UHD USRP Source的参数:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz): freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

现在,我们的流图应该是这样的:

检查下你的设置是否正确。

使用软件进行频谱分析

        现在运行你的流图,你应该会看到你真实的信号。滑动相关按钮,注意图形的变化。默认的GNU Radio QT FFT sink内有许多有用的特性,例如均值和保峰值,尽量花一些时间去熟悉它们。

创建FM广播接收

        现在,有一个基本的接收器应用程序实时显示接收数据,让我们建立一个有用的应用程序!我们将添加更多的功能到流程,模块和数量如下:

1x Rational Resampler

1x WBFM Receiver

1x Audio Sink

2x Variable

        我们数据的流向是:USRP Source->Rational Resampler->WBFM Receiver->Audio Sink.按照这个顺序连接好这些模块,期间可能会有报错,现在我么就来修改相应的参数,来解决这些报错。

        首先,添加两个variable blocks,设置相应的参数:

Variable:

ID: audio_interp

Value: 4

Variable:

ID: audio_rate

Value: 48e3

        现在让我们把之前的sample rate改为250e3(250kHz).

Variable: samp_rate

ID: samp_rate

Value: 250e3

        然后,我们配置其余的3个模块。

Audio Sink

        这是一个比较简单的模块。它需要信号流的输入并通过扬声器播放它们。这个模块在GR的音频库初始化,这个音频库是包含在GNU Radio配置里面的。这里面有一些常见的速率设置,最常见的就是48kHz,现在我们使用的就是这个速率的。

设置Audio Sink参数:

Sample Rate: audio_rate

OK to Block: "No"

        现在你只需要把你的速率设置为你的声卡支持的速率就可以了。

Rational Resampler

        我们设置的USRP Source的速率为samp_rate,数值为250e3。设置的Audio Sink的速率为audio rate,数值为48e3。这里有一个问题,我们的源数据的采样率不是音频速率的整数倍:250000/48000=5.208。为了解决这个问题,我们必须进行重采样,这就需要用到Rational Resampler模块,将输入的速率转化为输出的速率。

Rational Resampler允许我们调整数据流的速度,通过插值或者抽取实现的。因为进来的数据的采样率为250k,我们就设定抽取的数值为250k,但是采样率是一个浮点型数据,所以设置抽取数值的时候注意需要将其转换为整型。然后,我们插值,所以再来设置插入的数据。由于WBFM进行了一个4次插值,所以我们可以利用audio_interp和audio_rate设置插入的速率。这样,设置的参数如下:

Type: Complex->Complex (Complex Taps)

Interpolation: audio_rate * audio_interp

Decimation: int(samp_rate)

        其余的参数,默认就可以了。

WBFM Receiver

        现在来配置最后的解调模块。这里仅仅需要设置两个参数:输入的速率以及抽取值。通过之前的例子,我们知道,输入的速率就是Rational Resampler的输入速率,抽取的就是audio_rate.

Quadrature Rate: audio_rate * audo_interp

Audio Decimation: audio_interp

        注意这里的插入和抽取速率是可以自己设定,我们使用参数,是为了保证得到的结果一定是整数。


调试FM广播

        现在参数调整已经好了,应该看不到红色的报错信息了。整个流图如下:

        运行流图,应该可以看到如下的界面,不同的版本可能会有所差异。改变freq,调谐到本地的FM频段,通过电脑的扬声器就可以听到广播了。


总结

        现在我们已经利用GNU Radio成功的搭建了无线电的收发平台。这些应用相对来说是比较简单的,他们利用GNU Radio提供的模块直接连接硬件组成无线系统。也说明了,将仿真带入真实的无线电系统在GNU Radio平台下是一件比较容易的事情。


硬件安装指导

ETTUS USRP大部分(除了B系列)都需要配置射频前端,也就是射频子板。这里是以USRP X310+SBX射频子板为例,介绍了USRP 的硬件安装方法。其他的类型(比如N系列),也可以参照此方法

安装步骤:

https://kb.ettus.com/USRP_X_Series_Quick_Start_(Daughterboard_Installation)

GNU Radio培训

GNU Radio介绍

什么是GNU Radio?

        GNU Radio是一个完全开源的软件无线电结构平台,它可以用来设计和仿真,也可以用来连接真实的无线电系统。GNU Radio是一个高度模块化,采用流图类形式的软件架构平台,它本身提供了许多模块库,使用者可以很快速的使用这些模块来建立关于信号处理的流程。

为什么要用GNU Radio?

        从前,在开发无线通信设备时,工程师必须开发一种特定的信号级检测电路,设计一个特定的集成电路,该芯片将能够解码或编码。软件无线电(SDR)采用模块化处理,处理无线电信号的算法在计算机上实现。 

        你当然可以用你的电脑连接无线设备在一个程序中你从头开始编写算法。但这就变得很麻烦:为什么你要重新执行一个标准的滤波器?为什么你要关心如何在不同的处理模块之间移动数据?用高度优化的方法,而不用自己写不是最好的吗?你如何让你的程序在多核架构上很好地扩展,而且在嵌入式设备上运行得很好? 

        进入GNU Radio:框架致力于编写计算机信号处理中的应用。GNU Radio包易于使用且可重用的模块功能,提供良好的可扩展性,还提供了一个广泛的标准算法库,适用于各种不同的通用平台。平台本身提供了大量的实例,供使用者参考。

信号处理流程

关于信号的一些原理 

        首先设备接收到的是模拟信号,电脑不能识别和处理,我们必须转化成数字信号。经过ADC转化成数字信号后,我们的电脑就能识别,可以对数据进行处理,比如数字滤波,调制解调,信号识别等。

 模块化流程化的数字信号处理 

        为了对数字信号进行处理,我们必须首先考虑信号处理的步骤(滤波、调制解调、分析,检测),然后我们调用相关的模块,用流程图的方式连接起来就组成了一个无线通信系统。最简单的一个实例如下:

        当一个应用被创建时,一个完整的模块化的流程图就建立起来了。这个在GNU Radio就叫流程图。下面是一个多个模块组成的流程图:

        GNU Radio是一个利用这些信号处理模块创建流程图的软件架构平台,这些组成了GNU Radio各种应用。

        作为一个GNU Radio的使用者,你可以使用这些GNU Radio提供的信号处理模块,也可以把它们嵌入到你自己的更加复杂的信号处理流程图中,而不用关心这些数据如何在这些模块之间流动,一旦你的程序连接好,它们会自动进行。

        GNU Radio包括了大量的常用模块,这里列出了一些仅供参考:

信号产生模块:

Constant Source

Noise Source

Signal Source

...

调制解调模块:

AM Demod

Continuous Phase Modulation

PSK Mod / Demod

...

仪器模块

Constellation Sink

Frequency Sink

Time Sink

...

信道模块

Channel Model

Fading Model

Dynamic Channel Model

...

滤波器模块

Band Pass / Reject Filter

Low / High Pass Filter

IIR Filter

...

信号分析模块

FFT

Log Power FFT

Goertzel {{collapse(Resamplers)

...

        使用这些模块,许多标准的任务,如同步,测量和可视化,可以通过只连接适当的模块到您的信号处理流程图就可以实现。此外,你可以自己写信号处理模块,把现有的块与一些提供新的智能功能,连同一些逻辑实现。或您可以开发自己的模块,对输入数据和输出数据进行控制。因此,GNU Radio是一个信号处理块和开发者互动的发展框架。它有一个广泛的标准库的块,并且有很多系统可供开发人员参考。




第一次使用USRP

        请根据你购买的设备在 1,2,3,4 点中选择相应的方法配置你的计算机和设备。然后再根据 5,6 项测试软件环境和设备。


1 USRP 网络接口系列(USRP N200,USRP N210,USRP 2)

            主机网络设置:USRP 网络接口系列初始 IP 地址为 192.168.10.2 。需要把 PC 机的 IP 设置为与 USRP 在同一网络。

1.1 左键单击桌面右上角的网络连接图标,然后选择下拉菜单的“编辑连接..”选项打开“网络连接”窗口。


1.2 在“有线”选项卡中点击“添加”,设置网络连接名称为任意名称(以 usrp为例),并在“设备 MAC 地址”下拉菜单中选择将用于连接 USRP 的网卡:


1.3 点击“IPv4 设置”选项卡,点击添加按钮,输入 IP 地址: 192.168.10.1,子网掩码:255.255.255.0。完成后保存设置。


1.4 给 USRP 供电,并用网线连接 USRP 和 PC。在 PC 机桌面右上角左键单击网络连接图标,在下拉菜单中选择 usrp 连接。


1.5 在终端运行:uhd_find_devices,看 PC 机是否已经连接上 USRP:


1.6 给 USRP 烧写固件(一般在第一次使用或更新 UHD 时需要做这一步):sudo usrp_n2xx_simple_net_burner


到此,整个 UHD+GNU Radio 平台就算搭建好了。

2 USRP B100 和 B110

        给 USRP 供电,并用配套的 USB 连接线连接 USRP 和 PC 机。由于每次运行程序,UHD 会自动给 USRP 装载固件和 FPGA 镜像,该系列不需要进行特别设置。


3 USRP B210 和 B200

提示:

1) B200 不需要额外供电,所以 Ettus 没有提供电源适配器;

2) B210 在 1 收 1 发情况下,也不需要电源,双收双发情况下才需要外接电源适配器。为了方便烧写固件和 FPGA 镜像,先不使用电源适配器,等烧写完成后,在有需要的情况下再接上电源。

用配套的 USB 连接线连接 USRP 和计算机。在终端运行 

uhd_usrp_probe

烧写完 firmwa 后,很可能没继续烧写 FPGA 镜像,显示 No devices found, 如下图所示:


这时候将 USRP 的 USB 连接线从计算机上拔出来,再马上插回去,重新运行 uhd_usrp_probe


这时可以正常烧写固件和 FPGA 镜像了。

4 X310 和 X300

X3x0 提供了多种连接方式到计算机。

1) 千兆网口 将 X3x0 配套的万兆网转千兆网适配器(SFP Adapter for 1GigE)接在 X3x0 的 port 0 万兆网口,如下图所示。


        该网口默认 IP 地址是 192.168.10.2,用配套的网线连接 X3x0 到计算机的千兆网口。计算机对应网口的 IP 地址配置为 192.168.10.1,具体配置方式和 1.1,1.2,1.3 一致。然后按照 1.4,1.5 检测计算机是否能找到 USRP 设备。

        接下来运行 uhd_usrp_probe,可以查看设备详细信息。如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.10.2

如下图所示

烧写完毕后重启设备即可。


2)万兆网口 将万兆网卡安装到计算的 PCI-E 插槽,然后将万兆网线一端连接到万兆网卡中的任意一个网口(Ettus 提供的万兆网卡有 2 个网口,计算机能够识别为 2 张网卡),万兆网线的另外一段连接到 X3x0 的 port 1 万兆网口:


给设备供电,并且按下 X3x0 的电源开关,这时计算机能够识别到有新的网络,编辑该网络:将网络连接名称修改为容易识别的名称,然后修改 MTU 为 9000。


接下点击“IPv4 设置”选项卡,修改网卡 IP 地址为 192.168.40.1(因为X3x0 的 port 1 网卡默认 IP 地址为 192.168.40.2),保持设置。


重启 X3x0 设备,运行 uhd_find_devices,查看设备是否能被计算机识别。然后运行 uhd_usrp_probe,查看设备详细信息,如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.40.2

如下图所示

烧写完毕后重启设备即可。


3)PCI-E 连接卡(PCI‐Express Connectivity Kit 或者 ExpressCard PCIe Interface Kit) 将 PCI‐Express Connectivity Kit 中的板卡安装到计算机的 PCI-E插槽,(如果是笔记本用的 ExpressCard PCIe Interface Kit,将扩展卡连接到笔记本相应接口),用配套的连接线连接板卡和 X310 面板的 pcie x4 接口:


为了在 linux 系统中使用 PCIE 连接卡,需要在计算机中安装 NI USRP RIO kernelmodules。安装步骤如下:

A. 到 http://files.ettus.com/binaries/niusrprio/niusrprio-installer.tar.gz 下载安装软件压缩包;

B. 解压tar zxf niusrprio-installer.tar.gz


C. 安装:

sudo niusrprio-installer/INSTALL

所有安装提示都选择 y,安装脚本将会下载安装所有需要的文件。

D. NI USRP RIO kernel modules 使用方法:

打开 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie start

关闭 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie stop

查询状态:

sudo /usr/local/bin/niusrprio_pcie status

使用 PCI-E 接口卡连接 X3x0 时,不能热拔插。拔出连接线或者关闭 X3x0 之前,需要关闭 PCI-E 接口卡:sudo /usr/local/bin/niusrprio_pcie stop

安装完 NI USRP RIO kernel modules 后,运行sudo /usr/local/bin/niusrprio_pcie start

打开 PCI-E 接口卡,然后检查 X3x0 是否与计算机连接:uhd_find_devices。然后运行 uhd_usrp_probe 查看设备详细信息。如果

提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --resource=rio0


GNU Radio流程图编程

开始了解GRC

        我们已经知道GNU Radio是一个各种信号处理模块的“容器”。在这里,我们将从一个简单的例子讲起,展示如何使用GNU Radio Companion(GRC).我们需要清楚的是,GRC是允许我们创建Python文件图形的,不过流程图的方式更加简化了GNU Radio的使用。

        首先我们来看一下GNU Radio Companion的界面。它包括4个区域:模块库、工具栏、函数输出窗口和工作区域。

        学会一个东西最好的方法就是亲自尝试,想到一个问题,然后自己找出答案。大家可以首先在界面摸索,打开GRC的方式,在终端输入命令:

gnuradio-companion


找到自己需要的模块

        在右边的模块库里面有各种不同类型的信号处理模块,包括了GNU Radio的标准模块和我们初始化的模块。怎样快速的找到我们自己需要的模块呢?假设我们需要一个产生信号的模块,我们可以看到有一个叫做Waveform Generator的类型,打开就可以看到各种产生信号的模块了。那么假设我们需要一个展示波形图,但是又不确定哪种模块是效果最好的,又怎么办呢?我们在上一章节知道,有一个叫sink的类型,但是右边并没有发现sink的类型。这个时候我们就需要使用搜索的功能了,按Ctrl+f,或者点击搜索按钮,然后输入模块的关键字sink,我们可以看到很多关于sink的模块了:

现在让我们添加一个叫QT GUI Time Sink的模块。我们可以通过双击或拖动的方式。

修改模块的参数

        工作区域里面包含各种信号处理模块和变量。我们双击打开模块,设置它的参数属性。如下图:

        在不同的应用系统中,我们可能需要修改这些默认的参数。我们把原来的名字去掉,可以看到ID字样编程蓝色。这种颜色表明信息已经被修改,但是还没有保存。我们再尝试一下修改windows size为300,300,单击OK。然后我们可以看到尺寸的改变。然后,我们看到documentation:

        看用颜色标记的字段,我们知道ID用来确定python文件名字和相关类的名字。

        然后,我们删除掉ID里面的字符串,看到最底下出现了红色的报错信息,同时,ID也变成了红色,这样我们能够很方便的确定错误的所在。

        为了方便,我们取ID的名字为”tutorial_two_1”,同时将Generate Options改成”QT GUI”,因为我们采用的是QT GUI sink,而不是WX GUI sink,在最新版的GNU Radio,默认的是QT GUI.GRC是一个图形化的界面,它是基于python环境的。所以当我们执行一个流程图时,实际上我们真的运行的是一个python程序。ID是用来命名python文件名,与GRC文件保存在同样的路径下。默认情况下,ID是top_block,所以它创建一个为top_block.py的文件。更改ID使我们可以更改保存的文件名,以更好进行文件管理。

        这个GRC-Python连接另一个结果是,Python可以控制GRC的参数属性。事实上,所有的输入框属性或变量,我们使用时被解释为Python。这意味着我们可以使用Python调用设置属性,如调用NumPy或其他GNU Radio功能。这方面的一个常见用途是称为filter.firdes滤波器设计工具从GNU Radio建立我们的滤波器抽头。

        注意的另一个关键是接口不同的颜色。这些实际上对应于不同的数据类型,我们将在本教程后面稍后覆盖。


第一个信号流程图

        现在我们了解如何找到块,如何将它们添加到工作区,以及如何编辑块属性,我们尝试建立一个将信号输出到示波器的流程图,注意模块之间的数据类型的匹配:

        注意到有一个叫throttle block的模块:在本教程后面的更详细的解释是什么。现在,可以了解的是这个模块确保流程图不消耗100%的CPU周期,不然你的电脑可能反应不过来。

        在此之前,我们先来看一下工具栏。

        这里主要是一些流程图软件执行的一些命令,如新建,打开,保存等。让我们开始我们的流程图,我们给它取名叫做tutorial_two。这里有几个重要的工具,Generate flowgraph,excute flowgraph,分别是产生GRC,和运行GRC。在help里面的type,我们可以看到每种数据类型对应的颜色。


关于Generate Options设置

        Generate Options有两种常用的设置QT GUI和WX GUI。最常见的错误就是设置的Generate Options与实际我们用的不匹配。具体来讲,就是我们Generate Options设置的是QT GUI,但是我们构造的流程图却是WX GUI我们会的到如下的报错信息:

        反过来的话,也会得到类似的报错信息。所以,我们必须首先确定自己选用的是QT GUI还是WX GUI。


查看输出

        让我们点击Execute按钮启动程序,我们可以看到如下的波形:

        这是一个复数类型的波形。我们简单化一些,选用别的数据类型。关掉程序,我们打开Help-Type,可以看到如下的数据类型的代表颜色:

        在这里,我们基本上可以找到所有的数据类型。我们看到我们的流程图的接口是蓝色的,很明显这是32位浮点型组成复数形式,现在我们可以解释刚才输出有两个波形的情况了,Time Sink输入一个复数,然后输出它的实部和虚部。现在,我们尝试修改以下信号源的数据类型,将其改为浮点型,然后我们看到它的接口编程橘黄色的,当我们把它和Throttle Block连接时,看到有红色的报错,我们点击工具栏的红色的横杆,可以看到具体的报错信息:

        报错信息显示,数据长度不匹配。这是由于我们的数据类型不匹配的原因。GNU Radio不允许不同的数据类型之间直接连接。我们把所有的模块都改成浮点型的,然后再次运行,可以看到如下的波形:

        现在我们可以看到,只有一个波形输出了,我们可以尝试用鼠标放大或者缩小。


使用GNU Radio Companion

        现在我们已经能够创建自己的流图了,我们进一步的来学习一些GNU Radio Companion有关知识。

关于Throttle Block

        首先,我们来讨论下Throttle Block,之前在我们的流图有用到过。下图是添加Throttle 模块和不添加Throttle 模块的CPU的使用率对比:

        我们可以看到,当流图没有连接硬件也没有连接Throttle 的时候,CPU基本是满负载运行的。在一个流图中我们只需要一个Throttle 就可以了,不管它是有几个输入输出。我们可以认为Throttle 起到限速的作用,设置高的速率,流图执行快,设置低的速率流图执行慢。打个比方,比如我们设置Throttle 为1e6,另一个设置1e3,我们可以看到CPU在1e6的情况下比1e3占用更多的资源。当有硬件连接的时候,我们不需要Throttle 模块,因为硬件本身已经对速率有了限制。

关于采样率

        我们已经知道硬件需要设定特定的采样率来实现某些特定的功能,现在我们来自己创建一个GRC,来看看不同的采样率之间有什么区别:

根据上图配置好参数:

QT GUI Chooser模块设置3个采样速率,ID改为samp_rate

所有的source模块的Sampling Rate改为samp_rate

音频模块改为48e3

所有的sink模块的sampling rate改为audio_rate

        在这里,我们可以看到没有Throttle 模块,这是因为这里有音频硬件。点击运行,设置sample rate为48e3,可以听到熟悉的电话的拨号音,再看一下fft,确实有两个分别为440Hz和350Hz的频段。

        尝试下,当改变sampling rate比audio sampling低的时候,看能否还能听到拨号音。再尝试下,当改变sampling rate比audio sampling高的时候,看能否还能听到拨号音。正常的话,应该听不到拨号音,因为声卡的速率和我们采样的速率不匹配。所以,任何时候,都应该设置正确的采样率。


瀑布图

        现在来看一个由probe,soundcard以及QT Sink模块组成的正弦信号瀑布图:

        请参考上图设置好参数,另外,必须注意的是Audio Sink的Sample Rate。设置好后,点击运行,可以看到:


总结

        现在我们应该知道流图的基本原理,能有找到自己需要的信号处理模块,正确的设置采样率。如何发现并定位错误,怎样设置相应的数据类型,用户可以自己动手,多多尝试,这样就能够比较快的上手GRC了。

GNU Radio与硬件

使用UHD Blocks

        这里我们采用的是Ettus USRP B200,使用的驱动是UHD,所以我们可以在gr-uhd找到我们需要的source和sink模块。为了使用UHD Blocks,首先的必须装好UHD。用户可以在嘉兆科技的官网找到相应的安装方法。如果是直接从源代码编译安装的,安装成功后,在GNU Radio Companion中会发现UHD的相关模块。

发射一个QPSK信号

        首先我们利用现有的模块建立一个流图。然后,通过移掉相关模块来实现QPSK的发射。流图如下:

        运行结果如下:

        然后,我们移除一些和添加一些模块,来连接发射一个真实的信号。由于是真实的无线信道,所以移除noise和add模块。因为有硬件限制速率,所以也不再需要Throttle block。转变成真实的无线系统是很容易的,我们在UHD Sink里找到UHD USRP Sink模块,然后添加到刚才的流图的最后的输出当中,当做流图的信号发射模块。

配置UHD Sink参数

        GNU Radio支持变量模块,用户可以通过修改变量模块的值,来改变整个流图的值,而不用去依次修改,这是非常方便的。复制和粘贴你的samp_rate变量模块两次,分别来控制中心频率和增益。我们设置的中心频率和增益必须是你所使用的硬件设备支持的,不同的设备支持的频段可能是不同的。这里,我们设置中心频率为2.421GHz,增益设置为30dB,这是这个设备支持的发射增益的1/3。

        现在,可以利用新的变量模块来调整UHD里面的参数了。打开UHD USRP Sink,你会看到一个参数列表,这里有许多的参数我们需要调整。向下滚动到列表的底部,相应地设置以下属性:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz: freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

        需要特别注意的一点是任何大于1的值都会引起削波,这意味着振幅被“截断”在1。总的来说,必须设置幅度小雨1。在这个例子中,我们将添加乘0.5乘法器的输出,以确保处于正确的幅度。现在,流图如下:

        如果你执行你的图,你会看到通常的初始化和GUI启动除,而不是一切都被模拟,你实际上是发送你的QPSK信号。如果我们看一下分析仪上的频谱,你应该能够清楚地看到你选择的频率的信号。如果你看不到,仔细检查一下你的参数,也试着修改下增益。

可以看到,跟我们设置是符合的,这说明我们已经成功的发射了QPSK信号。

创建一个FM接收机

        在这一节中,我们将建立一个工作调频收音机接收器,你可以使用它收听你当地调频广播电台。


创建一个软件频谱分析仪

        一个基本的但是却非常有用的是你可以利用GNU Radio创建一个实时的频谱分析的fft,这是一个用软件实现的无线电频谱分析仪,利用它用户能够验证你的硬件是否工作正常,在这里,我们可以利用它来确定我们所在地区的广播电台的频段,以便我们可以调谐到相应的频段。

        现在我们来创建一个流图。找到UHD USRP Source和QT GUI Sink模块。之前我们用固定的中心频率和增益,现在来把它变成实时可调的。找到QT GUI Range模块,添加两个这样的模块到流图中。设置相应的参数,这里使用的是USRP B200:

QT GUI Range 1:

ID: freq

Label: freq

Default Value: 1e9

Start: 70e6

Stop: 6e9

Step: 10e6


QT GUI Range 2:

ID: gain

Label: gain

Default Value: 0

Start: 0

Stop: 74

Step: 1

        尝试修改你的samp_rate,会发现一些有意思的东西。这里设置的是32MSps.现在来设置UHD USRP Source的参数:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz): freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

现在,我们的流图应该是这样的:

检查下你的设置是否正确。

使用软件进行频谱分析

        现在运行你的流图,你应该会看到你真实的信号。滑动相关按钮,注意图形的变化。默认的GNU Radio QT FFT sink内有许多有用的特性,例如均值和保峰值,尽量花一些时间去熟悉它们。

创建FM广播接收

        现在,有一个基本的接收器应用程序实时显示接收数据,让我们建立一个有用的应用程序!我们将添加更多的功能到流程,模块和数量如下:

1x Rational Resampler

1x WBFM Receiver

1x Audio Sink

2x Variable

        我们数据的流向是:USRP Source->Rational Resampler->WBFM Receiver->Audio Sink.按照这个顺序连接好这些模块,期间可能会有报错,现在我么就来修改相应的参数,来解决这些报错。

        首先,添加两个variable blocks,设置相应的参数:

Variable:

ID: audio_interp

Value: 4

Variable:

ID: audio_rate

Value: 48e3

        现在让我们把之前的sample rate改为250e3(250kHz).

Variable: samp_rate

ID: samp_rate

Value: 250e3

        然后,我们配置其余的3个模块。

Audio Sink

        这是一个比较简单的模块。它需要信号流的输入并通过扬声器播放它们。这个模块在GR的音频库初始化,这个音频库是包含在GNU Radio配置里面的。这里面有一些常见的速率设置,最常见的就是48kHz,现在我们使用的就是这个速率的。

设置Audio Sink参数:

Sample Rate: audio_rate

OK to Block: "No"

        现在你只需要把你的速率设置为你的声卡支持的速率就可以了。

Rational Resampler

        我们设置的USRP Source的速率为samp_rate,数值为250e3。设置的Audio Sink的速率为audio rate,数值为48e3。这里有一个问题,我们的源数据的采样率不是音频速率的整数倍:250000/48000=5.208。为了解决这个问题,我们必须进行重采样,这就需要用到Rational Resampler模块,将输入的速率转化为输出的速率。

Rational Resampler允许我们调整数据流的速度,通过插值或者抽取实现的。因为进来的数据的采样率为250k,我们就设定抽取的数值为250k,但是采样率是一个浮点型数据,所以设置抽取数值的时候注意需要将其转换为整型。然后,我们插值,所以再来设置插入的数据。由于WBFM进行了一个4次插值,所以我们可以利用audio_interp和audio_rate设置插入的速率。这样,设置的参数如下:

Type: Complex->Complex (Complex Taps)

Interpolation: audio_rate * audio_interp

Decimation: int(samp_rate)

        其余的参数,默认就可以了。

WBFM Receiver

        现在来配置最后的解调模块。这里仅仅需要设置两个参数:输入的速率以及抽取值。通过之前的例子,我们知道,输入的速率就是Rational Resampler的输入速率,抽取的就是audio_rate.

Quadrature Rate: audio_rate * audo_interp

Audio Decimation: audio_interp

        注意这里的插入和抽取速率是可以自己设定,我们使用参数,是为了保证得到的结果一定是整数。


调试FM广播

        现在参数调整已经好了,应该看不到红色的报错信息了。整个流图如下:

        运行流图,应该可以看到如下的界面,不同的版本可能会有所差异。改变freq,调谐到本地的FM频段,通过电脑的扬声器就可以听到广播了。


总结

        现在我们已经利用GNU Radio成功的搭建了无线电的收发平台。这些应用相对来说是比较简单的,他们利用GNU Radio提供的模块直接连接硬件组成无线系统。也说明了,将仿真带入真实的无线电系统在GNU Radio平台下是一件比较容易的事情。


1 USRP 网络接口系列(USRP N200,USRP N210,USRP 2)

            主机网络设置:USRP 网络接口系列初始 IP 地址为 192.168.10.2 。需要把 PC 机的 IP 设置为与 USRP 在同一网络。

1.1 左键单击桌面右上角的网络连接图标,然后选择下拉菜单的“编辑连接..”选项打开“网络连接”窗口。


1.2 在“有线”选项卡中点击“添加”,设置网络连接名称为任意名称(以 usrp为例),并在“设备 MAC 地址”下拉菜单中选择将用于连接 USRP 的网卡:


1.3 点击“IPv4 设置”选项卡,点击添加按钮,输入 IP 地址: 192.168.10.1,子网掩码:255.255.255.0。完成后保存设置。


1.4 给 USRP 供电,并用网线连接 USRP 和 PC。在 PC 机桌面右上角左键单击网络连接图标,在下拉菜单中选择 usrp 连接。


1.5 在终端运行:uhd_find_devices,看 PC 机是否已经连接上 USRP:


1.6 给 USRP 烧写固件(一般在第一次使用或更新 UHD 时需要做这一步):sudo usrp_n2xx_simple_net_burner


到此,整个 UHD+GNU Radio 平台就算搭建好了。

2 USRP B100 和 B110

        给 USRP 供电,并用配套的 USB 连接线连接 USRP 和 PC 机。由于每次运行程序,UHD 会自动给 USRP 装载固件和 FPGA 镜像,该系列不需要进行特别设置。


3 USRP B210 和 B200

提示:

1) B200 不需要额外供电,所以 Ettus 没有提供电源适配器;

2) B210 在 1 收 1 发情况下,也不需要电源,双收双发情况下才需要外接电源适配器。为了方便烧写固件和 FPGA 镜像,先不使用电源适配器,等烧写完成后,在有需要的情况下再接上电源。

用配套的 USB 连接线连接 USRP 和计算机。在终端运行 

uhd_usrp_probe

烧写完 firmwa 后,很可能没继续烧写 FPGA 镜像,显示 No devices found, 如下图所示:


这时候将 USRP 的 USB 连接线从计算机上拔出来,再马上插回去,重新运行 uhd_usrp_probe


这时可以正常烧写固件和 FPGA 镜像了。

4 X310 和 X300

X3x0 提供了多种连接方式到计算机。

1) 千兆网口 将 X3x0 配套的万兆网转千兆网适配器(SFP Adapter for 1GigE)接在 X3x0 的 port 0 万兆网口,如下图所示。


        该网口默认 IP 地址是 192.168.10.2,用配套的网线连接 X3x0 到计算机的千兆网口。计算机对应网口的 IP 地址配置为 192.168.10.1,具体配置方式和 1.1,1.2,1.3 一致。然后按照 1.4,1.5 检测计算机是否能找到 USRP 设备。

        接下来运行 uhd_usrp_probe,可以查看设备详细信息。如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.10.2

如下图所示

烧写完毕后重启设备即可。


2)万兆网口 将万兆网卡安装到计算的 PCI-E 插槽,然后将万兆网线一端连接到万兆网卡中的任意一个网口(Ettus 提供的万兆网卡有 2 个网口,计算机能够识别为 2 张网卡),万兆网线的另外一段连接到 X3x0 的 port 1 万兆网口:


给设备供电,并且按下 X3x0 的电源开关,这时计算机能够识别到有新的网络,编辑该网络:将网络连接名称修改为容易识别的名称,然后修改 MTU 为 9000。


接下点击“IPv4 设置”选项卡,修改网卡 IP 地址为 192.168.40.1(因为X3x0 的 port 1 网卡默认 IP 地址为 192.168.40.2),保持设置。


重启 X3x0 设备,运行 uhd_find_devices,查看设备是否能被计算机识别。然后运行 uhd_usrp_probe,查看设备详细信息,如果提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:

/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --addr=192.168.40.2

如下图所示

烧写完毕后重启设备即可。


3)PCI-E 连接卡(PCI‐Express Connectivity Kit 或者 ExpressCard PCIe Interface Kit) 将 PCI‐Express Connectivity Kit 中的板卡安装到计算机的 PCI-E插槽,(如果是笔记本用的 ExpressCard PCIe Interface Kit,将扩展卡连接到笔记本相应接口),用配套的连接线连接板卡和 X310 面板的 pcie x4 接口:


为了在 linux 系统中使用 PCIE 连接卡,需要在计算机中安装 NI USRP RIO kernelmodules。安装步骤如下:

A. 到 http://files.ettus.com/binaries/niusrprio/niusrprio-installer.tar.gz 下载安装软件压缩包;

B. 解压tar zxf niusrprio-installer.tar.gz


C. 安装:

sudo niusrprio-installer/INSTALL

所有安装提示都选择 y,安装脚本将会下载安装所有需要的文件。

D. NI USRP RIO kernel modules 使用方法:

打开 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie start

关闭 PCI-E 接口卡:

sudo /usr/local/bin/niusrprio_pcie stop

查询状态:

sudo /usr/local/bin/niusrprio_pcie status

使用 PCI-E 接口卡连接 X3x0 时,不能热拔插。拔出连接线或者关闭 X3x0 之前,需要关闭 PCI-E 接口卡:sudo /usr/local/bin/niusrprio_pcie stop

安装完 NI USRP RIO kernel modules 后,运行sudo /usr/local/bin/niusrprio_pcie start

打开 PCI-E 接口卡,然后检查 X3x0 是否与计算机连接:uhd_find_devices。然后运行 uhd_usrp_probe 查看设备详细信息。如果

提示 fpga 镜像和 uhd 版本不兼容,请运行以下命令烧写 fpga 镜像:/usr/local/lib/uhd/utils/usrp_x3xx_fpga_burner --resource=rio0


Visual Studio开发环境配置

Visual Studio安装配置

参考文档

http://shannon.ece.ufl.edu:6528/index.php/Blog:Djgreene/Installing_UHD_and_Boost_in_Windows

安装Microsoft Visual Studio 2015

其中两个版本的下载地址:

企业版: https://www.microsoft.com/en-us/download/details.aspx?id=48143

社区版: https://www.microsoft.com/en-us/download/details.aspx?id=48146

各个版本任选其一。

按照C++开发的需要安装,在此不做详细介绍。

安装Boost

二进制安装包下载地址: 

https://sourceforge.net/projects/boost/files/boost-binaries/1.61.0/boost_1_61_0-msvc-14.0-32.exe/download (32位)

https://sourceforge.net/projects/boost/files/boost-binaries/1.61.0/boost_1_61_0-msvc-14.0-64.exe/download (64位)

本文选择以32位为例,因此Boost也选择32位的。

按照默认安装,安装路径是C:\local\boost_1_61_0 

安装UHD

下载地址 http://www.ettus.com.cn/Download/software/UHD.html

选择对应vs2015的VS2015后缀的版本,如本文选择了32位的对应vs2015的版本

http://www.ettus.com.cn/Download/software/uhd_win32_vs2015.html 下载后双击安装。

据称UHD的安装文件有bug,所以在选择是否添加环境变量这一步中,选择“Do not add UHD to the system PATH”。

这里安装路径这里选择默认(你也可以选择其他路径):

其余的步骤默认。

安装好之后的目录是这样的:

配置系统环境变量

在系统环境变量的PATH变量中增加UHD的bin目录,也就是我们安装UHD的目录下的bin目录,比如我们在上面的步骤中把UHD安装到了C:\Program Files (x86)\UHD中,然后选择里面的bin目录,增加到系统的PATH变量内,使得命令行下能方便地识别UHD的命令。

下面是设置环境变量的具体方法:

点击桌面左下角Windows按钮,在“计算机”按钮上点击右键,选择“属性”

在打开的窗口左边点“高级系统设置”

在弹出的“系统属性”窗口点击下方的“环境变量”按钮

在弹出的“环境变量”窗口中,选中下方“系统变量”列表中的“Path”变量,然后点击下方的“编辑”按钮,在”变量值”最后面加入新安装的UHD的bin目录的路径,C:\Program Files (x86)\UHD\bin,注意,在加入这个路径前,需要在原来的路径后面加上英文半角分号“;”,以保证变量值有效。

然后一路点击确定。鉴于有些程序不一定能立刻识别到系统环境变量的变化,建议注销用户重新登录。

验证UHD环境配置效果

连接好USRP设备,打开cmd,执行uhd_find_devices.exe

找到了我们连接到PC的设备,证明UHD安装成功了。


安装USB驱动


USRP设备接上电源(如果需要),然后用USB线连接USRPPC,第一次连接很可能会报告未能安装设备驱动 

打开PC的设备管理器,会发现有个未知设备,在“其他设备”àWestBridge”这里,


需要到官网下载驱动: http://www.ettus.com.cn/Download/software/windows_install.html

解压到一个新建的目录,并复制此目录的地址到剪贴板。如我的地址是D:\RecPlay_Dev\erllc_uhd_winusb_driver


在设备管理器的未知设备“WestBridge”上点击右键,“更新驱动程序软件”“浏览计算机以查找驱动程序软件”,“在以下位置搜索驱动程序软件”输入框中黏贴刚才复制的驱动程序路径,然后点击“下一步”,将会提示是否安装驱动程序,

点击“安装”。

安装成功后,设备管理器中多了一个USRP的设备信息。

执行uhd_find_devices,可以看到已经能找到设备了。

更新系统驱动

有时我们需要用到更大的采样率,比如USRP x310下200Ms/s采样率的时候,会发现USRP和系统之间的链接会出问题,主要是USRP报告丢包,溢出等。此时需要保证驱动最新,建议到设备厂商官方网站去找最新驱动,因为之前碰到过用“驱动xx”等第三方驱动管理工具却搜不到最新驱动的问题。建议更新的还包括BIOS、操作系统等IO相关的设备。

通过UHD自带的C:\Program Files (x86)\UHD\lib\uhd\examples\benchmark_rate.exe来验证链路性能是否达到指标。

创建自己的工程,并用上UHD

打开VS2015,创建新工程:

修改为Release配置

右键选中新建的项目,点击properties打开项目属性页面。

在项目属性页,把项目配置修改为Release。(由于我们通过二进制包安装的UHD是release版本的,所以最好用Release的项目配置)

增加额外的头文件目录:

在项目属性页的C/C++  General Additional Include Directories 中,选择右边的小三角,然后选择<Edit…>

在弹出来的Additional Include Directories窗口中,点击右上角的新建按钮,依次选择UHD安装目录下的include目录,和Boost的安装目录。如下图

点击OK确认修改。

增加额外的库文件及目录:

同样是在项目属性页,选择LinkerGeneralAdditional Library Directories,点击右边的小三角,选择<Edit…>

在弹出的Addititonal Library Directories窗口中,添加UHD的库目录和Boost的库目录,按照我们之前安装UHD和Boost的选项,路径是这样的

其实就是uhd.lib所在目录和boost_unit_test_framework-vc140-mt-gd-1_61.lib等boost库文件的所在目录。

然后,还需要在项目属性页面的LinkerInputAdditional Dependencies中,添加uhd.lib的文件名称

添加源文件及代码:

右键点击项目窗口的Source File筛选器,选择AddNew Item

选择Visual C++C++ File(.cpp),然后在窗口下方输入文件名,这里起的文件名是main.cpp

然后在新文件中填入代码,这个代码是最简单的获取已连接的设备信息。

// General Includes
#include <cmath>
#include <complex>
#include <csignal>
#include <fstream>
#include <iostream>
 
// UHD Includes
#include <uhd/exception.hpp>
#include <uhd/types/tune_request.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/thread_priority.hpp>
 
// Boost Incudes
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/program_options.hpp>
#include <boost/thread/thread.hpp>
 
 
int main(void) {
 
// Look for connected USRPs
uhd::device_addr_t hint;
uhd::device_addrs_t device_addrs = uhd::device::find(hint);
 
// Exit if none were found
if (device_addrs.size() == 0)
	std::cerr << "No UHD Devices Found" << std::endl;
 
// Display the USRPs Found
else for (size_t i = 0; i < device_addrs.size(); i++) {
	std::cout << "--------------------------------------------------" << std::endl;
	std::cout << "-- UHD Device " << i << std::endl;
	std::cout << "--------------------------------------------------" << std::endl;
	std::cout << device_addrs[i].to_pp_string() << std::endl << std::endl;
}
 
// Pause for the user
system("pause");
 
// Exit the program
return 0;
}

编译运行

添加完代码后保存,按快捷键F7编译项目。

红框内容表示编译链接成功(详情部分在不同环境下可能会有不同的输出)。

连接好设备,按快捷键F5以调试模式运行程序。

成功获取到设备信息

Visual Studio安装配置

参考文档

http://shannon.ece.ufl.edu:6528/index.php/Blog:Djgreene/Installing_UHD_and_Boost_in_Windows

安装Microsoft Visual Studio 2015

其中两个版本的下载地址:

企业版: https://www.microsoft.com/en-us/download/details.aspx?id=48143

社区版: https://www.microsoft.com/en-us/download/details.aspx?id=48146

各个版本任选其一。

按照C++开发的需要安装,在此不做详细介绍。

安装Boost

二进制安装包下载地址: 

https://sourceforge.net/projects/boost/files/boost-binaries/1.61.0/boost_1_61_0-msvc-14.0-32.exe/download (32位)

https://sourceforge.net/projects/boost/files/boost-binaries/1.61.0/boost_1_61_0-msvc-14.0-64.exe/download (64位)

本文选择以32位为例,因此Boost也选择32位的。

按照默认安装,安装路径是C:\local\boost_1_61_0 

安装UHD

下载地址 http://www.ettus.com.cn/Download/software/UHD.html

选择对应vs2015的VS2015后缀的版本,如本文选择了32位的对应vs2015的版本

http://www.ettus.com.cn/Download/software/uhd_win32_vs2015.html 下载后双击安装。

据称UHD的安装文件有bug,所以在选择是否添加环境变量这一步中,选择“Do not add UHD to the system PATH”。

这里安装路径这里选择默认(你也可以选择其他路径):

其余的步骤默认。

安装好之后的目录是这样的:

配置系统环境变量

在系统环境变量的PATH变量中增加UHD的bin目录,也就是我们安装UHD的目录下的bin目录,比如我们在上面的步骤中把UHD安装到了C:\Program Files (x86)\UHD中,然后选择里面的bin目录,增加到系统的PATH变量内,使得命令行下能方便地识别UHD的命令。

下面是设置环境变量的具体方法:

点击桌面左下角Windows按钮,在“计算机”按钮上点击右键,选择“属性”

在打开的窗口左边点“高级系统设置”

在弹出的“系统属性”窗口点击下方的“环境变量”按钮

在弹出的“环境变量”窗口中,选中下方“系统变量”列表中的“Path”变量,然后点击下方的“编辑”按钮,在”变量值”最后面加入新安装的UHD的bin目录的路径,C:\Program Files (x86)\UHD\bin,注意,在加入这个路径前,需要在原来的路径后面加上英文半角分号“;”,以保证变量值有效。

然后一路点击确定。鉴于有些程序不一定能立刻识别到系统环境变量的变化,建议注销用户重新登录。

验证UHD环境配置效果

连接好USRP设备,打开cmd,执行uhd_find_devices.exe

找到了我们连接到PC的设备,证明UHD安装成功了。


安装USB驱动


USRP设备接上电源(如果需要),然后用USB线连接USRPPC,第一次连接很可能会报告未能安装设备驱动 

打开PC的设备管理器,会发现有个未知设备,在“其他设备”àWestBridge”这里,


需要到官网下载驱动: http://www.ettus.com.cn/Download/software/windows_install.html

解压到一个新建的目录,并复制此目录的地址到剪贴板。如我的地址是D:\RecPlay_Dev\erllc_uhd_winusb_driver


在设备管理器的未知设备“WestBridge”上点击右键,“更新驱动程序软件”“浏览计算机以查找驱动程序软件”,“在以下位置搜索驱动程序软件”输入框中黏贴刚才复制的驱动程序路径,然后点击“下一步”,将会提示是否安装驱动程序,

点击“安装”。

安装成功后,设备管理器中多了一个USRP的设备信息。

执行uhd_find_devices,可以看到已经能找到设备了。

更新系统驱动

有时我们需要用到更大的采样率,比如USRP x310下200Ms/s采样率的时候,会发现USRP和系统之间的链接会出问题,主要是USRP报告丢包,溢出等。此时需要保证驱动最新,建议到设备厂商官方网站去找最新驱动,因为之前碰到过用“驱动xx”等第三方驱动管理工具却搜不到最新驱动的问题。建议更新的还包括BIOS、操作系统等IO相关的设备。

通过UHD自带的C:\Program Files (x86)\UHD\lib\uhd\examples\benchmark_rate.exe来验证链路性能是否达到指标。

创建自己的工程,并用上UHD

打开VS2015,创建新工程:

修改为Release配置

右键选中新建的项目,点击properties打开项目属性页面。

在项目属性页,把项目配置修改为Release。(由于我们通过二进制包安装的UHD是release版本的,所以最好用Release的项目配置)

增加额外的头文件目录:

在项目属性页的C/C++  General Additional Include Directories 中,选择右边的小三角,然后选择<Edit…>

在弹出来的Additional Include Directories窗口中,点击右上角的新建按钮,依次选择UHD安装目录下的include目录,和Boost的安装目录。如下图

点击OK确认修改。

增加额外的库文件及目录:

同样是在项目属性页,选择LinkerGeneralAdditional Library Directories,点击右边的小三角,选择<Edit…>

在弹出的Addititonal Library Directories窗口中,添加UHD的库目录和Boost的库目录,按照我们之前安装UHD和Boost的选项,路径是这样的

其实就是uhd.lib所在目录和boost_unit_test_framework-vc140-mt-gd-1_61.lib等boost库文件的所在目录。

然后,还需要在项目属性页面的LinkerInputAdditional Dependencies中,添加uhd.lib的文件名称

添加源文件及代码:

右键点击项目窗口的Source File筛选器,选择AddNew Item

选择Visual C++C++ File(.cpp),然后在窗口下方输入文件名,这里起的文件名是main.cpp

然后在新文件中填入代码,这个代码是最简单的获取已连接的设备信息。

// General Includes
#include <cmath>
#include <complex>
#include <csignal>
#include <fstream>
#include <iostream>
 
// UHD Includes
#include <uhd/exception.hpp>
#include <uhd/types/tune_request.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/thread_priority.hpp>
 
// Boost Incudes
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/program_options.hpp>
#include <boost/thread/thread.hpp>
 
 
int main(void) {
 
// Look for connected USRPs
uhd::device_addr_t hint;
uhd::device_addrs_t device_addrs = uhd::device::find(hint);
 
// Exit if none were found
if (device_addrs.size() == 0)
	std::cerr << "No UHD Devices Found" << std::endl;
 
// Display the USRPs Found
else for (size_t i = 0; i < device_addrs.size(); i++) {
	std::cout << "--------------------------------------------------" << std::endl;
	std::cout << "-- UHD Device " << i << std::endl;
	std::cout << "--------------------------------------------------" << std::endl;
	std::cout << device_addrs[i].to_pp_string() << std::endl << std::endl;
}
 
// Pause for the user
system("pause");
 
// Exit the program
return 0;
}

编译运行

添加完代码后保存,按快捷键F7编译项目。

红框内容表示编译链接成功(详情部分在不同环境下可能会有不同的输出)。

连接好设备,按快捷键F5以调试模式运行程序。

成功获取到设备信息

什么是GNU Radio?

        GNU Radio是一个完全开源的软件无线电结构平台,它可以用来设计和仿真,也可以用来连接真实的无线电系统。GNU Radio是一个高度模块化,采用流图类形式的软件架构平台,它本身提供了许多模块库,使用者可以很快速的使用这些模块来建立关于信号处理的流程。

为什么要用GNU Radio?

        从前,在开发无线通信设备时,工程师必须开发一种特定的信号级检测电路,设计一个特定的集成电路,该芯片将能够解码或编码。软件无线电(SDR)采用模块化处理,处理无线电信号的算法在计算机上实现。 

        你当然可以用你的电脑连接无线设备在一个程序中你从头开始编写算法。但这就变得很麻烦:为什么你要重新执行一个标准的滤波器?为什么你要关心如何在不同的处理模块之间移动数据?用高度优化的方法,而不用自己写不是最好的吗?你如何让你的程序在多核架构上很好地扩展,而且在嵌入式设备上运行得很好? 

        进入GNU Radio:框架致力于编写计算机信号处理中的应用。GNU Radio包易于使用且可重用的模块功能,提供良好的可扩展性,还提供了一个广泛的标准算法库,适用于各种不同的通用平台。平台本身提供了大量的实例,供使用者参考。

信号处理流程

关于信号的一些原理 

        首先设备接收到的是模拟信号,电脑不能识别和处理,我们必须转化成数字信号。经过ADC转化成数字信号后,我们的电脑就能识别,可以对数据进行处理,比如数字滤波,调制解调,信号识别等。

 模块化流程化的数字信号处理 

        为了对数字信号进行处理,我们必须首先考虑信号处理的步骤(滤波、调制解调、分析,检测),然后我们调用相关的模块,用流程图的方式连接起来就组成了一个无线通信系统。最简单的一个实例如下:

        当一个应用被创建时,一个完整的模块化的流程图就建立起来了。这个在GNU Radio就叫流程图。下面是一个多个模块组成的流程图:

        GNU Radio是一个利用这些信号处理模块创建流程图的软件架构平台,这些组成了GNU Radio各种应用。

        作为一个GNU Radio的使用者,你可以使用这些GNU Radio提供的信号处理模块,也可以把它们嵌入到你自己的更加复杂的信号处理流程图中,而不用关心这些数据如何在这些模块之间流动,一旦你的程序连接好,它们会自动进行。

        GNU Radio包括了大量的常用模块,这里列出了一些仅供参考:

信号产生模块:

Constant Source

Noise Source

Signal Source

...

调制解调模块:

AM Demod

Continuous Phase Modulation

PSK Mod / Demod

...

仪器模块

Constellation Sink

Frequency Sink

Time Sink

...

信道模块

Channel Model

Fading Model

Dynamic Channel Model

...

滤波器模块

Band Pass / Reject Filter

Low / High Pass Filter

IIR Filter

...

信号分析模块

FFT

Log Power FFT

Goertzel {{collapse(Resamplers)

...

        使用这些模块,许多标准的任务,如同步,测量和可视化,可以通过只连接适当的模块到您的信号处理流程图就可以实现。此外,你可以自己写信号处理模块,把现有的块与一些提供新的智能功能,连同一些逻辑实现。或您可以开发自己的模块,对输入数据和输出数据进行控制。因此,GNU Radio是一个信号处理块和开发者互动的发展框架。它有一个广泛的标准库的块,并且有很多系统可供开发人员参考。




使用UHD Blocks

        这里我们采用的是Ettus USRP B200,使用的驱动是UHD,所以我们可以在gr-uhd找到我们需要的source和sink模块。为了使用UHD Blocks,首先的必须装好UHD。用户可以在嘉兆科技的官网找到相应的安装方法。如果是直接从源代码编译安装的,安装成功后,在GNU Radio Companion中会发现UHD的相关模块。

发射一个QPSK信号

        首先我们利用现有的模块建立一个流图。然后,通过移掉相关模块来实现QPSK的发射。流图如下:

        运行结果如下:

        然后,我们移除一些和添加一些模块,来连接发射一个真实的信号。由于是真实的无线信道,所以移除noise和add模块。因为有硬件限制速率,所以也不再需要Throttle block。转变成真实的无线系统是很容易的,我们在UHD Sink里找到UHD USRP Sink模块,然后添加到刚才的流图的最后的输出当中,当做流图的信号发射模块。

配置UHD Sink参数

        GNU Radio支持变量模块,用户可以通过修改变量模块的值,来改变整个流图的值,而不用去依次修改,这是非常方便的。复制和粘贴你的samp_rate变量模块两次,分别来控制中心频率和增益。我们设置的中心频率和增益必须是你所使用的硬件设备支持的,不同的设备支持的频段可能是不同的。这里,我们设置中心频率为2.421GHz,增益设置为30dB,这是这个设备支持的发射增益的1/3。

        现在,可以利用新的变量模块来调整UHD里面的参数了。打开UHD USRP Sink,你会看到一个参数列表,这里有许多的参数我们需要调整。向下滚动到列表的底部,相应地设置以下属性:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz: freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

        需要特别注意的一点是任何大于1的值都会引起削波,这意味着振幅被“截断”在1。总的来说,必须设置幅度小雨1。在这个例子中,我们将添加乘0.5乘法器的输出,以确保处于正确的幅度。现在,流图如下:

        如果你执行你的图,你会看到通常的初始化和GUI启动除,而不是一切都被模拟,你实际上是发送你的QPSK信号。如果我们看一下分析仪上的频谱,你应该能够清楚地看到你选择的频率的信号。如果你看不到,仔细检查一下你的参数,也试着修改下增益。

可以看到,跟我们设置是符合的,这说明我们已经成功的发射了QPSK信号。

创建一个FM接收机

        在这一节中,我们将建立一个工作调频收音机接收器,你可以使用它收听你当地调频广播电台。


创建一个软件频谱分析仪

        一个基本的但是却非常有用的是你可以利用GNU Radio创建一个实时的频谱分析的fft,这是一个用软件实现的无线电频谱分析仪,利用它用户能够验证你的硬件是否工作正常,在这里,我们可以利用它来确定我们所在地区的广播电台的频段,以便我们可以调谐到相应的频段。

        现在我们来创建一个流图。找到UHD USRP Source和QT GUI Sink模块。之前我们用固定的中心频率和增益,现在来把它变成实时可调的。找到QT GUI Range模块,添加两个这样的模块到流图中。设置相应的参数,这里使用的是USRP B200:

QT GUI Range 1:

ID: freq

Label: freq

Default Value: 1e9

Start: 70e6

Stop: 6e9

Step: 10e6


QT GUI Range 2:

ID: gain

Label: gain

Default Value: 0

Start: 0

Stop: 74

Step: 1

        尝试修改你的samp_rate,会发现一些有意思的东西。这里设置的是32MSps.现在来设置UHD USRP Source的参数:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz): freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

现在,我们的流图应该是这样的:

检查下你的设置是否正确。

使用软件进行频谱分析

        现在运行你的流图,你应该会看到你真实的信号。滑动相关按钮,注意图形的变化。默认的GNU Radio QT FFT sink内有许多有用的特性,例如均值和保峰值,尽量花一些时间去熟悉它们。

创建FM广播接收

        现在,有一个基本的接收器应用程序实时显示接收数据,让我们建立一个有用的应用程序!我们将添加更多的功能到流程,模块和数量如下:

1x Rational Resampler

1x WBFM Receiver

1x Audio Sink

2x Variable

        我们数据的流向是:USRP Source->Rational Resampler->WBFM Receiver->Audio Sink.按照这个顺序连接好这些模块,期间可能会有报错,现在我么就来修改相应的参数,来解决这些报错。

        首先,添加两个variable blocks,设置相应的参数:

Variable:

ID: audio_interp

Value: 4

Variable:

ID: audio_rate

Value: 48e3

        现在让我们把之前的sample rate改为250e3(250kHz).

Variable: samp_rate

ID: samp_rate

Value: 250e3

        然后,我们配置其余的3个模块。

Audio Sink

        这是一个比较简单的模块。它需要信号流的输入并通过扬声器播放它们。这个模块在GR的音频库初始化,这个音频库是包含在GNU Radio配置里面的。这里面有一些常见的速率设置,最常见的就是48kHz,现在我们使用的就是这个速率的。

设置Audio Sink参数:

Sample Rate: audio_rate

OK to Block: "No"

        现在你只需要把你的速率设置为你的声卡支持的速率就可以了。

Rational Resampler

        我们设置的USRP Source的速率为samp_rate,数值为250e3。设置的Audio Sink的速率为audio rate,数值为48e3。这里有一个问题,我们的源数据的采样率不是音频速率的整数倍:250000/48000=5.208。为了解决这个问题,我们必须进行重采样,这就需要用到Rational Resampler模块,将输入的速率转化为输出的速率。

Rational Resampler允许我们调整数据流的速度,通过插值或者抽取实现的。因为进来的数据的采样率为250k,我们就设定抽取的数值为250k,但是采样率是一个浮点型数据,所以设置抽取数值的时候注意需要将其转换为整型。然后,我们插值,所以再来设置插入的数据。由于WBFM进行了一个4次插值,所以我们可以利用audio_interp和audio_rate设置插入的速率。这样,设置的参数如下:

Type: Complex->Complex (Complex Taps)

Interpolation: audio_rate * audio_interp

Decimation: int(samp_rate)

        其余的参数,默认就可以了。

WBFM Receiver

        现在来配置最后的解调模块。这里仅仅需要设置两个参数:输入的速率以及抽取值。通过之前的例子,我们知道,输入的速率就是Rational Resampler的输入速率,抽取的就是audio_rate.

Quadrature Rate: audio_rate * audo_interp

Audio Decimation: audio_interp

        注意这里的插入和抽取速率是可以自己设定,我们使用参数,是为了保证得到的结果一定是整数。


调试FM广播

        现在参数调整已经好了,应该看不到红色的报错信息了。整个流图如下:

        运行流图,应该可以看到如下的界面,不同的版本可能会有所差异。改变freq,调谐到本地的FM频段,通过电脑的扬声器就可以听到广播了。


创建一个软件频谱分析仪

        一个基本的但是却非常有用的是你可以利用GNU Radio创建一个实时的频谱分析的fft,这是一个用软件实现的无线电频谱分析仪,利用它用户能够验证你的硬件是否工作正常,在这里,我们可以利用它来确定我们所在地区的广播电台的频段,以便我们可以调谐到相应的频段。

        现在我们来创建一个流图。找到UHD USRP Source和QT GUI Sink模块。之前我们用固定的中心频率和增益,现在来把它变成实时可调的。找到QT GUI Range模块,添加两个这样的模块到流图中。设置相应的参数,这里使用的是USRP B200:

QT GUI Range 1:

ID: freq

Label: freq

Default Value: 1e9

Start: 70e6

Stop: 6e9

Step: 10e6


QT GUI Range 2:

ID: gain

Label: gain

Default Value: 0

Start: 0

Stop: 74

Step: 1

        尝试修改你的samp_rate,会发现一些有意思的东西。这里设置的是32MSps.现在来设置UHD USRP Source的参数:

Samp Rate (Sps): samp_rate

Ch0: Center Freq (Hz): freq

Ch0: Gain (dB): gain

Ch0: Antenna: "TX/RX"

Ch0: Bandwidth (Hz): samp_rate

现在,我们的流图应该是这样的:

检查下你的设置是否正确。

使用软件进行频谱分析

        现在运行你的流图,你应该会看到你真实的信号。滑动相关按钮,注意图形的变化。默认的GNU Radio QT FFT sink内有许多有用的特性,例如均值和保峰值,尽量花一些时间去熟悉它们。

创建FM广播接收

        现在,有一个基本的接收器应用程序实时显示接收数据,让我们建立一个有用的应用程序!我们将添加更多的功能到流程,模块和数量如下:

1x Rational Resampler

1x WBFM Receiver

1x Audio Sink

2x Variable

        我们数据的流向是:USRP Source->Rational Resampler->WBFM Receiver->Audio Sink.按照这个顺序连接好这些模块,期间可能会有报错,现在我么就来修改相应的参数,来解决这些报错。

        首先,添加两个variable blocks,设置相应的参数:

Variable:

ID: audio_interp

Value: 4

Variable:

ID: audio_rate

Value: 48e3

        现在让我们把之前的sample rate改为250e3(250kHz).

Variable: samp_rate

ID: samp_rate

Value: 250e3

        然后,我们配置其余的3个模块。

Audio Sink

        这是一个比较简单的模块。它需要信号流的输入并通过扬声器播放它们。这个模块在GR的音频库初始化,这个音频库是包含在GNU Radio配置里面的。这里面有一些常见的速率设置,最常见的就是48kHz,现在我们使用的就是这个速率的。

设置Audio Sink参数:

Sample Rate: audio_rate

OK to Block: "No"

        现在你只需要把你的速率设置为你的声卡支持的速率就可以了。

Rational Resampler

        我们设置的USRP Source的速率为samp_rate,数值为250e3。设置的Audio Sink的速率为audio rate,数值为48e3。这里有一个问题,我们的源数据的采样率不是音频速率的整数倍:250000/48000=5.208。为了解决这个问题,我们必须进行重采样,这就需要用到Rational Resampler模块,将输入的速率转化为输出的速率。

Rational Resampler允许我们调整数据流的速度,通过插值或者抽取实现的。因为进来的数据的采样率为250k,我们就设定抽取的数值为250k,但是采样率是一个浮点型数据,所以设置抽取数值的时候注意需要将其转换为整型。然后,我们插值,所以再来设置插入的数据。由于WBFM进行了一个4次插值,所以我们可以利用audio_interp和audio_rate设置插入的速率。这样,设置的参数如下:

Type: Complex->Complex (Complex Taps)

Interpolation: audio_rate * audio_interp

Decimation: int(samp_rate)

        其余的参数,默认就可以了。

WBFM Receiver

        现在来配置最后的解调模块。这里仅仅需要设置两个参数:输入的速率以及抽取值。通过之前的例子,我们知道,输入的速率就是Rational Resampler的输入速率,抽取的就是audio_rate.

Quadrature Rate: audio_rate * audo_interp

Audio Decimation: audio_interp

        注意这里的插入和抽取速率是可以自己设定,我们使用参数,是为了保证得到的结果一定是整数。


调试FM广播

        现在参数调整已经好了,应该看不到红色的报错信息了。整个流图如下:

        运行流图,应该可以看到如下的界面,不同的版本可能会有所差异。改变freq,调谐到本地的FM频段,通过电脑的扬声器就可以听到广播了。


总结

        现在我们已经利用GNU Radio成功的搭建了无线电的收发平台。这些应用相对来说是比较简单的,他们利用GNU Radio提供的模块直接连接硬件组成无线系统。也说明了,将仿真带入真实的无线电系统在GNU Radio平台下是一件比较容易的事情。


开始了解GRC

        我们已经知道GNU Radio是一个各种信号处理模块的“容器”。在这里,我们将从一个简单的例子讲起,展示如何使用GNU Radio Companion(GRC).我们需要清楚的是,GRC是允许我们创建Python文件图形的,不过流程图的方式更加简化了GNU Radio的使用。

        首先我们来看一下GNU Radio Companion的界面。它包括4个区域:模块库、工具栏、函数输出窗口和工作区域。

        学会一个东西最好的方法就是亲自尝试,想到一个问题,然后自己找出答案。大家可以首先在界面摸索,打开GRC的方式,在终端输入命令:

gnuradio-companion


找到自己需要的模块

        在右边的模块库里面有各种不同类型的信号处理模块,包括了GNU Radio的标准模块和我们初始化的模块。怎样快速的找到我们自己需要的模块呢?假设我们需要一个产生信号的模块,我们可以看到有一个叫做Waveform Generator的类型,打开就可以看到各种产生信号的模块了。那么假设我们需要一个展示波形图,但是又不确定哪种模块是效果最好的,又怎么办呢?我们在上一章节知道,有一个叫sink的类型,但是右边并没有发现sink的类型。这个时候我们就需要使用搜索的功能了,按Ctrl+f,或者点击搜索按钮,然后输入模块的关键字sink,我们可以看到很多关于sink的模块了:

现在让我们添加一个叫QT GUI Time Sink的模块。我们可以通过双击或拖动的方式。

修改模块的参数

        工作区域里面包含各种信号处理模块和变量。我们双击打开模块,设置它的参数属性。如下图:

        在不同的应用系统中,我们可能需要修改这些默认的参数。我们把原来的名字去掉,可以看到ID字样编程蓝色。这种颜色表明信息已经被修改,但是还没有保存。我们再尝试一下修改windows size为300,300,单击OK。然后我们可以看到尺寸的改变。然后,我们看到documentation:

        看用颜色标记的字段,我们知道ID用来确定python文件名字和相关类的名字。

        然后,我们删除掉ID里面的字符串,看到最底下出现了红色的报错信息,同时,ID也变成了红色,这样我们能够很方便的确定错误的所在。

        为了方便,我们取ID的名字为”tutorial_two_1”,同时将Generate Options改成”QT GUI”,因为我们采用的是QT GUI sink,而不是WX GUI sink,在最新版的GNU Radio,默认的是QT GUI.GRC是一个图形化的界面,它是基于python环境的。所以当我们执行一个流程图时,实际上我们真的运行的是一个python程序。ID是用来命名python文件名,与GRC文件保存在同样的路径下。默认情况下,ID是top_block,所以它创建一个为top_block.py的文件。更改ID使我们可以更改保存的文件名,以更好进行文件管理。

        这个GRC-Python连接另一个结果是,Python可以控制GRC的参数属性。事实上,所有的输入框属性或变量,我们使用时被解释为Python。这意味着我们可以使用Python调用设置属性,如调用NumPy或其他GNU Radio功能。这方面的一个常见用途是称为filter.firdes滤波器设计工具从GNU Radio建立我们的滤波器抽头。

        注意的另一个关键是接口不同的颜色。这些实际上对应于不同的数据类型,我们将在本教程后面稍后覆盖。


第一个信号流程图

        现在我们了解如何找到块,如何将它们添加到工作区,以及如何编辑块属性,我们尝试建立一个将信号输出到示波器的流程图,注意模块之间的数据类型的匹配:

        注意到有一个叫throttle block的模块:在本教程后面的更详细的解释是什么。现在,可以了解的是这个模块确保流程图不消耗100%的CPU周期,不然你的电脑可能反应不过来。

        在此之前,我们先来看一下工具栏。

        这里主要是一些流程图软件执行的一些命令,如新建,打开,保存等。让我们开始我们的流程图,我们给它取名叫做tutorial_two。这里有几个重要的工具,Generate flowgraph,excute flowgraph,分别是产生GRC,和运行GRC。在help里面的type,我们可以看到每种数据类型对应的颜色。


关于Generate Options设置

        Generate Options有两种常用的设置QT GUI和WX GUI。最常见的错误就是设置的Generate Options与实际我们用的不匹配。具体来讲,就是我们Generate Options设置的是QT GUI,但是我们构造的流程图却是WX GUI我们会的到如下的报错信息:

        反过来的话,也会得到类似的报错信息。所以,我们必须首先确定自己选用的是QT GUI还是WX GUI。


查看输出

        让我们点击Execute按钮启动程序,我们可以看到如下的波形:

        这是一个复数类型的波形。我们简单化一些,选用别的数据类型。关掉程序,我们打开Help-Type,可以看到如下的数据类型的代表颜色:

        在这里,我们基本上可以找到所有的数据类型。我们看到我们的流程图的接口是蓝色的,很明显这是32位浮点型组成复数形式,现在我们可以解释刚才输出有两个波形的情况了,Time Sink输入一个复数,然后输出它的实部和虚部。现在,我们尝试修改以下信号源的数据类型,将其改为浮点型,然后我们看到它的接口编程橘黄色的,当我们把它和Throttle Block连接时,看到有红色的报错,我们点击工具栏的红色的横杆,可以看到具体的报错信息:

        报错信息显示,数据长度不匹配。这是由于我们的数据类型不匹配的原因。GNU Radio不允许不同的数据类型之间直接连接。我们把所有的模块都改成浮点型的,然后再次运行,可以看到如下的波形:

        现在我们可以看到,只有一个波形输出了,我们可以尝试用鼠标放大或者缩小。


使用GNU Radio Companion

        现在我们已经能够创建自己的流图了,我们进一步的来学习一些GNU Radio Companion有关知识。

关于Throttle Block

        首先,我们来讨论下Throttle Block,之前在我们的流图有用到过。下图是添加Throttle 模块和不添加Throttle 模块的CPU的使用率对比:

        我们可以看到,当流图没有连接硬件也没有连接Throttle 的时候,CPU基本是满负载运行的。在一个流图中我们只需要一个Throttle 就可以了,不管它是有几个输入输出。我们可以认为Throttle 起到限速的作用,设置高的速率,流图执行快,设置低的速率流图执行慢。打个比方,比如我们设置Throttle 为1e6,另一个设置1e3,我们可以看到CPU在1e6的情况下比1e3占用更多的资源。当有硬件连接的时候,我们不需要Throttle 模块,因为硬件本身已经对速率有了限制。

关于采样率

        我们已经知道硬件需要设定特定的采样率来实现某些特定的功能,现在我们来自己创建一个GRC,来看看不同的采样率之间有什么区别:

根据上图配置好参数:

QT GUI Chooser模块设置3个采样速率,ID改为samp_rate

所有的source模块的Sampling Rate改为samp_rate

音频模块改为48e3

所有的sink模块的sampling rate改为audio_rate

        在这里,我们可以看到没有Throttle 模块,这是因为这里有音频硬件。点击运行,设置sample rate为48e3,可以听到熟悉的电话的拨号音,再看一下fft,确实有两个分别为440Hz和350Hz的频段。

        尝试下,当改变sampling rate比audio sampling低的时候,看能否还能听到拨号音。再尝试下,当改变sampling rate比audio sampling高的时候,看能否还能听到拨号音。正常的话,应该听不到拨号音,因为声卡的速率和我们采样的速率不匹配。所以,任何时候,都应该设置正确的采样率。


瀑布图

        现在来看一个由probe,soundcard以及QT Sink模块组成的正弦信号瀑布图:

        请参考上图设置好参数,另外,必须注意的是Audio Sink的Sample Rate。设置好后,点击运行,可以看到:


关于Throttle Block

        首先,我们来讨论下Throttle Block,之前在我们的流图有用到过。下图是添加Throttle 模块和不添加Throttle 模块的CPU的使用率对比:

        我们可以看到,当流图没有连接硬件也没有连接Throttle 的时候,CPU基本是满负载运行的。在一个流图中我们只需要一个Throttle 就可以了,不管它是有几个输入输出。我们可以认为Throttle 起到限速的作用,设置高的速率,流图执行快,设置低的速率流图执行慢。打个比方,比如我们设置Throttle 为1e6,另一个设置1e3,我们可以看到CPU在1e6的情况下比1e3占用更多的资源。当有硬件连接的时候,我们不需要Throttle 模块,因为硬件本身已经对速率有了限制。

关于采样率

        我们已经知道硬件需要设定特定的采样率来实现某些特定的功能,现在我们来自己创建一个GRC,来看看不同的采样率之间有什么区别:

根据上图配置好参数:

QT GUI Chooser模块设置3个采样速率,ID改为samp_rate

所有的source模块的Sampling Rate改为samp_rate

音频模块改为48e3

所有的sink模块的sampling rate改为audio_rate

        在这里,我们可以看到没有Throttle 模块,这是因为这里有音频硬件。点击运行,设置sample rate为48e3,可以听到熟悉的电话的拨号音,再看一下fft,确实有两个分别为440Hz和350Hz的频段。

        尝试下,当改变sampling rate比audio sampling低的时候,看能否还能听到拨号音。再尝试下,当改变sampling rate比audio sampling高的时候,看能否还能听到拨号音。正常的话,应该听不到拨号音,因为声卡的速率和我们采样的速率不匹配。所以,任何时候,都应该设置正确的采样率。


瀑布图

        现在来看一个由probe,soundcard以及QT Sink模块组成的正弦信号瀑布图:

        请参考上图设置好参数,另外,必须注意的是Audio Sink的Sample Rate。设置好后,点击运行,可以看到:


总结

        现在我们应该知道流图的基本原理,能有找到自己需要的信号处理模块,正确的设置采样率。如何发现并定位错误,怎样设置相应的数据类型,用户可以自己动手,多多尝试,这样就能够比较快的上手GRC了。

SDR软件
RFNoC
UHD
GNU Radio
LabVIEW
MATLAB & SIMULINK
OpenBTS
OpenAirInterface (OAI)
srsLTE
gqrx
关于我们
联系我们
关于CORAD
关于Ettus
产品介绍
USRP X系列
USRP 网口系列
USRP USB接口系列
USRP嵌入式系列
射频子板
天线
线缆
附件
其他服务
TNM网站
公司新闻
行业动态
入门培训
GNU Radio培训
Visual Studio开发环境配置
硬件安装指导
关注我们
版权信息
USRP中文官方网(ettus.com.cn)所发布展示的“产品信息”,“培训资料”版权归USRP中文官方网所有和发布企业所有,任何收集本站产品信息并未经USRP中文官方网许可,USRP中文官方网将保留追究侵权者法律责任的权利。

粤ICP备 06126740-7号 © Copyright 2015.Corad All rights reserved. ettus.com.cn