欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

基于FPGA线性序列机驱动TLC5615模块

程序员文章站 2022-06-26 14:58:35
TLC5615模块之FPGA驱动1、芯片介绍TLC5615 为美国德州仪器公司 1999 年推出的产品,是具有串行接口的数模转换器,其输出为电压型,最大输出电压是基准电压值的两倍。带有上电复位功能,即把 DAC 寄存器复位至全零。性能比早期电流型输出的 DAC 要好。只需要通过 3 根串行总线就可以完成 10 位数据的串行输入, 易于和工业标准的微处理器或微控制器(单片机) 接口, 适用于电池供电的测试仪表、移动电话,也适用于数字失...

TLC5615模块之FPGA驱动

1、芯片介绍
      TLC5615 为美国德州仪器公司 1999 年推出的产品,是具有串行接口的数模转换器,其输出为电压型,最大输出电压是基准电压值的两倍。带有上电复位功能,即把 DAC 寄存器复位至全零。性能比早期电流型输出的 DAC 要好。只需要通过 3 根串行总线就可以完成 10 位数据的串行输入, 易于和工业标准的微处理器或微控制器(单片机) 接口, 适用于电池供电的测试仪表、移动电话,也适用于数字失调与增益调整以及工业控制场合。

DIN: 串行数据输入端;
TLC5615引脚图
TLC5615引脚图
SCLK: 串行时钟输入端;
/CS: 芯片选用通端,低电平有效;
DOUT: 用于级联时的串行数据输出端;
AGND: 模拟地;
REFIN:基准电压输入端, 2V~ (VDD - 2);
OUT: DAC 模拟电压输出端;
VDD: 正电源端,4.5~5.5V ,通常取 5V。
基于FPGA线性序列机驱动TLC5615模块
      TLC5615 工作时序如上图所示。 可以看出,只有当片选 CS 为低电平时, 串行输入数据才能被移入16位移位寄存器。当 CS 为低电平时,在每一个 SCLK 时钟的上升沿将 DIN 的一位数据移入 16 位移寄存器。注意, 二进制最高有效位被导前移入。接着,CS 的上升沿将 16 位移位寄存器的 10 位有效数据锁存于 10 位 DAC 寄存器, 供 DAC 电路进行转换; 当片选 CS 为高电平时,串行输入数据不能被移入 16 位移位寄存器。注意, CS 的上升和下降都必须发生在 SCL K 为低电平期间。
2、时钟确定
      根据下面时序图和芯片资料算出最大串行时钟速率近似为14M,因为核心板时钟为50M,故采用sclk串行时钟为12.5M,即采用四分频方式。
基于FPGA线性序列机驱动TLC5615模块
但是在芯片手册中说:为了使时钟馈通最小。CS在高电平时,sclk应该保持低电平。因此为了方便时钟的控制,不采用PLL生成的方式。采用线性序列机的方法生成可控的sclk。

3、注意
      因为DAC的寄存器为12位,但是数据位只有10位,因此要将数据位低位添加两个0,或者左移两位。

4、代码

module TLC5615_CTRL(
  input sys_clk,
  input rst,
  input conv_en,   //DA转换使能信号
  input [11:0] conv_data, //DA转换输入数据

  
  
  output reg cs,
  output reg conv_end, //DA转换完成信号
  output reg tlc5615_clk,
  output reg tlc5615_data
  
);

  reg [6:0] cnt;
 
