模拟电路前端工程化设计——2.任意波形发生器
使用串行DAC AD5626设计一款任意波形发生器,搭配单片机或FPGA或其它方式的控制逻辑能够产生10Hz到20KHz范围内的正弦波信号,输出信号幅度要达到3Vpp,直流偏移可调1.5V到3.5V
标签
任意波形发生器
模拟
模拟电路前端
冷月烟
更新2023-06-25
420

一、项目要求

  • 使用串行DAC AD5626设计一款任意波形发生器
  • 搭配单片机或FPGA或其它方式的控制逻辑能够产生10Hz到20KHz范围内的正弦波信号
  • 输出信号幅度要达到3Vpp,直流偏移可调1.5V到3.5V
  • -使用ADALP2000模拟套件中的器件实现
  • 使用套件中的Micro USB适配器通过USB给面包板供电,供电电压为5V
  • 使用ADALP2000套件中的运算放大器搭建一个Sallen-Key滤波器,滤除40KHz以上的混叠信号,输出运算放大器也选自ADALP2000套件
  • 运算放大器可从套件中提供的几个型号中选用
  • DAC采用AD5626
  • -实现方式:
  • 设计电路并使用LTSpice或CircuitJS进行仿真
  • 搭建实际的电路进行测试验证
  • 撰写一个不少于2000字的设计报告,并拍摄3-5分钟短视频分享在电子森林网站上
 

二、需求分析

  1. 搭配单片机或FPGA或其它方式的控制逻辑能够产生10Hz到20KHz范围内的正弦波信号:使用STM32+iCE40平台,里面的ICE40UP5K FPGA做本次控制,使用按键对输出频率进行调节。
  2. 输出信号幅度要达到3Vpp,直流偏移可调1.5V到3.5V:要求输出3Vpp,使用AD5626本身即可做到,在输出3Vpp时偏移1.5V,波形整体在0-3V的范围内;偏移3.5V时,波形在2-5V的范围内。这样的话使用运放使用5V单电源供电即可实现功能。
  3. 使用ADALP2000套件中的运算放大器搭建一个Sallen-Key滤波器,滤除40KHz以上的混叠信号,输出运算放大器也选自ADALP2000套件:利用Analog Filter Wizard进行设计,LTSpice仿真优化即可。
  4. DAC采用AD5626:依照要求使用。

 

三、仿真电路搭建

1.整体电路

FldpG1ANsSDyzY5bTTv1XGiBgDMm

 

2.搭建滤波器

Sallen-key是设计有源滤波器设计的一种拓扑结构,VCVS(Voltage-controlled voltage-source)滤波器的变种,由麻省理工学院林肯实验室的R. P. Sallen and E. L. Key 在1955所提出。

Sallen-key拓扑的特点:

  1. 高输入阻抗
  2. 增益容易被配置
  3. 运放被配置为电压跟随(Voltage Follower)模式

Fqy9wRzlRy4-eJ1CeWPfVjmkmDPK

这是Sallen-key滤波器的低通滤波器模型。模型中运放被配置成电压跟随模式。

本次需要设计一个40KHz低通滤波器,类型为Sallen-Key,使用ADALP2000套件器件搭建,由于可选器件不多,核心思想是尽可能简单,先用Analog Filter Wizard进行设计,再用LTSpice在ADALP2000套件可以搭建的范围进行慢慢实验。

Fq3VWnGr3G7TqPy0095o7fO61W8y

可以看到最终输出的截止频率在43.5kHz左右,与要求相符合。

FswwGdCb9cprxmSYs-swuvdtttPp

 

3.搭建直流偏置电路

运放直流偏置电路是一种基于运算放大器的电路,它通过添加适当大小和极性的直流电压来调整输入信号的直流分量,使其能够被运算放大器正确地处理。

这里我设计了一个放大倍数为1的反相放大电路,通过调节运放正输入端的电压调节输出偏移。

搭建实际电路时 V3 电源将使用电阻与滑动变阻器代替。

FmelLt_ZaLgQIUSNXvjNJoTiAmHZ

调整输出偏移为1.5V时。

FvnLMHjvhFvq4zYWF6VobyNrII4X

调整输出偏移为2.5V时。

FuRbZXJzR03suwMaH6FFVJBcq2jQ

调整输出偏移为3.5V时

FvJn6AdzFr_kWUifHHWW8vIrDOIV

 

四、DAC电路设计

1.DAC输出硬件设计

AD5626属于nanoDAC®系列,是一款完整的串行输入、12位电压输出数模转换器(DAC),采用5 V单电源供电。它集成了DAC、输入移位寄存器和锁存、基准电压源和一个轨到轨输出放大器。AD5626单芯片DAC适合仅有5 V电源的系统应用,具有成本低、易于使用的特点,输出运算放大器摆幅可达到任一供电轨,且设置范围为0 V至4.095 V,分辨率为每位1 mV。它能提供5 mA的吸电流和源电流。片内集成经激光调整后的基准电压源,提供精确的4.095 V满量程输出电压。该器件采用高速、三线式、兼容数据输入(SDIN)的DSP、时钟(SCLK)和负载选通(LDAC)的串线接口。它还有芯片选择引脚,可连接多个DAC。

