(DDS)正弦波形发生器——幅值、频率、相位可调(二)
(DDS)正弦波形发生器——幅值、频率、相位可调(二)
主要关于调相方面
一、项目任务:
- 设计一个幅值、频率、相位均可调的正弦波发生器。
- 频率每次增加10kHz
- 相位每次增加 PI/2
- 幅值每次增加两倍
- ROM的深度为1024、宽度为8
二、文章内容:
- 完成调相模块并验证功能
- 完成调幅模块
- 按结构图来连接各个模块并仿真验证
1、调相
从图像上来理解调整相位就是原函数在X轴上进行水平移动。
在本项目中函数的波形图按照顺序存在ROM中,我们只要按照比例调整读取ROM的地址,即可调相。
前文中我们使用32位寄存器的高8位用做ROM的地址,因此只要有按键按下,我们按照相位同比例的调整读取ROM的地址即可。
ROM的深度为1024、宽度为8储存标准正弦函数,那么可知其式为:
\[% MathType!MTEF!2!1!+-
% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaqGMbGaaiikaiaadIhacaGGPaGaeyyp
% a0JaaGymaiaaikdacaaI4aGaci4CaiaacMgacaGGUbGaaiikamaala
% aabaGaamiEaaqaaiaaiwdacaaIXaGaaGOmaaaacqaHapaCcaGGPaaa
% aa!4ECD!
{\rm{f}}(x) = 128\sin (\frac{x}{{512}}\pi )+128
\]这里x对应的是ROM地址、y对应的是ROM中数据也即幅值。范围取x从0到1023、y从0到255。
若按键一次,相位增加PI/2,则有:
\[% MathType!MTEF!2!1!+-
% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakqaabeqaaiaadEgacaGGOaGaamiEaiaacMca
% cqGH9aqpcaaIXaGaaGOmaiaaiIdaciGGZbGaaiyAaiaac6gacaGGOa
% WaaSaaaeaacaWG4baabaGaaGynaiaaigdacaaIYaaaaiabec8aWjab
% gUcaRmaalaaabaGaeqiWdahabaGaaGOmaaaacaGGPaGaey4kaSIaaG
% ymaiaaikdacaaI4aaabaGaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7
% caaMe8UaaGjbVlaaysW7caaMe8Uaeyypa0JaaGymaiaaikdacaaI4a
% Gaci4CaiaacMgacaGGUbGaaiikaiaacIcadaWcaaqaaiaadIhaaeaa
% caaI1aGaaGymaiaaikdaaaGaey4kaSYaaSaaaeaacaaIXaaabaGaaG
% OmaaaacaGGPaGaeqiWdaNaaiykaiabgUcaRiaaigdacaaIYaGaaGio
% aaqaaiaaysW7caaMe8UaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7ca
% aMe8UaaGjbVlabg2da9iaaigdacaaIYaGaaGioaiGacohacaGGPbGa
% aiOBaiaacIcacaGGOaWaaSaaaeaacaWG4bGaey4kaSIaaGOmaiaaiw
% dacaaI2aaabaGaaGynaiaaigdacaaIYaaaaiaacMcacqaHapaCcaGG
% PaGaey4kaSIaaGymaiaaikdacaaI4aaaaaa!9896!
\begin{array}{l}
g(x) = 128\sin (\frac{x}{{512}}\pi + \frac{\pi }{2}) + 128\\
\;\;\;\;\;\;\;\;\; = 128\sin ((\frac{x}{{512}} + \frac{1}{2})\pi ) + 128\\
\;\;\;\;\;\;\;\;\; = 128\sin ((\frac{{x + 256}}{{512}})\pi ) + 128
\end{array}
\]
其中绿色为f(x),紫色为调整相位后的g(x)。
即每次按下按键后相当于将图像向左平移256,那么也就是按下按键后,提前读取256个地址之后的数据。
module phase_ctrl(
input clk,
input rst_n,
input f_phase, output [9:0] initiala_address
);
assign initiala_address = 10'd256;
endmodule module addr_ctrl(
input clk,
input rst_n,
input [31:0] freq_num,
input [9:0] initiala_address,
input f_phase, output [9:0] address
); reg [31:0] cnt; always @(posedge clk,negedge rst_n)
begin
if(rst_n == 0)
cnt <= 32'd0;
else
if(f_phase == 1)
cnt[31:22] <= cnt[31:22] + initiala_address;
else
cnt <= cnt + freq_num;
end
assign address = cnt[31:22];
endmodule
验证:选取三个变频前后的点将其与理论计算的值进行对比
重点关注在f_phase拉高前后,正弦波上3个点(address,data)的大小