//计数器 
  always @(posedge sys_clk or negedge rst)
    if(!rst)
	   cnt <= 7'd0;
	 else if(conv_en == 1 | (cnt != 7'd0)) begin
	      if(cnt == 7'd64)
			   cnt <= 7'd0;
			else
			   cnt <= cnt + 7'd1;
	   end
	 else
	   cnt <= 7'd0;
 
  
  always @(posedge sys_clk or negedge rst)
    if(!rst) begin 
	   conv_end <= 1'b0;
	   tlc5615_clk <= 1'b0;
      tlc5615_data <= 1'b0;
		cs <= 1'b1;
		end
	 else begin
	  case(cnt)
	     0:
		     begin 
			  conv_end <= 1'b0;
	        tlc5615_clk <= 1'b0;
           tlc5615_data <= 1'b0;
			  cs <= 1'b1;
			  end
		  1:  
		     begin
		     tlc5615_data <= conv_data[11];
			  cs <= 1'b0;
			  end
		  2: tlc5615_clk <= 1'b1;
		  
		  4: tlc5615_clk <= 1'b0;
		  5: tlc5615_data <= conv_data[10];
		  6: tlc5615_clk <= 1'b1;
		  
		  8: tlc5615_clk <= 1'b0;
		  9: tlc5615_data <= conv_data[9];
		  10:tlc5615_clk <= 1'b1;
		  
		  12:tlc5615_clk <= 1'b0;
		  13:tlc5615_data <= conv_data[8];
		  14:tlc5615_clk <= 1'b1;
		  
		  16:tlc5615_clk <= 1'b0;
		  17:tlc5615_data <= conv_data[7];
		  18:tlc5615_clk <= 1'b1;
		  
		  20:tlc5615_clk <= 1'b0;
		  21:tlc5615_data <= conv_data[6];
		  22:tlc5615_clk <= 1'b1;
		  
		  24:tlc5615_clk <= 1'b0;
		  25:tlc5615_data <= conv_data[5];
		  26:tlc5615_clk <= 1'b1;
		  
		  28:tlc5615_clk <= 1'b0;
		  29:tlc5615_data <= conv_data[4];
		  30:tlc5615_clk <= 1'b1;
		  
		  32:tlc5615_clk <= 1'b0;
		  33:tlc5615_data <= conv_data[3];
		  34:tlc5615_clk <= 1'b1;
		  
		  36:tlc5615_clk <= 1'b0;
		  37:tlc5615_data <= conv_data[2];
		  38:tlc5615_clk <= 1'b1;
		  
		  40:tlc5615_clk <= 1'b0;
		  41:tlc5615_data <= conv_data[1];
		  42:tlc5615_clk <= 1'b1;
		  
		  44:tlc5615_clk <= 1'b0;
		  45:tlc5615_data <= conv_data[0];
		  46:tlc5615_clk <= 1'b1;
		  
		  
		  64:
		     begin
		     tlc5615_clk <= 1'b0;
			  cs <= 1'b1;
			  conv_end <= 1'b1;
			  end
		  
		
		 endcase
		  
	  
	  end


endmodule 代码片

5、测试模块

`timescale 1ns/1ns


module TLC5615_CTRL_tb;

  reg sys_clk;
  reg rst;
  reg conv_en;  
  reg [11:0] conv_data;

  
  
  wire cs;
  wire conv_end; 
  wire tlc5615_clk;
  wire tlc5615_data;





TLC5615_CTRL TLC5615_CTRL(
  .sys_clk(sys_clk),
  .rst(rst),
  .conv_en(conv_en),   
  .conv_data(conv_data), 
  .cs(cs),
  .conv_end(conv_end), 
  .tlc5615_clk(tlc5615_clk),
  .tlc5615_data(tlc5615_data)
);


 initial sys_clk =1;
 always #10 sys_clk = ~sys_clk;
 initial begin
    rst = 1'b0;
	 conv_en = 1'b0;
	 conv_data = 0;
	 
	 #201;
	 rst = 1'b1;
	 
	 #100;
	 conv_data = {10'h2aa,2'b00};
	 conv_en = 1'b1;
	 #100;
	 conv_en = 1'b0;
	 
	 @(posedge conv_end);
	 #400;
	 conv_data = {10'h3e8,2'b00};
	 conv_en = 1'b1;
    @(posedge conv_end);
	 #400;
	 $stop;
	 
	 end
	 
endmodule 

6、仿真图
基于FPGA线性序列机驱动TLC5615模块
7、验证
      将程序下载至开发板后,将对应的引脚连接至TLC5615模块上,利用万用表测出电压值与实际相符合。
PS:基于FPGA线性序列机驱动TLC5615模块
V为转换后的电压值,Vref为参考电压,data为转换为十进制的值。

本文地址:https://blog.csdn.net/explode_boom/article/details/109479167