FPGA驱动DAC芯片输出(以TLV5618为例)
一、任务
使用FPGA芯片控制DAC采集芯片,输出指定的电压值。
二、硬件部分
为了将FPGA输出的数字电压转换成模拟电压,我们使用到了数模转换芯片(简称DAC)TLV5618。进行设计前,我们先到网上检索并查看了该芯片的数据手册。
1.芯片功能图
2.端口功能表
从功能图和功能表中我们可以看出,TLV5618有四个输入端口:
片选信号CS、数据串行输入端口DIN、模拟参考电压REF、数字时钟SCLK。
两个输出端分别为OUTA和OUTB,均为对应的模拟电压输出端。
3.时序图
从时序图中我们可以看到使用该芯片时要注意这几个参数:
tw(L):低电平最小宽度,25ns。
tw(H):高电平最小宽度,25ns。
tsu(D):数据最短建立时间。
th(D):数据最短保持时间。
tsu(CS-CK):片选信号下降沿到第一个时钟下降沿最短时间。
th(CSH):片选信号最短拉高时间。
在我们写FPGA代码时,需要根据严格按照时序图来。
4.输出电压计算
由手册给出的公式知,输出电压与输入的编码值成正比,同时还要乘以一个系数REF,这个系数从芯片的REF引脚输入。我们打开并查看开发板的原理图:
从图中知,我们用到了芯片LM4040-2.0给DAC供电,这个芯片工作时输出电压为4.028V(即精度为12位),故参数REF为4.028。
5.时钟频率与刷新率计算
我们查阅手册后知道,使用该芯片时,时钟最大频率为20MHz,刷新率为时钟频率的1/16。而开发板提供的原始时钟为50MHz,因此可以采用四分频后得到12.5MHz的时钟频率。
三、设计方案
我们考虑用FPGA设计一个DAC驱动,通过CS、sclk、din三根信号线与DAC芯片连接,设计输入端口Data[15:0]。同时为了便于与其他模块共同协作,我们加上了使能端口en和转换完成标志位Conv_done,这是FPGA设计时必须考虑的一点,对于复杂的驱动模块,这两个信号是不可或缺的。
四、软件部分
这里直接上代码部分,注释里面有解读。
// 驱动部分
module tlv5618(Clk,Rst_n,DAC_DATA, //并行数据输入端Start, //开始标志位Set_Done, //完成标志位DAC_CS_N, //片选DAC_DIN, //串行数据送给ADC芯片DAC_SCLK, //工作时钟SCLKDAC_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; //转换完成后将使能关闭elseen <= en; //分频计数器always@(posedge Clk or negedge Rst_n)if(!Rst_n)DIV_CNT <= 4'd0;else if(en)beginif(DIV_CNT == (DIV_PARAM - 1'b1)) //前面设置了分频系数为2,这里计数器能够容纳2拍时钟脉冲DIV_CNT <= 4'd0;else DIV_CNT <= DIV_CNT + 1'b1;endelseDIV_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;elseSCLK2X <= 1'b0;//生成序列计数器,对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;elseSCLK_GEN_CNT <= SCLK_GEN_CNT + 1'd1;endelseSCLK_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;elser_DAC_DATA <= r_DAC_DATA;//依次将数据移出到DAC芯片always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginDAC_DIN <= 1'b1;DAC_SCLK <= 1'b0;DAC_CS_N <= 1'b1;endelse if(!Set_Done && SCLK2X) begincase(SCLK_GEN_CNT)0:begin //高脉冲期间内,计数为0时了,打开片选使能,给予时钟上升沿,将最高位数据送给ADC芯片DAC_CS_N <= 1'b0;DAC_DIN <= r_DAC_DATA[15];DAC_SCLK <= 1'b1;end1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31:beginDAC_SCLK <= 1'b0; //时钟低电平end2: begin DAC_DIN <= r_DAC_DATA[14]; DAC_SCLK <= 1'b1; end4: begin DAC_DIN <= r_DAC_DATA[13]; DAC_SCLK <= 1'b1; end6: begin DAC_DIN <= r_DAC_DATA[12]; DAC_SCLK <= 1'b1; end8: begin DAC_DIN <= r_DAC_DATA[11]; DAC_SCLK <= 1'b1; end 10: begin DAC_DIN <= r_DAC_DATA[10]; DAC_SCLK <= 1'b1; end12: begin DAC_DIN <= r_DAC_DATA[9]; DAC_SCLK <= 1'b1; end14: begin DAC_DIN <= r_DAC_DATA[8]; DAC_SCLK <= 1'b1; end16: begin DAC_DIN <= r_DAC_DATA[7]; DAC_SCLK <= 1'b1; end 18: begin DAC_DIN <= r_DAC_DATA[6]; DAC_SCLK <= 1'b1; end20: begin DAC_DIN <= r_DAC_DATA[5]; DAC_SCLK <= 1'b1; end 22: begin DAC_DIN <= r_DAC_DATA[4]; DAC_SCLK <= 1'b1; end24: begin DAC_DIN <= r_DAC_DATA[3]; DAC_SCLK <= 1'b1; end26: begin DAC_DIN <= r_DAC_DATA[2]; DAC_SCLK <= 1'b1; end28: begin DAC_DIN <= r_DAC_DATA[1]; DAC_SCLK <= 1'b1; end 30: begin DAC_DIN <= r_DAC_DATA[0]; DAC_SCLK <= 1'b1; end32: DAC_SCLK <= 1'b1; //时钟拉高33: DAC_CS_N <= 1'b1; //关闭片选default:;endcaseendassign 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;elseSet_Done <= 1'b0;endmodule
//顶层模块
module DAC_test(Clk, //模块时钟50MRst_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;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;elseStart <= 1'd0;endmodule
五、仿真
FPGA驱动DAC芯片输出(以TLV5618为例)相关推荐
- 基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动
基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动,已上板调通 品牌型号 CAN SJA1000T 与世面上的不同,代码不是SJA1000T芯片代码,而是驱动 ...
- 一文读懂如何使用FPGA驱动PHY芯片
这里写自定义目录标题 如何使用FPGA驱动PHY芯片 前言 必要的硬件知识 如何确定PHY芯片的物理地址? 如何确定PHY芯片的工作模式? 如何驱动PHY芯片? MDIO的通讯协议是什么? PHY芯片 ...
- FPGA驱动FT601实现USB3.0相机 OV5640视频采集 提供2套工程源码和QT上位机源码
目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.vivado工程1--彩条视 ...
- FPGA驱动FT601实现USB3.0相机HDMI视频采集 提供工程源码和QT上位机源码
目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.详细设计方案 5.vivad ...
- 用FPGA驱动AD9910输出跳频信号
使用FPGA驱动AD9910的方法总结 文章目录 使用FPGA驱动AD9910的方法总结 前言 一.概述 二.寄存器配置 1.SPI串行接口 1.SPI读写时序 2.状态机设计实现寄存器读写 3.单频 ...
- 74HC595驱动(并转串,fpga与时钟匹配,fpga与外部芯片的连接注意事项)
上一次设计的动态扫描数码管显示电路模型如上,这是一个32位并行数据[31:0]disp_num选通输出并行数据[7:0]select和[7:0]段选的电路.因此需要输出16个信号 而在开发板上的电路与 ...
- STM32管脚模拟协议驱动双路16位DAC芯片TM8211
STM32管脚模拟协议驱动双路16位DAC芯片TM8211 TM8211是一款国产的低成本双路16位DAC驱动芯片,可以应用于普通数模转换领域及音频转换领域等.这里介绍STM32 HAL库驱动TM82 ...
- FPGA与某个DAC芯片的SPI配置
//FPGA做主机,数模转换器(DAC)芯片做从机,实现SPI接口的配置(SPI串行外设接口) //该DAC芯片的SPI配置的寄存器是8位的 //第7位是读写选择信号,读信号高有效,写信号低有效 // ...
- dac生成信号频率取决于_基于DAC芯片的信号源生成系统的制作方法
本发明涉及干扰机技术领域,特别是基于DAC芯片的信号源生成系统. 背景技术: 随着现在通信技术的高速发展,对于装备的小型化.集成化.成本控制要求越来越高,如何设计出低成本.高集成度.小型化的装备是现阶 ...
最新文章
- sign的oracle,oracle sign
- shell 脚本比较字符串相等_shell字符串比较判断是否为数字
- 【机器学习算法专题(蓄力计划)】五、机器学习中的线性代数的基础操作
- Protocol Buffer入门——轻松搭建java环境 .
- 使用Lucene的搜索服务器搜索Jira问题
- 谁说程序员找不到女朋友,你们是不知道当程序员撩妹,一撩一个准
- 河南理工大学计算机科学与技术怎么样,河南理工大学计算机科学与技术怎么样...
- 转:jwgkvsq.vmx手工清除方法(针对病毒变种补充完整)
- 高精度IP地址定位接口的使用场景
- 网络创业理论与实践(网络通识)
- 【excel入门学习】
- 使用IntelliJ IDEA 配置Maven(入门)
- vue+element-ui文件导出模板及导入xlsx文件
- 专业修图工具:Affinity Photo for mac
- 如何做好微信朋友圈推广?
- 使用BoundsChecker查找内存泄露
- PyTorch 2.0 重磅发布:一行代码提速 30%
- 批量导出excel中的超链接图片?只需要一招
- linux命令查看cpu序列号,Linux下用命令查看CPU ID以及厂家等信息
- Linux下调试器工作原理
热门文章
- Wscript.shell对象参考手册
- Oracle GoldenGate(OGG)- 超级详细
- 02-Spring Boot 2.0 配置改变
- hibernate 学习 并且与spring 整合
- 如何防止php漏洞,关于如何防止PHP漏洞?
- 计算机应用技术故事会教案,信息技术教学故事
- Postman下载安装教程
- mp4文件moov atom放置在mdat atom之前 代码实现
- x3d:了解x3dom
- 怎样设置锁定计算机密码忘了怎么办,电脑怎么设置密码锁屏 电脑密码忘了怎么办...