FPGA开发之DAC8532驱动

2 篇文章 0 订阅
1 篇文章 0 订阅
本文档详细介绍了DAC8532接口特性、时序要求和工作模式,特别关注了正常模式下的操作。通过示例展示了如何在第二次完成时将指定值同时写入DACA和DACB模拟输出。程序部分包括了底层模块`dac8532_drive.v`和顶层模块`dac8532_demo.v`的代码实现,用于控制D/A转换并同步模拟输出更新。
摘要由CSDN通过智能技术生成

手册学习:

一、接口部分:

封装图
Vdd:电源输入,2.7 V至5.5 V;
Vref:参考电压输入;
VoutA/VoutB:DAC A/B 的模拟输出电压;
SYNC:输入数据的帧同步信号输入,低电平有效,当 SYNC 处于低电平,它使能输入移位寄存器,数据在 SCLK 的下降沿传输;
SCLK: 串行时钟输入,数据可以以高达 30 MHz 的速率在 5 V 下传输;

VDD 在 3.6 V ~ 5.5 V 时,SCLK最大30M;
VDD 在 2.7 V ~ 3.6 V 时,SCLK最大20M;

DIN :串行数据输入,数据在串行时钟输入的下降沿被计时到 24 位输入移位寄存器;
GND:


二、 时序要求

时序图

三、设备功能模式

DAC8532 的输入移位寄存器为 24 位宽(见图),由 8 个控制位,(DB16–DB23) 和 16 个数据位 (DB0–DB15) 组成。前两个控制位(DB22 和 DB23)是保留的,必须为 0 才能正常运行。 LD A (DB20) 和 LD B (DB21) 控制每个模拟输出的更新指定的 16 位数据值或掉电命令。位 DB19 是无关位,不影响DAC8532 的操作,可以是 1 或 0。下面的控制位,缓冲器选择 (DB18),控制DAC A 和 DAC B 之间数据(或掉电命令)的目的地。最后两个控制位,PD0(DB16) 和 PD1 (DB17),选择一个或两个 DAC 通道的掉电模式。四种模式是正常模式或三种掉电模式中的任何一种。更完整的操作模式描述DAC8532 可在“掉电模式”部分找到。 24 位输入的其余 16 位字组成数据位。这些被传送到指定的数据缓冲器或 DAC 寄存器,具体取决于控制字节发出的命令,在 SCLK 的第 24 个下降沿。寄存器配置
一般就用正常模式

四、操作举例

本驱动用到的是例1:DACA 和 DACB 模拟输出在第二次完成后同时稳定到指定值的写顺序(在该寄存器转换发生和模拟输出更新的同时,Load 命令将数字数据从数据缓冲器移动到 DAC 寄存器。在SYNC LOW 后的第 24 个SCLK下降沿完成)
例1

五、程序

底层 dac8532_drive.v

module dac8532_drive(
input 	wire				sys_clk,
input 	wire				sys_rst,
input   wire    [15:0]      data_dout,
input   wire                start,

output  reg                 done,
output 	wire 				P_SCLK,
output 	reg 				P_SYNC,
output 	reg				    P_DIN
           
);


reg                     div_clk;
reg 	                sclk_en;
reg 	[7:0]		    DAC_ctrl_state; 
reg 	[7:0]           SPI_cnt;
reg 	[7:0]		    div10_cnt;
reg 	[23:0]		    DAC_buf_A;
reg 	[23:0]		    DAC_buf_B;


assign  P_SCLK = sclk_en ? sys_clk : 1'b0 ; 

