设备同步

下面的应用注意解释了怎么去同步多台设备,为了达成发送或接收时间同步采样,在mimo或者其它需要多台设备同步操作的应用中。

注意:下面的内容不能用于usrp1.

通用参考信号:

usrp使用两个参考信号去同步同步时间和时钟:

  1. 一个10M的参考,给两台设备提供信号频率参考。
  2.  一个pps,用于跨平台的采样时间同步。
  3. mimo cable 发送编码的时间消息从一个设备到另一个设备。

PPS和10M的参考信号:

连接设备上的射频接口到参考时钟源。典型的,这些信号由一个外部的GPSDO。然而,一些usrp设备可以提供时钟。

usrp->set_clock_source("external");
usrp->set_time_source("external");

某些时候,pps的延时将会导致其到达设备的时间在FPGA的时钟持续时间内,这将引起pps的边沿和FPGA的时钟分散。在这种情况下,可以使用下面的设置:

usrp->set_time_source("_external_");

注2:对于为外部SMA连接器生成自己信号的用户,PPS应使用10 MHz参考时钟。 有关特定信号要求,请参阅设备的应用说明。

MIMO cable reference signals

用mimo cable共享参考源(USRP2和N系列)。mimo cable 用来同步一台设备和另一台设备。mimo cable的用户可以用方法一去(下面解释)同步多台成对的设备。

同步设备时间:

PPS信号的目的是同步的将时间锁存到设备中,你可以用 uhd::usrp::multi_usrp::set_time_next_pps()函数来初始化采样时间为0或者一个绝对的时间,比如说一个GPS时间或者UTC时间。对于到达同步设备的目的,设置的初始化时间是没有太大影响的。

方法一:轮询USRP时间寄存器

一个初始化PPS边缘的方法是轮询从设备处得到的“last pps”的时间,当这个时间发生改变的时候就意味着一个pps已经发生了。

const uhd::time_spec_t last_pps_time = usrp->get_time_last_pps();
while (last_pps_time == usrp->get_time_last_pps()){
    //sleep 100 milliseconds (give or take)
}
// This command will be processed fairly soon after the last PPS edge:
usrp->set_time_next_pps(uhd::time_spec_t(0.0));

以上代码实现了以pps为基准,设置了设备的时间,当大家都检测到pps到来的时候将设备的时间设置为0.

方法二:请求GPSDO时间

大多数的GPSDO可以通过配置实现每一个PPS都通过串口输出一个NMEA字符串,用户可以通过等待这个字符串来确定PPS的边沿,也可以通过解析这个字符串得到GPS时间:

//call user's function to wait for NMEA message...
usrp->set_time_next_pps(uhd::time_spec_t(0.0));
-- OR --
//call user's function to wait for NMEA message...
//call user's function to parse the NMEA message...
gps_time = VALUE_IN_NMEA_MESSAGE;
// At the next PPS edge, set the device time to the GPS time:
usrp->set_time_next_pps(uhd::time_spec_t(gps_time+1));
// Now the device time should be in sync with the GPS time.

这样就同步了设备的时间。通过查看sync_to_gps 例子得到更多的细节。

方法三:mimo cable

这种方法仅仅应用在USRP2和N200/N210上,这种方法不需要再接pps,但是只能同步两台设备。

通过mimo cable一个USRP2设备可以和另一台实现时间同步,和其它方法不同,这种方法,这种方法并不是用真正的"pulse per second".在本方法中,usrp设备通过米末cable发送一个编码的时间消息。从设备就会和主设备自动实现时间同步。参见Using the MIMO Cable for more detail.

同步通道相位:

在DSP中实现相位同步

为了实现USRP设备间的相位同步,两台usrp设备之间的相位偏移必须一样。通过在流命令中加上时间属性很容易实现这一目标,它可以指导流在特定的时刻开始。当设备已经通过10M和pps实现同步之后,流将会在精准的同一时刻开始。相位偏移在每一个 start-of-burst命令中重置,因此用户可以保证每一个start-of-burst在同一时间进行。

在接收端,一个突发当用户发布一个流命令的时候才会开始,这个流命令含有一个时间标签:

uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
stream_cmd.num_samps = samps_to_recv;
stream_cmd.stream_now = false;
stream_cmd.time_spec = time_to_recv;
usrp->issue_stream_cmd(stream_cmd);

对于发送端,当用户调用send()是一个突发才会发送,相应的元数据应该有一个时间时间标签:

uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = true;
md.time_spec = time_to_send;
//send a single packet
size_t num_tx_samps = tx_streamer->send(buffs, samps_to_send, md);

在射频前端同步lo(本振)

运用时间命令,多个前端在同一时刻转换。这个时间转换确保相位锁相环引入的相位误差保持为一个常数。

只有X3x0系列支持与UBX的相位同步
与SBX的相位同步适用于N2x0和X3x0系列
任何两个前端之间都存在随机相位偏移
对于不同的LO频率,该相位偏移是不同的
重新调整后,此相位偏移保持不变
由于热和其他特性,该相位偏移将随时间漂移
相位相干应用需要定期校准

相应代码片段:

//we will tune the frontends in 100ms from now
uhd::time_spec_t cmd_time = usrp->get_time_now() + uhd::time_spec_t(0.1);
//sets command time on all devices
//the next commands are all timed
usrp->set_command_time(cmd_time);
//tune channel 0 and channel 1
usrp->set_rx_freq(1.03e9, 0); // Channel 0
usrp->set_rx_freq(1.03e9, 1); // Channel 1
//end timed commands
usrp->clear_command_time();

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在USRP N321上启用两个通道,并使用C语言编写相应的代码,你需要使用UHD(USRP Hardware Driver)库和相关函数来控制USRP设备。 以下是一个简单的示例代码,演示了如何在USRP N321上启用两个通道: ```c #include <stdio.h> #include <uhd.h> int main() { uhd_usrp_handle usrp; uhd_stream_args_t stream_args; uhd_stream_cmd_t stream_cmd; uhd_rx_metadata_handle metadata; // 创建USRP设备句柄 uhd_usrp_make(&usrp, ""); // 设置通道A的参数 uhd_stream_args_set_channel(&stream_args, 0); uhd_stream_args_set_cpu_format(&stream_args, UHD_STREAM_CPU_FORMAT_SC16); // 设置通道B的参数 uhd_stream_args_set_channel(&stream_args, 1); uhd_stream_args_set_cpu_format(&stream_args, UHD_STREAM_CPU_FORMAT_SC16); // 创建接收流 uhd_rx_streamer_make(&usrp, &stream_args, &metadata); // 启动接收流 uhd_rx_streamer_start(&usrp, &stream_cmd, NULL, 0); // 接收数据并进行处理 while (1) { uhd_rx_streamer_recv(&usrp, buffer, num_samples, &metadata, timeout); // 在这里处理接收到的数据 } // 关闭接收流 uhd_rx_streamer_stop(&usrp); // 释放资源 uhd_usrp_free(&usrp); return 0; } ``` 在这个示例代码中,你需要使用UHD库中的函数来创建USRP设备句柄,设置通道参数,创建流对象,启动接收流,并进行数据处理。请确保已经正确安装了UHD库,并在编译时链接该库。 请注意,这只是一个示例代码,你可能需要根据具体的需求进行修改和完善。具体的参数和配置取决于你要实现的功能和USRP设备的具体配置。 希望这个示例能对你有所帮助!如果你有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值