通信人家园

 找回密码
 注册

只需一步,快速开始

短信验证,便捷登录

搜索

军衔等级:

  上等兵

注册:2016-11-212
跳转到指定楼层
1#
发表于 2016-11-21 16:43:57 |只看该作者 |倒序浏览
本帖最后由 weixingguang 于 2016-11-24 12:14 编辑

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



1. UHD库函数简介1.1 发送函数
新建一个usrp设备
  1. std::string args = " "; args指定USRP地址,配置USRP参数等
  2. uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
复制代码

设置时钟源和时钟频率
  1. std::string ref = "internal"; // internal,external, MIMO.
  2. usrp->set_clock_source(ref);
  3. double rate = 40e6;
  4. usrp->set_master_clock_rate(rate);
  5. usrp->get_clock_source() //获取当前的时钟源
  6. usrp->get_clock_sources() //获取所有可用的时钟源
  7. usrp->get_master_clock_rate(); //获取时钟频率
复制代码

设置采样率
  1. double samp_rate = 20e6;
  2. usrp->set_tx_rate(samp_rate);
  3. usrp->get_tx_rate() //获取当前的采样率
  4. usrp->get_tx_rates() //获取采样率的采样范围
复制代码

设置发射中心频点
  1. double freq = 2.412e9;
  2. usrp->set_tx_freq(freq);
  3. usrp->get_fe_tx_freq_range();
  4. usrp->get_tx_freq();
  5. usrp->get_tx__freq_range();
复制代码

设置发射增益
  1. double tx_gain = 60;
  2. usrp->set_tx_gain(tx_gain);
复制代码

设置发射天线
默认情况下无需设置发射天线,如需指定特定发射天线时设置。
  1. usrp->set_tx_antenna(0);
  2. usrp->get_tx_antenna();
  3. usrp->get_tx_antennas();
复制代码

创建发送流
新建发送流参数
  1. std::string cpu_format = "fc32";
  2. 目前cpu_format支持的类型有:fc64 - complex fc32 - complex sc16 - complex sc8 - complex
  3. std::string wire_format = "sc16";
  4. 目前wire_format支持的类型有:sc16 - Q16 I16 sc8 - Q8_1 I8_1 Q8_0 I8_0
  5. uhd::stream_args_t stream_args(cpu_format,wire_format);
  6. uhd::tx_streamer::sptr tx_stream =usrp->get_tx_stream(stream_args);
复制代码

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


1.2 接收函数
创建一个usrp
  1. std::string args = " ";
  2. uhd::usrp::multi_usrp::sptr usrp =uhd::usrp::multi_usrp::make(args);
复制代码

设置时钟源和时钟频率
  1. std::string ref = "internal"; //internal,external and MIMO
  2. usrp->set_clock_source(ref);
  3. double clock_rate = 40e6;
  4. usrp->set_master_clock_rate(clock_rate);
复制代码

设置采样率
  1. double rate = 20e6;
  2. usrp->set_rx_rate(rate);
复制代码

设置中心频率
  1. double freq = 2.412e9;
  2. usrp->set_rx_freq(freq);
复制代码

设置增益
  1. double rx_gain = 50;
  2. usrp->set_rx_gain(rx_gain);
复制代码

创建接收流
  1. std::string cpu_format = "fc32";
  2. std::string wire_format = "sc16";
  3. uhd::stream_args_t stream_args(cpu_format,wire_format);
  4. uhd::rx_streamer::sptr rx_stream =usrp->get_rx_stream(stream_args);
复制代码

设置接收模式
  1. uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
  2. //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
  3. stream_cmd.num_samps = 1000; // 接收采样点数
  4. stream_cmd.stream_now = true; //现在开始接收
  5. rx_stream->issue_stream_cmd(stream_cmd); //配置rx_stream参数
复制代码


2. USRP发送数据
  代码实现USRP发送二进制文件802.11a_BUPT41.seg内的数据。里面的数据为float complex类型,复数的实部和虚部交替存储。即如下图所示。用户可以把要发送的数据生成对应的二进制文件,也可以直接写成数组放在代码中。注意:float类型数据的单位1就是 “1”。
