36_ZYNQ7020开发板串行序列机SPI协议接口DAC_TLV5618

模数转换D/A,指数字信号转变为模拟信号的电子元件
一、TLV5618型DAC工作原理
是一个基于电压输出型双通道12位单电源数模转换器。
在这里插入图片描述
二、TLV5618型DAC芯片引脚功能
在这里插入图片描述
在这里插入图片描述
三、原理图
在这里插入图片描述
四、DAC芯片输出电压计算原理

TLV5618是由两个电阻网络实现两路数模转换,**每路DAC的核心是一个拥有4096(2的12次方)个节点电阻,对应4096种不同的组合,**每个电阻网络的一段接到GND。

则DAC的输出电压范围0V~VREF
其中每个DAC通道的电阻网络电压输出后级,连接了一个2倍增益的放大器。
将DAC单元的额输出电压放大2倍后输出到管脚。

则输出电压0V~4.096v
输出电压V = 2 * REF * code /4096
REF为基准电压,本电路为2.048V,code是数字电压输入值,范围为0~4095。
在这里插入图片描述
五、DAC的SPI时序
在这里插入图片描述
数据格式:

在这里插入图片描述
一般选两组数据,分别是通道A和通道B
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
六、线性序列机的DAC模块
在这里插入图片描述
在这里插入图片描述
代码:
DAC_test.v

module DAC_test(
			Clk,   //模块时钟50M
			Rst_n, //模块复位
			
			DAC_CS_N,  //TLV5618的CS_N接口
			DAC_DIN,   //TLV5618的DIN接口
			DAC_SCLK   //TLV5618的SCLK接口
		);
	input Clk;
	input Rst_n;
	
	output DAC_CS_N;
	output DAC_DIN;
	output DAC_SCLK;
	
	reg Start;
	reg [15:0]r_DAC_DATA;
	wire DAC_State;
	wire [15:0]DAC_DATA;
	wire Set_Done;
	
	assign DAC_DATA = 16'hCFFF;

	tlv5618 tlv5618(
		.Clk(Clk),
		.Rst_n(Rst_n),
		
		.DAC_DATA(DAC_DATA),
		.Start(Start),
		.Set_Done(Set_Done),
		
		.DAC_CS_N(DAC_CS_N),
		.DAC_DIN(DAC_DIN),
		.DAC_SCLK(DAC_SCLK),
		.DAC_State(DAC_State)
	);

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		r_DAC_DATA <= 16'd0;
	else if(DAC_State)
		r_DAC_DATA <= DAC_DATA;
		
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		Start <= 1'd0;
	else if(r_DAC_DATA != DAC_DATA) 
		Start <= 1'b1;
	else
		Start <= 1'd0;

endmodule

tlv5618.v

