首页 > 其他分享 >DAC转化——FPGA驱动LTC1446

DAC转化——FPGA驱动LTC1446

时间:2023-12-28 19:57:41浏览次数:32  
标签:LTC1446 LD FPGA clk 芯片 DAC 低电平 spi CS

目录

一、前言

最近在学习利用FPGA结合DAC芯片实现数模转换,在实验中选择的LTC1446这款芯片。接下来自己将结合芯片手册进行分析,并编写Verilog代码并进行仿真验证。

二、结合LTC1446芯片手册分析

在这里插入图片描述

  1. 首先从上述第一处可以看出该款芯片为双通道输入,最多可将24位的数字信号进行转换。
  2. 对于第二处,所谓的三线通信其实在这里就是Spi通信的“变种”,因为版权的原因,很多公司这样进行描述,这里是clk,cs,mosi三线;另外,其提高更新频率为500KHZ,则我们在将数字信号输入的频率是不能超过500KHZ的,不然该芯片不能正确工作。

image-20230103234823204

  1. 第三处,展示的是芯片和一般微处理器的连接方式,从而印证了第二处所说的是spi的主设备数据输出,从设备数据输入模式。

image-20230104122537091

  1. 第四处,可以看到当$\overline{CS}$/LD为低电平时,数据是被锁存的,不能输出;当$\overline{CS}$/LD为高电平时,数字信号转化为模拟信号输出,这在写代码的时候也是需要注意的。
  2. 第五处,$D_{OUT}$需要在clk上升沿的时候才可以获取其输出,不过在这个实验仿真中不需要用到,所以需要额外关注。

image-20230104124041673

  1. 第六处的时序转换是最需要我们关注的
  • 首先看clk信号,初始状态为高电平,则在仿真过程中编写testbench时需要注意,另外可以看到对于时钟信号的周期是有标注时间的,需要我们看一下有无限制。

在这里插入图片描述

可以看到最小时钟周期为120ns,1/(120*$10^{-9}$)=8.3MHZ,一般我们使用的FPGA的时钟信号为50MHZ.所以需要进行分频得到芯片的输入时钟信号。

  • 再看$D_{IN}$信号,传输数据是时候是先对应A通道的12位,从高到底;然后再是对应A通道的12位,从高到底。
  • 再看$\overline{CS}$/LD信号,其开始为低电平,在clk为高电平时,$\overline{CS}$/LD由低电平转为高电平;在clk为低电平时,$\overline{CS}$/LD由高电平转为低电平
  • $D_{OUT}$可以看出输出的滞后一个24位数据帧的。

image-20230104131830316

  1. 再看第七处
  • 在时钟上升沿数据被加载进入转换寄存器
  • 先A通道的12bit,再B通道的12bit,且从分别从高位到低位,和时序图中描述的一样
  • $\overline{CS}$/LD被拉高的时候,数据加载到DAC寄存器
  • 时钟内部被禁用当$\overline{CS}$/LD被拉高的时候
  • 在clk为低电平时,$\overline{CS}$/LD由高电平转为低电平,和时序图中的描述一致

三、Verilog代码与仿真

先画出输入输出的模块框图如下:

image-20230104133112881

输入:

clk:FPGA时钟信号

n_rst:复位信号

data_in:24位数字信号

set:使能信号

输出:

spi_clk:生成的输入到芯片的时钟

spi_cs:生成的输入到芯片的cs信号

spi_din:生成的输入到芯片符合时序的数字信号

工程代码:

