上一篇寫了基于Xilinx FPGA的通用信號發(fā)生器的案例,反響比較好,很多朋友和我探討相關(guān)的技術(shù),其中就涉及到信號的采集,為了使該文更有血有肉,我在寫一篇基于Xilinx FPGA的通用信號采集器,望能形成呼應(yīng),以解答大家的疑問。目的:1.通過設(shè)計實現(xiàn)信號采集與分析,掌握組合邏輯設(shè)計方法;2.通過設(shè)計實現(xiàn)信號的采集與分析,掌握信號采集原理。原理:利用FPGA芯片,用verilog語言編寫邏輯,控制AD0809進行AD轉(zhuǎn)換。AD0809是帶有8位AD轉(zhuǎn)換器、8路多路開關(guān)以及微處理機兼容的控制邏輯的CMOS組件,它是逐次逼近式的AD轉(zhuǎn)換器。AD0809的內(nèi)部結(jié)構(gòu)圖如下:

由上圖可知,多路開關(guān)可選通8 個
模擬通道,允許8路模擬量分時輸入,共用AD轉(zhuǎn)換器進行轉(zhuǎn)換,三態(tài)輸出鎖存器用于鎖存AD轉(zhuǎn)換完成后的數(shù)字量,當(dāng)OE為高時才可以從鎖存器取出轉(zhuǎn)換后的數(shù)據(jù)。通道選擇如下圖所示:

