admin管理员组

文章数量:1536095

2024年7月18日发(作者:)

Exploring-gnuradio

简介:

软件无线电是一门让软件代码尽可能靠近接收天线的技术。它把无线电的硬

件问题放到软件中来解决。软件无线电最基本的特征是软件定义(调制)无线电

传输的波形,软件解调接收到的波形。这个和目前大多数的由模拟电路或者由模

拟数字组合电路组成的无线电有鲜明的区别。GNU Radio是一个开源的可以构

建软件无线电平台的软件包。

软 件无线电是无线电设计领域的一次革命,使得建立无线电设备更加灵活,给

用户带来更多的机遇。软件无线电能够很好的实现传统无线电所能实现的功能,

另外,软 件无线电最精彩的特性是由软件提供给我们的灵活性,一些年以后,

我们将会看到传统的由很多固定元件组成的无线电设备将会被通用的通信设备

来取代。可以想 像,一个软件无线电设备能够变体成为蜂窝电话,能够灵活的

使用GPRS,802.11 Wi-Fi,802.16 WiMax,卫星链路,或者将出现的其他通讯标准

进行通讯,而硬件设备无需改动,只需要软件设置。你能够决定使用GPS,GLONASS

或者两个一起使用来给自己定位。

也 许,最令人激动的是使用软件无线电来建立一个分布式个人通讯系统。

当今的通讯系统,大多数是采用自上而下的结构,广播和电视系统提供一个单向

链路,内容被 严格控制在一小部分人的手里。蜂窝电话系统给人们带来极大的

便利,但是你的手机提供的功能是由运营商来控制的,而不是你自己。这种集中

控制的系统限制了人们的创新,代替做蜂窝电话系统的二等公民,我们可以建造

一个智能设备,这些设备能够自组织的,在使用者之间建成一个网络。

处理流程图

图一,表示一个典型的软件无线电处理流程图。

为了理解无线电的软件模块,首先需要理解和其关联的硬件。在这个图中的接收

路径上,能够看到一个天线,一个神奇的RF前端,一个模拟数字转换器ADC

和一堆代码。ADC是一个连接连续模拟的自然世界和离散的数字世界的桥梁。

ADC有两个主要特性,抽样率和动态范围。抽样率是ADC测量模拟信号的速度,

动态范围是ADC区别最低信号值和最大信号值的精度,这决定ADC数字信号输出

的比特数(位数)。例如,8位的AD转换器最多能代表256个信号层次,而一

个16位的转换器能够代表65536个层次信号。总的来说,ADC的物理特性和价

格决定了抽样率和动态范围。

在我们深入研究软件之前,先来了解一些理论知识,在1927年,出生于瑞典

的物理和电子学家 Harry Nyquist提出了如果AD转换想没有混叠现象发生,那

么抽样率至少是目标信号带宽的2倍。

混叠现象就像是车子重复的碾在过去的车轮印迹上一样,让你分不清楚是本

次的还是以前碾过的车轮印迹。假设我们要处理一个低通信号,我们感兴趣的信

号带宽是 0到fmax,按照Nyquist理论,抽样率必须至少是2*fmax。如果我们

的ADC工作在20MHZ,但是我们想收听92.1MHZ的FM电台,我 们该怎么办呢?

答案是使用RF前端,接收机的RF前端能够把它接收到的高频段信号下变频到一

个低频段信号后输出。例如,我们能让RF前端把90- 100MHZ频段内的信号下变

频到0-10MHZ的低频范围内,那么我们的20MHZ的ADC就能够派上用场了。

大多数情况下,我们把RF前端当作一个信号控制的黑盒子,负责处理输

入信号的中心频率。举一个具体例子,一个调制解调器的调制模块能够把50M

到800M 之间的6M带宽的中心频率下变频到一个中心频率是5.75MHZ的输出。

这个输出的中心频率通常称作中频(IF)。

按照越简单越易用的原则,RF前端最好也能够被去掉,有一个GNU Radio

用户已经成功的使用一个100英尺(译注:等于12英寸,合0.305米)的天线

直接连接到一个20M抽样率的ADC上收听到了AM和短波广播。

深入软件内部

GNU Radio提供一个信号处理模块的库,并且有个机制可以把单个的处理

模块连接在一起形成一个系统。编程者通过建立一个流向图(flow graph)就能

搭建成一个无线电系统。信号处理模块是使用C++来实现的,理论上说,信号数

据流不停的从输入端口流入从输出端口流出。信号处理块 (blocks)的属性包括