`timescale 1ns/1ns

module tlv5618(
	Clk,
	Rst_n,
	
	DAC_DATA,
	Start,
	Set_Done,
	
	DAC_CS_N,
	DAC_DIN,
	DAC_SCLK,
	DAC_State
);
	
	parameter fCLK = 50;
	parameter DIV_PARAM = 2;

	input Clk;
	input Rst_n;
	input [15:0]DAC_DATA;
	input Start;
	output reg Set_Done;
	
	output reg DAC_CS_N;
	output reg DAC_DIN;
	output reg DAC_SCLK;
	output DAC_State;
	
	assign DAC_State = DAC_CS_N;
	
	reg [15:0]r_DAC_DATA;
	
	reg [3:0]DIV_CNT;//分频计数器
	reg SCLK2X;//2倍SCLK的采样时钟
	
	reg [5:0]SCLK_GEN_CNT;//SCLK生成暨序列机计数器
	
	reg en;//转换使能信号
	
	wire trans_done; //转换序列完成标志信号
	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		en  <= #1  1'b0;
	else if(Start)
		en  <= #1  1'b1;
	else if(trans_done)
		en  <= #1  1'b0;
	else
		en  <= #1  en;

	//生成2倍SCLK使能时钟计数器
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		DIV_CNT  <= #1  4'd0;
	else if(en)begin
		if(DIV_CNT == (DIV_PARAM - 1'b1))
			DIV_CNT  <= #1  4'd0;
		else 
			DIV_CNT  <= #1  DIV_CNT + 1'b1;
	end else	
		DIV_CNT  <= #1  4'd0;

	//生成2倍SCLK使能时钟计数器
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		SCLK2X  <= #1  1'b0;
	else if(en && (DIV_CNT == (DIV_PARAM - 1'b1)))
		SCLK2X  <= #1  1'b1;
	else
		SCLK2X  <= #1  1'b0;
		
	//生成序列计数器
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		SCLK_GEN_CNT  <= #1  6'd0;
	else if(SCLK2X && en)begin
		if(SCLK_GEN_CNT == 6'd33)
			SCLK_GEN_CNT  <= #1  6'd0;
		else
			SCLK_GEN_CNT  <= #1  SCLK_GEN_CNT + 1'd1;
	end else
		SCLK_GEN_CNT  <= #1  SCLK_GEN_CNT;

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		r_DAC_DATA  <= #1  16'd0;
	else if(Start)//收到开始发送命令时,寄存DAC_DATA值	
		r_DAC_DATA  <= #1  DAC_DATA;
	else
		r_DAC_DATA  <= #1  r_DAC_DATA;
				
	//依次将数据移出到DAC芯片		
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)begin
		DAC_DIN  <= #1  1'b1;
		DAC_SCLK  <= #1  1'b0;
		DAC_CS_N <= #1 1'b1;
	end else if(!Set_Done && SCLK2X) begin
		case(SCLK_GEN_CNT)
			0:
				begin
					DAC_CS_N <= #1 1'b0;
					DAC_DIN  <= #1 r_DAC_DATA[15];
					DAC_SCLK  <= #1  1'b1;
				end
		
			1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31:
				begin
					DAC_SCLK  <= #1  1'b0;
				end
			
			2:  begin DAC_DIN  <= #1 r_DAC_DATA[14]; DAC_SCLK  <= #1 1'b1; end
			4:  begin DAC_DIN  <= #1 r_DAC_DATA[13]; DAC_SCLK  <= #1 1'b1; end
			6:  begin DAC_DIN  <= #1 r_DAC_DATA[12]; DAC_SCLK  <= #1 1'b1; end
			8:  begin DAC_DIN  <= #1 r_DAC_DATA[11]; DAC_SCLK  <= #1 1'b1; end			
			10: begin DAC_DIN  <= #1 r_DAC_DATA[10]; DAC_SCLK  <= #1 1'b1; end
			12: begin DAC_DIN  <= #1 r_DAC_DATA[9];  DAC_SCLK  <= #1 1'b1; end
			14: begin DAC_DIN  <= #1 r_DAC_DATA[8];  DAC_SCLK  <= #1 1'b1; end
			16: begin DAC_DIN  <= #1 r_DAC_DATA[7];  DAC_SCLK  <= #1 1'b1; end	
			18: begin DAC_DIN  <= #1 r_DAC_DATA[6];  DAC_SCLK  <= #1 1'b1; end
			20: begin DAC_DIN  <= #1 r_DAC_DATA[5];  DAC_SCLK  <= #1 1'b1; end				
			22: begin DAC_DIN  <= #1 r_DAC_DATA[4];  DAC_SCLK  <= #1 1'b1; end
			24: begin DAC_DIN  <= #1 r_DAC_DATA[3];  DAC_SCLK  <= #1 1'b1; end
			26: begin DAC_DIN  <= #1 r_DAC_DATA[2];  DAC_SCLK  <= #1 1'b1; end
			28: begin DAC_DIN  <= #1 r_DAC_DATA[1];  DAC_SCLK  <= #1 1'b1; end			
			30: begin DAC_DIN  <= #1 r_DAC_DATA[0];  DAC_SCLK  <= #1 1'b1; end
			
			32: DAC_SCLK  <= #1 1'b1; 
			33: DAC_CS_N  <= #1 1'b1;
			default:;
		endcase
	end
	
	assign trans_done = (SCLK_GEN_CNT == 33) && SCLK2X;
	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		Set_Done <= 1'b0;
	else if(trans_done)
		Set_Done <= 1'b1;
	else
		Set_Done <= 1'b0;
	
endmodule

在这里插入图片描述

**当输入:assign DAC_DATA = 16’hCFFF;**输出A通道
在这里插入图片描述
当输入:assign DAC_DATA = 16’h47FF;输出B通道
在这里插入图片描述
当输入:assign DAC_DATA = 16’hC1FF;采集A通道
在这里插入图片描述
当输入:assign DAC_DATA = 16’h4000;采集B通道
在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值