16-QAM的Gardner符号定时

        从网上找的程序修改而来,网上的程序都是4倍采样,而看Gardner的资料介绍都是2倍采样。故改了一个2倍采样的16qam定时程序,第一版。

N = 1e4;
M = 16;
data = randi([0 M-1],N,1);
sig = qammod(data,M,'UnitAveragePower',true);
rrc = rcosdesign(0.25,8,4,'sqrt');
tx = conv(upsample(sig,4),rrc,'same');
tx_off = uk_filter(tx,0.5);               % 构造0.5个符号的延迟
ch = awgn(tx_off,20,'measured');
rx = conv(ch,rrc,'same');
rx_down = resample(rx,1,2);               % 抽取到2倍符号采样,gardner每个符号要求2个采样点

w = 0.5;                                  
y = zeros(length(rx_down)/2,1);
y_cnt = 0;

strobe = 0;      % 最佳观测点指示
w3 = zeros(3,1); % 三个插值输出点
c1 = 5.41e-3;    % 来自https://blog.csdn.net/weixin_44884357/article/details/95619955
c2 = 3.82e-6;    % 来自https://blog.csdn.net/weixin_44884357/article/details/95619955

loopout = 0;     % 环路滤波器输出
loopint = 0;     % 环路滤波器积分
nco = 0;         % NCO
uk = 0;          % 分数间隔

for i=4:length(rx_down)

    y_f = uk_filter(rx_down(i-3:i),uk); % 每次将4个采样点输入插值滤波器

    w3 = [y_f(end);w3(1:2)];            % 每次将插值滤波器的输出存入缓存中,采用点间隔1/2符号,共存3个符号

                                        %                                [y(k) , y(k-1/2) , y(k-1)]
    if strobe == 1                      % 最佳观测点,输出,此时,缓存w3的内容[strobe,  error   , strobe];
        y_cnt = y_cnt + 1;
        y(y_cnt) = y_f(end);            % 输出为最佳观测点

        % uk=yi(k-1/2)*[yi(k)-yi(k-1)] + yq(k-1/2)*[yq(k)-yq(k-1)]    计算TED的公式
        ted = real(w3(2))*(real(w3(1))-real(w3(3))) + imag(w3(2))*(imag(w3(1))-imag(w3(3)));
    else
        ted = 0;                        % 没有中值点,[error,strobe,error],不计算定时误差
    end

    % 环路滤波
    loopout = ted*c1 + loopint;
    loopint = ted*c2 + loopint;

    w = loopout + 0.5;                  % 每个采样点,都将增加0.5,及每2个采样点必将产生一个最佳观测点输出
    if nco < w                          % 0<=uk<1             
        strobe = 1;
        uk = nco/w;                     % 计算最佳观测点的插值分数间隔
    else
        strobe = 0;
    end
    nco = mod(nco - w,1);               % 模1运算,0<=nco<1
end

y0 = y(500:end);

plot(real(rx_down(2:2:end)),imag(rx_down(2:2:end)),'.r');
hold on;
plot(real(y0),imag(y0),'.b');
hold off;

程序运行后的星座图如下,uk为0.7884,猜猜为什么。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 19:00:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 19:00:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 19:00:03       58 阅读
  4. Python语言-面向对象

    2024-07-19 19:00:03       69 阅读

热门阅读

  1. 带有致命Bug的B-树代码(用C++/Python/Rust还原)

    2024-07-19 19:00:03       21 阅读
  2. 无极与有极电容的区别

    2024-07-19 19:00:03       21 阅读
  3. Flutter 中的基本数据类型:num、int 和 double

    2024-07-19 19:00:03       19 阅读
  4. Docker 常用命令详解

    2024-07-19 19:00:03       26 阅读
  5. 将AWS RDS MySQL实例从存储未加密改为加密的方案

    2024-07-19 19:00:03       25 阅读
  6. C++设计模式

    2024-07-19 19:00:03       19 阅读
  7. 【React】使用 antd 加载组件实现 iframe 的加载效果

    2024-07-19 19:00:03       23 阅读
  8. 初步认识HTML

    2024-07-19 19:00:03       21 阅读
  9. Spring中用了哪些设计模式?

    2024-07-19 19:00:03       18 阅读
  10. 常见日志报错及解决方法

    2024-07-19 19:00:03       19 阅读
  11. OpenSNN推文:目前在哪些方面AI能完全取代人类

    2024-07-19 19:00:03       17 阅读
  12. 面试问题:React基本概念,和所遇到的CPU和IO问题

    2024-07-19 19:00:03       20 阅读