1、TLV5618 型 DAC 芯片输出电压计算原理
该电阻网络型
DAC
的输出 电压范围应该为0V~VREF
,对应到
AC620
板上的电路,即
0V~2.048V
。另外在每个
DAC通道的电阻网络电压输出后级,连接了一个 2
倍增益的轨对轨放大器。将电阻网络
DAC
单元的输出电压放大为 2
倍后输出到管脚。所以,
TLV5618
芯片的实际输出电压范围为0V~2*VREF,对应到
AC620
板上的电路,即
0V~4.096V
。当芯片上电时,
DAC 的值全部被复位到 0。每个 DAC 通道的输出可由下列公式计算得出:
![](https://img-blog.csdnimg.cn/direct/0e6cd99820874154ae00a65056c3b64a.png)
REF
是基准电压,本电路中为
2.048V
;
CODE
是数字电压输入值,范围
0
到
2^
12
- 1;输出电压对应着0~2*REF,即0~4.096V
2、TLV5618 型 DAC 接口时序
(1)SCLK下降沿时,读取数据,数据保持稳定,DIN应在SCLK上升沿时变化。
(2) 当片选(CS̅)信号为低电平时,输入数据信号线(DIN)上的值在每个SCLK信号的下降沿被移入芯片内部的寄存器。 16 位的数据按照高位在前,低位在后的顺序依次移入。
3、TLV5618 的 16 位DIN数据格式
如下图(前4位是控制位,后12位是数据位)
其中,SPD 为速度控制位,PWR 为电源控制位。
R1
与
R0
所有可能的组合以及代表的含义如下所示。如果其中一个寄存器或者缓冲区
被选择,那么
12
位数据将决定新的
DAC
输出电压值。
4、TLV5618驱动模块示意图
5、代码设计
module tlv5618(
input wire Clk,
input wire Rst_n,
input wire [15:0] DAC_DATA, //并行数据输入端
input wire Start, //开始标志
output reg Set_Done, //完成标志
output reg DAC_CS_N, //DAC片选信号
output reg DAC_DIN, //DAC串行数据输出信号
output reg DAC_SCLK, //DAC工作时钟信号
output wire DAC_State
);
parameter fCLK = 50;
parameter DIV_PARAM = 2;
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; //转换序列完成标志信号
assign DAC_State = DAC_CS_N;
//生成使能信号。当开始标志start有效时使能信号en置1,当转换完成信号有效时使能信号en置0
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
en <= 1'b0;
else if(Start)
en <= 1'b1;
else if(trans_done)
en <= 1'b0;
else
en <= en;
//生成2倍SCLK时钟的分频计数器
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
DIV_CNT <= 4'd0;
else if(en)begin
if(DIV_CNT == (DIV_PARAM - 1'b1))
DIV_CNT <= 4'd0;
else
DIV_CNT <= DIV_CNT + 1'b1;
end else
DIV_CNT <= 4'd0;
//生成2倍SCLK时钟
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
SCLK2X <= 1'b0;
else if(en && (DIV_CNT == (DIV_PARAM - 1'b1)))
SCLK2X <= 1'b1;
else
SCLK2X <= 1'b0;
//生成序列计数器,对SCLK脉冲进行计数(由于SPI有34个状态,故计数0~33)
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
SCLK_GEN_CNT <= 6'd0;
else if(SCLK2X && en)begin
if(SCLK_GEN_CNT == 6'd33)
SCLK_GEN_CNT <= 6'd0;
else
SCLK_GEN_CNT <= SCLK_GEN_CNT + 1'd1;
end else
SCLK_GEN_CNT <= SCLK_GEN_CNT;
//数据缓存:收到开始发送命令时,寄存DAC_DATA值
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
r_DAC_DATA <= 16'd0;
else if(Start)
r_DAC_DATA <= DAC_DATA;
else
r_DAC_DATA <= r_DAC_DATA;
//依次将数据移出到DAC芯片
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
DAC_DIN <= 1'b1;
DAC_SCLK <= 1'b0;
DAC_CS_N <= 1'b1;
end else if(!Set_Done && SCLK2X) begin
case(SCLK_GEN_CNT)
0:
begin
DAC_CS_N <= 1'b0;
DAC_DIN <= r_DAC_DATA[15]; DAC_SCLK <= 1'b1;
end
1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31:
begin
DAC_SCLK <= 1'b0;
end
2: begin DAC_DIN <= r_DAC_DATA[14]; DAC_SCLK <= 1'b1; end
4: begin DAC_DIN <= r_DAC_DATA[13]; DAC_SCLK <= 1'b1; end
6: begin DAC_DIN <= r_DAC_DATA[12]; DAC_SCLK <= 1'b1; end
8: begin DAC_DIN <= r_DAC_DATA[11]; DAC_SCLK <= 1'b1; end
10: begin DAC_DIN <= r_DAC_DATA[10]; DAC_SCLK <= 1'b1; end
12: begin DAC_DIN <= r_DAC_DATA[9]; DAC_SCLK <= 1'b1; end
14: begin DAC_DIN <= r_DAC_DATA[8]; DAC_SCLK <= 1'b1; end
16: begin DAC_DIN <= r_DAC_DATA[7]; DAC_SCLK <= 1'b1; end
18: begin DAC_DIN <= r_DAC_DATA[6]; DAC_SCLK <= 1'b1; end
20: begin DAC_DIN <= r_DAC_DATA[5]; DAC_SCLK <= 1'b1; end
22: begin DAC_DIN <= r_DAC_DATA[4]; DAC_SCLK <= 1'b1; end
24: begin DAC_DIN <= r_DAC_DATA[3]; DAC_SCLK <= 1'b1; end
26: begin DAC_DIN <= r_DAC_DATA[2]; DAC_SCLK <= 1'b1; end
28: begin DAC_DIN <= r_DAC_DATA[1]; DAC_SCLK <= 1'b1; end
30: begin DAC_DIN <= r_DAC_DATA[0]; DAC_SCLK <= 1'b1; end
32: DAC_SCLK <= 1'b1;
33: DAC_CS_N <= 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
`timescale 1ns/1ns
module tlv5618_tb();
reg Clk;
reg Rst_n;
reg [15:0]DAC_DATA;
reg Start;
wire Set_Done;
wire DAC_CS_N;
wire DAC_DIN;
wire DAC_SCLK;
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()
);
initial Clk = 1;
always#10 Clk = ~Clk;
initial begin
Rst_n = 0;
Start = 0;
DAC_DATA = 0;
#201;
Rst_n = 1;
#200;
DAC_DATA = 16'hC_AAA;
Start = 1;
#20;
Start = 0;
#200;
wait(Set_Done);
#20000;
DAC_DATA = 16'h4_555;
Start = 1;
#20;
Start = 0;
#200;
wait(Set_Done);
#20000;
DAC_DATA = 16'h1_555;
Start = 1;
#20;
Start = 0;
#200;
wait(Set_Done);
#20000;
DAC_DATA = 16'hf_555;
Start = 1;
#20;
Start = 0;
#200;
wait(Set_Done);
#20000;
$stop;
end
endmodule