`timescale 1ns/1ns
module LTC1446_DA
(
    input clk,   //50MHZ时钟输入
    input n_rst,
    
    input [23:0] data_in,  //输入的电压数值(高12位:通道A输出 ;低12位:通道B输出)
    input set,
    
    output reg spi_clk,
    output reg spi_cs,
    output spi_din
);

//0-15计数,用于16分频使用
reg [3:0] cnt;
always@(posedge clk or negedge n_rst)
begin
    if(n_rst==1'b0)
        cnt<=4'h0;
    else if(set==1'b1)
        cnt<=4'h0;
    else
        cnt<=cnt+1'b1;
end

reg [5:0] len_cnt;//发送为数据计数
always@(posedge clk or negedge n_rst)
begin
    if(n_rst==1'b0)
        len_cnt<=6'h0;
    else if(set==1'b1)
        len_cnt<=6'd25; //一帧数据数为25
    else if((cnt==4'd15)&&(len_cnt>1'b0))  //cnt==15时,发送一位数据,即spi_clk时钟下降沿时,使得其上升沿可读取稳定数值
        len_cnt<=len_cnt-6'd1;
    else
        len_cnt<=len_cnt;
end

reg [23:0] data_reg;//输出SPI_DIN数据
always@(posedge clk or negedge n_rst)
begin
    if(n_rst==1'b0)
        data_reg<=23'h0;
    else if(set==1'b1)
        data_reg<={data_in};
    else if((cnt==4'd15)&&(len_cnt>1'b0))
        data_reg<={data_reg[22:0],1'b0};//在spi_clk的下降沿,将数据最高位发送到spi_din
    else
        data_reg<=data_reg;
end

assign spi_din=data_reg[23];

//生成spi_clk时钟信号(clk/16分频)
always@(posedge clk or negedge n_rst)
begin
    if(n_rst==1'b0)
        spi_clk<=1'b1;
    else if(set==1'b1)
        spi_clk<=1'b1;
    else if(len_cnt>1'b0)
        spi_clk<=cnt[3]; //对clk/16分频
    else
        spi_clk<=1'b1;
end

always@(posedge clk or negedge n_rst)
begin
    if(n_rst==1'b0)
        spi_cs<=1'b0;
    else if(set==1'b1)
        spi_cs<=1'b0;
    else if((len_cnt==6'd2)&&(cnt>4'd11))//已完成24位数据发送&当spi_clk下降沿之前
        spi_cs<=1'b1;  //cnt=[12-15]期间为高电平,其余为低电平
    else
        spi_cs<=1'b0;
end

endmodule

仿真代码:

`timescale 1ns/1ns
module tb_LTC1446_DA();

reg clk;
reg n_rst;
reg [23:0] data_in;
reg set;

wire spi_clk;
wire spi_cs;
wire spi_din;

always #10 clk=~clk;

initial 
begin
    clk=0;
    n_rst<=1;
    data_in<=0;
    set<=0;
    #10
    n_rst<=0;
    #20
    n_rst<=1;
    #20
    data_in<=24'b1110_1010_1100_0101_1100_1010;
    set<=1;
    #20
    set<=0;
end
LTC1446_DA LTC1446_DA_inst
(
    .clk     (clk    )   ,
    .n_rst   (n_rst  )   ,
    
    .data_in (data_in)   ,
    .set     (set    )   ,

    .spi_clk (spi_clk)   ,
    .spi_cs  (spi_cs )   ,
    .spi_din (spi_din)
);

endmodule

仿真结果:

image-20230104133951330

分析的时候对应每个信号判断时候符合要求即可。

四、总结

对于这类工程,我觉得最重要的就是厘清芯片手册的中不同信号对应的时序,各种限制如时间周期等才能写出能正常驱动芯片的代码。当然自己的水平是非常有限的,对于不同的芯片手册自己学习中经常会有看的不知所云,无法把握重点的情况,但是我坚信自己一定不是第一个使用该手册的人,前人一定会有相关描述或工程可以借鉴,通过检索不断学习,一定会找到解决问题的办法。加油,努力成为一名优秀的工程师!

标签:LTC1446,LD,FPGA,clk,芯片,DAC,低电平,spi,CS
From: https://www.cnblogs.com/lgziyan/p/17933433.html

