串行DAC——基于小梅哥AC620
导读:
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相关推荐
- 基于小梅哥AC620开发板的NIOS II LWIP百兆以太网例程移植到自己做的板子上
原程序是运行在小梅哥AC620开发板上的:基于小梅哥AC620开发板的NIOS II LWIP百兆以太网例程_ZLK1214的专栏-CSDN博客_小梅哥ac620[开发板]开发板型号:小梅哥AC620 ...
- FPGA 20个例程篇:4.串行DAC输出模拟电压控制LED亮度
二.常用通信协议,摸索探究: 4.串行DAC输出模拟电压控制LED亮度 TLC5615是一颗在实战项目中广泛使用的串行DAC,通过这个例程的学习实践,一方面我们可以掌握SPI通信的底层逻辑,另一方面D ...
- 基于小梅哥的Xlinx FPGA开发视频的布置作业--用串口控制一个24小时数字钟
刚看完小梅哥的视频,花了几个钟头写成了作业,就两个功能,24小时计时和用串口设置时间.默认波特率为115200,上电开始从00:00:00计时,开发板是720,漏洞坑定有,还请各位指正.话不多说上代码 ...
- 小梅哥AC620学习记录—UART_EEPROM_part2
串口传输数据到EEPROM 解决第二步中命令解析部分的仿真后,开始搭建系统整体并进行仿真,RTL电路结构如下 rtl结构,包含I2C模块,UART发送和接收模块,命令解析模块 仿真波形记录 model ...
- 串行 RapidIO接口介绍
串行 RapidIO: 高性能嵌入式互连技术 作者: 德州仪器技术应用工程师 冯华亮/ Brighton Feng/ bf@ti.com 摘要 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而 ...
- 串行 RapidIO: 高性能嵌入式互连技术
原文地址: http://www.ti.com.cn/general/cn/docs/gencontent.tsp?contentId=50741 收藏,学习!! 摘要 串行RapidIO针对高性能嵌 ...
- FPGA知识汇集-串行 RapidIO: 高性能嵌入式互连技术
本文摘自:德州仪器网站 串行RapidIO: 高性能嵌入式互连技术 | 德州仪器 (ti.com.cn) 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而设计,它将是未来十几年中嵌入式系统互连 ...
- 小梅哥FPGA:基于线性序列机的TLC5620型DAC驱动设计
小梅哥FPGA:基于线性序列机的TLC5620型DAC驱动设计 目标:学会使用线性序列机的思想设计常见的有串行执行特征的时序逻辑 实验现象:在QuartusⅡ软件中,使用ISSP工具,输入希望输出的电 ...
- 基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板)
基于FPGA的简易数字频率计+上板测试(小梅哥AC620FPGA开发板 目录 主要架构 1.计数模块 2.数码显示模块 3.控制信号模块 4.分频模块 例化模块 上板测试图 附:74HC595移位寄存 ...
最新文章
- 146. Leetcode 51. N 皇后 (回溯算法-棋盘问题)
- python捕获全局异常统一管理_python中如何用sys.excepthook来对全局异常进行捕获、显示及输出到error日志中...
- 4.2 算法之数论 185 反正切函数的应用 python
- Oracle结构化查询语言(Structured Query Language)
- kali foremost 分离文件_软件架构之分离关注点
- 互联网广告类型的分析--弹出式广告【3】
- 写会议纪要必备的录音转文字软件推荐,让你再也不用担心职场会议
- 平面设计素材的优秀网站有哪些?好用的都放在这里啦!
- 数据中心加湿系统计算及方法探讨【新规范加湿方式对比及计算分析】
- apt cyg 安装php,Windows下安装Cygwin及apt-cyg
- linux文件读取程序,Linux系统编程:文件的读取写入
- Qt入门极简教程(二)
- MyBatis遇到:There is no getter for property named ‘Xxx‘ in ‘class xxx.xxx.Xxx‘问题
- 拼多多运营该怎么做你知道吗?
- 天下文章一大抄 mysql远程连接
- GL calls GL verts FPS
- 学习软件工程的知名网站
- C语言 怎样定义指针变量
- 洛谷1726 上白泽慧音 tarjan模板
- Guitar Pro8.0.1最新中文版本吉他谱下载及使用教程
热门文章
- 基于Java的XML编辑器:Oxygen XML Editor Mac中文版
- 【python--教程】python读写word文档
- CSS进阶(3)- 布局
- gRPC(一)入门:什么是RPC?
- 计算机5大的控件的功能,7款顶级功能插件,每一款都堪称办公宝典!
- CVE-2012-1889(暴雷)漏洞分析
- Linux(CentOS7) NVIDIA GeForece GTX 745 显卡驱动
- 英雄之刃显示服务器断开怎么办,英魂之刃手游新手常见问题
- 深度 | 详解可视化利器t-SNE算法:数无形时少直觉
- 100个python算法超详细讲解:分糖果