//--两段式状态机
always@(posedge sys_clk or negedge sys_rst)       
begin
    if(sys_rst == 1'b0)
        DAC_ctrl_state                   <= 8'd0;
    else
    begin
        case (DAC_ctrl_state)
            8'd0: 
            begin
                if(start == 1'b0)
                    DAC_ctrl_state       <= 8'd0;  
                else
                    DAC_ctrl_state       <= 8'd1;
            end  
           //--写24b数据到寄存器
            8'd1:
            begin
                if(SPI_cnt < 8'd24)
                    DAC_ctrl_state       <= 8'd1;
                else
                    DAC_ctrl_state       <= 8'd2;
            end
            8'd2:
                DAC_ctrl_state           <= 8'd3;
            //--寄存器数据同时装载到DAC寄存器
            8'd3:
            begin
                if(SPI_cnt < 8'd24)
                    DAC_ctrl_state       <= 8'd3;
                else
                    DAC_ctrl_state       <= 8'd0;
            end
            default: 
                DAC_ctrl_state           <= 8'd0;
        endcase
    end
end

//--
always@(posedge sys_clk or negedge sys_rst)       
begin
if(sys_rst == 1'b0)
begin           
	sclk_en					    <= 1'b0;
	P_SYNC				   	    <= 1'b1;         
	P_DIN    				    <= 1'b0;
    done                    	<= 1'b0;
	SPI_cnt                     <= 8'd0;
    DAC_ctrl_state 		        <= 8'd0;
	DAC_buf_A[23:0]             <= 24'h0;	
	DAC_buf_B[23:0]             <= 24'h0;	
end
else
begin
	case(DAC_ctrl_state)     
	    8'd0:   
	    begin
            done            	<= 1'b0;
	    	DAC_buf_A[23:0]     <= {8'b00000000, data_dout};							
	    	DAC_buf_B[23:0]     <= {8'b00110100, data_dout};							
	    end
	    8'd1:     
	    begin
	        P_SYNC              <= 1'b0;
  	    	sclk_en             <= 1'b1; 
	    	if(SPI_cnt < 8'd24)
	    	begin
	    		P_DIN           <= DAC_buf_A[23];       
	    		DAC_buf_A[23:1] <= DAC_buf_A[22:0];
	    		DAC_buf_A[0]    <= 1'b0; 			
	    		SPI_cnt         <= SPI_cnt + 8'd1;  
	    	end
	    	else
	    	begin
	    		sclk_en         <= 1'b0;
                P_SYNC          <= 1'b1; 
	    		SPI_cnt         <= 8'd0; 
	    	end
	    end
	    8'd3:   
	    begin
	        P_SYNC              <= 1'b0; 
	    	sclk_en             <= 1'b1; 
	    	if(SPI_cnt < 8'd24)
	    	begin
	    		P_DIN           <= DAC_buf_B[23];       
	    		DAC_buf_B[23:1] <= DAC_buf_B[22:0];
	    		DAC_buf_B[0]    <= 1'b0; 			
	    		SPI_cnt         <= SPI_cnt + 8'd1;  
	    	end
	    	else
	    	begin
	    		sclk_en         <= 1'b0;
	    		SPI_cnt         <= 8'd0; 
	    		P_SYNC          <= 1'b1;
                done        	<= 1'b1;
	    	end
	    end	
	    default:
	        P_SYNC              <= P_SYNC;
	endcase	
end
end
endmodule


顶层 dac8532_demo.v

module dac8532_demo(
input 	wire				sys_clk,
input 	wire				sys_rst,

output 	wire 				DAC_SCLK,
output 	wire 				DAC_SYNC,
output 	wire				DAC_DIN
           
);
reg     [15:0]              DAC_data;//--根据公式修改:Vout = Vref * ( DAC_data / 65536 )
wire                        DAC_done;//--完成一次转换操作
reg                         DAC_start;//--开始转换

reg     [23:0]              cnt;
always @(posedge sys_clk or negedge sys_rst) 
begin
    if(sys_rst == 1'b0)
    begin
        DAC_data            <= 16'hFFFF;
        DAC_start           <= 1'b0;
        cnt                 <= 24'd0;
    end
    else
    begin
        if(cnt < 24'd10_0000)
        begin
            cnt             <= cnt + 24'd1;
            DAC_start       <= 1'b0;
        end
        else
        begin
            cnt             <= 24'd0;
            DAC_start       <= 1'b1;
        end
    end
end
dac8532_drive dac8532_drive_1(
    .sys_clk                (sys_clk),
    .sys_rst                (sys_rst),
    .data_dout              (DAC_data),
    .start                  (DAC_start),
    .done                   (DAC_done),
    .P_SCLK                 (DAC_SCLK),
    .P_SYNC                 (DAC_SYNC),
    .P_DIN                  (DAC_DIN)
           
);

endmodule


仿真 tb_sim1.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/12/02 14:25:02
// Design Name: 
// Module Name: tb_sim1
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_sim1;

reg clk;
reg rst;
parameter SYSCLK_PERIOD = 100;
initial begin
    clk   = 0;
    rst   = 0;
end
initial
begin
    #(SYSCLK_PERIOD * 10 )
        rst = 1'b1;
end
always #(SYSCLK_PERIOD / 2.0) clk = ~clk; //一个周期 



wire    DAC_SCLK; 
wire    DAC_SYNC; 
wire    DAC_DIN ;  
dac8532_demo dac8532_demo_1(
    .sys_clk                (clk),
    .sys_rst                (rst),
    .DAC_SCLK               (DAC_SCLK ),
    .DAC_SYNC               (DAC_SYNC ),
    .DAC_DIN                (DAC_DIN  )
           
);
endmodule

vivado前仿真:

仿真图

DAC904E是一种高性能数字模拟转换器(DAC)芯片,专为应用于FPGA(现场可编程门阵列)设计而开发的。FPGA是一种可编程的集成电路,可以灵活地配置和重新配置其硬件功能,使其适应不同的应用需求。 在FPGA驱动方面,DAC904E需要一些特定的硬件资源和逻辑电路来实现其功能。首先,FPGA需要提供与DAC904E的通信接口,通常使用I2C或SPI等串行通信协议。通过这个接口,FPGA可以向DAC发送数字数据,控制其工作模式和输出电压等参数。 其次,DAC904E需要与FPGA之间建立正确的时钟同步。FPGA可以通过时钟管理模块提供符合DAC904E要求的时钟信号,以确保数据传输的准确性和稳定性。 除了基本的通信和时钟同步,驱动程序还需要实现一些附加功能,如数据格式选择、输出电压范围设置和校准等。这些功能可通过FPGA编程完成,使用如Verilog或VHDL等硬件描述语言实现相关逻辑电路。 在驱动开发过程中,我们需要仔细阅读DAC904E的数据手册,了解其寄存器配置和工作原理等信息。根据需求,编写相应的驱动代码,并进行功能测试和性能优化。此外,还需要与其它硬件模块或外部设备进行接口对接,以实现系统级别的功能。 总结来说,DAC904E FPGA驱动需要通过适当的通信接口和时钟同步方式,与FPGA进行数据交互和控制。通过编写相应的驱动代码,实现DAC的配置和控制功能,使之能够在FPGA系统中发挥其数字模拟转换的作用。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值