输入和输出的端口数,流过它们的数据的类型,经常使用的数据流的类型是短整

型(short),浮点型(float),和复数 (complex)类型。一些处理模块仅仅有输入

端口或者输出端口,它们分别成为信号源(data source)和信号接收器(sink)。

有的信号源从文件或者ADC读入数据,信号接收器写入文件或者DAC或者PC的

多媒体接口。GNU Radio提供了超过100个信号处理块,并且扩展新的处理模块

也是非常容易的。软件图形化接口和信号处理模块的链接机制是通过python脚

本语言来进行的,例1,是一个GNURadio “Hello World”的例子。它产生两

个sine波形并且把他们输出到声卡,一个输出到声卡的左声道,一个输出到右

声道。

例子1.输出拨号音

#!/usr/bin/env python

from gnuradio import gr

from gnuradio import audio

def build_graph ():

sampling_freq = 48000

ampl = 0.1

fg = _graph ()

src0 = _source_f (sampling_freq, _SIN_WAVE, 350, ampl)

src1 = _source_f (sampling_freq, _SIN_WAVE, 440, ampl)

dst = (sampling_freq)

t ((src0, 0), (dst, 0))

t ((src1, 0), (dst, 1))

return fg

if __name__ == '__main__':

fg = build_graph ()

()

raw_input ('Press Enter to quit: ')

()

我们开始建立一个流向图(flow graph)把所有的信号处理模块连接到一

起,调用gr_sig_source_f产生两个sine波形,后缀f表面这个信号源的数据

类型是浮点型的,一 个波形是350HZ,另外一个是440HZ,合在一起他们听起来

像一个美国电话拨号音。audio_sink是一个接收器,它把接收到的信号输入到

声卡 中,我们把3个信号处理模块用流向图的connect方法连接到一起。connect

方法有两个参数,源端点和目的端点,用来建立一个从源到目的处理模块 的链

路。每个端点(endpoint)有两个成员:一个信号处理模块和一个端口号。端口号

表示哪个输入或者输出端口应该被连接的。通常端点使用 python语言的tuple

来表示,像:(block,port_number)。当端口号是0时,portt_number可以被

省略的。

下面的两个表示方法是一样的:

t ((src1, 0), (dst, 1))

t (src1, (dst, 1))

一旦流向图被建立了,我们调用start生成一个或者多个线程去运行

它,按下任意键程序控制权就会返回给调用者。

一个完整的FM接收机

例2是一个简单化的但是是一个完整的FM广播接收机,它包括对RF前端

的控制和所有FM信号的处理。这个例子的RF前端是使用一个cable调制解调器

和一个20M抽样率的ADC来实现的。

例广播接收机

#!/usr/bin/env python

from gnuradio import gr

from gnuradio import audio

from gnuradio import mc4020

import sys

def high_speed_adc (fg, input_rate):

# return _source (_short, "", False)

return (input_rate, _CH3_EN |

_ALL_1V)

#

# return a _graph

#

def build_graph (freq1, freq2):

input_rate = 20e6

cfir_decimation = 125

audio_decimation = 5

quad_rate = input_rate / cfir_decimation

audio_rate = quad_rate / audio_decimation

fg = _graph ()

# use high speed ADC as input source

src = high_speed_adc (fg, input_rate)

# compute FIR filter taps for channel selection

channel_coeffs =

_pass (1.0, # gain

input_rate, # sampling rate

250e3, # low pass cutoff freq

8*100e3, # width of trans. band

_HAMMING)

# input: short; output: complex

chan_filter1 =

_xlating_fir_filter_scf (cfir_decimation,

channel_coeffs,

freq1, # 1st station freq

input_rate)

(head1, tail1) = build_pipeline (fg, quad_rate, audio_decimation)

# sound card as final sink

audio_sink = (int (audio_rate))

# now wire it all together

t (src, chan_filter1)

t (chan_filter1, head1)

t (tail1, (audio_sink, 0))

return fg

def build_pipeline (fg, quad_rate, audio_decimation):

'''Given a flow_graph, fg, construct a pipeline

for demodulating a broadcast FM signal. The

input is the downconverted complex baseband

signal. The output is the demodulated audio.

build_pipeline returns a two element tuple

containing the input and output endpoints.

'''

fm_demod_gain = 2200.0/32768.0

audio_rate = quad_rate / audio_decimation

volume = 1.0

# input: complex; output: float

fm_demod = ture_demod_cf (volume*fm_demod_gain)

# compute FIR filter taps for audio filter

width_of_transition_band = audio_rate / 32