这里写图片描述
源码
  1. #include <uhd/usrp/multi_usrp.hpp>
  2. #include <signal.h>
  3. #define SAMPLE_PER_BUFF 2000
  4. int stop_signal_called = 0;
  5. void sig_int_handle(int)
  6. {
  7. stop_signal_called = 1;
  8. printf("stop tx.........\n");
  9. exit(0);
  10. }
  11. int main()
  12. {
  13. std::string addr_args = " ";
  14. uhd::usrp::multi_usrp::sptr usrp =uhd::usrp::multi_usrp::make(addr_args);
  15. printf("Create a usrp......\n");
  16. // set the ref and clock rate
  17. std::string ref = "internal";
  18. usrp->set_clock_source(ref);
  19. float clock_rate = 40e6;
  20. usrp->set_master_clock_rate(clock_rate);
  21. printf("set the clock rate %0.2f \n",usrp->get_master_clock_rate() );
  22. // set the sample rate
  23. float samp_rate = 20e6;
  24. usrp->set_tx_rate(samp_rate);
  25. printf("set the tx sample rate to %0.2f \n",usrp->get_tx_rate());
  26. // set the center frequency
  27. float center_freq = 2.412e9;
  28. usrp->set_tx_freq(center_freq);
  29. printf("set the tx center freq to %0.2f \n",usrp->get_tx_freq());
  30. // set the rf gain
  31. float tx_gain = 90;
  32. usrp->set_tx_gain(tx_gain);
  33. printf("set the tx gain to %0.2f \n",usrp->get_tx_gain());
  34. // create a tx stream
  35. std::string cpu_format = "fc32";
  36. std::string wire_format = "sc16";
  37. uhd::stream_args_t stream_args(cpu_format,wire_format);
  38. uhd::tx_streamer::sptr tx_stream =usrp->get_tx_stream(stream_args);
  39. uhd::tx_metadata_t md;
  40. // catch the INT signal
  41. signal(SIGINT, sig_int_handle);
  42. float read_buff[SAMPLE_PER_BUFF * 2] = {0};
  43. while(!stop_signal_called)
  44. {
  45. FILE *fp = fopen("802.11a_BUPT41.seg","rb");
  46. md.start_of_burst = false;
  47. md.end_of_burst = false;
  48. while( (!md.end_of_burst) && (!stop_signal_called))
  49. {
  50. int read_length = 0;
  51. if( (read_length = fread(read_buff, sizeof(uint32_t),SAMPLE_PER_BUFF * 2, fp) ) == (SAMPLE_PER_BUFF * 2) )
  52. {
  53. //int index;
  54. //for(index = 0; index < SAMPLE_PER_BUFF * 2;index++)
  55. // printf("%0.2f ", read_buff[index]);
  56. //puts("");
  57. //md.start_of_burst = true;
  58. tx_stream->send(read_buff, SAMPLE_PER_BUFF, md);
  59. //md.start_of_burst = false;
  60. //sleep(1);
  61. }
  62. else if(read_length >= 0)
  63. {
  64. md.end_of_burst = true;
  65. }
  66. }
  67. fclose(fp);
  68. }
  69. return 0;
  70. }
复制代码

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


3. USRP接收数据
  启动USRP,并使USRP一直接收数据。
源码
  1. #include <uhd/usrp/multi_usrp.hpp>
  2. #include <csignal>
  3. #define SAMPLE_PER_BUFF 2000
  4. int stop_signal_called = false;
  5. void sig_int_handle()
  6. {
  7. stop_signal_called = true;
  8. }
  9. int main()
  10. {
  11. std::string addr_args = " ";
  12. uhd::usrp::multi_usrp::sptr usrp =uhd::usrp::multi_usrp::make(addr_args);
  13. // set the clock source and clock rate
  14. std::string ref = "internal";
  15. usrp->set_clock_source(ref);
  16. float clock_rate = 40e6;
  17. usrp->set_master_clock_rate(clock_rate);
  18. printf("set the clock rate %0.2f \n",usrp->get_master_clock_rate() );
  19. // set the sample rate
  20. float samp_rate = 20e6;
  21. usrp->set_rx_rate(samp_rate);
  22. printf("set the tx sample rate to %0.2f \n",usrp->get_rx_rate());
  23. // set the center frequency
  24. float center_freq = 2.412e9;
  25. usrp->set_rx_freq(center_freq);
  26. printf("set the tx center freq to %0.2f \n",usrp->get_rx_freq());
  27. // set the rf gain
  28. float rx_gain = 80;
  29. usrp->set_rx_gain(rx_gain);
  30. printf("set the tx gain to %0.2f \n",usrp->get_rx_gain());
  31. std::string cpu_format = "fc32";
  32. std::string wire_format = "sc16";
  33. uhd::stream_args_t stream_args(cpu_format,wire_format);
  34. uhd::rx_streamer::sptr rx_stream =usrp->get_rx_stream(stream_args);
  35. uhd::rx_metadata_t md;
  36. //uhd::stream_cmd_tstream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
  37. uhd::stream_cmd_tstream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
  38. stream_cmd.num_samps = SAMPLE_PER_BUFF;
  39. stream_cmd.stream_now = true;
  40. //stream_cmd.time_spec = uhd::time_spec_t();
  41. stream_cmd.time_spec = usrp->get_time_now();
  42. rx_stream->issue_stream_cmd(stream_cmd);
  43. uint32_t buff[SAMPLE_PER_BUFF*2] = {0};
  44. unsigned long long num_total_samps = 0;
  45. while(!stop_signal_called)
  46. {
  47. //int num_rx_samps = rx_stream->recv(buff,SAMPLE_PER_BUFF, md);
  48. memset(buff, 0, SAMPLE_PER_BUFF * sizeof(uint32_t));
  49. int num_rx_samps = rx_stream->recv(buff,SAMPLE_PER_BUFF, md, 3.0, false);
  50. if(md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
  51. {
  52. printf("Timeout while streaming......\n");
  53. break;
  54. }
  55. if(md.error_code ==uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
  56. {
  57. printf("Overflowing while stream......\n");
  58. continue;
  59. }
  60. if(md.error_code !=uhd::rx_metadata_t::ERROR_CODE_NONE)
  61. {
  62. //printf("Receive error: %s \n",md.strerror());
  63. continue;
  64. }
  65. //rintf("num_rx_samps = %d\n",num_rx_samps);
  66. num_total_samps += num_rx_samps;
  67. }
  68. printf("num_total_samps = %d \n",num_total_samps);
  69. stream_cmd.stream_mode =uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
  70. rx_stream->issue_stream_cmd(stream_cmd);
  71. return 0;
  72. }
复制代码

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


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



举报本楼

您需要登录后才可以回帖 登录 | 注册 |

手机版|C114 ( 沪ICP备12002291号-1 )|联系我们 |网站地图  

GMT+8, 2024-11-20 00:36 , Processed in 0.354253 second(s), 15 queries , Gzip On.

Copyright © 1999-2023 C114 All Rights Reserved

Discuz Licensed

回顶部