FPGA控制DAC8550

1. DAC8550数模转换器简介

通信方式:SPI,时钟速率达到30MHz
分辨率:16bit
封装:VSSOP
引脚定义如图1所示
在这里插入图片描述

图1 引脚定义

重要的几个引脚描述:
SYNC:电平触发的控制输入(低电平有效)。 这是输入数据的帧同步信号。 当SYNC变为低电平时,它使能输入移位寄存器,并在随后的时钟的下降沿传输数据。 DAC在第24个时钟后更新(除非在该边沿之前将SYNC设为高电平,否则SYNC的上升沿将作为中断,并且DAC8550将忽略写序列)。 施密特触发器逻辑输入。
SCLK:串行时钟
Din:串行数据输入,在SCLK的下降沿输入移位寄存器。
写入数据的波形如图2所示:
在这里插入图片描述

图2 数据写入时序

注意一点,FPGA输出的数据要在SCLK的上升沿改变,以便DAC在下降沿锁存数据。
以下是我的代码:

`timescale 					1ns / 1ps

//***********************************************************
//Project Name									ProjectDAC
//Author										chaonan Song
//Email											songchaonan@gmail.com
//moduleName									ProjectDAC
//Create Time 									2020/2/26
//***********************************************************
module							ProjectDAC(
	input						clk,
	input						rst_n,
	input						endac,
	output		reg				sclk,
	output		reg				SYNC_n,
	output		reg				dout,
	output		reg[15:0]		data_out,
	output		reg[4:0]		bit_cnt
);
//-----------------------------------------------------------
//------------------鍐呴儴绔彛澹版槑-----------------------------
//-----------------------------------------------------------

//reg			[23:0]				shift_reg;
//reg			[15:0]				data_out;
reg			[1:0]				cnt;
wire			[23:0]			shift_reg;
//reg			[4:0]				bit_cnt;
//-----------------------------------------------------------
//------------------閫昏緫鍔熻兘瀹炵幇-----------------------------
//-----------------------------------------------------------
//------------------cnt--------------------------------------
always	@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt <= 2'b00;
	else if(cnt == 2'b11)
		cnt <= 2'b00;
	else 
		cnt <= cnt + 1'b1;
//-----------------sclk-------------------------------------
always	@(posedge clk or negedge rst_n)
	if(!rst_n)
		sclk <= 1'b0;
	else if(cnt == 2'b01)
		sclk <= !sclk;
	else
		sclk <= sclk;
//------------------SYNC_n----------------------------------
always	@(posedge sclk or negedge rst_n)
	if(!rst_n)
		SYNC_n <= 1'b1;
	else if(bit_cnt == 5'd23)
		SYNC_n <= 1'b1;
	else if(endac)
		SYNC_n <= 1'b0;
	else
		SYNC_n <= SYNC_n;
//-------------------bit_cnt--------------------------------
always @(posedge sclk or negedge rst_n)
	if(!rst_n)
		bit_cnt <= 1'b0;
	else if(bit_cnt == 5'd23 || SYNC_n == 1'b1)
		bit_cnt <= 1'b0;
	else if(SYNC_n == 1'b0)
		bit_cnt <= bit_cnt + 1'b1;
	else
		bit_cnt <= bit_cnt;
//-----------------------data_out--------------------------
always	@(posedge sclk or negedge rst_n)
	if(!rst_n)
		data_out <= 16'b0;
	else if(data_out == 16'd100)
		data_out <= 16'd0;
	else if(bit_cnt == 5'd23)
		data_out <= data_out + 1'b1;
	else
		data_out <= data_out;
//-----------------------shift_reg-------------------------
assign shift_reg = {8'b0, data_out};
//----------------------dout-------------------------------
always	@(posedge sclk or negedge rst_n)
	if(!rst_n)
		dout <= 1'b1;
	else if(SYNC_n == 1'b0 )
		dout <= shift_reg[bit_cnt];
	else if(bit_cnt == 5'd23)
		dout <= 1'b1;
	else
		dout <= 1'b1;
endmodule

以下是我进行测试的代码

`timescale 					1ns / 1ps
`define			CLOCK		20
//***********************************************************
//Project Name									ProjectDAC
//Author										chaonan Song
//Email											songchaonan@gmail.com
//moduleName									ProjectDAC_tb
//Create Time 									2020/2/26
//***********************************************************
module						ProjectDAC_tb();
reg							clk;
reg							rst_n;
reg							endac;
wire						sclk;
wire						SYNC_n;
wire						dout;
wire		[15:0]			data_out;
reg			[23:0]			data_rec;
wire		[4:0]			bit_cnt;
//------------------------initial----------------------------
initial
begin
	clk 		<= 		1'b0;
	rst_n		<= 		1'b0;
	endac 		<= 		1'b0;
	data_rec	<= 		24'b0;
	#(10 * `CLOCK)
	rst_n 		<= 		1'b1;
	#(10 * `CLOCK)
	endac 		<= 		1'b1;
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
	#(16 * `CLOCK)
	datareceive();
end
always 
	#(`CLOCK/2)	clk <= ~clk;
task	datareceive;
	integer		i;
	begin
		for(i = 0; i <= 23; i = i+1)
		begin
			@(posedge sclk)
			data_rec <= {dout, data_rec[23:1]};
		end
	end
endtask
ProjectDAC				ProjectDAC_Init(
	.clk				(clk),
	.rst_n				(rst_n),
	.endac				(endac),
	.sclk				(sclk),
	.SYNC_n				(SYNC_n),
	.dout				(dout),
	.data_out			(data_out),
	.bit_cnt			(bit_cnt)
);
endmodule

今天的内容到此结束。


版权声明:本文为qq_30357727原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。