导读:

DAC(Digital to Analog Conver ),是指将数字信号转变为模拟信号的电子元件。

分类:

电压型(TLV5618):常作为高速 DAC 使用。

电流型(AD7533):

1、芯片简介

1.1、TLV5618工作原理

1.2、芯片引脚

1.3、输出电压计算

其中,REF 是基准电压,本电路中为 2.0 48V ;CODE 是数字电压输入值,范围 0 到 212 -1 。

1.4、接口时序

1 6 位 的 数据 按照高位在前, 低位在 后的顺序依次移入。

SP D 为速度控制位, PWR 为电源控制位。

2、线性序列机设计思想

经查阅手册可知器件工作频率SCLK 最大为 20 MH z ,设计 时 留下 一定余量,因此 这里定义其工作频率为 12.5 MH z 。 设置一个两倍于 SCLK 的采样时钟 SCLK2X ,使用 50 M 系统时钟二分频而来即 SCLK2X 为 25 MH z

3、DAC驱动设计(tlv5618.v)

1、根据示意图编写端口

//========================================================================

module tlv5618(

Clk,

Rst_n,

DAC_DATA,

Start,

Set_Done,

DAC_CS_N,

DAC_DIN,

DAC_SCLK,

DAC_State

);

input Clk;

input Rst_n;

input [15:0]DAC_DATA;

input Start;

output reg Set_Done;

output DAC_CS_N;

output DAC_DIN;

output DAC_SCLK;

output DAC_State;

/* 具体如下*/

endmodule

//========================================================================

2、使能信号

//========================================================================

reg en;//转换使能信号

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;

//========================================================================

3、生成2倍SCLK使能时钟计数器

//========================================================================

parameter DIV_PARAM = 2;

reg [3:0]DIV_CNT;//分频计数器

reg SCLK2X;//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;

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;

//========================================================================

4、生成序列计数器

//========================================================================

reg [5:0]SCLK_GEN_CNT;//SCLK生成暨序列机计数器

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;

//========================================================================

5、将收到的data寄存到寄存器中

//========================================================================

reg [15:0]r_DAC_DATA;

always@(posedge Clk or negedge Rst_n)

if(!Rst_n)

r_DAC_DATA  <=  16'd0;

else if(Start)//收到开始发送命令时,寄存DAC_DATA值

r_DAC_DATA  <=  DAC_DATA;

else

r_DAC_DATA  <=  r_DAC_DATA;

//========================================================================

6、依次将数据移出到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

//========================================================================

7、产生转换完成结束信号

//========================================================================

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;

//========================================================================

总代码

//========================================================================

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'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;

//生成序列计数器

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;

always@(posedge Clk or negedge Rst_n)

if(!Rst_n)

r_DAC_DATA  <=  16'd0;

else if(Start)//收到开始发送命令时,寄存DAC_DATA值

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

//========================================================================

4、测试激励

//========================================================================

