一、任务

使用FPGA芯片控制DAC采集芯片,输出指定的电压值。

二、硬件部分

为了将FPGA输出的数字电压转换成模拟电压,我们使用到了数模转换芯片(简称DAC)TLV5618。进行设计前,我们先到网上检索并查看了该芯片的数据手册。

1.芯片功能图

2.端口功能表


从功能图和功能表中我们可以看出,TLV5618有四个输入端口:
片选信号CS、数据串行输入端口DIN、模拟参考电压REF、数字时钟SCLK
两个输出端分别为OUTAOUTB,均为对应的模拟电压输出端。

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为例)相关推荐

  1. 基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动

    基于FPGA的CAN通信,FPGA驱动SJA1000T芯片代码,实现标准帧与扩展帧的通信驱动,已上板调通 品牌型号 CAN SJA1000T 与世面上的不同,代码不是SJA1000T芯片代码,而是驱动 ...

  2. 一文读懂如何使用FPGA驱动PHY芯片

    这里写自定义目录标题 如何使用FPGA驱动PHY芯片 前言 必要的硬件知识 如何确定PHY芯片的物理地址? 如何确定PHY芯片的工作模式? 如何驱动PHY芯片? MDIO的通讯协议是什么? PHY芯片 ...

  3. FPGA驱动FT601实现USB3.0相机 OV5640视频采集 提供2套工程源码和QT上位机源码

    目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.vivado工程1--彩条视 ...

  4. FPGA驱动FT601实现USB3.0相机HDMI视频采集 提供工程源码和QT上位机源码

    目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.详细设计方案 5.vivad ...

  5. 用FPGA驱动AD9910输出跳频信号

    使用FPGA驱动AD9910的方法总结 文章目录 使用FPGA驱动AD9910的方法总结 前言 一.概述 二.寄存器配置 1.SPI串行接口 1.SPI读写时序 2.状态机设计实现寄存器读写 3.单频 ...

  6. 74HC595驱动(并转串,fpga与时钟匹配,fpga与外部芯片的连接注意事项)

    上一次设计的动态扫描数码管显示电路模型如上,这是一个32位并行数据[31:0]disp_num选通输出并行数据[7:0]select和[7:0]段选的电路.因此需要输出16个信号 而在开发板上的电路与 ...

  7. STM32管脚模拟协议驱动双路16位DAC芯片TM8211

    STM32管脚模拟协议驱动双路16位DAC芯片TM8211 TM8211是一款国产的低成本双路16位DAC驱动芯片,可以应用于普通数模转换领域及音频转换领域等.这里介绍STM32 HAL库驱动TM82 ...

  8. FPGA与某个DAC芯片的SPI配置

    //FPGA做主机,数模转换器(DAC)芯片做从机,实现SPI接口的配置(SPI串行外设接口) //该DAC芯片的SPI配置的寄存器是8位的 //第7位是读写选择信号,读信号高有效,写信号低有效 // ...

  9. dac生成信号频率取决于_基于DAC芯片的信号源生成系统的制作方法

    本发明涉及干扰机技术领域,特别是基于DAC芯片的信号源生成系统. 背景技术: 随着现在通信技术的高速发展,对于装备的小型化.集成化.成本控制要求越来越高,如何设计出低成本.高集成度.小型化的装备是现阶 ...

最新文章

  1. sign的oracle,oracle sign
  2. shell 脚本比较字符串相等_shell字符串比较判断是否为数字
  3. 【机器学习算法专题(蓄力计划)】五、机器学习中的线性代数的基础操作
  4. Protocol Buffer入门——轻松搭建java环境 .
  5. 使用Lucene的搜索服务器搜索Jira问题
  6. 谁说程序员找不到女朋友,你们是不知道当程序员撩妹,一撩一个准
  7. 河南理工大学计算机科学与技术怎么样,河南理工大学计算机科学与技术怎么样...
  8. 转:jwgkvsq.vmx手工清除方法(针对病毒变种补充完整)
  9. 高精度IP地址定位接口的使用场景
  10. 网络创业理论与实践(网络通识)
  11. 【excel入门学习】
  12. 使用IntelliJ IDEA 配置Maven(入门)
  13. vue+element-ui文件导出模板及导入xlsx文件
  14. 专业修图工具:Affinity Photo for mac
  15. 如何做好微信朋友圈推广?
  16. 使用BoundsChecker查找内存泄露
  17. PyTorch 2.0 重磅发布:一行代码提速 30%
  18. 批量导出excel中的超链接图片?只需要一招
  19. linux命令查看cpu序列号,Linux下用命令查看CPU ID以及厂家等信息
  20. Linux下调试器工作原理

热门文章

  1. Wscript.shell对象参考手册
  2. Oracle GoldenGate(OGG)- 超级详细
  3. 02-Spring Boot 2.0 配置改变
  4. hibernate 学习 并且与spring 整合
  5. 如何防止php漏洞,关于如何防止PHP漏洞?
  6. 计算机应用技术故事会教案,信息技术教学故事
  7. Postman下载安装教程
  8. mp4文件moov atom放置在mdat atom之前 代码实现
  9. x3d:了解x3dom
  10. 怎样设置锁定计算机密码忘了怎么办,电脑怎么设置密码锁屏 电脑密码忘了怎么办...