設(shè)計(jì)背景: 數(shù)模轉(zhuǎn)換器(Digital to Analog Converter)即DAC,,是數(shù)字世界和模擬世界之間的橋梁。人類生活在模擬世界中,,雖然數(shù)字器件及設(shè)備的比重日益增強(qiáng),,但是DAC的發(fā)展仍是必不可少的。 從航空航天,、國(guó)防軍事到民用通信,、多媒體、數(shù)字信號(hào)處理等都涉及到DAC應(yīng)用,。DAC基本上由4個(gè)部分組成,,即權(quán)電阻網(wǎng)絡(luò)、運(yùn)算放大器,、基準(zhǔn)電源和模擬開關(guān),。它是一種將二進(jìn)制數(shù)字量形式的離散信號(hào)轉(zhuǎn)換成以參考電壓為基準(zhǔn)的模擬量的轉(zhuǎn)換器。 設(shè)計(jì)原理: 本設(shè)計(jì)采用串行數(shù)/模轉(zhuǎn)換芯片TLC5620,,TLC5620是一個(gè)擁有四路輸出的數(shù)/模轉(zhuǎn)換器,,時(shí)鐘頻率最大可達(dá)到1MHz。TLC5620芯片接口如下: 該芯片主要有以下特點(diǎn):四通道8位電壓輸出DA轉(zhuǎn)換器,、5V單電源供電,、串行接口、高阻抗基準(zhǔn)輸入,、可編程1或2輸出范圍,、同時(shí)更新設(shè)備、內(nèi)部上電復(fù)位,、低功耗,、半緩沖輸出。該芯片主要應(yīng)用于:可編程電源,、數(shù)字控制放大器/誤差器,、移動(dòng)通信,、自動(dòng)測(cè)試設(shè)備、研發(fā)過程檢測(cè)和控制和信號(hào)合成等,。 轉(zhuǎn)換公式:V = REF*(CODE/256)* (1 RNG) V:實(shí)際電壓,;REF:基準(zhǔn)電壓;CODE:輸入8位數(shù)據(jù),;RNG:范圍,。 TLC5620的接口時(shí)序如下列圖所示: 圖1 LOAD控制更新(LDAC為低電平)
圖2 LDAC控制更新(LDAC為低電平)
圖3 LOAD控制更新(使用8位串行數(shù)據(jù),LOAD為低電平)
圖4 LDAC控制更新(使用8位串行數(shù)據(jù)) 如圖1所示:當(dāng)LOAD為高電平時(shí),,數(shù)據(jù)在CLK的下降沿被鎖存至DATA,只要所有數(shù)據(jù)被鎖存,,則將LOAD拉低,,將數(shù)據(jù)從串行輸入寄存器傳送到所選擇的DAC。 如圖2所示:串行編程期間LDAC為高電平,,數(shù)據(jù)在LOAD為低電平時(shí)進(jìn)行鎖存,,當(dāng)LDAC變?yōu)榈碗娖綍r(shí)傳送至DAC輸出。如圖3,、4所示:輸入數(shù)據(jù)最高位(MSB)在前,,數(shù)據(jù)傳輸使用兩個(gè)8個(gè)時(shí)鐘周期。 在本設(shè)計(jì)中運(yùn)用的是圖1的工作時(shí)序:
數(shù)據(jù)通道選擇:
RNG:控制DAC輸出范圍,。當(dāng)RNG為低時(shí),,輸出范圍在基準(zhǔn)電壓和GND之間;當(dāng)RNG為高時(shí),,輸出范圍為兩倍的基準(zhǔn)電壓和GND,。 設(shè)計(jì)架構(gòu)圖: 本設(shè)計(jì)驅(qū)動(dòng)TLC5620將輸入的數(shù)字量轉(zhuǎn)換為實(shí)際的模擬量(電壓),通過四個(gè)按鍵控制四路輸出的電壓變化,,每按一次,,電壓值也隨之上升,同時(shí)在數(shù)碼管上也依次顯示相應(yīng)的值(依次為A1,A0,RNG,輸入DATA),。本設(shè)計(jì)采用的開發(fā)板的基準(zhǔn)電壓為2.5V,。設(shè)計(jì)架構(gòu)圖如下所示:
key_test模塊通過四個(gè)按鍵輸入的值,組合輸出兩個(gè)數(shù)據(jù),,11位的wr_data是TLC_DA模塊解碼所需的數(shù)據(jù),。20位的out_data是seg_num模塊數(shù)碼管顯示所需的數(shù)據(jù)。
設(shè)計(jì)代碼: key_test模塊代碼如下: 0 module key_test( //按鍵控制模塊 1 //端口信號(hào):模塊的輸入輸出接口 2 input clk, //50MHZ 3 input rst_n, //低電平復(fù)位 4 input [3:0] key, //四個(gè)按鍵組合信號(hào) 5 6 output [10:0] wr_data, //輸出一幀數(shù)據(jù),,為DA模塊的輸入數(shù)字量 7 output [19:0] out_data //輸出數(shù)碼管顯示數(shù)據(jù) 8 ); 9 10 //計(jì)數(shù)器時(shí)鐘分頻 11 reg [30:0] cnt; 12 reg clk_r; //分頻時(shí)鐘:在消除抖動(dòng)的時(shí)鐘頻率下進(jìn)行按鍵的檢測(cè) 13 always@(posedge clk or negedge rst_n) //按鍵消抖,,時(shí)間為0.2s進(jìn)行一次檢測(cè) 14 if(!rst_n) 15 begin 16 cnt <= 0; 17 clk_r <= 0; 18 end 19 else if(cnt < 30'd1000_0000) 20 cnt <= cnt 1'b1; 21 else 22 begin 23 cnt <= 0; 24 clk_r <= ~clk_r; 25 end 26 27 //按鍵為低電平有效,當(dāng)檢測(cè)到對(duì)應(yīng)按鍵之后,,相應(yīng)數(shù)值加1,,并顯示相應(yīng)的通道 28 reg [7:0] data; //按鍵輸入數(shù)據(jù) 29 reg [1:0] channel; //通道選擇 30 reg [7:0] key1,key2,key3,key4; //相應(yīng)四個(gè)按鍵 31 always@(posedge clk_r or negedge rst_n ) 32 if(!rst_n) 33 begin 34 key1 <= 8'h00; 35 key2 <= 8'h00; 36 key3 <= 8'h00; 37 key4 <= 8'h00; 38 data <= 8'h00; 39 channel <= 2'b00; 40 end 41 else 42 case(key) 43 4'b1110 : begin //按鍵1:選擇通道A,,且輸入數(shù)字量加1 44 channel <= 2'b00; 45 key1 <= key1 1'b1; 46 data <= key1; 47 end 48 4'b1101 : begin //按鍵2:選擇通道B,且輸入數(shù)字量加1 49 channel <= 2'b01; 50 key2 <= key2 1'b1; 51 data <= key2; 52 end 53 4'b1011 : begin //按鍵3:選擇通道C,,且輸入數(shù)字量加1 54 channel <= 2'b10; 55 key3 <= key3 1'b1; 56 data <= key3; 57 end 58 4'b0111 : begin //按鍵4:選擇通道D,,且輸入數(shù)字量加1 59 channel <= 2'b11; 60 key4 <= key4 1'b1; 61 data <= key4; 62 end 63 default :; 64 endcase 65 66 //用賦值語句將需要的數(shù)據(jù)組合起來,在此例中將RNG默認(rèn)為1 67 assign wr_data = {channel,1'b1,data}; assignout_data={{3'b000,channel[1]},3'b000,channel[0],4'h1,data}; 68 69 endmodule TLC_DA模塊代碼如下: 0 module TLC_DA( //輸入數(shù)字量轉(zhuǎn)換為模擬量模塊,,本實(shí)驗(yàn)用TLC5620 1 //端口信號(hào):模塊的輸入輸出接口 2 input clk, //系統(tǒng)時(shí)鐘50MHz 3 input rst_n, //低電平復(fù)位 4 input [10:0] data_in, //輸入一幀數(shù)據(jù) 5 output da_data, //串行數(shù)據(jù)接口 6 output da_clk, //串行時(shí)鐘接口 7 output reg da_ldac, //更新控制信號(hào) 8 output reg da_load //串行加載控制接口 9 ); 10 11 //計(jì)數(shù)器時(shí)鐘分頻:根據(jù)芯片內(nèi)部的時(shí)序要求進(jìn)行分頻 12 reg [30:0] cnt; 13 wire da_clk_r; //TLC 5620內(nèi)部時(shí)鐘信號(hào) 14 always@(posedge clk or negedge rst_n) //滿足協(xié)議中的時(shí)鐘要求,,在TLC 5620中時(shí)鐘要求不大于1MHZ 15 if(!rst_n) 16 cnt <= 6'd0; 17 else 18 cnt <= cnt 1'b1; 19 20 assign da_clk_r = cnt[5]; 21 22 //接收時(shí)序狀態(tài)機(jī) 23 reg [2:0] state; 24 reg [3:0] cnt_da; 25 reg da_data_r; 26 reg da_data_en; //限定da_data,da_clk的有效區(qū)域 27 always@(posedge da_clk_r or negedge rst_n) 28 if(!rst_n) 29 begin 30 state <= 0; 31 cnt_da <= 0; 32 da_load <= 1; 33 da_ldac <= 0; 34 da_data_r <= 1'b1; 35 da_data_en <= 0; 36 end 37 else 38 case(state) 39 0: state <= 1; 40 1: begin 41 da_load <= 1; 42 da_data_en <= 1; 43 if(cnt_da <= 10) 44 begin 45 cnt_da <= cnt_da 1'b1; 46 case(cnt_da) 47 0: da_data_r <= data_in[10]; 48 1: da_data_r <= data_in[9]; 49 2: da_data_r <= data_in[8]; 50 3: da_data_r <= data_in[7]; 51 4: da_data_r <= data_in[6]; 52 5: da_data_r <= data_in[5]; 53 6: da_data_r <= data_in[4]; 54 7: da_data_r <= data_in[3]; 55 8: da_data_r <= data_in[2]; 56 9: da_data_r <= data_in[1]; 57 10: da_data_r <= data_in[0]; 58 default:; 59 endcase 60 state <= 1; 61 end 62 else 63 begin 64 cnt_da <= 0; 65 state <= 2; 66 da_data_en <= 0; 67 end 68 end 69 2: begin 70 da_load <= 0; 71 state <= 3; 72 end 73 3: begin 74 da_load <= 1; 75 state <= 0; 76 end 77 default: state <= 0; 78 endcase 79 80 assign da_data = (da_data_en) ? da_data_r : 1'b1; 81 assign da_clk = (da_data_en)?da_clk_r : 1'b0; 82 83 endmodule seg_num模塊代碼如下: 0 module seg_num( //數(shù)碼管顯示模塊:選擇數(shù)碼管0-4共5個(gè)數(shù)碼管顯示{A1,A0,,RNG,,DATA} 1 //端口信號(hào):模塊的輸入輸出接口 2 input clk, //系統(tǒng)時(shí)鐘50MHz 3 input rst_n, //低電平復(fù)位 4 input [19:0] data_in, //20位輸入數(shù)據(jù) 5 6 output reg [7:0] seg, //數(shù)碼管段選 7 output reg [2:0] sel //數(shù)碼管位選 8 ); 9 10 //通過查找表的方式,將相應(yīng)位的數(shù)碼管與數(shù)據(jù)的相應(yīng)位一一對(duì)應(yīng) 11 reg [3:0] num; 12 always@(*) 13 case(sel) 14 4: num = data_in[3:0]; //第五個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[3:0] 15 3: num = data_in[7:4]; //第四個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[7:4] 16 2: num = data_in[11:8]; //第三個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[11:8] 17 1: num = data_in[15:12]; //第二個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[15:12] 18 0: num = data_in[19:16]; //第一個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[19:16] 19 default:; 20 endcase 21 22 //通過查找表的方式,,將數(shù)據(jù)與數(shù)碼管的顯示方式一一對(duì)應(yīng) 23 always@(*) 24 case(num) 25 0: seg <= 8'hC0; //8'b1100_0000 26 1: seg <= 8'hF9; //8'b1111_1001 27 2: seg <= 8'hA4; //8'b1010_0100 28 3: seg <= 8'hB0; //8'b1011_0000 29 4: seg <= 8'h99; //8'b1001_1001 30 5: seg <= 8'h92; //8'b1001_0010 31 6: seg <= 8'h82; //8'b1000_0010 32 7: seg <= 8'hF8; //8'b1111_1000 33 8: seg <= 8'h80; //8'b1000_0000 34 9: seg <= 8'h90; //8'b1001_0000 35 default:seg <= 8'hFF; //8'b1111_1111 36 endcase 37 38 //計(jì)數(shù)器時(shí)鐘分頻:用cnt第10位的變化作為分頻時(shí)鐘 39 reg [23:0] cnt; 40 always@(posedge clk or negedge rst_n) 41 if(!rst_n) 42 cnt <= 4'd0; 43 else 44 cnt <= cnt 1'b1; 45 //在分頻時(shí)鐘下,,數(shù)碼管的0-5位依次循環(huán) 46 always@(posedge cnt[10] or negedge rst_n) //分頻時(shí)鐘為2^10/50M 47 if(!rst_n) 48 sel <= 0; 49 else if(sel < 4) 50 sel <= sel 1'b1; 51 else 52 sel <= 0; 53 54 endmodule top頂層模塊代碼如下: 0 module top( //頂層模塊:將各個(gè)模塊組合 1 //外部接口 2 input clk, //系統(tǒng)時(shí)鐘50MHz 3 input rst_n, //低電平復(fù)位 4 input [3:0] key, //四個(gè)按鍵組成的按鍵信號(hào),低電平有效 5 6 output da_data,//DA串行接口數(shù)據(jù) 7 output da_clk, //DA串行接口時(shí)鐘 8 output da_ldac,//DA更新信號(hào) 9 output da_load, //DA串行接口加載控制信號(hào) 10 output [7:0] seg, //數(shù)碼管段選 11 output [2:0] sel //數(shù)碼管位選 12 ); 13 //內(nèi)部信號(hào):模塊內(nèi)部的接口信號(hào),,比如模塊TLC_DA的輸出信號(hào)data_in,,通過內(nèi)部信號(hào)r_data與模塊key_test的輸入信號(hào)wr_data相連 14 wire [10:0] wr_data; 15 wire [19:0] out_data; //輸入給數(shù)碼管的數(shù)據(jù) 16 17 //模塊例化 18 TLC_DA TLC_DA_inst( //輸入數(shù)字量轉(zhuǎn)換為模擬量模塊 19 .clk(clk), 20 .rst_n(rst_n), 21 .da_clk(da_clk), 22 .da_data(da_data), 23 .da_ldac(da_ldac), 24 .da_load(da_load), 25 .data_in(wr_data) 26 ); 27 28 key_test key_test_inst( //按鍵控制模塊 29 .clk(clk), 30 .rst_n(rst_n), 31 .key(key), 32 .wr_data(wr_data), 33 .out_data(out_data) 34 ); 35 36 seg_num seg_num_inst( //數(shù)碼管顯示模塊 37 .clk(clk), 38 .rst_n(rst_n), 39 .data_in(out_data), 40 .seg(seg), 41 .sel(sel) 42 ); 43 44 endmodule test頂層模塊測(cè)試代碼: 0 `timescale 1 ns/ 1 ns //設(shè)置仿真時(shí)間單位與精度分別為1ns/1ns 1 //若設(shè)為`timescale 1ns/1ps (#200 就是延時(shí)200 ns; 1ps就是仿真的精度) 2 module test; //測(cè)試模塊:主要是將激勵(lì)信號(hào)賦相應(yīng)的值,仿真之后觀察波形,,驗(yàn)證與實(shí)際功能是否一樣 3 4 //端口信號(hào)定義,,激勵(lì)信號(hào)為reg型 5 reg clk; 6 reg rst_n; 7 reg [3:0] key; 8 wire [7:0] seg; 9 wire [2:0] sel; 10 11 //模塊例化 12 top top( 13 .clk(clk), 14 .rst_n(rst_n), 15 .key(key), 16 .seg(seg), 17 .sel(sel) 18 ); 19 20 //初始化激勵(lì),以及給相應(yīng)激勵(lì)賦值 21 initial 22 begin 23 clk = 0;rst_n = 0; key = 4'b1111; //在復(fù)位階段,,將激勵(lì)賦初值 24 25 #200 rst_n = 1; //在延時(shí)200ns后將復(fù)位信號(hào)置為1 26 27 //實(shí)現(xiàn)按鍵1開,,關(guān) 28 #500000 key = 4'b1110; 29 #500000 key = 4'b1111; 30 31 end 32 33 always #10 clk = ~clk; //時(shí)鐘的表示,即每隔10ns翻轉(zhuǎn)一次,,一個(gè)周期的時(shí)間即為20ns,,時(shí)鐘為1/20ns = 50MHZ 34 35 endmodule 仿真圖: 由于仿真時(shí)間原因,這里只測(cè)試按鍵1按下時(shí)的數(shù)碼管顯示,,顯示為00100,,表示通道A,RNG為1,,輸入數(shù)字量為00,。之后實(shí)際下板驗(yàn)證,用萬用表也可測(cè)出輸入數(shù)字量對(duì)應(yīng)的電壓值,。 |
|