`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

//========================================================================

7、顶层文件(创建ISSP核)

//========================================================================

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;

ISSP ISSP(

.probe(),

.source(DAC_DATA)

);

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

//========================================================================

串行DAC——基于小梅哥AC620相关推荐

  1. 基于小梅哥AC620开发板的NIOS II LWIP百兆以太网例程移植到自己做的板子上

    原程序是运行在小梅哥AC620开发板上的:基于小梅哥AC620开发板的NIOS II LWIP百兆以太网例程_ZLK1214的专栏-CSDN博客_小梅哥ac620[开发板]开发板型号:小梅哥AC620 ...

  2. FPGA 20个例程篇:4.串行DAC输出模拟电压控制LED亮度

    二.常用通信协议,摸索探究: 4.串行DAC输出模拟电压控制LED亮度 TLC5615是一颗在实战项目中广泛使用的串行DAC,通过这个例程的学习实践,一方面我们可以掌握SPI通信的底层逻辑,另一方面D ...

  3. 基于小梅哥的Xlinx FPGA开发视频的布置作业--用串口控制一个24小时数字钟

    刚看完小梅哥的视频,花了几个钟头写成了作业,就两个功能,24小时计时和用串口设置时间.默认波特率为115200,上电开始从00:00:00计时,开发板是720,漏洞坑定有,还请各位指正.话不多说上代码 ...

  4. 小梅哥AC620学习记录—UART_EEPROM_part2

    串口传输数据到EEPROM 解决第二步中命令解析部分的仿真后,开始搭建系统整体并进行仿真,RTL电路结构如下 rtl结构,包含I2C模块,UART发送和接收模块,命令解析模块 仿真波形记录 model ...

  5. 串行 RapidIO接口介绍

    串行 RapidIO: 高性能嵌入式互连技术 作者: 德州仪器技术应用工程师 冯华亮/ Brighton Feng/ bf@ti.com 摘要 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而 ...

  6. 串行 RapidIO: 高性能嵌入式互连技术

    原文地址: http://www.ti.com.cn/general/cn/docs/gencontent.tsp?contentId=50741 收藏,学习!! 摘要 串行RapidIO针对高性能嵌 ...

  7. FPGA知识汇集-串行 RapidIO: 高性能嵌入式互连技术

    本文摘自:德州仪器网站 串行RapidIO: 高性能嵌入式互连技术 | 德州仪器 (ti.com.cn) 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而设计,它将是未来十几年中嵌入式系统互连 ...

  8. 小梅哥FPGA:基于线性序列机的TLC5620型DAC驱动设计

    小梅哥FPGA:基于线性序列机的TLC5620型DAC驱动设计 目标:学会使用线性序列机的思想设计常见的有串行执行特征的时序逻辑 实验现象:在QuartusⅡ软件中,使用ISSP工具,输入希望输出的电 ...

  9. 基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板)

    基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板 目录 主要架构 1.计数模块 2.数码显示模块 3.控制信号模块 4.分频模块 例化模块 上板测试图 附:74HC595移位寄存 ...

最新文章

  1. 146. Leetcode 51. N 皇后 (回溯算法-棋盘问题)
  2. python捕获全局异常统一管理_python中如何用sys.excepthook来对全局异常进行捕获、显示及输出到error日志中...
  3. 4.2 算法之数论 185 反正切函数的应用 python
  4. Oracle结构化查询语言(Structured Query Language)
  5. kali foremost 分离文件_软件架构之分离关注点
  6. 互联网广告类型的分析--弹出式广告【3】
  7. 写会议纪要必备的录音转文字软件推荐,让你再也不用担心职场会议
  8. 平面设计素材的优秀网站有哪些?好用的都放在这里啦!
  9. 数据中心加湿系统计算及方法探讨【新规范加湿方式对比及计算分析】
  10. apt cyg 安装php,Windows下安装Cygwin及apt-cyg
  11. linux文件读取程序,Linux系统编程:文件的读取写入
  12. Qt入门极简教程(二)
  13. MyBatis遇到:There is no getter for property named ‘Xxx‘ in ‘class xxx.xxx.Xxx‘问题
  14. 拼多多运营该怎么做你知道吗?
  15. 天下文章一大抄 mysql远程连接
  16. GL calls GL verts FPS
  17. 学习软件工程的知名网站
  18. C语言 怎样定义指针变量
  19. 洛谷1726 上白泽慧音 tarjan模板
  20. Guitar Pro8.0.1最新中文版本吉他谱下载及使用教程

热门文章

  1. 基于Java的XML编辑器:Oxygen XML Editor Mac中文版
  2. 【python--教程】python读写word文档
  3. CSS进阶(3)- 布局
  4. gRPC(一)入门:什么是RPC?
  5. 计算机5大的控件的功能,7款顶级功能插件,每一款都堪称办公宝典!
  6. CVE-2012-1889(暴雷)漏洞分析
  7. Linux(CentOS7) NVIDIA GeForece GTX 745 显卡驱动
  8. 英雄之刃显示服务器断开怎么办,英魂之刃手游新手常见问题
  9. 深度 | 详解可视化利器t-SNE算法:数无形时少直觉
  10. 100个python算法超详细讲解:分糖果