国产精品免费无遮挡无码永久视频-国产高潮视频在线观看-精品久久国产字幕高潮-国产精品99精品无码视亚

小梅哥和你一起深入學習FPGA之DAC驅動

發布時間:2016-1-28 09:59    發布者:designapp
關鍵詞: FPGA , DAC
  本實驗中,我們使用FPGA來驅動了一片DAC芯片TLC5620,該芯片的特性如下所示:
  TLC5620特性:
  4路8位電壓輸出;
  單電源5V供電;
  串行接口;
  參考電壓輸入高阻;
  可編程的1次或2次輸出范圍;
  同時更新的能力;
  內部自帶上電復位功能;
  低功耗;
  半緩沖輸出。
  小梅哥設計的該芯片的驅動模塊的接口如下所示:
  


  各個端口定義如下:
  以下是代碼片段:
  input Clk;
  input Rst_n;
  input Do_DA; /*使能單次轉換*/
  input [10:0]Data;/*{Addr1,Addr0,Range,Data_bit[7:0]}*/
  output reg DAC_Dout; /*DAC數據線*/
  output reg DAC_Clk; /*DAC時鐘線,最高速度1M*/
  output reg DAC_LDAC; /**/
  output reg DAC_LOAD; /**/
  output reg DA_Done; /*單次轉換完成標志信號*/
  該芯片提供了類似于SPI的數字接口,因此,我們只需要使用該接口與芯片進行通信,再配合LOAD和LDAC兩個控制線,即可實現對該DAC芯片的控制。TLC5620一次轉換的操作時序如下:
  


  圖1 TLC5620單次轉換時序圖
  TLC5620每次寫入的數據為11位,其中前兩位為DAC選擇位A1、A0,通過不同的組合可以選擇不同通道的DAC,具體分配為:
  


  表1 DAC通道選擇位與對應通道關系
  第三位是電壓輸出增益位,0代表不變,1代表兩倍,當設定參考電壓為2.5V時,取這一位為1就可以得到最高5V的輸出電壓。后面8位是數據位,其中第四位是數據的最高位。對于TLC5620的輸出電壓公式是:
  VO=VREF ×CODE/256×(1+RNG)
  VREF是參考電壓,CODE是待轉換的8位二進制代碼,RNG是增益倍數。
  寫入數據時,首先LOAD和LDAC寫高電平,這樣在CLK的每個下降沿寫入的每位數據被鎖存到DATA端,當11位數據傳送完畢后,拉低LOAD,芯片根據前兩位數據,判斷是哪一路DAC通道,然后將8位數據移入相應的通道,進行DA轉換,這時拉低LDAC,再拉高LDAC,就可以再下次轉化之前,保持此次的模擬輸出。
  TLC5620正常工作時的具體電壓和時間參數如下表所示,通過該表,可知該芯片串行數字接口的時鐘信號(CLK)最高為1MHz。該參數將作為我們采用FPGA產生TLC5620數字接口時鐘的依據。同時,還有輸入數據建立時間tsu(data-clk)為50ns,即,FPGA數據送出,到能夠被TLC5620正常讀取,至少需要50ns,因此FPGA單位數據輸出保持時間不得少于50ns。tv(data-clk)為時鐘下降沿到來后多久時間數據線上的數據才能被芯片內部采集,該時間確定了,時鐘下降沿出現多久后,數據線上的數據可以被更新。tsu(LOAD-LDAC)為LOAD的上升沿到LDAC下降沿的建立時間,這里最小為0ns,因此忽略,即兩者同時發生即可。tw(LDAC)為LDAC低電平所需的最短時間,為250ns。
  

  表2 TLC5620關鍵參數
  通過對TLC5620一次完整轉換的時序進行分析,列出以下序列機對應的序列點:該序列機總共包含26個點,其中,當Cnt1=0(ST0)時,為空閑態,ST1—ST22為數據發送狀態,ST23時拉低LOAD,即將數據加載入對應通道的DAC中,ST24時釋放LOAD,同時拉低LDAC,以產生LDAC的下降沿,將對應通道的模擬輸出保持住。ST25拉高LDAC,完成一次轉換。


  表3 TLC5620單次轉換控制序列機
  序列機的計數器計數條件如下

  表4 TLC5620序列機計數器計數條件
                               
                  線性序列機計數器Cnt1的控制代碼如下:
  以下是代碼片段:
  always @(posedge Clk or negedge Rst_n)
  if(!Rst_n)
  Cnt1
  else if(Cnt_State == DO_CNT)
  begin
  if(Cnt1 == 5'd25)
  Cnt1
  else if(Cnt2 == Cnt2_Top)
  Cnt1
  else
  Cnt1
  end
  else
  Cnt1
  其中,涉及到了兩個狀態,當Cnt_State = 0時,表示沒有轉換請求,即系統處于空閑狀態,DAC不工作,當外部有轉換請求時,則系統進入轉換狀態,每當計數使能信號到來時,Cnt1自加一,當Cnt1=25后,表明一次轉換完成,將計數器清零,同時狀態跳回空閑態,等待下一次使能信號的到來。具體的狀態轉移圖如下所示:
  


  圖2 系統狀態轉移圖
  該狀態機的代碼對應如下:
  以下是代碼片段:
  always @(posedge Clk or negedge Rst_n)
  if(!Rst_n)
  Cnt_State
  else
  begin
  case(Cnt_State)
  IDEL:
  if(Do_DA)
  Cnt_State
  else
  Cnt_State
  DO_CNT:
  if(Cnt1 == 5'd25)
  Cnt_State
  else
  Cnt_State
  default:;
  endcase
  end
  因此,我們,只需要將Do_DA給出1個時鐘周期的高脈沖,即可啟動一次轉換。同時,在檢測到該脈沖時,模塊內部會將數據端口Data上的數據讀入到內部數據寄存器中,代碼如下:
  以下是代碼片段:
  always@(posedge Clk or negedge Rst_n)
  if(!Rst_n)
  Data_r
  else if(Do_DA)
  Data_r
  else
  Data_r
  同時,為了產生1MHz的時鐘,系統中使用了一個計數器Cnt2來專門產生該信號,該計數器對系統時鐘進行計數,如當系統時鐘為50M(周期為20ns)時,Cnt2計數到24,即計數了500ns,產生一個時鐘周期的標志信號,則Cnt1在檢測到這個標志信號后,便會自加1,因此,該標志信號出現兩次則表明計時1000ns,對應時鐘頻率為1Mhz,即DAC芯片數字接口的時鐘頻率。該部分代碼如下:
  以下是代碼片段:
  always @ (posedge Clk or negedge Rst_n)
  if(!Rst_n)
  Cnt2
  else if(Cnt_State == DO_CNT)
  begin
  if(Cnt2 == Cnt2_Top)
  Cnt2
  else
  Cnt2
  end
  else
  Cnt2
  為了兼容不同的系統時鐘,這里采用參數化定制,得出對應的計數最大值,具體代碼如下:
  以下是代碼片段:
  Localparam system_clk = 50_000_000; /*系統時鐘*/
  Localparam Cnt2_Top = system_clk / 1_000_000 / 2 - 1; /*500ns技術器計數最大值*/
  系統時鐘設置為50M,則計數最大值為50000000/1000000/2– 1 = 24,當系統時鐘改變后,只需要修改system_clk的值,即可保證Cnt2計數一次的時間為500ns。
  最后,附上主序列中的操作代碼:
  以下是代碼片段:
  always@(posedge Clk or negedge Rst_n)
  if(!Rst_n)
  begin
  DAC_Dout
  DAC_Clk
  DAC_LOAD
  DAC_LDAC
  DA_Done
  end
  else
  begin
  case(Cnt1)
  0:
  begin
  DAC_Dout
  DAC_Clk
  DAC_LOAD
  DAC_LDAC
  DA_Done
  end
  1:begin DAC_Dout
  2AC_Clk
  3:begin DAC_Dout
  4AC_Clk
  5:begin DAC_Dout
  6AC_Clk
  7:begin DAC_Dout
  8AC_Clk
  9:begin DAC_Dout
  10AC_Clk
  11:begin DAC_Dout
  12AC_Clk
  13:begin DAC_Dout
  14AC_Clk
  15:begin DAC_Dout
  16AC_Clk
  17:begin DAC_Dout
  18AC_Clk
  19:begin DAC_Dout
  20AC_Clk
  21:begin DAC_Dout
  22:DAC_Clk
  23:DAC_LOAD
  24:begin DAC_LOAD
  25:begin DAC_LDAC
  default:;
  endcase
  end
  該設計的仿真結果如下如所示:
  


  由該仿真結果可知,時鐘頻率為1MHz,滿足芯片工作要求,其它時序均與手冊給出的時序保持一致。為了設計簡潔,這里將LOAD和LDAC的低電平脈沖時間都設置為了500ns,而非最小時間250ns,這里主要是為了方便序列機的設計。當然,如此設計在一定程度上會影響DAC 的轉換速率,不過在大多數應用場合已經足夠,如需更加高效的設計,只需要對代碼稍加修改即可。
  本驅動的testbench編寫較為簡單,這里只附上對應代碼,不做詳細解釋:
  以下是代碼片段:
  `timescale 1ns/1ns
  module TLC5620_Driver_tb;
  reg Clk;
  reg Rst_n;
  reg Do_DA; /*使能單次轉換*/
  reg [10:0]Data;/*{Addr1,Addr0,Range,Data_bit[7:0]}*/
  wire DAC_Dout; /*DAC數據線*/
  wire DAC_Clk; /*DAC時鐘線,最高速度1M*/
  wire DAC_LDAC; /**/
  wire DAC_LOAD; /**/
  wire DA_Done; /*單次轉換完成標志信號*/
  TLC5620_Driver u1(
  .Clk(Clk),
  .Rst_n(Rst_n),
  .Do_DA(Do_DA),
  .Data(Data),
  .DAC_Dout(DAC_Dout),
  .DAC_Clk(DAC_Clk),
  .DAC_LDAC(DAC_LDAC),
  .DAC_LOAD(DAC_LOAD),
  .DA_Done(DA_Done)
  );
  initial begin
  Clk = 1;
  Rst_n = 0;
  Do_DA = 0;
  Data = 11'd0;
  #200;
  Rst_n = 1;
  #400;
  Data = 11'b110_1011_1001;
  Do_DA = 1;
  @(posedge DA_Done)
  Data = 11'b110_0000_1111;
  #20
  Do_DA = 1;
  #20;
  Do_DA = 0;
  @(posedge DA_Done)
  Data = 11'b110_1111_0000;
  #20
  Do_DA = 1;
  #20;
  Do_DA = 0;
  @(posedge DA_Done)
  #400;
  $stop;
  end
  always #10 Clk = ~Clk;
  endmodule
  因為時間關系,這里只開發了該芯片的驅動,并用modelsim對該驅動進行了仿真,詳細的調試和應用,小梅哥將在下一個實驗中介紹。
                               
               
本文地址:http://www.4huy16.com/thread-160455-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • 常見深度學習模型介紹及應用培訓教程
  • “芯”光璀璨,鵬城共賞——2025 Microchip中國技術精英年會深圳站回顧
  • Microchip第22屆中國技術精英年會——采訪篇
  • Microchip第22屆中國技術精英年會上海首站開幕
  • 貿澤電子(Mouser)專區

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表