整体框图

FoxtUXFkxXzgKUbpJHFvUwW95-gV
芯片引脚
FjtCAhpH-th9VIySV3s_zCOo08Uk

2.DAC输出软件设计

整体参考之前设计过的基于STM32+iCE40平台实现的DDS任意波形发生器项目进行改动。

AD5626时序图片

Fh0UHMk-ys9glerms-IZ22tmhuYa

dds部分

module dds(
	input sys_clk,
	input sys_rst_n,
	input [2:0] wave_type,
	input [23:0] wave_freq,
	input [4:0] wave_range,
	output [11:0] wave_dac
	);

reg [32:0] dds_phase;//33位相位累加器
always @(posedge sys_clk) dds_phase <= dds_phase + wave_freq * 33'd716;//33'd179;   //在12MHz的主时钟时,输出对应频率的波形
	
wire [9:0] sin_data; //sin波
wire [9:0] square_data; //方波
wire [9:0] trig_data; //三角波
reg [15:0] wave_data;
reg [9:0] a_ver;

sin_table u_sin_table(
	.address(dds_phase[32:25]),
	.sin(sin_data)
);
assign square_data = {10{dds_phase[32]}};
assign trig_data = dds_phase[32] ? ~dds_phase[31:22]: dds_phase[31:22];
always @(*)begin
	case(wave_type)
		3'd0: wave_data = 0;
		3'd1: wave_data = square_data * a_ver;
		3'd2: wave_data = trig_data * a_ver;
		3'd3: wave_data = sin_data * a_ver;
	endcase
end

always @(*)begin
	begin
		case(wave_range)
			5'd0: a_ver = 10'd0;
			5'd1: a_ver = 10'd3;
			5'd2: a_ver = 10'd5;
			5'd3: a_ver = 10'd8;
			5'd4: a_ver = 10'd11;
			5'd5: a_ver = 10'd13;
			5'd6: a_ver = 10'd16;
			5'd7: a_ver = 10'd19;
			5'd8: a_ver = 10'd21;
			5'd9: a_ver = 10'd23;
			5'd10: a_ver = 10'd26;
		endcase
	end
end

assign wave_dac = wave_data[14:3];

endmodule

sin生成部分

module sin_table(
	input  [7:0] address,
	output reg [9:0] sin
	);
 
wire [1:0] section;
reg [5:0] lut_address;
reg [8:0] lut_sin;
assign section = address[7:6];

always@(address)begin
	case(section)
		2'b00: begin
			lut_address = address[5:0];
			sin = 9'h1ff + lut_sin;
		end
		2'b01: begin
			lut_address = ~address[5:0];
			sin = 9'h1ff + lut_sin;
		end
		2'b10: begin
			lut_address = address[5:0];
			sin = 9'h1ff - lut_sin;
		end
		2'b11: begin
			lut_address = ~address[5:0];
			sin = 9'h1ff - lut_sin;
		end			   
	endcase
end

always @(lut_address)
	begin
		case(lut_address) 
			6'h0: lut_sin=9'h0;
			6'h1: lut_sin=9'hC;
			6'h2: lut_sin=9'h19;
			6'h3: lut_sin=9'h25;
			6'h4: lut_sin=9'h32;
			6'h5: lut_sin=9'h3E;
			6'h6: lut_sin=9'h4B;
			6'h7: lut_sin=9'h57;
			6'h8: lut_sin=9'h63;
			6'h9: lut_sin=9'h70;
			6'ha: lut_sin=9'h7C;
			6'hb: lut_sin=9'h88;
			6'hc: lut_sin=9'h94;
			6'hd: lut_sin=9'hA0;
			6'he: lut_sin=9'hAC;
			6'hf: lut_sin=9'hB8;
			6'h10: lut_sin=9'hC3;
			6'h11: lut_sin=9'hCF;
			6'h12: lut_sin=9'hDA;
			6'h13: lut_sin=9'hE6;
			6'h14: lut_sin=9'hF1;
			6'h15: lut_sin=9'hFC;
			6'h16: lut_sin=9'h107;
			6'h17: lut_sin=9'h111;
			6'h18: lut_sin=9'h11C;
			6'h19: lut_sin=9'h126;
			6'h1a: lut_sin=9'h130;
			6'h1b: lut_sin=9'h13A;
			6'h1c: lut_sin=9'h144;
			6'h1d: lut_sin=9'h14E;
			6'h1e: lut_sin=9'h157;
			6'h1f: lut_sin=9'h161;
			6'h20: lut_sin=9'h16A;
			6'h21: lut_sin=9'h172;
			6'h22: lut_sin=9'h17B;
			6'h23: lut_sin=9'h183;
			6'h24: lut_sin=9'h18B;
			6'h25: lut_sin=9'h193;
			6'h26: lut_sin=9'h19B;
			6'h27: lut_sin=9'h1A2;
			6'h28: lut_sin=9'h1A9;
			6'h29: lut_sin=9'h1B0;
			6'h2a: lut_sin=9'h1B7;
			6'h2b: lut_sin=9'h1BD;
			6'h2c: lut_sin=9'h1C3;
			6'h2d: lut_sin=9'h1C9;
			6'h2e: lut_sin=9'h1CE;
			6'h2f: lut_sin=9'h1D4;
			6'h30: lut_sin=9'h1D9;
			6'h31: lut_sin=9'h1DD;
			6'h32: lut_sin=9'h1E2;
			6'h33: lut_sin=9'h1E6;
			6'h34: lut_sin=9'h1E9;
			6'h35: lut_sin=9'h1ED;
			6'h36: lut_sin=9'h1F0;
			6'h37: lut_sin=9'h1F3;
			6'h38: lut_sin=9'h1F6;
			6'h39: lut_sin=9'h1F8;
			6'h3a: lut_sin=9'h1FA;
			6'h3b: lut_sin=9'h1FC;
			6'h3c: lut_sin=9'h1FD;
			6'h3d: lut_sin=9'h1FE;
			6'h3e: lut_sin=9'h1FF;
			6'h3f: lut_sin=9'h1FF;
		endcase
	end