audio_coeffs = _pass (1.0, # gain

quad_rate, # sampling rate

audio_rate/2 -

width_of_transition_band,

width_of_transition_band,

_HAMMING)

# input: float; output: float

audio_filter = _filter_fff (audio_decimation, audio_coeffs)

t (fm_demod, audio_filter)

return ((fm_demod, 0), (audio_filter, 0))

def main (args):

nargs = len (args)

if nargs == 1:

# get station frequency from command line

freq1 = float (args[0]) * 1e6

else:

('usage: fm_demod freqn')

(1)

# connect to RF front end

rf_front_end = une_4937_eval_board ()

if not rf_front__present_p ():

raise IOError, 'RF front end not found'

# set front end gain

rf_front__AGC (300)

# determine the front end's "Intermediate Frequency"

IF_freq = rf_front__output_freq () # 5.75e6

# Tell the front end to tune to freq1.

# I.e., freq1 is translated down to the IF frequency

rf_front__RF_freq (freq1)

# build the flow graph

fg = build_graph (IF_freq, None)

() # fork thread(s) and return

raw_input ('Press Enter to quit: ')

()

if __name__ == '__main__':

main ([1:])

和Hello World的例子一样,这个例子建立了一个流向图,把所有的信

号处理模块连接到了一起然后开始运行。在这个例子中,是一个

和 Measurement Computing PCI-DAS 4020/12 高速 ADC的连接接口。在它后面

连接一个_xlating_fir_filter_scf,这是一个有限脉冲响应(FIR)滤

波器,负责选择 FM广播的电台频段并且把它变频到基带(0HZ,直流)。然后

用20M的converter和解调器,我们就能够接收到邻近的6MHZ带宽的频率了,

在这 个频带中大概能包含10个或者更多频道的FM电台。接着使用

_xlating_fir_filter_scf来选择一个我们想收听的频道。 在这个例子

中,我们选择了RF前端精确的中频频率5.75MHZ,

_xlating_fir_filter_scf的输出是一个经过 160,000次/秒的复采样

数据流,然后把复基带信号输出给ture_demod_cf进行积分取模,这

个模块负责真正的FM解调。 ture_demod_cf通过比较每个邻近的复

采样信号的角度(by subtracting the angle of each adjacent complex sample)

来有效的区分频率,ture_demod_cf的输出包含了FM立体声的左加右

声道信号(left-plus- right FM mono audio signal),19kHZ的立体声的控

制音(pilot tone),中心频率是38KHZ的左减右(left-minus-right)信号和

其他的在这个上面的次载波(sub-carriers)信号。在这 个简单的接收机中,

我们使用低通滤波和抽取滤波,提取出了left-plus-right信号信息, 把这个

信号送给声卡,经过声卡的32,000HZ的DAC,就能够把数字信号还原成模拟声

音,到此我们可以听到FM广播信号了。如果想进一步了解FM接收 机的原理,

请参考:"Listening to FM, Step by Step."

图形化用户接口

GNU Radio应用程序的图形化接口是使用python来实现的,接口能使用

pyhone的任何toolkit来实现,我们推荐使用wxPython,它能最大化的实现跨平

台应用。GNU Radio提供由C++到Python的连接机制。

硬件要求

GNU Radio是硬件独立的,今天带有单独浮点运算单元的上GHZ的CPU已经

很常见了,这给台式机实现数字信号处理功能带来了可能。一个3G的 Pentium

或者 Athlon处理器能够每秒处理30亿次浮点FIR运算。我们现在能够在PC上

建立软件通讯系统,这是几年前所不敢想象的。 你的硬件要求依赖于你想做什

么。总的来说,一个1G或者2G带有256M内存的机器应该是足够了。你也需要

一些其他的模拟外设连接在你的PC上,包括内置 的声卡或者96 kHz, 24-bit

高保真声卡。使用这些模拟设备,你只能处理有限的窄带信号。另外的方案是使

用高速的PCI模拟到数字的外设,这些设备可以达到20M的抽样率,但是他们是

比较昂贵的,差不多是买一台PC的价钱。使用这些高速板,调制解调器可以作

为RF前端来使用。 为了有一个更满意的替代产品,现在我们已经设计了一个通

用软件无线电外设(USRP)。

通用软件无线电外设

我们首选的硬件解决方案是USRP,USRP是Matt Ettus的杰作,USRP是

一个非常灵活的USB设备,它把你的PC连接到RF世界。USRP包含一个小

的母板,母板包含4个12bit /64M抽样率的ADC,4个14bit/128M DAC,一个

