ASK数字调制解调实现

ASK数字调制解调实现

调制解调原理

在这里插入图片描述

  • 对于为什么全波整流+低通能够还原包络,我的理解是这样的
    在这里插入图片描述
  • 首先整流将电路转化为右图所示,
  • 然后对于黑圈中变化较为快的高频部分,用低通滤波器去除,转化为红色线所示的包络。
    在这里插入图片描述
  • 即上图所示的
    在这里插入图片描述
  • 用matlab仿真可以看出
  • ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210415182808155.png- Matlab仿真

Matlab仿真

fc = 7*10^5; %载波频率
fb = 1*10^3; %码率
fs = 8*fb;  %采样频率
order = 3; %(n+1)进制调制
qm = 12;
%s随机产生基波
y = randi([0,order],[1, 200]); 
%基波采样
x_begin=0;
x_end=1;
mt = 0;
x=0:fb/fs:length(y);
for i=1:length(y)
    if(y(i)==1)
        mt = mt + y(i).*(x>=x_begin&x<x_end);
    else
        mt = mt + y(i).*(x>=x_begin&x<x_end);
    end
    x_begin=x_begin+1;
    x_end=x_end+1;
end

%载波采样,载波频率大于采样频率时,确保sc不为0
t = 0:1/fs:(length(mt) - 1)/fs;
sc = cos(2*pi*fc*t);
s = mt.*sc;

%画图时域
subplot(411);
plot(t,s,'r-',t,mt,'b-');
xlabel('时域t');ylabel('Magnitude');title('调制时域波形');
legend('调制后','基波');

s=s/max(abs(s));         %归一化处理
s=round(s*(2^(qm-1)-1)); %12比特量化
%生成波形文件
fid = fopen('E:\Work\IC\Modem\code\ASK\Matlab\testdata.txt','w');
for i=1:length(s)
data = dec2bin(s(i) + (s(i) < 0)*2^qm,qm);
  for j = 1:qm
    if data(j) == '1'
        tb = 1;
    else
        tb = 0;
    end
     fprintf(fid,'%d',tb);
  end
     fprintf(fid,'\r\n');
end
fclose(fid);

%画图频域
subplot(412);
s_f = 20*log10(abs(fft(s)));
s_f = s_f - max(s_f);
x_f = 1:(fs/length(s_f)):fs/2;
s_f = s_f(1:length(x_f));
plot(x_f,s_f,'-');
xlabel('频域(Hz)');ylabel('Magnitude(dB)');title('调制后频域波形');

%解调
%相干解调 载波相乘+低通
s1 = s.*sc;
%非相干解调:整流+低通
s = abs(s);
%设计低通滤波器
n = 15;%阶数
qm = 12;%量化位数
f = [1.5*10^3 2*10^3];

fc = [0 f(1)*2/fs f(1)*2/fs f(2)*2/fs f(2)*2/fs 1];%过渡带
mag = [1 1 0.2 0.2 0 0];%低通

%滤波
hn = fir2(n,fc,mag);

b_pm = round(hn/max(abs(hn))*(2^(qm-1) -1));%12量化

%生成系数写入文件
fid=fopen('E:\Work\IC\Modem\code\ASK\Matlab\coe.txt','w');
for i = 1: length(b_pm)
    B_hex=dec2hex(b_pm(i)+(b_pm(i)<0)*2^qm,qm);
for j = 1:qm
      %k = strcat(B_hex);
      fprintf(fid,'%c',B_hex(j));
end
fprintf(fid,'\r\n');
end
fclose(fid);

filter_s = filter(hn,1,s);
filter_s1 = filter(hn,1,s1);

%求信号的幅频响应
m_s = 20*log10(abs(fft(s,1024)));
m_s = m_s - max(m_s);
%滤波后的幅频响应
m_filter_s = 20*log10(abs(fft(filter_s,1024)));
m_filter_s = m_filter_s - max(m_filter_s);
%滤波器本身的幅频响应
m_hn = 20*log10(abs(fft(hn,1024)));
m_hn = m_hn - max(m_hn);
m_s = m_s(1:length(x_f));
m_filter_s = m_filter_s(1:length(x_f));
m_hn = m_hn(1:length(x_f));

%绘制幅频响应曲线
subplot(413)
plot(x_f,m_s,'r-.',x_f,m_filter_s,'b-.',x_f,m_hn,'g-.');
%plot(x_f,m_s,'r-.');
xlabel('频率(Hz)');ylabel('幅度(dB)');title('Matlab仿真合成单频信号滤波前后的频谱');
legend('输入信号频谱','输出信号频谱','滤波器响应');

subplot(414)
plot(t,filter_s,'-',t,filter_s1,'--');
legend('非相干解调','相干解调');
filter_s=filter_s/max(abs(filter_s));  %归一化处理
filter_s=round(filter_s*(2^(qm-1)-1)); %12比特量化

fid1 = fopen('E:\Work\IC\Modem\code\ASK\Matlab\filterdata.txt','w');
for i=1:length(filter_s)
data1 = dec2bin(filter_s(i) + (filter_s(i) < 0)*2^qm,qm);
  for j = 1:qm
    if data1(j) == '1'
        tb = 1;
    else
        tb = 0;
    end
     fprintf(fid1,'%d',tb);
  end
     fprintf(fid1,'\r\n');
end
fclose(fid1);
  • 2ASK
    在这里插入图片描述
  • 4ASK
    在这里插入图片描述

Verilog仿真

  • 测试文件
`timescale 1ns/1ps
module test();
reg clk;
reg rst;
reg [11: 0] din;
wire[28: 0] dout;

reg [11: 0] filter;
ask u1
    ( .clk(clk),
      .rst(rst),
      .din(din),
      .dout(dout)
    );

//rst
initial begin
  rst = 1'b1;
  #400000 $finish;
end

//clk
initial begin
  clk = 1'b1;
  forever #10 clk = ~clk;
end

reg [11: 0] mem [0:2000];
reg [11: 0] f_mem [0:1600];
integer i,j;

//读取Matlab调制后的波形
initial begin
  $readmemb("/home/IC/Mylearn/ASK/testdata.txt", mem);
  i = 0;
  repeat(1999) begin
    i = i + 1;
    din = mem[i];
    #20;
  end
end
//读取Matlab解调的波形
initial begin
  $readmemb("/home/IC/Mylearn/ASK/filterdata.txt", f_mem);
  j = 0;
  repeat(1599) begin
    j = j + 1;
    filter = f_mem[j];
    #20;
  end
end

 initial begin
  $fsdbDumpfile("ask.fsdb");
  $fsdbDumpvars;
 end
 endmodule
 var foo = 'bar';
  • 顶层文件
module ask
(
   input clk,
   input rst,
   input  [11 :0] din,
   output [29 :0] dout
);
reg[11: 0] abs_din ;
//补码取绝对值
always@ (posedge clk or negedge rst) begin
if(din[11] == 0) 
  abs_din <= din;
else 
  abs_din <= {{1'b0},~din[10:0]} + 1'b1;
end
fir  #(
     .iwidth(12),
     .owidth(29),
     .order(16)
) 
u1 (
     .clk(clk),
     .rst(rst),
     .din(abs_din),
     .dout(dout)

);
endmodule
  • 5
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值