(43,161) (43+256,251)=(299,251)

(754,0) (754+256)=(1010,117)

(856,18) (856+256-1024,193)=(88,193)
理论计算:

(43,161)(43,251) (754,0)(754,117) (856,18) (856,193)
可以看到调相模块准确的完成了每次按键按下,相移PI/2的任务。
2、调幅
这一部分在代码方面比较简单,实际验证还需要数模转换和示波器的配合,限于条件无法达到,因此只展仿真结果。
在程序上要注意位宽的变化,由于不断的放大,因此将输出data设计为32位。
每次按键按下。幅值放大两倍。
module amplitude_ctrl(
input clk,
input rst_n,
input f_ampli,
input [7:0] data_in, output [31:0] data
); reg [23:0] ampli_num; always @(posedge clk,negedge rst_n)
begin
if(rst_n == 0)
ampli_num <= 24'd1;
else
if(f_ampli == 1)
ampli_num <= ampli_num * 24'd2;
else
ampli_num <= ampli_num;
end assign data = ampli_num * data_in; endmodule

3、模块连接及总体功能验证
系统结构图为:


ModelSim仿真:
频率变化:
相位变化:
幅值变化:
测试代码:
`timescale 1ns/1ns
module key_dds_tb(); reg clk;
reg rst_n;
reg key_freq;
reg key_phase;
reg key_ampli; wire [31:0] data; key_dds key_dds_inst(
.clk (clk),
.rst_n (rst_n),
.key_freq (key_freq),
.key_phase(key_phase),
.key_ampli(key_ampli), .data (data)
); initial clk = 1;
always #10 clk = !clk; initial
begin
rst_n = 0;
key_freq = 1;
key_phase = 1;
key_ampli = 1;
#200 rst_n = 1;
#200 key_freq = 1;
#10000000
key_freq = 0;
#2000
key_freq = 1;
#10000000
key_freq = 0;
#1000000 key_freq = 1;
#10000000 key_phase = 1;
#2000000
key_phase = 0;
#70000
key_phase = 1;
#11500
key_phase = 0;
#70000
key_phase = 1;
#25000
key_phase = 0;
#23333 key_phase = 1;
#1000000 key_ampli = 1;
#10000000
key_ampli = 0;
#2000
key_ampli = 1;
#1000000 #10000
$stop;
end endmodule
备注:
- 之后有时间我想试着在屏幕上输出DDS产生的波形,看看效果。
- mif文件
- 按键部分的功能是进行消陡然后输出一个同系统时钟的标志信号flag。
作者:13tree
出处:https://www.cnblogs.com/13tree/
本文版权归作者所有,如需转载请保留此段声明。
(DDS)正弦波形发生器——幅值、频率、相位可调(二)的更多相关文章
- (DDS)正弦波形发生器——幅值、频率、相位可调(一)
(DDS)正弦波形发生器--幅值.频率.相位可调 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加1kHz. 相位每次增加 2*PI/256 幅值每次增加两倍 二.文章内容 ...
- 基于FPGA的DDS任意波形发生器设计
一.简介 DDS技术最初是作为频率合成技术提出的,由于其易于控制,相位连续,输出频率稳定度高,分辨率高, 频率转换速度快等优点,现在被广泛应用于任意波形发生器(AWG).基于DDS技术的任 ...
- 基于DDS的任意波形发生器
实验原理 DDS的原理 DDS(Direct Digital Frequency Synthesizer)直接数字频率合成器,也可叫DDFS. DDS是从相位的概念直接合成所需波形的一种频率合成技术. ...
- FFT之频率与幅值的确定(转)
FFT之后得到的是什么数 FFT之后得到的那一串复数是波形对应频率下的幅度特征,注意这个是幅度特征不是复制,下面要讲两个问题:1.如何获取频率,2.如何获取幅值 获取频率 FFT变换如何获取频率?傅里 ...
- STM32 基DMA的DAC波形发生器
DAC是STM32系列的一个基本外设,可以将数字信号转化成模拟信号,这次我将使用DAC来输出一个特定波形. 首先确定工作方法,由于我目前在做的简易示波器在输出波形的同时还需要显示输入信号,所以不能占用 ...
- 在Modelsim波形中查看值
在Modelsim的波形中查看值时,可以利用右键选择变量的数据类型.如果变量值为0,可以选择unsigned类型观察,可以1位显示0. 长度较大的数据以十六进制显示时,即使值为0,也依然显示为长度较长 ...
- JAVA之旅(三)——数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想
JAVA之旅(三)--数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想 我们继续JAVA之旅 一.数组 1.概念 数组就是同一种类型数据的集合,就是一个容器 数组的好 ...
- Matlab绘制幅值谱和相位谱
1. 对于直接给出频响函数的情况 这里以滑动平均的频响函数作为例子,滑动窗口为[0, 4]. 上式中M2=4. >> w=0:0.001:2*pi; >> h1=1-exp(- ...
- numpy 傅立叶得到幅值和频率
做个备份,对 numpy 不熟,每次都找函数找半天. 代码里分几块: 1. 从 argc[1] 的文档中读取数据,并转化为 float.文档中有 2001 行,第一行为头,后面 2000 个是采样数据 ...
随机推荐
- Redis 的 3 种集群方案对比
数据持久化 主从复制 自动故障恢复 集群化 数据持久化本质上是为了做数据备份,有了数据持久化,当Redis宕机时,我们可以把数据从磁盘上恢复回来,但在数据恢复之前,服务是不可用的,而且数据恢复的时间取 ...
- 第二十四个知识点:描述一个二进制m组的滑动窗口指数算法
第二十四个知识点:描述一个二进制m组的滑动窗口指数算法 简单回顾一下我们知道的. 大量的密码学算法的大数是基于指数问题的安全性,例如RSA或者DH算法.因此,现代密码学需要大指数模幂算法的有效实现.我 ...
- Certified Adversarial Robustness via Randomized Smoothing
目录 概 主要内容 定理1 代码 Cohen J., Rosenfeld E., Kolter J. Certified Adversarial Robustness via Randomized S ...
- html2canvas 返回的toDataURL()数据为 data:,的解决方法
1.使用的场景是把html转换成PDF保存下来,代码: /* eslint-disable */ import html2canvas from 'html2canvas'; import JsPDF ...
- 使用 JavaScript 中的 document 对象的属性,根据下拉框中选择的属性,更改页面中的字体颜色和背景颜色
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 document 对象的属性,根据下拉框中选择的属性,更改页面中的字体颜色和背景颜色 实现思路: 在页面的 <body&g ...
- MySQL数据操作与查询笔记 • 【第2章 表结构管理】
全部章节 >>>> 本章目录 2.1 关系模型与数据表 2.1.1 关系模型 2.1.2 数据表 2.2 MySQL 数据类型 2.2.1 MySQL 常见数据类型 2.2 ...
- CSS基础-4 定位
CSS定位和浮动 css定位:改变页面的位置 定位机制有以下三种 普通流 浮动 绝对布局 定位的属性: position:把元素放在一个静态的.相对的.绝对的.或固定的位置中 top ...
- Identity Server 4到今年年底就停止支持了,试一下使用Orchard Core 作为认证服务
Identity Server 4到今年年底就停止支持了,新的版本需要收费(好像目前是按企业规模,不过将来说不准).我们需要为这种情况做一些技术准备,至少需要为用户多准备一些可选方案.从目前成熟的开源 ...
- Selenium_单选框和复选框的选中状态判定以及元素是否可用和可见判定(10)
简单写个单选框和复选框界面 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /&g ...
- Go语言系列之依赖管理
依赖管理 为什么需要依赖管理? 最早的时候,Go所依赖的所有的第三方库都放在GOPATH这个目录下面.这就导致了同一个库只能保存一个版本的代码.如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解 ...



