模数转换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通道