内容介绍
内容介绍
一、项目简述
-
通过板上的高速DAC(10bits/125Msps)配合FPGA内部DDS的逻辑,生成波形可调(正弦波、三角波、方波)、频率可调(DC-)、幅度可调的波形
- 生成模拟信号的频率范围为DC-20MHz,调节精度为1Hz
- 生成模拟信号的幅度为最大1Vpp,调节范围为0.1V-1V
- 在OLED上显示当前波形的形状、波形的频率以及幅度
- 利用板上旋转编码器和按键能够对波形进行切换、进行参数调节
二、使用设备
本项目所使用的主要器件包括Lattice小脚丫XO-4000HC FPGA核心板以及相
应的硬禾学堂电赛训练板,使用了基于3PD5651E(10-Bit, 50MSPS, CMOS模数变换
器)芯片的DAC模块,显示模块使用的是基于ssd1306芯片的128x64的OLED屏幕。
3、作品可完成要求
- 通过板 上的高速DAC (10bits/125Msps) 配合FPGA 内部DDS的逻辑,生成波形可调(正弦波、三角波、锯齿波、方波)、频率可调(DC-)、 幅度可调的波形
- 生成模拟信号的频率范围为DC- 20MHz,调节精度可为1Hz
- 生成模拟信号的幅度为0.1-1.0Vpp
- 可以在OLED上显示当前波形、频率以及幅度
- 利用板上旋转编码器能够对波形进行切换、进行参数调节
四、设计思路
本文通过按键输入模块(按键+旋转编码器)进行参数(波形/频率/幅值)输入,OLED模块直接将参数显示出来,同时通过DDS主逻辑将各个参数转换为对应的波形输出。
逻辑和流程
五、主要代码片段及说明
1、dds生成
module dds(
input sys_clk,
input sys_rst_n,
input [1:0] wave_type,
input [31:0] wave_freq,
output reg [9:0] wave_dac
);
wire [9:0] Cos_Dac;
wire [9:0] Square_Dac;
wire [9:0] Trig_Dac;
wire [9:0] Saw_Dac;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
wave_dac <= 10'd0;
end else begin
case(wave_type)
2'b00: wave_dac <= Cos_Dac;
2'b01: wave_dac <= Square_Dac;
2'b10: wave_dac <= Trig_Dac;
2'b11: wave_dac <= Saw_Dac;
endcase
end
end
reg [27:0] dds_phase;
wire [27:0] dds_phase_add;
assign dds_phase_add = (wave_freq << 1) + (wave_freq >> 3) + (wave_freq >> 4) + (wave_freq >> 4) + (wave_freq >> 5) + (wave_freq >> 6) + (wave_freq >> 9) + (wave_freq >> 11) + (wave_freq >> 13);
//wave_freq*2.2369384765625
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
dds_phase <= 28'd0;
end else begin
dds_phase <= dds_phase + dds_phase_add;
end
end
lut u_lut(
.address(dds_phase[27:20]),
.cos(Cos_Dac)
);
assign Square_Dac = {10{dds_phase[27]}};
assign Trig_Dac = dds_phase[27] ? ~dds_phase[26:17]: dds_phase[26:17];
assign Saw_Daac = dds_phase[27:18];
endmodule
2、oled驱动
显示部分的代码主要参考寒假在家练项目(https://www.eetree.cn/project/detail/251)分享的Lattice小脚丫网盘资料
module oled
(
input sys_clk, //12MHz系统时钟
input sys_rst_n, //系统复位,低有效
input[1:0] dis_type,
input[31:0] dis_freq,
input[3:0] dis_amp,//
output reg oled_csn, //OLCD液晶屏使能
output reg oled_rst, //OLCD液晶屏复位
output reg oled_dcn, //OLCD数据指令控制
output reg oled_clk, //OLCD时钟信号
output reg oled_dat //OLCD数据信号
);
localparam INIT_DEPTH = 16'd25; //LCD初始化的命令的数量
localparam IDLE = 6'h1, MAIN = 6'h2, INIT = 6'h4, SCAN = 6'h8, WRITE = 6'h10, DELAY = 6'h20;
localparam HIGH = 1'b1, LOW = 1'b0;
localparam DATA = 1'b1, CMD = 1'b0;
reg [7:0] cmd [24:0];
reg [39:0] mem [122:0];
reg [127:0] mem_hanzi[16:0];
reg [7:0] mem_hanzi_num;
reg [7:0] y_p,x_ph,x_pl;
reg [(8*21-1):0] char;
reg [7:0] num;
reg [7:0] char_reg;
reg [4:0] cnt_main,cnt_init,cnt_scan,cnt_write;
reg [5:0] cnt_chinese;
reg [15:0] num_delay,cnt_delay,cnt;
reg [6:0] state,state_back;
reg[(3*8-1):0] dis_type_buff;
wire[(9*8-1):0]dis_freq_buff;
wire[(7*8-1):0]dis_amp_buff;
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
dis_type_buff <= "Sin";
end else begin
case(dis_type)
2'b00:dis_type_buff <="Sin";
2'b01:dis_type_buff <="Squ";
2'b10:dis_type_buff <="Trg";
2'b11:dis_type_buff <="Saw";
endcase
3、查找表
根据phase(相位累加器的高8位),进行波形查找。由于波形表波形一个周期256个采样点,1/4个周期64个采样点,故而取phase的高2位划分状态,共计四个状态构成一个完整周期,并对波形数据进行处理,使四个状态共同构成一个完整的周期信号。
module lut(
input [7:0] address,
output reg [9:0] cos
);
wire [1:0] section;
reg [5:0] lut_address;
reg [8:0] lut_cos;
assign section = address[7:6];
always@(address)begin
case(section)
2'b00:begin
lut_address = address[5:0];
cos = 9'h1ff + lut_cos;
end
2'b01:begin
lut_address = ~address[5:0];
cos = 9'h1ff + lut_cos;
end
2'b10:begin
lut_address = address[5:0];
cos = 9'h1ff - lut_cos;
end
2'b11:begin
lut_address = ~address[5:0];
cos = 9'h1ff + lut_cos;
end
endcase
end
always@(lut_address)begin
case(lut_address)
6'h0: lut_cos=9'h0;
6'h1: lut_cos=9'hC;
6'h2: lut_cos=9'h19;
6'h3: lut_cos=9'h25;
6'h4: lut_cos=9'h32;
6'h5: lut_cos=9'h3E;
6'h6: lut_cos=9'h4B;
6'h7: lut_cos=9'h57;
6'h8: lut_cos=9'h63;
6'h9: lut_cos=9'h70;
6'ha: lut_cos=9'h7C;
6'hb: lut_cos=9'h88;
6'hc: lut_cos=9'h94;
6'hd: lut_cos=9'hA0;
6'he: lut_cos=9'hAC;
6'hf: lut_cos=9'h88;
6'h10: lut_cos=9'hC3;
6'h11: lut_cos=9'hCF;
6'h12: lut_cos=9'hDA;
6'h13: lut_cos=9'hE6;
6'h14: lut_cos=9'hF1;
6'h15: lut_cos=9'hFC;
6'h16: lut_cos=9'h107;
6'h17: lut_cos=9'h111;
6'h18: lut_cos=9'h11C;
6'h19: lut_cos=9'h126;
6'h1a: lut_cos=9'h130;
6'h1b: lut_cos=9'h13A;
6'h1c: lut_cos=9'h144;
6'h1d: lut_cos=9'h14E;
6'h1e: lut_cos=9'h157;
6'h1f: lut_cos=9'h161;
6'h20: lut_cos=9'h16A;
6'h21: lut_cos=9'h172;
6'h22: lut_cos=9'h17B;
6'h23: lut_cos=9'h183;
6'h24: lut_cos=9'h18B;
6'h25: lut_cos=9'h193;
6'h26: lut_cos=9'h19B;
6'h27: lut_cos=9'h1A2;
6'h28: lut_cos=9'h1A9;
6'h29: lut_cos=9'h1B0;
6'h2a: lut_cos=9'h1B7;
6'h2b: lut_cos=9'h1BD;
6'h2c: lut_cos=9'h1C3;
6'h2d: lut_cos=9'h1C9;
6'h2e: lut_cos=9'h1CE;
6'h2f: lut_cos=9'h1D4;
6'h30: lut_cos=9'h1D9;
6'h31: lut_cos=9'h1DD;
6'h32: lut_cos=9'h1E2;
6'h33: lut_cos=9'h1E6;
6'h34: lut_cos=9'h1E9;
6'h35: lut_cos=9'h1ED;
6'h36: lut_cos=9'h1F0;
6'h37: lut_cos=9'h1F3;
6'h38: lut_cos=9'h1F6;
6'h39: lut_cos=9'h1F8;
6'h3a: lut_cos=9'h1FA;
6'h3b: lut_cos=9'h1FC;
6'h3c: lut_cos=9'h1FD;
6'h3d: lut_cos=9'h1FE;
6'h3e: lut_cos=9'h1FF;
6'h3f: lut_cos=9'h1FF;
endcase
end
endmodule
4、pll
六、项目实现图片
七、资源使用报告
八、遇到的主要难题及解决方法
1、第一次接触verilog语言,花了较长时间学习
2、diamond软件,调用pll都是纯英文,需要适应
3、这次能做出来基本参考了电子森林的代码,基本是像搭积木一样每个模块模块的学习搭成dds这个项目,非常感谢电子森林翔实的资料
九、未来的计划
多多参加硬禾学堂的相关活动,更加熟练地使用这个开发板。
软硬件
附件下载
DDS.jed
可执行文件
dds.7z
工程
团队介绍
来自华北电力大学的唐可可
团队成员
唐可可
评论
0 / 100
查看更多