ROM存储1/4周期正弦信号构造DDS详解

matlab仿真
注意:由于采用了1/4周期存储,要求整个周期的数值是中心对称的,半个周期的数值是轴对称的。这就意味着采样点中不应该有0值得存在。
matlab仿真——rom表存储数据
%% rom产生 (无符号数)
rom_n=2^10; %rom表深度
data_l=14; %rom位宽
t=1:rom_n;
y=(2^data_l-1)*(sin(2*pi*(t-0.5)/rom_n/4));%-0.5保证对称性
rom_data=round(y);
matlab仿真——dds程序(请原谅我没有用case……)
%% 正弦波dds产生
f_clk=10*10^6; %时钟频率10m
pinc_in_l=32; %增量长度
dds_clk=10*10^3; %dds输出频率10k
phase_in=0; %初始相位
pinc=round(dds_clk*2^pinc_in_l/f_clk); %相位增量
sim_l=4000; %仿真长度
phase=phase_in+pinc*(0:sim_l-1);
addr=mod((floor(phase/2^pinc_in_l*rom_n)),rom_n*4);
flag=floor(addr/rom_n);
dds_out=1:sim_l;
for i=1:sim_l
if(flag(i)==0)
dds_out(i)=rom_data(addr(i)+1);
else if(flag(i)==1)
dds_out(i)=rom_data(2047-addr(i)+1);
else if(flag(i)==2)
dds_out(i)=-rom_data(addr(i)-2048+1);
else
dds_out(i)=-rom_data(4095-addr(i)+1);
end
end
end
end
plot(dds_out);
3.dds的解释
xilinx的dds核的user guide中队dds做了很详细的说明,本节不再重复此内容,本节将叙述一种全新的dds理解方式。这种理解方式解决了频率控制字长于rom表深度时dds的理解上的问题。
连续还是离散?
连续还是离散,在于我们用什么眼光去看待。如下图所示,我们可以理解蓝色的图是离散的,而红色的线是连续的。然而,对于我们要获取的信息而言,这两幅图是完全没有区别的。抽样定理中有理想抽样和平顶抽样(采样保持电路)之分,然而在频域效果上,是并没有很大区别的。
rom表存储的是连续的数值
按照上面的理论,可以认为rom表中存储的是正弦信号的平顶采样结果。如下图所示(一个全周期的rom表,对称性满足1/4周期存储的要求)
上图的频谱在信号与系统中有提及,上述波形的形成方式可以认为是在乘以周期为t的冲击函数,之后卷积一个宽度为t的窗函数。对应可以求得其频域。(具体可参考平顶抽样)
频率控制字
频率控制字控制对上述的阶梯函数的采样,如果这样理解的话,就没有所谓的相位截取取rom表的值的疑惑了。频谱图能够清晰的表现这一过程,然而由于blog表达不便,此处不做详细说明。
此处能够解释dds产生的杂散。
4.verilog实现
老师教导我们,verilog和matlab代码应该是完全一致的,也就是说程序的思路,命名是一样的。但是下面的程序没有做到一致性……
`timescale 1ns / 1ps
module dds_10k(
input clk_10m,
input rst,
output[13:0] d_sin,
output[13:0] d_cos
);
parameter pinc=32‘d4294967; //10k
reg[31:0] addr_temp=32’d0;
reg[9:0] addra,addrb;
reg mark_a,mark_b;
always@(posedge(clk_10m)) //复位
begin
if(rst==0)
addr_temp《=32‘d0;
else
addr_temp《=addr_temp+pinc;
end
always@(posedge(clk_10m)) //1/4周期控制
begin
case(addr_temp[31:30])
2’b00:
begin
addra《=addr_temp[29:20];
mark_a《=0;
addrb《=~addr_temp[29:20];
mark_b《=0;
end
2‘b01:
begin
addra《=~addr_temp[29:20];
mark_a《=0;
addrb《=addr_temp[29:20];
mark_b《=1;
end
2’b10:
begin
addra《=addr_temp[29:20];
mark_a《=1;
addrb《=~addr_temp[29:20];
mark_b《=1;
end
2‘b11:
begin
addra《=~addr_temp[29:20];
mark_a《=1;
addrb《=addr_temp[29:20];
mark_b《=0;
end
endcase
end
//rom表读取
rom_sin_1k18 rom_dds (
.clka(clk_10m), // input clka
.addra(addra), // input [9 : 0] addra
.douta(d_sin[12:0]), // output [12 : 0] douta
.clkb(clk_10m), // input clkb
.addrb(addrb), // input [9 : 0] addrb
.doutb(d_cos[12:0]) // output [12 : 0] doutb
);
reg sin_mark_temp;
reg cos_mark_temp;
assign d_sin[13]=sin_mark_temp;
assign d_cos[13]=cos_mark_temp;
//此处rom没有添加register,因此输出和地址有一个周期的延时,故mark也要有一周期延时
always@(posedge(clk_10m))
begin
sin_mark_temp《=mark_a;
cos_mark_temp《=mark_b;
end

电脑的USB连接口给手机充电为什么速度慢
科创板铂力特创始人及高管信息大全
使用MAX11254模数转换器进行精密压力传感器测量
车用LED的应用范围将进一步扩大
步进电机的使能信号的作用和接线方法
ROM存储1/4周期正弦信号构造DDS详解
智慧镜子显示屏的新应用,拥有丰富多彩的多媒体功能
什么是电源中的遥感(RS)线 如何使用它呢
五大平台已下架所有互联网存款产品
安森美应用于UPS的SiC方案
基于测量可调节的30V-4A线性电源
“锌”材料NiZn镍锌充电电池问世
如何在5G时代快速打造全球规模最大的5G网络
PLC编程标准化的重要性分析
压力传感器在压裂车中的作用
iPhone7马上要来了,将取消16G搭配更高版本?
基于微波传感原理的无创血糖监测系统
导热硅脂的散热性如何才能发挥到好的状态呢?
导热凝胶已应用于自动驾驶毫米波雷达散热
10kv变频器电路