相关文章

  • FPGA驱动AD9240实现AD转换
    目录一、前言二、时序原理三、代码设计四、结果验证一、前言在做项目中,经常会用到AD转换模块。前段时间做毕业设计的时候需要用到FPGA驱动AD9240模块实现模拟数据的采集和转换,尽管相对来说AD9240算比较简单的驱动模块,但是也想记录下分析和设计过程。二、时序原理首先通过芯片......
  • 基于FPGA的图像差分运算及目标提取实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述      基于FPGA(Field-ProgrammableGateArray)的图像差分运算及目标提取实现主要涉及图像处理、差分运算和目标提取等原理和数学公式。 一、图像处理原理       图像处理是......
  • 01 FPGA流水灯实验
    软件版本:VIVADO2021.1操作系统:WIN1064bitaa硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述本章课程以大家熟悉的流水灯为例子,详细讲解了VIVADO软件的使用,包括创建FPGA工程,编写Verilog代码,添加......
  • 基于FPGA的图像PSNR质量评估计算实现,包含testbench和MATLAB辅助验证程序
    1.算法运行效果图预览设置较大的干扰,PSNR=15。   设置较小的干扰,PSNR=25。   2.算法运行软件版本matlab2022a vivado2019.2  3.算法理论概述      基于FPGA的图像PSNR(峰值信噪比)质量评估计算实现涉及到数字图像处理、硬件设计和编程等多个领域......
  • FPGA学习笔记---verilog学习(2)--过程块always@(*)
    在Verilog中always@(*)语句的意思是always模块中的任何一个输入信号或电平发生变化时,该语句下方的模块将被执行。1、always语句有两种触发方式。第一种是电平触发,例如always@(aorborc),a、b、c均为变量,当其中一个发生变化时,下方的语句将被执行。2、第二种是沿触发,例如always......
  • 最大工作频率为32MHz,R7F100GPL2DFA、R7F100GPL3CFA低功耗MCU,10M08SAU169C8GGB MAX® 1
    一、RL78/G23 新一代RL78微控制器,最大工作频率为32MHz,外围功能得到进一步扩展,低功耗性能也有所提升。RL78/G23微控制器是RL78系列的新一代产品,CPU工作时的功耗为41μA/MHz,STOP(保持4KBSRAM)时的功耗为210nA,其低功耗在业内首屈一指。此外,由于采用SNOOZE模式定序器,它还能大幅度减少......
  • 基于Zynq FPGA对雷龙SD NAND的测试
    文章目录一、SDNAND特征1.1SD卡简介1.2SD卡Block图二、SD卡样片三、Zynq测试平台搭建3.1测试流程3.2SOC搭建四、软件搭建五、测试结果六、总结一、SDNAND特征1.1SD卡简介  雷龙的SDNAND有很多型号,在测试中使用的是CSNP4GCR01-AWM与CSNP32GCR01-AOW。芯片是基于NANDFLASH......
  • 【FPGA基础】状态机
    状态机由状态寄存器和组合逻辑电路组成;在不同的当前状态下,能够控制信号的变化进行状态的转移,从而实现相关信号的赋值,完成特定控制时序的设计。状态机的三个基本要素:      状态变迁(当前状态current_state和下一状态next_state      输入条件(状态变化的触发事件 ......
  • 高云FPGA的LVDS应用
    本板卡提供如下例程,主要基于具体案例,聚焦于摄像头采集,LCD屏驱动显示等图像处理相关。像GPIO,CLK,LED等这种简单的操作都放到具体实例中了,不再一一介绍,常用的IP也是非常简单的操作,高云文档有些写得不太仔细,如遇到不清楚的地方可以联系官方FAE或者我这边。3.1LVDS的应用LVDS使用......
  • ubuntu 18.04.6 编译Preloader提示 没有规则可制作目标 /host_tools/altera/preloader
     生成spl_bsp后,在spl_bsp路径下输入make 提示:没有规则可制作目标/host_tools/altera/preloader/uboot-socfpga.tar.gz 原来要先运行 ./embeddedcommandshell.sh,并在该终端窗口下输入make   ......