START為轉(zhuǎn)換啟動信號。當(dāng)START上跳沿時,所有內(nèi)部寄存器清零;下跳沿時,開始進行A/D 轉(zhuǎn)換;在轉(zhuǎn)換期間,START應(yīng)保持低電平。EOC 為轉(zhuǎn)換結(jié)束信號。當(dāng)EOC 為高電平時,表明轉(zhuǎn)換結(jié)束;否則,表明正在進行A/D 轉(zhuǎn)換。OE為輸出允許信號,用于控制三條輸出鎖存器向
單片機輸出轉(zhuǎn)換得到的數(shù)據(jù)。OE=1,輸出轉(zhuǎn)換得到的數(shù)據(jù);OE=0,輸出數(shù)據(jù)線呈高阻狀態(tài)。時序如下圖所示:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254源代碼1.Verilog源代碼,dat
aCollect.vmodule dataCollect(sysclk,
rst, adda, addb, ad
dc, start, oe, ????????dat
ain,
led_sel, led_seg);????input sysclk, rst;????input wire [7:0] datain;????output reg adda, addb, addc, start, oe;????output reg[3:0] led_sel;????output reg[7:0] led_seg;?????reg [3:0] coun
ter1;????reg [7:0] readdata;?????reg [9:0] counter2;????reg [15:0] sum;????reg [7:0] averdata;?????reg [7:0] temp;????reg [3:0] dataout1, dataout2, dataout3;?????reg [3:0] counter3;?????pa
rameter ZERO = 8'b11111100,ONE = 8'b01100000, TWO = 8'b11011010;????parameter THREE = 8'b11110010, FOUR =8'b01100110;????parameter FIVE = 8'b10110110, SIX = 8'b10111110, SEVEN =8'b11100000;????parameter EIGHT = 8'b11111110, NINE = 8'b11110110, BLANK = 8'b00000000;??????always @(posedge sysclk
or negedge rst)????begin????????if (!rst)????????begin????????????adda = 0;????????????addb = 0;????????????addc = 0;?????????????oe = 1;?????????????counter1 = 0;????????end????????else????????begin????????????counter1 = counter1 + 1;????????????case (counter1)????????????????3 : start = 0;????????????????4 : start = 1;????????????????5 : start = 0;????????????????10 : readdata = datain;????????????????15 : counter1 = 0;????????????????default : counter1 = counter1;????????????endcase????????end????end?????always @(posedge sysclk or negedge rst)????begin????????if (!rst)????????begin????????????counter2 = 0;????????????sum = 0;????????????averdata = 0;????????end????????else????????begin????????????counter2 = counter2 + 1;????????????if ((counter2%16) == 0)????????????????sum = sum + readdata;????????????else if (counter2 > 512)????????????begin????????????????averdata = sum / 32;????????????????sum = 0;????????????????counter2 = 0;????????????end????????end????end??????always @(averdata)????begin????????temp = averdata;????????if (temp > 199)????????????dataout3 = 2;????????else if (temp > 99)????????????dataout3 = 1;????????else????????????dataout3 = 0;????????????????temp = temp - dataout3 * 100;????????if (temp > 89)????????????dataout2 = 9;????????else if (temp > 79)????????????dataout2 = 8;????????else if (temp > 69)????????????dataout2 = 7;????????else if (temp > 59)????????????dataout2 = 6;????????else if (temp > 49)????????????dataout2 = 5;????????else if (temp > 39)????????????dataout2 = 4;????????else if (temp > 29)????????????dataout2 = 3;????????else if (temp > 19)????????????dataout2 = 2;????????else if (temp > 9)????????????dataout2 = 1;????????else????????????dataout2 = 0;?????????temp = temp - dataout2 * 10;????????dataout1 = temp;?????????if ((dataout3==0) && (dataout2==0))????????begin????????????dataout3 = 10;????????????dataout2 = 10;????????end????????else if (dataout3 == 0)????????????dataout3 = 10;????????else????????????dataout3 = dataout3;????end??????always @(posedge sysclk or negedge rst)????begin????????if (!rst)????????begin????????????counter3 = 0;????????????led_sel = 4'b0001;????? ????????end????????else????????begin????????????????if (counter3 == 4)????????????????begin????????????????????counter3 = 0;????????????????????if (led_sel == 4'b1000)????????????????????????led_sel = 4'b0001;????????????????????else????????????????????????led_sel = led_sel << 1;????????????????end????????????????counter3 = counter3 + 1;????????end????????????end?????always @(led_sel, dataout1, dataout2, dataout3)????begin????????case (led_sel)????????????4'b0001 :????????????begin????????????????case (dataout1)????????????????????0 : led_seg = ZERO;????????????????????1 : led_seg = ONE;????????????????????2 : led_seg = TWO;????????????????????3 : led_seg = THREE;????????????????????4 : led_seg = FOUR;????????????????????5 : led_seg = FIVE;????????????????????6 : led_seg = SIX;????????????????????7 : led_seg = SEVEN;????????????????????8 : led_seg = EIGHT;????????????????????9 : led_seg = NINE;????????????????????default : led_seg = BLANK;????????????????endcase????????????end????????????4'b0010 :????????????begin????????????????case (dataout2)????????????????????0 : led_seg = ZERO;????????????????????1 : led_seg = ONE;????????????????????2 : led_seg = TWO;????????????????????3 : led_seg = THREE;????????????????????4 : led_seg = FOUR;????????????????????5 : led_seg = FIVE;????????????????????6 : led_seg = SIX;????????????????????7 : led_seg = SEVEN;????????????????????8 : led_seg = EIGHT;????????????????????9 : led_seg = NINE;????????????????????default : led_seg = BLANK;????????????????endcase????????????end????????????4'b0100 :????????????begin????????????????case (dataout3)????????????????????0 : led_seg = ZERO;????????????????????1 : led_seg = ONE;????????????????????2 : led_seg = TWO;????????????????????3 : led_seg = THREE;????????????????????4 : led_seg = FOUR;????????????????????5 : led_seg = FIVE;????????????????????6 : led_seg = SIX;????????????????????7 : led_seg = SEVEN;????????????????????8 : led_seg = EIGHT;????????????????????9 : led_seg = NINE;????????????????????default : led_seg = BLANK;????????????????endcase????????????end????????????4'b1000 :????????????begin????????????????case (10)????????????????????0 : led_seg = ZERO;????????????????????1 : led_seg = ONE;????????????????????2 : led_seg = TWO;????????????????????3 : led_seg = THREE;????????????????????4 : led_seg = FOUR;????????????????????5 : led_seg = FIVE;????????????????????6 : led_seg = SIX;????????????????????7 : led_seg = SEVEN;????????????????????8 : led_seg = EIGHT;????????????????????9 : led_seg = NINE;????????????????????default : led_seg = BLANK;????????????????endcase????????????end????????????default :????????????begin????????????????led_seg = 1'hx;????????????end????????endcase????end?endmodule?2.引腳分配源代碼,dataCollect.ucfnet sysclk loc = p80;net rst loc = p57;?net adda loc = p14;net addb loc = p16;net addc loc = p18;?net oe loc = p23;net start loc = p27;?net datain<7> loc = p30;net datain<6> loc = p33;net datain<5> loc = p35;net datain<4> loc = p37;net datain<3> loc = p42;net datain<2> loc = p44;net datain<1> loc = p46;net datain<0> loc = p48;?net led_sel<3> loc = p3;net led_sel<2> loc = p5;net led_sel<1> loc = p7;net led_sel<0> loc = p9;?net led_seg<7> loc = p206;net led_seg<6> loc = p204;net led_seg<5> loc = p202;net led_seg<4> loc = p200;net led_seg<3> loc = p195;net led_seg<2> loc = p193;net led_seg<1> loc = p191;net led_seg<0> loc = p187;?OK了,可以使用了,按照為器件分配的引腳進行連線,系統(tǒng)
時鐘輸入連1KMHZ,可以旋轉(zhuǎn)
電位器以改變輸入電壓,此時可觀察到數(shù)據(jù)管上數(shù)據(jù)變化。FPGA,融入其中,樂趣無窮。。。。
評論