基于FPGA的数字电压表设计
提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 一、項目設計目標
- 二、系統總體設計
- 1.頂層模塊(Top.v)
- 2.A/D轉換模塊(PmodAD1.v)
- 3.數據處理模塊(data_ad_pro.v)
- 4.電壓顯示模塊(display.v)
- 5.引腳約束文件(這里使用Nexys4ddr,注意:數碼管是共陽極顯示!!)
- 三.參考資料
前言
提示:這里可以添加本文要記錄的大概內容:
第一次寫博客。。。如果有什么問題大家可以在評論區告訴我,謝謝大家。
提示:以下是本篇文章正文內容,下面案例可供參考
一、項目設計目標
(1)項目綜合描述
本項目要求設計并實現一個數字電壓表的裝置,該裝置能夠對0~200V范圍的直流電壓進行測量。測量分為4擋:200mV、2V、20V和200V。輸入為模擬直流電壓,輸出為數字量,并在必要的輔助輸出顯示設備上顯示。同時具有正、負電壓極性顯示,小數點顯示。能判讀并顯示被測量信號超出所選擇的量程范圍。并根據不同的量程能自動調整小數點。
(2)任務要求
① 數字電壓表有4個測量擋:200mV、2V、20V和200V,能將被測的模擬直流電壓在顯示設備上顯示出來。
② 數字電壓表以基本量程為基礎,同時設計衰減器進行量程的擴展。
③ 具有位(三位半)顯示:有3位完整的顯示,另外最高位只顯示0或1。
④ 能夠判讀并顯示被測電壓的極性。 1
⑤ 測量速度為2~5 次/秒,分辨率為0.1mV,測量誤差<0.1%。
(3)發揮部分
①設計并調試自動量程轉換電路。
②設計并調試小數點自動切換電路。
二、系統總體設計
系統總體框架如下圖所示:
主要有五個模塊:衰減電路、放大電路、反向電路、A/D轉換模塊、FPGA處理及顯示。
(1)衰減電路:將不同電壓分別送入不同的檔位,通過開關控制檔位的選擇,最后四檔電壓都衰減到-0.2v-0.2v,再送入放大電路;
(2)放大電路:對衰減電路送入的電壓進行放大,利用NE5532放大器進行放大10倍;
(3)反向電路:對于輸入的負電壓,電壓經衰減和放大后,還需要經過反向電路進行反向,這里利用NE5532放大器放大-1倍進行反向;
(4)A/D轉換模塊:對處理得到的0-2V電壓進行12位的模數轉換,轉換輸出為0-4095的二進制電平;
(5)FPGA處理及顯示模塊:利用FPGA里面燒入的程序對A/D轉換后的數據進行處理,還原到其輸入值,并通過手動控制FPGA上的開關進行量程選擇,控制小數點的顯示,以及控制正負號的顯示,最后通過七段數碼管顯示輸入的電壓值。
#三、程序代碼
1.頂層模塊(Top.v)
`timescale 1ns / 1ps
module Top(clk,sw,led,flag, ADC_sdata, ADC_sclk,ADC_csn,slec_wei,slec_duan);
input clk;
input [3:0]sw;
output reg [7:0] led;
input flag;
input ADC_sdata;
output ADC_sclk,ADC_csn;
output [7:0] slec_wei;
output [7:0] slec_duan;
wire [11:0] adc_res;
wire adc_valid;
wire [19:0]cout;
always@(posedge clk)if(adc_valid) led<=adc_res[11:4];
PmodAD1 U0(
.clk(clk),
.rst(1’b0),
.ADC_sdata(ADC_sdata),
.ADC_sclk(ADC_sclk),
.ADC_csn(ADC_csn),
.adc_res(adc_res),
.adc_valid(adc_valid)
);
data_ad_pro U1(
.sys_clk(clk),
.rst_n(1’b1),
.pre_data(adc_res[11:4]),
.cout(cout)
);
display U2(
.sys_clk(clk),
.rst_n(1’b1),
.cout(cout),
.sw(sw),
.flag(flag),
.slec_wei(slec_wei),
.slec_duan(slec_duan)
);
endmodule
2.A/D轉換模塊(PmodAD1.v)
module PmodAD1( clk,rst, ADC_sdata,ADC_sclk,ADC_csn,adc_res,adc_valid);input clk,rst, ADC_sdata;output reg ADC_sclk,ADC_csn;output reg [11:0] adc_res;output reg adc_valid; reg [7:0] cntr; always@(posedge clk) if(rst)cntr<=0;else if(cntr==34)cntr<=0;else cntr<=cntr+1;always@(posedge clk) case (cntr) 0: ADC_csn<=0; 33: ADC_csn<=1; endcase always@(posedge clk) case(cntr) 34,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,33:ADC_sclk<=1; default ADC_sclk<=0; endcase always@(posedge clk) case(cntr)8: adc_res[11]<= ADC_sdata;10:adc_res[10]<= ADC_sdata;12:adc_res[9]<= ADC_sdata;14:adc_res[8]<= ADC_sdata;16:adc_res[7]<= ADC_sdata;18:adc_res[6]<= ADC_sdata;20:adc_res[5]<= ADC_sdata;22:adc_res[4]<= ADC_sdata;24:adc_res[3]<= ADC_sdata;26:adc_res[2]<= ADC_sdata;28:adc_res[1]<= ADC_sdata; 30:adc_res[0]<= ADC_sdata; endcase always@(posedge clk)adc_valid<=cntr==32;endmodule
3.數據處理模塊(data_ad_pro.v)
`timescale 1ns / 1ps // // module data_ad_pro(//inputsys_clk, //輸入系統時鐘50MHzrst_n, //輸入復位信號pre_data, //輸入AD采樣模塊傳來的數據 //outputcout //輸出處理后的12位電壓數據); input sys_clk; input rst_n; input [7:0] pre_data;output [19:0] cout;reg [19:0] L; always @ (posedge sys_clk)case(pre_data[3:0]) //pre_data[3:0]=adc_res[7:4],0.00164'h1: L <= 20'h00260;4'h2: L <= 20'h00520;4'h3: L <= 20'h00780;4'h4: L <= 20'h01039;4'h5: L <= 20'h01300;4'h6: L <= 20'h01559;4'h7: L <= 20'h01819;4'h8: L <= 20'h02079;4'h9: L <= 20'h02339;//4'ha: L <= 20'h02598;4'hb: L <= 20'h02858;4'hc: L <= 20'h03118;4'hd: L <= 20'h03378;4'he: L <= 20'h03638;4'hf: L <= 20'h03898;default: L <= 20'h00000;endcasereg [19:0] H; always @ (posedge sys_clk)case(pre_data[7:4]) //H = n * 12'h080(n=1、2、3、、f),pre_data[7:4]=adc_res[11:8]4'h1: H <= 20'h04157; 4'h2: H <= 20'h08315; 4'h3: H <= 20'h12472; 4'h4: H <= 20'h16630; 4'h5: H <= 20'h20787; //只需要顯示0-2V 4'h6: H <= 20'h00000; 4'h7: H <= 20'h00000; 4'h8: H <= 20'h00000; 4'h9: H <= 20'h00000; // 4'ha: H <= 20'h00000; 4'hb: H <= 20'h00000; 4'hc: H <= 20'h00000;4'hd: H <= 20'h00000; 4'he: H <= 20'h00000; 4'hf: H <= 20'h00000; default: H <= 20'h00000; endcasereg c0; always @ (posedge sys_clk) beginif(H[3:0] + L[3:0] > 4'd9) c0 <= 1;elsec0 <= 0;endreg c1; always @ (posedge sys_clk) beginif(H[7:4] + L[7:4] > 4'd9) c1 <= 1;elsec1 <= 0;endreg c2; always @ (posedge sys_clk) beginif(H[11:8] + L[11:8] > 4'd9) c2 <= 1;elsec2 <= 0;endreg c3; always @ (posedge sys_clk) beginif(H[15:12] + L[15:12] > 4'd9) c3 <= 1;elsec3 <= 0;endreg [19:0] cout; always @(c1 or c0 or c2 or c3 ) begincase({c3,c2,c1,c0})4'b0000: begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12];cout[11:8] <= H[11:8] + L[11:8];cout[7:4] <= H[7:4] + L[7:4];cout[3:0] <= H[3:0] + L[3:0];end 4'b0001: begin if(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12];cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001)<= 9)&&((H[11:8] + L[11:8] + 4'b0001)<=9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12];cout[11:8] <= H[11:8] + L[11:8];cout[7:4] <= H[7:4] + L[7:4]+4'b0001;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endend4'b0010:begin if(((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12];cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endend 4'b0011:begin if(((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12];cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endend 4'b0100:beginif((H[15:12] + L[15:12] + 4'b0001) > 9) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4];cout[3:0] <= H[3:0] + L[3:0];//加上6endelse if((H[15:12] + L[15:12] + 4'b0001) <= 9) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4];cout[3:0] <= H[3:0] + L[3:0];//加上6end end 4'b0101:beginif(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[15:12] + L[15:12] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001)<=9)&&((H[15:12] + L[15:12] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4]+4'b0001;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) <= 9)&&((H[15:12] + L[15:12] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4]+4'b0001;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endend 4'b0110:beginif((H[15:12] + L[15:12] + 4'b0001) > 9) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endelse if((H[15:12] + L[15:12] + 4'b0001) <= 9) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6end end 4'b0111:beginif((H[15:12] + L[15:12] + 4'b0001) > 9) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if((H[15:12] + L[15:12] + 4'b0001) <= 9) begin cout[19:16] <= H[19:16] + L[19:16];cout[15:12] <= H[15:12] + L[15:12]+4'b0001;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6end end 4'b1000:begincout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+ 4'b0110;cout[11:8] <= H[11:8] + L[11:8];cout[7:4] <= H[7:4] + L[7:4];cout[3:0] <= H[3:0] + L[3:0];end 4'b1001:beginif(((H[7:4] + L[7:4] + 4'b0001) > 9)&&((H[11:8] + L[11:8] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) >9)&&((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0110;cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) <=9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0110;cout[11:8] <= H[11:8] + L[11:8];cout[7:4] <= H[7:4] + L[7:4]+4'b0001;cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110;//加上6endend 4'b1010:beginif(((H[11:8] + L[11:8] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0110;cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];//加上6endend 4'b1011:beginif(((H[11:8] + L[11:8] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[11:8] + L[11:8] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0110;cout[11:8] <= H[11:8] + L[11:8]+4'b0001;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endend 4'b1100:begincout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4];cout[3:0] <= H[3:0] + L[3:0];end 4'b1101:beginif(((H[7:4] + L[7:4] + 4'b0001) > 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6endelse if(((H[7:4] + L[7:4] + 4'b0001) <= 9)) begin cout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0110;cout[7:4] <= H[7:4] + L[7:4]+4'b0001;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;//加上6end end 4'b1110:begincout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0110;cout[3:0] <= H[3:0] + L[3:0];end 4'b1111:begincout[19:16] <= H[19:16] + L[19:16]+4'b0001;cout[15:12] <= H[15:12] + L[15:12]+4'b0111;cout[11:8] <= H[11:8] + L[11:8]+4'b0111;cout[7:4] <= H[7:4] + L[7:4]+4'b0111;cout[3:0] <= H[3:0] + L[3:0]+4'b0110;endendcaseend
endmodule
4.電壓顯示模塊(display.v)
`timescale 1ns / 1ps//module display(//inputsys_clk, //輸系統時鐘50MHzrst_n, //輸入復位信號cout, //輸入數據處理模塊傳來的12位電壓數據sw, flag, //output slec_wei, //輸出數碼管位選信號slec_duan //輸出數碼管段選信號 ); input sys_clk; input rst_n; input [19:0] cout; input [3:0] sw; input flag; output [7:0] slec_wei; output [7:0] slec_duan; parameter SEG_NUM0 = 8'b1100_0000, //數碼管顯示0SEG_NUM1 = 8'b1111_1001, //數碼管顯示1SEG_NUM2 = 8'b1010_0100, //數碼管顯示2SEG_NUM3 = 8'b1011_0000, //數碼管顯示3SEG_NUM4 = 8'b1001_1001, //數碼管顯示4SEG_NUM5 = 8'b1001_0010, //數碼管顯示5SEG_NUM6 = 8'b1000_0010, //數碼管顯示6SEG_NUM7 = 8'b1111_1000, //數碼管顯示7SEG_NUM8 = 8'b1000_0000, //數碼管顯示8SEG_NUM = 8'b1111_1111, SEG_NUM9 = 8'b1001_0000, //數碼管顯示9SEG_NUMF = 8'b1011_1111;parameter T1MS = 16'd49999; //1ms計數//1ms計數器 reg [15:0] cnt; always @(posedge sys_clk or negedge rst_n)if(!rst_n) cnt <= 16'd0;else if(cnt == T1MS) cnt <= 16'd0;elsecnt <= cnt + 1'b1;/**********************************************/ //數碼管輪流導通 reg [2:0] i; reg [7:0] slec_wei; reg [7:0] slec_duan;reg [7:0] data0;always @ (posedge sys_clk)case(cout[19:16]) //進行編碼 高4'h0: data0 <= SEG_NUM0;4'h1: data0 <= SEG_NUM1;4'h2: data0 <= SEG_NUM2;4'h3: data0 <= SEG_NUM3;4'h4: data0 <= SEG_NUM4;4'h5: data0 <= SEG_NUM5;4'h6: data0 <= SEG_NUM6;4'h7: data0 <= SEG_NUM7;4'h8: data0 <= SEG_NUM8;4'h9: data0 <= SEG_NUM9;default:data0 <= SEG_NUM0; endcasereg [7:0] data1;always @ (posedge sys_clk)case(cout[15:12]) //進行編碼 高4'h0: data1 <= SEG_NUM0;4'h1: data1 <= SEG_NUM1;4'h2: data1 <= SEG_NUM2;4'h3: data1 <= SEG_NUM3;4'h4: data1 <= SEG_NUM4;4'h5: data1 <= SEG_NUM5;4'h6: data1 <= SEG_NUM6;4'h7: data1 <= SEG_NUM7;4'h8: data1 <= SEG_NUM8;4'h9: data1 <= SEG_NUM9;default:data1 <= SEG_NUM0; endcasereg [7:0] data2;always @ (posedge sys_clk)case(cout[11:8]) //進行編碼 高4'h0: data2 <= SEG_NUM0;4'h1: data2 <= SEG_NUM1;4'h2: data2 <= SEG_NUM2;4'h3: data2 <= SEG_NUM3;4'h4: data2 <= SEG_NUM4;4'h5: data2 <= SEG_NUM5;4'h6: data2 <= SEG_NUM6;4'h7: data2 <= SEG_NUM7;4'h8: data2 <= SEG_NUM8;4'h9: data2 <= SEG_NUM9;default:data2 <= SEG_NUM0; endcase/*****************************************/ reg [7:0] data3;always @ (posedge sys_clk) case(cout[7:4]) //進行編碼 中4'h0: data3 <= SEG_NUM0;4'h1: data3 <= SEG_NUM1;4'h2: data3 <= SEG_NUM2;4'h3: data3 <= SEG_NUM3;4'h4: data3 <= SEG_NUM4;4'h5: data3 <= SEG_NUM5;4'h6: data3 <= SEG_NUM6;4'h7: data3 <= SEG_NUM7;4'h8: data3 <= SEG_NUM8;4'h9: data3 <= SEG_NUM9;default:data3 <= SEG_NUM0; endcase/*****************************************/ reg [7:0] data4;always @ (posedge sys_clk) case(cout[3:0]) //進行編碼 低4'h0: data4 <= SEG_NUM0;4'h1: data4 <= SEG_NUM1;4'h2: data4 <= SEG_NUM2;4'h3: data4 <= SEG_NUM3;4'h4: data4 <= SEG_NUM4;4'h5: data4 <= SEG_NUM5;4'h6: data4 <= SEG_NUM6;4'h7: data4 <= SEG_NUM7;4'h8: data4 <= SEG_NUM8;4'h9: data4 <= SEG_NUM9;default:data4 <= SEG_NUM0;endcase always @ (posedge sys_clk or negedge rst_n)if( !rst_n )begini <= 4'd0;slec_wei <= 8'b11111111;endelsecase( i ) 0: beginif( cnt == T1MS ) i <= i + 1'b1;else if (( cnt != T1MS )&&(sw==4'b0010))beginslec_wei <= 8'b11101111; slec_duan <= data0 + 8'b1000_0000;end //data0是整數位,加上小數點else if (( cnt != T1MS )&&(sw!=4'b0010))beginslec_wei <= 8'b11101111; slec_duan <= data0;endend 1: beginif( cnt == T1MS ) i <= i + 1'b1;else if (( cnt != T1MS )&&(sw==4'b0100))beginslec_wei <= 8'b11110111; slec_duan <= data1 + 8'b1000_0000;end //data1是整數位,加上小數點else if (( cnt != T1MS )&&(sw!=4'b0100))beginslec_wei <= 8'b11110111; slec_duan <= data1;endend 2: beginif( cnt == T1MS ) i <= i + 1'b1;else if (( cnt != T1MS )&&(sw==4'b1000))beginslec_wei <= 8'b11111011; slec_duan <= data2 + 8'b1000_0000;end //data2是整數位,加上小數點else if (( cnt != T1MS )&&(sw!=4'b1000))beginslec_wei <= 8'b11111011;slec_duan <= data2;endend 3: if( cnt == T1MS ) i <= i + 1'b1;else beginslec_wei <= 8'b11111101; slec_duan <= data3;end 4: beginif( cnt == T1MS ) i <= i + 1'b1;else if (( cnt != T1MS )&&(sw==4'b0001))beginslec_wei <= 8'b11011111; slec_duan <= SEG_NUM0 + 8'b1000_0000;end //0-200mv,加上小數點else if (( cnt != T1MS )&&(sw!=4'b0001))beginslec_wei <= 8'b11011111; slec_duan <= SEG_NUM0;endend 5: beginif( cnt == T1MS ) i <= i + 1'b1;else if(( cnt != T1MS )&&(flag==0))beginslec_wei <= 8'b10111111; slec_duan <= SEG_NUM;end else if(( cnt != T1MS )&&(flag==1))beginslec_wei <= 8'b10111111; slec_duan <= SEG_NUMF;endend 6: if( cnt == T1MS ) i <= i + 1'b1;else beginslec_wei <= 8'b01111111; slec_duan <= SEG_NUM;end 7: if( cnt == T1MS ) i <= 5'd0;else beginslec_wei <= 8'b11111110; slec_duan <= data4;end endcase endmodule5.引腳約束文件(這里使用Nexys4ddr,注意:數碼管是共陽極顯示!!)
## 7 segment display NET "slec_duan<0>" LOC=T10 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_A00_D16_14 NET "slec_duan<1>" LOC=R10 | IOSTANDARD=LVCMOS33; #IO_25_14 NET "slec_duan<2>" LOC=K16 | IOSTANDARD=LVCMOS33; #IO_25_15 NET "slec_duan<3>" LOC=K13 | IOSTANDARD=LVCMOS33; #IO_L17P_T2_A26_15 NET "slec_duan<4>" LOC=P15 | IOSTANDARD=LVCMOS33; #IO_L13P_T2_MRCC_14 NET "slec_duan<5>" LOC=T11 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A10_D26_14 NET "slec_duan<6>" LOC=L18 | IOSTANDARD=LVCMOS33; #IO_L4P_T0_D04_14 NET "slec_duan<7>" LOC=H15 | IOSTANDARD=LVCMOS33; #IO_L19N_T3_A21_VREF_15NET "slec_wei<0>" LOC=J17 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_FOE_B_15 NET "slec_wei<1>" LOC=J18 | IOSTANDARD=LVCMOS33; #IO_L23N_T3_FWE_B_15 NET "slec_wei<2>" LOC=T9 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_A01_D17_14 NET "slec_wei<3>" LOC=J14 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A22_15 NET "slec_wei<4>" LOC=P14 | IOSTANDARD=LVCMOS33; #IO_L8N_T1_D12_14 NET "slec_wei<5>" LOC=T14 | IOSTANDARD=LVCMOS33; #IO_L14P_T2_SRCC_14 NET "slec_wei<6>" LOC=K2 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_35 NET "slec_wei<7>" LOC=U13 | IOSTANDARD=LVCMOS33; #IO_L23N_T3_A02_D18_14#量程開關 NET "sw<0>" LOC=J15 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_RS0_15 NET "sw<1>" LOC=L16 | IOSTANDARD=LVCMOS33; #IO_L3N_T0_DQS_EMCCLK_14 NET "sw<2>" LOC=M13 | IOSTANDARD=LVCMOS33; #IO_L6N_T0_D08_VREF_14 NET "sw<3>" LOC=R15 | IOSTANDARD=LVCMOS33; #IO_L13N_T2_MRCC_14##判斷正負 NET "flag" LOC=V10 | IOSTANDARD=LVCMOS33; #IO_L21P_T3_DQS_14##時鐘 NET "clk" LOC=E3 | IOSTANDARD=LVCMOS33;##pmodad1 NET "ADC_csn" LOC=C17 | IOSTANDARD=LVCMOS33; #IO_L20N_T3_A19_15 NET "ADC_sdata" LOC=D18 | IOSTANDARD=LVCMOS33; #IO_L21N_T3_DQS_A18_15 NET "ADC_sclk" LOC=G17 | IOSTANDARD=LVCMOS33; #IO_L18N_T2_A23_15## NET "led<0>" LOC=H17 | IOSTANDARD=LVCMOS33; #IO_L18P_T2_A24_15 NET "led<1>" LOC=K15 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_RS1_15 NET "led<2>" LOC=J13 | IOSTANDARD=LVCMOS33; #IO_L17N_T2_A25_15 NET "led<3>" LOC=N14 | IOSTANDARD=LVCMOS33; #IO_L8P_T1_D11_14 NET "led<4>" LOC=R18 | IOSTANDARD=LVCMOS33; #IO_L7P_T1_D09_14 NET "led<5>" LOC=V17 | IOSTANDARD=LVCMOS33; #IO_L18N_T2_A11_D27_14 NET "led<6>" LOC=U17 | IOSTANDARD=LVCMOS33; #IO_L17P_T2_A14_D30_14 NET "led<7>" LOC=U16 | IOSTANDARD=LVCMOS33; #IO_L18P_T2_A12_D28_14三.參考資料
(1)羅杰,謝自美 電子線路設計.實驗.測試,電子工業出版社,2015
(2)康華光,張林《電子技術基礎:模擬部分(第七版)》,高等教育出版社,2021
(3)康華光,張林《電子技術基礎:數字部分(第七版)》,高等教育出版社,2021
(4) FPGA(Nexy4ddr)、Analog Discovery2以及PMODAD1和AD7476A芯片的相關資料。
www.analog.com/AD7476A
www.digilentinc.com
本文代碼參考了大佬的設計:https://blog.csdn.net/weixin_43586860/article/details/107331277?spm=1001.2014.3001.5506
感謝大佬,侵刪。
總結
以上是生活随笔為你收集整理的基于FPGA的数字电压表设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文件传输协议
- 下一篇: 微信公众号开发经验总结