endmodule

AD5626驱动

module ad5626(
  input sys_clk,
  input sys_rst_n,
  input [11:0] data, 
  output reg spi_clk,
  output reg spi_mosi, 
  output reg spi_cs,
  output reg pin_clr,
  output reg pin_ldac

);

reg [5:0] bit_cnt;
reg spi_en;
reg [11:0] data_r;


reg [2:0] freq_cnt;
always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	begin
		freq_cnt <= 0;
		spi_clk <= 1;
	end
	else
	begin
		if(freq_cnt == 0)
		begin
			spi_clk <= ~spi_clk;
			freq_cnt <= 0;
		end
		else
		begin
			freq_cnt <= freq_cnt + 1;
			spi_clk <= spi_clk; 
		end
	end
end
	
always@(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	begin
		spi_en<=0;
		pin_clr<=0;
	end
	else
	begin
		spi_en<=1;
		pin_clr<=1;
	end
end


always@(posedge spi_clk)
begin
	if(spi_en==0)
	begin
		bit_cnt<=20;
	end
	else
	begin
		case(bit_cnt)
		0:begin spi_cs<=0;pin_ldac<=1;bit_cnt<=1; data_r<=data;end 
		1:begin spi_mosi<=data_r[11];bit_cnt<=2; end
		2:begin spi_mosi<=data_r[10];bit_cnt<=3; end
		3:begin spi_mosi<=data_r[9];bit_cnt<=4; end
		4:begin spi_mosi<=data_r[8];bit_cnt<=5; end
		5:begin spi_mosi<=data_r[7];bit_cnt<=6; end
		6:begin spi_mosi<=data_r[6];bit_cnt<=7; end
		7:begin spi_mosi<=data_r[5];bit_cnt<=8; end
		8:begin spi_mosi<=data_r[4];bit_cnt<=9; end  
		9:begin spi_mosi<=data_r[3];bit_cnt<=10; end
		10:begin spi_mosi<=data_r[2];bit_cnt<=11; end
		11:begin spi_mosi<=data_r[1];bit_cnt<=12; end  	
		12:begin spi_mosi<=data_r[0];bit_cnt<=13; end
		13:begin spi_cs<=1;pin_ldac<=0;bit_cnt<=14;	end	
        default:begin spi_cs<=1;pin_ldac<=0;bit_cnt<=0; end  
		 endcase   
	end
end
endmodule

五、实际演示

实际电路

Fqscx8xl8hOnQlB3Bqf09zREaXB3

 

输出10KHz,3V幅度,1.5V偏移的正弦波

FloTXbFaChQ1lrlmgLO1p_ycuh1L

 

输出20KHz,3V幅度,1.5V偏移的正弦波

FrS91IFUkXAQpVSoKXcTx9GZIncx

 

输出10KHz,3V幅度,3.5V偏移的正弦波

FrkSsdodCjUYWv1M-LRoMIYL_9u7

 

输出43KHz,3V幅度的正弦波,可以看到被衰减为2.1V,基本符合-3dB衰减。

FotNakv9u225gJ7DCOUQb3OZOY1E

 

六、心得体会

通过参与这个项目,我获得了很多宝贵的经验和知识。在第二阶段的实战作业中,我学会了如何根据需求产生信号,深入了解LTSpice和ADI常用工具使用方式。这些实践项目让我对模拟电路有了更深入的了解,让我对这个领域有了更全面的认识。不仅学习了很多理论知识,还通过实践操作加深了对模拟电路的理解。这种结合理论和实践的教学方法让我更好地掌握了知识,也更容易应用到实际工作中。我相信这将对我的未来发展和工作起到很大的帮助作用。在第三阶段的实战项目中,我将会继续努力,让这个课程有一个圆满的结束。非常感谢硬禾学堂提供了这样一门精彩的课程,让我在这个领域有了更深入的了解和掌握。

附件下载
仿真2.asc
iCE40UP5K.zip
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号