百万门的FPGA芯片和一个可编程的USB2.0控制器。每个USRP母板支持4

个子板,2个接收,2个发射。RF前端是实现在子板上的,不 同的子板处理不

同的频率带宽。作为业余无线电使用,可以选择低能量的能够接收和发送

440MHZ和1.24GHZ的子板。一个仅有接收功能的基于 cable modem 调谐的

子板覆盖50MHZ到800MHZ频率范围被设计成容易手工来做原型的,目的是

为了方便实验。

Figure 2. Universal Software Radio Peripheral

USRP 的灵活性得益于2个可编程的元件,通过他们和PC上的host端交

互。为了对USRP有一个初步映像,让我们看一下它的启动过程。USRP本身

不含有 ROM,仅仅有一个存储VendorID和productID和版本号信息的

EEPROM。当USRP插到PC的USB口上以后,主机上的程序通过 VID,PID

和版本号识别这是一个未配置的USRP,主机上的程序第一步要做的是下载一个

8051固件到USB控制芯片上,这个固件控制USB的行为。 当USB固件下载

好后,USRP模拟一个USB设备的重枚举过程,此后主机识别到一个不同的设

备,VID,PID和版本号都不同了。现在这个USB固件定 义USB端口,接口和

用户自定义命令。其中一个命令是load FPGA,收到这个命令后USB设备就能

够把FPGA配置bitstream下载到FPGA芯片中开始工作。

FPGA是一个通用硬件,它的行为完全由配置的bitstream来决定,你可以

把bitstream看作是一个目标码。这个bitsteam是由一个高 级硬件描述语言编

译得到的,在USRP里面这是由verilog硬件描述语言来实现的。这些代码是开

源的,和其他的GNU Radio代码一样,是基于GNU的GPL协议的。

FPGA职责

FPGA 像一个小的,高性能的并行计算机一样,可以完成你设计的任务,

设计FPGA需要一些技能,并且如果不慎还会烧坏你的板子。还好我们已经提

供一个标准的适应 性很广的FPGA配置。通过使用一个好的USB控制器,USRP

能够有32M/s的处理能力,USB是半双工的,基于你的需要,USB能够在传输

和接收之 间转换。在接收方式下,标准的配置能够允许你选择你感兴趣的频率,

同时完成基带化和抽取滤波的工作。和RF前端处理方法一样,但现在做的是在

数字域的采 样。执行这些功能的代码叫做数字下变频转换器DDC((Figure 3,

“Digital Down Converter Block Diagram”),利用这些处理我们能够在数字域

快速的改变中心频率。

在传输路径上,执行一个完全反过来的过程。FPGA包含多个数字上下变频实

例,根据需要这些实例连接到相同或者不同的ADC上面。鉴于篇幅,这里不能介

绍所有的理论,在GNU Radio的wiki上有更加多的信息可以参考。

GNU Radio应用

除了上面提到的例子,GNU Radio还实现了一个完全的HDTV传输和接收的例

子,一个频谱分析仪,一个示波器,以及并发多通道接收器和很多调制解调的例

子。

目前利用GNU Radio在研究和进行中的工程有

一个和TiVo类似的无线电设备,但是它能够同时记录多个电台的信号.

TDMA 波形

利用广播TV信号作为信号源的无源雷达系统。利用它你也许可以侦测到从你

上空飞过的飞机。

天文无线电(译注: 射电望远镜?)

TETRA 收发机

Digital Radio Mundial (DRM).

软件GPS

分布式传感器网络

分布式频谱利用测量系统

业余无线电收发机

Ad Hoc自组织网络

RFID 系统

多输入多输出系统(MIMO)

政策问题

每项革新都会遇到政治上的阻碍,构建软件无线电也会遇到麻烦,在美国,

我们不小心站到了全美音像学会(Motion Picture Association of America)的对立

面,他们对TV数字信号进行加密以限制不同的接收器。另外,美国联邦通讯委

员会也已经发布一个感知无线电和软件无线电的制造规则提议(Proposed Rule

Making (NPRM))。在NPRM中有几个麻烦的问题被提出,包括限制高速DAC

的销售,软件无线电发出的信号需要被授权,和限制未授权的软件无线电在业余

无线电市场上的销售。

总结

软件无线电是一个很有意义的领域,GNU Radio提供了一个探索软件无线电

领域的工具,想对软件无线电有一个深入的了解需要很多学科的知识积累。我们

所做的就是尽可能的降低这个入门的门槛。(完)

本文标签: 软件信号能够使用设备