热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UHDC/C++编程实例USRP发送、接收数据

UHDCC++编程实例USRP发送、接收数据,Go语言社区,Golang程序员人脉社

UHD C/C++ 编程实例 USRP发送、接收数据

如有相关问题,欢迎随时讨论交流 jxwxg@foxmail.com

1. UHD库函数简介

1.1 发送函数

新建一个usrp设备
std::string args = " "; args指定USRP地址,配置USRP参数等
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);

设置时钟源和时钟频率
std::string ref = "internal"; // internal, external, MIMO.
usrp->set_clock_source(ref);
double rate = 40e6;
usrp->set_master_clock_rate(rate);

usrp->get_clock_source() //获取当前的时钟源
usrp->get_clock_sources() //获取所有可用的时钟源
usrp->get_master_clock_rate(); //获取时钟频率

设置采样率
double samp_rate = 20e6;
usrp->set_tx_rate(samp_rate);

usrp->get_tx_rate() //获取当前的采样率
usrp->get_tx_rates() //获取采样率的采样范围

设置发射中心频点
double freq = 2.412e9;
usrp->set_tx_freq(freq);

usrp->get_fe_tx_freq_range();
usrp->get_tx_freq();
usrp->get_tx__freq_range();

设置发射增益
double tx_gain = 60;
usrp->set_tx_gain(tx_gain);

设置发射天线
默认情况下无需设置发射天线,如需指定特定发射天线时设置。
usrp->set_tx_antenna(0);
usrp->get_tx_antenna();
usrp->get_tx_antennas();

创建发送流
新建发送流参数
std::string cpu_format = "fc32";
目前cpu_format支持的类型有:fc64 - complex fc32 - complex sc16 - complex sc8 - complex
std::string wire_format = "sc16";
目前wire_format支持的类型有:sc16 - Q16 I16 sc8 - Q8_1 I8_1 Q8_0 I8_0

uhd::stream_args_t stream_args(cpu_format, wire_format);
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);

中频数据管理
uhd::tx_metada_t md; //结构体描述接收到的中频信号
md.start_of_burst = false; // 设置为真的时候发送第一个数据包
md.end_of_burst = false; // 设置为真的时候发送最后一个数据包
md.has_time_spec = false; // 设置为false时立即发送,设置为真的时候在特定时间发送

1.2 接收函数

创建一个usrp
std::string args = " ";
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);

设置时钟源和时钟频率
std::string ref = "internal"; //internal, external and MIMO
usrp->set_clock_source(ref);

double clock_rate = 40e6;
usrp->set_master_clock_rate(clock_rate);

设置采样率
double rate = 20e6;
usrp->set_rx_rate(rate);

设置中心频率
double freq = 2.412e9;
usrp->set_rx_freq(freq);

设置增益
double rx_gain = 50;
usrp->set_rx_gain(rx_gain);

创建接收流
std::string cpu_format = "fc32";
std::string wire_format = "sc16";
uhd::stream_args_t stream_args(cpu_format, wire_format);
uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);

设置接收模式
uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);

//UHD_STREAM_MODE_START_COnTINUOUS=97, //UHD_STREAM_MODE_STOP_COnTINUOUS=111, //UHD_STREAM_MODE_NUM_SAMPS_AND_DOnE=100, //UHD_STREAM_MODE_NUM_SAMPS_AND_MORE=109

stream_cmd.num_samps = 1000; // 接收采样点数
stream_cmd.stream_now = true; //现在开始接收
rx_stream->issue_stream_cmd(stream_cmd); //配置rx_stream参数

2. USRP发送数据

  代码实现USRP发送二进制文件802.11a_BUPT41.seg内的数据。里面的数据为float complex类型,复数的实部和虚部交替存储。即如下图所示。用户可以把要发送的数据生成对应的二进制文件,也可以直接写成数组放在代码中。注意:float类型数据的单位1就是 “1”。
这里写图片描述

源码

#include 
#include 

#define SAMPLE_PER_BUFF 2000

int stop_signal_called = 0;
void sig_int_handle(int)
{
    stop_signal_called = 1;
    printf("stop tx.........n");
    exit(0);
}

