作者:李西銳??校對:陸輝
大俠好,歡迎來到FPGA技術(shù)江湖。本系列將帶來FPGA的系統(tǒng)性學(xué)習(xí),從最基本的數(shù)字電路基礎(chǔ)開始,最詳細(xì)操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業(yè)學(xué)生、初入職場小白及打算進(jìn)階提升的職業(yè)開發(fā)者都可以有系統(tǒng)性學(xué)習(xí)的機(jī)會。
系統(tǒng)性的掌握技術(shù)開發(fā)以及相關(guān)要求,對個人就業(yè)以及職業(yè)發(fā)展都有著潛在的幫助,希望對大家有所幫助。本次帶來Vivado系列,TLC5620驅(qū)動教程。話不多說,上貨。
TLC5620驅(qū)動教程
在FPGA處理完數(shù)字信號之后,我們有些情況下是需要將數(shù)字信號轉(zhuǎn)變?yōu)?a class="article-link" target="_blank" href="/baike/1589317.html">模擬信號再輸出的。比如音頻信號在濾波后,需要轉(zhuǎn)換為聲音信號進(jìn)行輸出。此次,我們要講數(shù)字信號轉(zhuǎn)換為電壓信號進(jìn)行輸出,以便我們后續(xù)可以用示波器之類的器械觀察信號。
我們采用的芯片為TLC5620,是一款8bit四通道的數(shù)模轉(zhuǎn)換器。
在四路通道中,我們可以設(shè)置4種不同的參考電壓進(jìn)行轉(zhuǎn)換使用。但是在此次實(shí)驗(yàn)中,我們采用的四路參考電壓一樣,如下圖:
接下來我們介紹一下此芯片的一些特征以及手冊對芯片的描述。下圖為官方手冊對芯片的一段描述:
TLC5620是一款使用3線串行總線控制的芯片。11bit的命令中包含8bit數(shù)據(jù)、2bit通道選擇、1bit輸出范圍選擇bit。輸出范圍選擇,可以輸出一倍或者兩倍的參考電壓差值范圍。當(dāng)兩級鎖存器都打開時,新的數(shù)據(jù)可以進(jìn)入到芯片。下圖為芯片的框圖:
端口介紹:
我們的數(shù)據(jù)為8bit,那也就是將電壓范圍劃分為256份,我們的數(shù)字信號會對應(yīng)成電壓進(jìn)行輸出,所以我們的輸出電壓的計(jì)算公式為:
接下來我們看一下時序圖:
當(dāng)LOAD為高電平時,數(shù)據(jù)被鎖存進(jìn)DATA在每一個時鐘下降沿,一旦數(shù)據(jù)所有的bit被采集到,LOAD被拉低,將寄存器中的數(shù)據(jù)傳輸到被選擇的DAC中。如圖一所示,當(dāng)LDAC為低電平時,LOAD信號拉低,被選擇的DAC芯片輸出電壓會更新。如果LDAC為高電平,電壓更新將會被禁止,直到我們將LDAC拉低,如圖二:
對于我們的通道選擇,如下圖:
當(dāng)RNG=0時,輸出電壓為一倍范圍,當(dāng)RNG=1時,輸出電壓為兩倍范圍。
接下來,我們來做一下芯片的驅(qū)動,同樣可以使用線性序列機(jī)。轉(zhuǎn)換總周期為11us的時間。
首先我們先新建工程。
新建代碼文件,寫入代碼:
驅(qū)動代碼如下:
1 module tlc5620_driver(
2
3 input wire clk,
4 input wire rst_n,
5 input wire [7:0] data,
6
7 output reg da_clk,
8 output reg da_data,
9 output wire da_ldac,
10 output reg da_load
11 );
12
13 parameter t = 550;
14 parameter select_bit = 2'b00;
15 parameter RNG = 1'b1; //0代表輸出1倍,1代表輸出兩???
16
17 reg [9:0] cnt;
18
19 assign da_ldac = 1'b0;
20
21 always @ (posedge clk, negedge rst_n)
22 begin
23 if(rst_n == 1'b0)
24 cnt <= 10'd0;
25 else if(cnt == t - 1)
26 cnt <= 10'd0;
27 else
28 cnt <= cnt + 1'b1;
29 end
30
31 always @ (posedge clk, negedge rst_n)
32 begin
33 if(rst_n == 1'b0)
34 begin
35 da_clk <= 1'b0;
36 da_data <= 1'b0;
37 da_load <= 1'b1;
38 end
39 else
40 case(cnt)
41 0 : begin da_clk <= 1'b1; da_data <= select_bit[1]; da_load <= 1'b1; end
42 24 : begin da_clk <= 1'b0; end
43 49 : begin da_clk <= 1'b1; da_data <= select_bit[0]; end
44 74 : begin da_clk <= 1'b0; end
45 99 : begin da_clk <= 1'b1; da_data <= RNG; end
46 124 : begin da_clk <= 1'b0; end
47 149 : begin da_clk <= 1'b1; da_data <= data[7]; end
48 174 : begin da_clk <= 1'b0; end
49 199 : begin da_clk <= 1'b1; da_data <= data[6]; end
50 224 : begin da_clk <= 1'b0; end
51 249 : begin da_clk <= 1'b1; da_data <= data[5]; end
52 274 : begin da_clk <= 1'b0; end
53 299 : begin da_clk <= 1'b1; da_data <= data[4]; end
54 324 : begin da_clk <= 1'b0; end
55 349 : begin da_clk <= 1'b1; da_data <= data[3]; end
56 374 : begin da_clk <= 1'b0; end
57 399 : begin da_clk <= 1'b1; da_data <= data[2]; end
58 424 : begin da_clk <= 1'b0; end
59 449 : begin da_clk <= 1'b1; da_data <= data[1]; end
60 474 : begin da_clk <= 1'b0; end
61 499 : begin da_clk <= 1'b1; da_data <= data[0]; end
62 524 : begin da_clk <= 1'b0; end
63 529 : begin da_load <= 1'b0; end
64 default : ;
65 endcase
66 end
67
68 endmodule
在寫驅(qū)動代碼時,我們需要注意時序圖中的一些時間要求,比如,數(shù)字信號的建立時間和保持時間,以及l(fā)oad信號的建立時間與保持時間。時間要求如下圖:
由上圖可以得出結(jié)論,芯片的驅(qū)動時鐘最大為1MHz。數(shù)據(jù)的建立時間與保持時間最小值都為50ns。如果我們在時鐘上升沿發(fā)送數(shù)據(jù),那么我們發(fā)送的數(shù)據(jù),建立時間與保持時間最小值為500ns。滿足條件。
接下來我們寫一下仿真看一下波形。
代碼如下:
1 `timescale 1ns / 1ps
2
3 module tlc5620_driver_tb;
4
5 reg clk;
6 reg rst_n;
7 reg [7:0] data;
8
9 wire da_clk;
10 wire da_data;
11 wire da_ldac;
12 wire da_load;
13
14 initial begin
15 clk = 1'b0;
16 rst_n = 1'b0;
17 data = {$random}%256;
18 #105;
19 rst_n = 1'b1;
20 #11000;
21 repeat(10) begin
22 data = {$random}%256;
23 #11000;
24 end
25 #1000;
26 $stop;
27 end
28
29 always #10 clk = ~clk;
30
31 tlc5620_driver tlc5620_driver_inst(
32
33 .clk (clk ),
34 .rst_n (rst_n ),
35 .data (data ),
36
37 .da_clk (da_clk),
38 .da_data (da_data),
39 .da_ldac (da_ldac),
40 .da_load (da_load)
41 );
42
43 endmodule
運(yùn)行波形,觀察仿真波形:
觀察da_clk、da_data、da_load、da_ldac波形全部正常,即說明驅(qū)動正確。