问答
登录
直播中
何立立
9年用户
86经验值
擅长:可编程逻辑 嵌入式技术
私信
关注
【Z-turn Board试用体验】+基于FPGA和DDS技术的三相正弦波的发生器设计
信号发生器
DDS
本帖最后由 何立立 于 2015-5-30 11:12 编辑
简介:根据现代
电子
系统对信号源的频率稳定度、准确度及分辨率越来越高的要求,结合直接数字式频率合成器(DDS)的优点,利用
FPGA
芯片的可编程性和实现方案易改动的特点,提出了一种基于FPGA和DDS技术的任意波形发生器设计方案。目前任意波形发生器的设计还在进行中。
本文只给出实验阶段的三相正弦波的产生代码和
仿真
波形,产生的并不是任意波形了。
DDS设计要求:频率分辨率<=0.001;输出正弦波40Hz-65Hz;输出三路正弦波;用RAM实现ROM查找表;RAM数据位宽16bit;
三路正弦波的一周期最少输出1024点;
基本原理:频率分辨率:ΔF=Fclk/(2^N);
输出波形频率:Fout=K *Fclk/(2^N);
( 其它原理以及怎么计算不再详细介绍,网上都可以直接查找到;)
实现框图:
根据上述公式可以计算得到(这里直接给出计算结果):累加器字长N=37,DDS频率Fclk=96KHz,ROM表深度4096,频率调制字长K为17位。
实现过程:
查找表是一个rom。所以这里用ISE自带的rom的ip核。既然用到了rom,那么就要对rom里面的值要写入我们需要的值。这里就用ise的rom的ip核的固定初始化文件coe文件。
Coe文件格式是:
第一行是: MEMORY_INI
ti
ALIZATION_RADIX=10; 后面的10表示数据是以什么进制表示,这里是10进制,所以是10.如果是16就是16进制表示。
第二行是:MEMORY_INITIALIZATION_VECTOR= 这个是固定的。
接下来第三行就是数据,数据以逗号相隔,最后一个数据以分号结束。
这里我们是要产生三路正弦波,所以需要三个rom。
那就要对三相正弦波分别生成rom初始化文件coe。用
matlab
来生成。
这里要注意,由于da只能转换正数值,所以要将sin的负值部分要处理一下,使之数据范围在0到1之间。
生成正弦波matlab代码:
0度:
t=0:2*pi/2^12:2*pi;
y=0.5*sin(t)+0.5;
r=ceil(y*(2^16-1));%将小数(0,1)转变为整数,并就将数值扩大,ceil()像上取整%
fid=fopen('sin_0du.coe','w');%写到sin.coe文件里,用来初始化sin_rom%
fprintf(fid,'memory_initialization_radix=10;n');
fprintf(fid,'memory_initialization_vector=n');
for i=1:1:2^12
fprintf(fid,'%d',r(i));
if i==2^12
fprintf(fid,';');
else
fprintf(fid,',n');
end
end
fclose(fid);
120度:
t=(2/3)*pi:2*pi/2^12:(8/3)*pi;
y=0.5*sin(t)+0.5 ;
r=ceil(y*(2^16-1));%将小数(0,1)转变为整数,并就将数值扩大,ceil()像上取整%
fid=fopen('sin_120du.coe','w');%写到sin.coe文件里,用来初始化sin_rom%
fprintf(fid,'memory_initialization_radix=10;n');
fprintf(fid,'memory_initialization_vector=n');
for i=1:1:2^12;
fprintf(fid,'%d',r(i));
if i==2^12
fprintf(fid,';');
else
fprintf(fid,',n');
end
end
fclose(fid);
-120度:
t=(4/3)*pi:2*pi/2^12:(10/3)*pi;
y=0.5*sin(t)+0.5 ;
r=ceil(y*(2^16-1));%将小数(0,1)转变为整数,并就将数值扩大,ceil()像上取整%
fid=fopen('sin_fu120du.coe','w');%写到sin.coe文件里,用来初始化sin_rom%
fprintf(fid,'memory_initialization_radix=10;n');
fprintf(fid,'memory_initialization_vector=n');
for i=1:1:2^12;
fprintf(fid,'%d',r(i));
if i==2^12
fprintf(fid,';');
else
fprintf(fid,',n');
end
end
fclose(fid);
FPGA中实现:
系统时钟分频实现96Khz的DDS时钟:
module dds_clk_ger(
rst_n,clk_24_576M,clk_96K
);
input rst_n;
input clk_24_576M;
output clk_96K;
reg clk_96K;
reg [6:0] cnt;//7位计数器
always @(posedge clk_24_576M or negedge rst_n ) //采用异步复位
begin
if(!rst_n)
begin
cnt<=0;
clk_96K<=0;
end
else
if(cnt==7'b1111111)//在第128个脉冲到来时进行频率翻转
begin
cnt<=0;
clk_96K<=!clk_96K;
end
else
begin
cnt<=cnt+1'b1;//这里的1一定要表明位宽 1'b1,不然会出现位宽不统一
clk_96K<=clk_96K;
end
end
endmodule
频率调制模块:
module frequency_tiaozhi(
rst_n,k,clk_96K, //DDS系统频率为80K
result
);
input rst_n;
input k;
input clk_96K;
output result;
wire [16:0] k;//频率控制字长k为17位
reg [26:0] result;//相位寄存器的输出结果,寄存器位数27位
wire [26:0] sum;//相加后的值,累加器的字长N=27
assign sum=k+result;
always@(posedge clk_96K or negedge rst_n)
begin
if(!rst_n)
result<=0;
else
begin
result<=sum;
end
end
endmodule
顶层模块:将前面几个模块接起来就好了:
其中U3,U4,U5是0读正弦波,120度,-120度正弦波例化ROM核。
添加测试文件:
module dds_top_tb;
// Inputs
reg clk_24_576M;
reg rst_n;
reg [16:0] k;
// Outputs
wire [15:0] dds_data_sin_0du;
wire [15:0] dds_data_sin_120du;
wire [15:0] dds_data_sin_fu120du;
// Instantiate the Unit Under Test (UUT)
dds_top uut (
.clk_24_576M(clk_24_576M),
.rst_n(rst_n),
.k(k),
.dds_data_sin_0du(dds_data_sin_0du),
.dds_data_sin_120du(dds_data_sin_120du),
.dds_data_sin_fu120du(dds_data_sin_fu120du)
);
initial begin
// Initialize Inputs
clk_24_576M = 0;
rst_n = 0;
k = 0;
// Wait 100 ns for global reset to finish
#100;
rst_n=1;
k=90877;
// Add stimulus here
end
always #20.345 clk_24_576M=!clk_24_576M;
endmodule
仿真波形:
K=55924时波形频率应该为40Hz
[size=14.3999996185303px] K=90877时波形频率应该为65Hz
这样就完成了一个简单的DDS波形发生器的实验了。
接下来是通过ARM向FPGA内RAM写波形数据,给频率控制字来实现任意波形的产生。
回帖
(8)
HelloWii
2015-5-31 10:57:55
学习一下。。。
学习一下。。。
举报
blackroot
2015-5-31 21:21:08
楼主,使用PL部分的时候,PL部分的时钟是怎样输入进来的?
楼主,使用PL部分的时候,PL部分的时钟是怎样输入进来的?
举报
blackroot
2015-5-31 21:24:41
比如PL部分的时钟管脚分配是在那个管脚上啊?
比如PL部分的时钟管脚分配是在那个管脚上啊?
举报
东东
2015-10-30 10:30:35
楼主好厉害,学习了----------
楼主好厉害,学习了----------
举报
更多回帖
rotate(-90deg);
回复
相关帖子
信号发生器
DDS
基于
DDS
技术
的高频
正弦波
发生器
的设计
113
基于
DDS
技术
的高频
正弦波
发生器
的设计
108
几乎纯
DDS
正弦波
调
发生器
2692
Z-turn
Board
Linux开发手册
0
Verilog实现
DDS
正弦波
发生器
1141
怎么实现基于
DDS
技术
的高频
正弦波
发生器
的设计?
1370
【
Z-turn
Board
试用
体验】+
Z-turn
调试计划
5073
dds
正弦波
信号
发生器
3040
基于ATmega128A的
三相
正弦波
发生器
的研究与设计
22
三相
正弦波
脉宽调制(SPWM)信号
发生器
SM2001
40
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分