int main()
{
    std::string addr_args = " ";
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(addr_args);
    printf("Create a usrp......n");

    // set the ref and clock rate
    std::string ref = "internal";
    usrp->set_clock_source(ref);

    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f n", usrp->get_master_clock_rate() );

    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_tx_rate(samp_rate);
    printf("set the tx sample rate to %0.2f n", usrp->get_tx_rate());

    // set the center frequency
    float center_freq = 2.412e9;
    usrp->set_tx_freq(center_freq);
    printf("set the tx center freq to %0.2f n", usrp->get_tx_freq());

    // set the rf gain
    float tx_gain = 90;
    usrp->set_tx_gain(tx_gain);
    printf("set the tx gain to %0.2f n", usrp->get_tx_gain());


    // create a tx stream
    std::string cpu_format = "fc32";
    std::string wire_format = "sc16";
    uhd::stream_args_t stream_args(cpu_format, wire_format);
    uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);

    uhd::tx_metadata_t md;

    // catch the INT signal
    signal(SIGINT, sig_int_handle);
    float read_buff[SAMPLE_PER_BUFF * 2] = {0};

    while(!stop_signal_called)
    {
        FILE *fp = fopen("802.11a_BUPT41.seg", "rb");
        md.start_of_burst = false;
        md.end_of_burst = false;


        while( (!md.end_of_burst) && (!stop_signal_called) )
        {
            int read_length = 0;
            if( (read_length = fread(read_buff, sizeof(uint32_t), SAMPLE_PER_BUFF * 2, fp) ) == (SAMPLE_PER_BUFF * 2) )
            {
                //int index;
                //for(index = 0; index 
                //    printf("%0.2f ", read_buff[index]);
                //puts("");

                //md.start_of_burst = true;
                tx_stream->send(read_buff, SAMPLE_PER_BUFF, md);
                //md.start_of_burst = false;
                //sleep(1);
            }
            else if(read_length >= 0)
            {
                md.end_of_burst = true;
            }
        }

        fclose(fp);
    }


    return 0;
}

编译
g++ 编译时需要链接uhd库,系统需提前安装UHD驱动。具体过程参见之前博客。Ubuntu14.04 源码安装 UHD3.8.0
g++ tx.cpp -o tx -luhd

3. USRP接收数据

  启动USRP,并使USRP一直接收数据。

源码

#include 
#include 

#define SAMPLE_PER_BUFF 2000

int stop_signal_called = false;
void sig_int_handle()
{
    stop_signal_called = true;
}

int main()
{
    std::string addr_args = " ";
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(addr_args);

    // set the clock source and clock rate
    std::string ref = "internal";
    usrp->set_clock_source(ref);

    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f n", usrp->get_master_clock_rate() );

    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_rx_rate(samp_rate);
    printf("set the tx sample rate to %0.2f n", usrp->get_rx_rate());

    // set the center frequency
    float center_freq = 2.412e9;
    usrp->set_rx_freq(center_freq);
    printf("set the tx center freq to %0.2f n", usrp->get_rx_freq());

    // set the rf gain
    float rx_gain = 80;
    usrp->set_rx_gain(rx_gain);
    printf("set the tx gain to %0.2f n", usrp->get_rx_gain());

    std::string cpu_format = "fc32";
    std::string wire_format = "sc16";
    uhd::stream_args_t stream_args(cpu_format, wire_format);
    uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);

    uhd::rx_metadata_t md;

    //uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
    stream_cmd.num_samps = SAMPLE_PER_BUFF;
    stream_cmd.stream_now = true;
    //stream_cmd.time_spec = uhd::time_spec_t();
    stream_cmd.time_spec = usrp->get_time_now();
    rx_stream->issue_stream_cmd(stream_cmd);

    uint32_t buff[SAMPLE_PER_BUFF*2] = {0};
    unsigned long long num_total_samps = 0;

    while(!stop_signal_called)
    {
        //int num_rx_samps = rx_stream->recv(buff, SAMPLE_PER_BUFF, md);
        memset(buff, 0, SAMPLE_PER_BUFF * sizeof(uint32_t));
        int num_rx_samps = rx_stream->recv(buff, SAMPLE_PER_BUFF, md, 3.0, false);
        if(md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
        {
            printf("Timeout while streaming......n");
            break;
        }
        if(md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
        {
            printf("Overflowing while stream......n");
            continue;
        }
        if(md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
        {
            //printf("Receive error: %s n", md.strerror());
            continue;
        }

    //printf("num_rx_samps = %d n",num_rx_samps);
        num_total_samps += num_rx_samps;

    }
    printf("num_total_samps = %d n", num_total_samps);

    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
    rx_stream->issue_stream_cmd(stream_cmd);

    return 0;
}

编译
g++ 编译时需要链接uhd库,系统需提前安装UHD驱动。具体过程参见之前博客。Ubuntu14.04 源码安装 UHD3.8.0
g++ rx.cpp -o rx -luhd

4. 结论

  以上代码在Ubuntu上采用USRP B200测试通过。
  掌握UHD库函数的使用、g++ 链接 UHD库等是基于USRP开发软件无线电项目的基础。之后,我们可以进一步设计发送程序和接收程序,用USRP搭建一套SDR 收发系统。


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
author-avatar
FM向前
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有