上一篇寫了基于Xilinx FPGA的通用信號(hào)發(fā)生器的案例,反響比較好,很多朋友和我探討相關(guān)的技術(shù),其中就涉及到信號(hào)的采集,為了使該文更有血有肉,我在寫一篇基于Xilinx FPGA的通用信號(hào)采集器,望能形成呼應(yīng),以解答大家的疑問。目的:1.通過設(shè)計(jì)實(shí)現(xiàn)信號(hào)采集與分析,掌握組合邏輯設(shè)計(jì)方法;2.通過設(shè)計(jì)實(shí)現(xiàn)信號(hào)的采集與分析,掌握信號(hào)采集原理。原理:利用FPGA芯片,用verilog語言編寫邏輯,控制AD0809進(jìn)行AD轉(zhuǎn)換。AD0809是帶有8位AD轉(zhuǎn)換器、8路多路開關(guān)以及微處理機(jī)兼容的控制邏輯的CMOS組件,它是逐次逼近式的AD轉(zhuǎn)換器。AD0809的內(nèi)部結(jié)構(gòu)圖如下:
由上圖可知,多路開關(guān)可選通8 個(gè)模擬通道,允許8路模擬量分時(shí)輸入,共用AD轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換,三態(tài)輸出鎖存器用于鎖存AD轉(zhuǎn)換完成后的數(shù)字量,當(dāng)OE為高時(shí)才可以從鎖存器取出轉(zhuǎn)換后的數(shù)據(jù)。通道選擇如下圖所示:
START為轉(zhuǎn)換啟動(dòng)信號(hào)。當(dāng)START上跳沿時(shí),所有內(nèi)部寄存器清零;下跳沿時(shí),開始進(jìn)行A/D 轉(zhuǎn)換;在轉(zhuǎn)換期間,START應(yīng)保持低電平。EOC 為轉(zhuǎn)換結(jié)束信號(hào)。當(dāng)EOC 為高電平時(shí),表明轉(zhuǎn)換結(jié)束;否則,表明正在進(jìn)行A/D 轉(zhuǎn)換。OE為輸出允許信號(hào),用于控制三條輸出鎖存器向單片機(jī)輸出轉(zhuǎn)換得到的數(shù)據(jù)。OE=1,輸出轉(zhuǎn)換得到的數(shù)據(jù);OE=0,輸出數(shù)據(jù)線呈高阻狀態(tài)。時(shí)序如下圖所示:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254源代碼1.Verilog源代碼,dataCollect.vmodule dataCollect(sysclk, rst, adda, addb, addc, start, oe, ????????datain, 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] counter1;????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;?????parameter 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了,可以使用了,按照為器件分配的引腳進(jìn)行連線,系統(tǒng)時(shí)鐘輸入連1KMHZ,可以旋轉(zhuǎn)電位器以改變輸入電壓,此時(shí)可觀察到數(shù)據(jù)管上數(shù)據(jù)變化。FPGA,融入其中,樂趣無窮。。。。
評(píng)論
查看更多