[实战] 用1 PPS 驯服本地恒温晶振(OCXO/TCXO)
1 PPS 驯服本地恒温晶振(OCXO/TCXO)
“让任何工程师都能在一周内做出自己的 GPSDO”
文章目录
- 1 PPS 驯服本地恒温晶振(OCXO/TCXO)
-
- 前言
- 1 系统总体框图
- 2 硬件清单与连接
- 3 时间间隔测量(TDC)原理
- 4 数字锁相环算法
-
- 4.1 算法总览
- 4.2 卡尔曼滤波器模型
- 4.3 二阶 PLL 控制器
- 5 实时运行步骤
- 6 调参 & 常见问题
- 7 性能测试
前言
“把 1 PPS 的长期准确度与 OCXO 的短期稳定度合二为一,是射频实验室里最划算的高稳时钟方案。”
GPS/北斗等卫星接收机输出的 1 PPS(1 Pulse-Per-Second) 长期频率准确度可达
σ y ( τ = 1 d a y ) ≈ 1 × 1 0 − 12 , \\sigma_y(\\tau=1\\ \\mathrm{day}) \\approx 1 \\times 10^{-12}\\ , σy(τ=1 day)≈1×10−12 ,
但短期抖动较大( σ x ≈20 n s rms \\sigma_x \\approx 20\\ \\mathrm{ns}\\ rms σx≈20 ns rms)。
本地 OCXO(恒温晶振) 的短期 Allan 方差优良:
σ y ( τ = 1 s ) ≈ 2 × 1 0 − 12 , \\sigma_y(\\tau=1\\ \\mathrm{s}) \\approx 2 \\times 10^{-12}\\ , σy(τ=1 s)≈2×10−12 ,
却存在缓慢漂移( ≈2×1 0 − 10 / d a y \\approx 2 \\times 10^{-10}/\\mathrm{day} ≈2×10−10/day)。
“驯服”就是用 数字锁相环(DPLL) 把两者的优点无缝融合:
- 用 1 PPS 的长期准确度 持续校准 OCXO;
- 用 OCXO 的短期稳定度 平滑 1 PPS 的抖动。
本文给出一条 从天线到 10 MHz 超低噪声时钟 的完整信号链,所有器件均在淘宝/立创可购,硬件成本 < 500 元。读完即可动手。
1 系统总体框图
#mermaid-svg-pTm4xhVFWsCmHHlt {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .error-icon{fill:#552222;}#mermaid-svg-pTm4xhVFWsCmHHlt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pTm4xhVFWsCmHHlt .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-pTm4xhVFWsCmHHlt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pTm4xhVFWsCmHHlt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pTm4xhVFWsCmHHlt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pTm4xhVFWsCmHHlt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pTm4xhVFWsCmHHlt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pTm4xhVFWsCmHHlt .marker.cross{stroke:#333333;}#mermaid-svg-pTm4xhVFWsCmHHlt svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pTm4xhVFWsCmHHlt .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .cluster-label text{fill:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .cluster-label span{color:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .label text,#mermaid-svg-pTm4xhVFWsCmHHlt span{fill:#333;color:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .node rect,#mermaid-svg-pTm4xhVFWsCmHHlt .node circle,#mermaid-svg-pTm4xhVFWsCmHHlt .node ellipse,#mermaid-svg-pTm4xhVFWsCmHHlt .node polygon,#mermaid-svg-pTm4xhVFWsCmHHlt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pTm4xhVFWsCmHHlt .node .label{text-align:center;}#mermaid-svg-pTm4xhVFWsCmHHlt .node.clickable{cursor:pointer;}#mermaid-svg-pTm4xhVFWsCmHHlt .arrowheadPath{fill:#333333;}#mermaid-svg-pTm4xhVFWsCmHHlt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pTm4xhVFWsCmHHlt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pTm4xhVFWsCmHHlt .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-pTm4xhVFWsCmHHlt .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-pTm4xhVFWsCmHHlt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pTm4xhVFWsCmHHlt .cluster text{fill:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt .cluster span{color:#333;}#mermaid-svg-pTm4xhVFWsCmHHlt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pTm4xhVFWsCmHHlt :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 1 PPS SPI Vc 50 MHz 10 MHz UART GNSS
NEO-M8T FPGA
EP4CE6 DAC
AD5761R OCXO
JKOC36C 50 MHz 输出缓冲 上位机
信号说明
2 硬件清单与连接
关键连线
- 1 PPS → FPGA IO(LVTTL,3.3 V)。
- 50 MHz → FPGA CLK0 → PLL 内部倍频 200 MHz 作为 TDC 计数时钟。
- DAC SPI → FPGA GPIO(SCLK/SDI/CS)。
- DAC OUT → OPA277 ×1 → OCXO VC。
3 时间间隔测量(TDC)原理
FPGA 内部 抽头延迟线(Tapped Delay Line) 实现 <200 ps 分辨率:(伪代码)
reg [127:0] delay_line /* synthesis keep */;always @(posedge clk200) delay_line <= {delay_line[126:0], 1pps};reg [6:0] tdc_cnt;always @(negedge clk1hz_local) begin integer i; tdc_cnt <= 7\'d0; for (i = 0; i < 128; i = i + 1) if (delay_line[i]) begin tdc_cnt <= i[6:0]; break; endend
测得时差
Δ t = ( t d c _ c n t × 200 p s ) − 0.5 s . \\Delta t = \\left(\\mathtt{tdc\\_cnt} \\times 200\\ \\mathrm{ps}\\right) - 0.5\\ \\mathrm{s}\\ . Δt=(tdc_cnt×200 ps)−0.5 s .
4 数字锁相环算法
4.1 算法总览
采用 二阶锁相环 + 卡尔曼滤波 两级架构:
- 卡尔曼滤波器:平滑 1 PPS 抖动,输出最优时差 Δ t ^ \\hat{\\Delta t} Δt^。
- 二阶 PLL:根据 Δ t ^ \\hat{\\Delta t} Δt^ 计算频率误差,积分得到控制电压 V c V_c Vc。
4.2 卡尔曼滤波器模型
状态向量
x k = [ Δ t k Δ f k ] , 其中 Δ f k = f OCXO − f GPS . \\mathbf{x}_k = \\begin{bmatrix} \\Delta t_k \\\\[4pt] \\Delta f_k \\end{bmatrix}, \\quad \\text{其中 }\\Delta f_k = f_\\text{OCXO} - f_\\text{GPS}. xk=[ΔtkΔfk],其中 Δfk=fOCXO−fGPS.
状态方程
x k + 1= F x k + w k , F = [ 1 T 0 1 ] , T = 1 s . \\mathbf{x}_{k+1} = \\mathbf{F}\\mathbf{x}_k + \\mathbf{w}_k,\\quad \\mathbf{F} = \\begin{bmatrix} 1 & T \\\\[4pt] 0 & 1 \\end{bmatrix},\\ T=1\\ \\mathrm{s}. xk+1=Fxk+wk,F=[10T1], T=1 s.
观测方程
z k = H x k + v k , H = [ 1 0 ] . z_k = \\mathbf{H}\\mathbf{x}_k + v_k,\\quad \\mathbf{H} = \\begin{bmatrix} 1 & 0 \\end{bmatrix}. zk=Hxk+vk,H=[10].
过程噪声协方差
Q = [ σ t 2 0 0 σ f 2] , σ t 2 , σ f 2 由 Allan 方差提取 . \\mathbf{Q} = \\begin{bmatrix} \\sigma_t^2 & 0 \\\\[4pt] 0 & \\sigma_f^2 \\end{bmatrix}, \\quad \\sigma_t^2,\\ \\sigma_f^2\\text{由 Allan 方差提取}. Q=[σt200σf2],σt2, σf2由 Allan 方差提取.
卡尔曼迭代
x ^ k ∣ k − 1 = Fx ^ k − 1 ∣ k − 1 , P k ∣ k − 1 = F P k − 1 ∣ k − 1 F T + Q , K k = P k ∣ k − 1 H T ( H P k ∣ k − 1 H T + σ v 2 ) − 1 , x ^ k ∣ k =x ^ k ∣ k − 1 + K k ( z k − Hx ^ k ∣ k − 1 ) , P k ∣ k = ( I − K k H ) P k ∣ k − 1 . \\begin{aligned} \\hat{\\mathbf{x}}_{k|k-1} &= \\mathbf{F}\\hat{\\mathbf{x}}_{k-1|k-1}, \\\\ \\mathbf{P}_{k|k-1} &= \\mathbf{F}\\mathbf{P}_{k-1|k-1}\\mathbf{F}^\\mathsf{T} + \\mathbf{Q}, \\\\ \\mathbf{K}_k &= \\mathbf{P}_{k|k-1}\\mathbf{H}^\\mathsf{T} \\left(\\mathbf{H}\\mathbf{P}_{k|k-1}\\mathbf{H}^\\mathsf{T} + \\sigma_v^2\\right)^{-1}, \\\\ \\hat{\\mathbf{x}}_{k|k} &= \\hat{\\mathbf{x}}_{k|k-1} + \\mathbf{K}_k(z_k - \\mathbf{H}\\hat{\\mathbf{x}}_{k|k-1}), \\\\ \\mathbf{P}_{k|k} &= (\\mathbf{I} - \\mathbf{K}_k\\mathbf{H})\\mathbf{P}_{k|k-1}. \\end{aligned} x^k∣k−1Pk∣k−1Kkx^k∣kPk∣k=Fx^k−1∣k−1,=FPk−1∣k−1FT+Q,=Pk∣k−1HT(HPk∣k−1HT+σv2)−1,=x^k∣k−1+Kk(zk−Hx^k∣k−1),=(I−KkH)Pk∣k−1.
FPGA 实现:
- 提前离线计算稳态增益 K ∞ \\mathbf{K}_\\infty K∞ 并量化成 16 bit 定点;
- 运行时仅需 2 次乘法 + 2 次加法。
4.3 二阶 PLL 控制器
定义
e k = Δ t ^ k , ω 0 = 2 π ⋅ 0.05 H z , ζ = 1 2. e_k = \\hat{\\Delta t}_k,\\quad \\omega_0 = 2\\pi \\cdot 0.05\\ \\mathrm{Hz},\\quad \\zeta = \\frac{1}{\\sqrt{2}}. ek=Δt^k,ω0=2π⋅0.05 Hz,ζ=21.
离散化 PI 系数
K p = ω 0 2 , K i = 2 ζ ω 0 T , T = 1 s . K_p = \\omega_0^2,\\quad K_i = 2\\zeta\\omega_0 T,\\quad T = 1\\ \\mathrm{s}. Kp=ω02,Ki=2ζω0T,T=1 s.
控制电压
V c ( k ) = V c ( k − 1 ) + K p [ e ( k ) − e ( k − 1 ) ] + K i e ( k ) . V_c(k) = V_c(k-1) + K_p\\bigl[e(k) - e(k-1)\\bigr] + K_i\\,e(k). Vc(k)=Vc(k−1)+Kp[e(k)−e(k−1)]+Kie(k).
为防止 DAC 溢出,限幅
V c ∈ [ 0.5 V , 4.5 V ] . V_c \\in [0.5\\ \\mathrm{V},\\ 4.5\\ \\mathrm{V}]. Vc∈[0.5 V, 4.5 V].
5 实时运行步骤
FPGA 主循环(SystemVerilog 伪代码)
always_ff @(posedge clk1hz_local) begin delta_t_raw <= tdc_cnt * 200ps; delta_t_kf <= kalman_fixed(delta_t_raw); vc <= pll(delta_t_kf); dac_spi <= vc;end
6 调参 & 常见问题
7 性能测试
- 测试仪器:Keysight 53230A 时间间隔分析仪 + Symmetricom 5125A Allan 方差测试仪。
- 测试环境:室内窗边,NEO-M8T,28 dB 有源天线。
最后,祝大家驯服愉快,时钟常稳!
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)