基于FPGA的數字示波器的設計_第1頁
已閱讀5頁,還剩37頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

題目:基于FPGA的數字示波器的設計 圖4-8液晶畫點流程圖如圖4-8所示為畫點的流程圖,通過不斷的改變連續的地址進行畫點,這樣這些點就組成了一條線。本設計上主要用到的是畫垂直的線,既x軸的地址不變,連續的改變y軸的地址進行畫點。示波器的波形的更新是采用先擦除上一次的一個片段,再畫上新的波形的片段來實現波形圖像的更新[12]。當處理的速度足夠快的時候看起來就像是整個波形是一起更新的。4.2.3同步觸發程序的設計圖4-9同步觸發程序流程圖本設計的觸發方式采用的是軟件同步觸發的方式,程序流程圖如圖4-9所示。既當讀完FIFO的數據的時候,對每個數據與一個觸發的閥值進行比較。當為上升沿觸發的時候,前一個數據小于閥值,后一個數據大于閥值表示此處產生了上升沿,然后從此處開顯示波形。當為下降沿觸發的時候,前一個數據大于閥值,后一個數據小與閥值表示此處產生了下降沿,然后從此處開顯示波形。當比較到剩余的數據不足以顯示一屏時,則放棄本組數據,重新從FIFO中讀取數據再重復這個過程,直到產生觸發為止。第5章系統的調試5.1硬件的調試圖5-SEQ圖5-\*ARABIC1系統實物圖 在前端信號處理電路焊接完成后,先用萬用表檢測電源兩端看有無短路,檢查通過后根據原理圖檢測各個芯片的引腳有無短路,檢查通過后進行上電檢查。觀察各個芯片的電源電壓是否正常。 上述檢查都完成后接入信號發生器和示波器調試電路的工作性能。 在實驗中發現輸出的波形噪聲非常大,輸出的信號中帶有很大的鋸齒波,經過排查是電源和電壓基準的噪聲引起的,在各個運放的電源端和電壓基準TL431的輸出端并入10uf的電容后改善效果十分明顯,電源的紋波降到了30mv左右。波形輸出后無明顯噪聲。 ADC的測試,用FPGA輸出1KHz的時鐘信號,前端不接入信號,使用FPGA讀取ADC的輸出數據,在數碼管上進行顯示。前端不接信號ADC采樣到的是2.5V的中位基線電壓,顯示的AD值應為120左右。測試中實際采樣的數據為118會有正負兩個字的跳動,表明ADC是正常工作的。5.2軟件的調試5.2.1FPGA程序的調試首先進行的是時鐘選擇電路的調試,采用FPGA開發板上的四個撥碼開關做為輸出通道的選擇,經過測試能準確的輸出1.25KHz到50MHz的時鐘信號。然后要進行的是FIFO的測試,這部分的測試要用到STM32跟FPGA一起來調試,先讓STM32向FIFO寫入數據,在從其中讀出數據跟寫入的進行比較,如果相同則表明FIFO正常。經測試FIFO能正常的工作。最后調試的是串入并出的程序,這部分的測試也要用到STM32跟FPGA一起來調試,先讓STM32根據設計的時序向FPGA寫入數據然后再觀察輸出的數據接到LED上,觀察LED的亮滅來判斷輸出的是否正常。經測試這部分功能正常。5.2.2STM32程序的調試 STM32程序的調試主要為波形的顯示程序和同步觸發程序的調試,由于液晶的驅動程序和按鍵的掃描程序都是以前寫好的模塊,這里就不在寫調試過程。 波形顯示程序的調試的過程為先用MTALAB生成幾個頻率不同正弦波的數據,再用讓STM32去顯示這幾組波形,每個波形保持1S,就切換另一個波形,看顯示是否正常。在測試的過程中也有遇到了一些問題,比如說最開始我沒有讓波形保持一定的時間,這個有時會有波形顯示非常的暗,后來發現是刷新過快的原因,在增加了波形保持后,問題得到解決。 在完成了波形顯示的調試后就可以進行同步觸發的調試了。調試過程中要先設置一定的觸發電平,我設置的是過零點觸發。還是使用那幾組數據去測試,觀察波形顯示的穩定程度。在實際中發現觸發不夠穩定,經排查發現時觸發電平的原因,在觸發的判斷中不能直接判斷這個設置的閥值,應該在這個閥值的基礎上再設置一個窗口,即以閥值為基礎設置一個判斷的區間,這樣判斷上升或下降沿會更穩定,不會有誤觸發。經過改善后觸發穩定性得到很大的提升。5.3整體的調試測試儀器:信號發生器UTG9020D示波器UTD2052CEL。1、測試信號為幅值5V的方波信號。表5-SEQ表5-\*ARABIC1幅值為5V的信號頻率的測量信號頻率10Hz100Hz1000Hz10000Hz100000Hz1000000Hz測量值9Hz98Hz999Hz9990Hz99990Hz999950Hz誤差10%2%0.1%0.1%0.01%0.005%由表5-1可知在測量小于1KHz的低頻信號時誤差較大,這是由于采用計數法測頻,導致在測低頻信號時由于門閘信號的原因會導致有較大的誤差。2、測試信號為頻率100KHz的方波。表5-SEQ表5-\*ARABIC2100KHz頻率下信號幅值的測量信號幅值1V2V3V4V5V測量值1.05V2.10V3.02V3.93V4.95V誤差5%5%0.6%1.75%1%信號幅值6V7V8V9V10V測量值5.83V6.86V7.77v8.729.65V誤差2.8%2%2.9%3.1%3.5%由表5-2可知在測量3V到5V時的誤差較小,在測量6V到10V的時候誤差較大,在測量1V到2V的信號時的誤差最大。經過排查是由于程控放大器的放大倍數與設定的存在差異和在信號輸入的時候耦合的有一定的壓降。圖5-2測試顯示波形 圖5-3UTD2052CEL示波器顯示波形如圖5-2和圖5-3為在輸入幅值為5V頻率100KHz的正弦波信號時本設計和UTD2052CEL示波器顯示波形的對比。可以看出系統工作穩定,各項參數基本一致,驗證了本設計的對信號的處理的正確性。

第6章結論本設計以FPGA為核心,STM32為輔助控制完成了數字示波器的設計,本設計在硬件部分完成了前端信號調理電路和AD轉換電路,實現了的對輸入模擬信號的處理。FPGA通過對采樣時鐘的控制實現了對ADC采樣率的控制,通過STM32對采樣到的數據進行處理后在液晶顯示器上重構出信號波形。經過測試之后設計中對頻率的測量,信號峰峰值得測量均達到了設計目標。不過本設計只是初步完成了一個示波器的基本功能,還有許多有用的功能如對信號進行單次的捕獲,對信號如上升時間的測量等功能都還沒有實現,需要以后進一步的完善。本設計中由于采用了軟件同步觸發所以觸發的效果不如硬件觸發的好,在長時間的測試過程中會出現觸發不穩定的情況,這在以后也需要改進。最后經過了本次設計的制作,我對大學期間所學的知識有了更直觀的了解,在模擬電路的設計制作過程中我了解了電源的噪聲對放大電路的影響,也對電源對電路的影響有了更加深刻的了解。本設計中的程控放大電路由運放和繼電器組成,控制簡單,十分適合在一些低成本的場合應用。

致謝 在一做畢業設計的一個多月中,我學到了很多,對自己的大學所學的知識做了一次梳理。在制作的過程中遇到了很多的困難,但是在同學和老師的幫助下一個個的被解決了。在此特別感謝我的指導老師——賴義漢老師,他在此過程中給了我悉心的指導,讓我感受到了他的學識淵博,視野廣闊。 同時還要感謝一下阿莫電子論壇的魏坤同學和其他壇友,要不是有魏坤同學的開源示波器項目和壇友們的各種討論。我也不可能在設計的初期規避了很多的錯誤,也在后期的制作工程中發現的一些問題也可以在他們的帖子中找到解決的辦法。最后,我再一次的感謝在本次設計中給予我幫助的師長和朋友們,沒有你們的幫助我不可能順利的完成此次設計。

參考文獻[1]孫建風.數字存儲示波器的原理,特點及發展動態[J].宇航計測量,1996,(6):52-61.[2]肖曉萍.電子測量儀器[M].電子工業出版社,2005.[3]褚振勇.翁木云.FPGA設計及應用[M].西安:西安電子科技大學出版社,2002.[4]龔世耀.單片機數字信息采集系統[J].南京郵電學院報,1994,(4):81-86.[5]蘇建加,廖聰裕,魯錦濤.基于FPGA的數字存儲式示波器設計[J].河北農機,2012,(3):G2-G3.[6]周金剛,左超,崔長生.基于FPGA的數字存儲示波器[J].電子工程師,2008,34(5):15-17.[7]魏坤.DIY數字示波器[J].無線電,2009,(1):41-43.[8]E.A.Parr.怎樣使用運算放大器[M].人民郵電出版社,1983.8.[9]夏宇聞.Verilog數字系統設計教程[M].北京:北京航空航天大學出版社,2003[10]潘松,黃繼業.EDA技術實用教程[M].第三版.北京:科學出版社,2009.[11]杜生海.FPGA設計實戰[M].人民郵電大學出版社,2009.6.[12]葉梵,周建明,張沁川.高速數字存儲示波器實現技術[J].電子測量與儀器學報,2005,19(3):42-45.

附錄一前端信號處理原理圖STM32原理圖FPGA原理圖

附錄二FPGA程序二分頻Verilog程序moduleDIV_2(clk,rst,clk_out); inputclk;//輸入時鐘 inputrst;//復位信號 outputclk_out;//輸出時鐘 regclk_out; //二分頻 always@(posedgeclkornegedgerst) if(!rst) clk_out<=1'b0; else clk_out<=~clk_out;endmodule五分頻Verilog程序moduleDIV_5(clk,rst,clk_out); inputclk,rst; outputclk_out; regp_clk;//上升沿分頻時鐘 regn_clk;//下降沿分頻時鐘 reg[2:0]p_cnt;//上升沿計數器 reg[2:0]n_cnt;//下降沿計數器 always@(posedgeclkornegedgerst)//上升沿計數 begin if(!rst) p_cnt<=3'd0; elseif(p_cnt==3'd4) p_cnt<=3'd0; else p_cnt<=p_cnt+3'd1; end always@(posedgeclkornegedgerst)//上升沿分頻時鐘輸出 begin if(!rst) p_clk<=1'b0; elseif(p_cnt<2) p_clk<=1'b1; else p_clk<=1'b0; endalways@(negedgeclkornegedgerst)//下降沿計數 begin if(!rst) n_cnt<=3'd0; elseif(n_cnt==3'd4) n_cnt<=3'd0; else n_cnt<=n_cnt+3'd1; end //下降沿分頻時鐘輸出 always@(negedgeclkornegedgerst) begin if(!rst) n_clk<=1'b0; elseif(n_cnt<2) n_clk<=1'b1; else n_clk<=1'b0; end assignclk_out=p_clk|n_clk;endmodule十分頻Verilog程序moduleDIV_10(clk,rst,clk_out); inputclk,rst; outputclk_out; regclk_out; reg[2:0]cnt; always@(posedgeclkornegedgerst) begin if(!rst) begin cnt<=3'd0; clk_out<=1'b0; end elseif(cnt==3'd4) begin clk_out<=~clk_out; cnt<=3'd0; end else cnt<=cnt+3'd1; endendmodule時鐘選擇模塊Verilog程序moduleDIV_MUX(ch0,ch1,ch2,ch3,clk_out,clk50M,clk25M,clk12_5M,clk5M,clk2_5M,clk1_25M,clk500k,clk250k,clk125k,clk50k,clk25k,clk12_5k,clk5k,clk2_5k,clk1_25k,clk500); inputch0,ch1,ch2,ch3;//時鐘輸出通道選擇 //輸入時鐘信號 inputclk50M,clk25M,clk12_5M,clk5M,clk2_5M,clk1_25M,clk500k; inputclk250k,clk125k,clk50k,clk25k,clk12_5k,clk5k,clk2_5k,clk1_25k,clk500; //輸出時鐘 outputclk_out; regclk_out; always@(*) begin case({ch3,ch2,ch1,ch0}) 5'd15:clk_out<=clk50M; 5'd14:clk_out<=clk25M; 5'd13:clk_out<=clk12_5M; 5'd12:clk_out<=clk5M; 5'd11:clk_out<=clk2_5M; 5'd10:clk_out<=clk1_25M; 5'd9:clk_out<=clk500k; 5'd8:clk_out<=clk250k; 5'd7:clk_out<=clk125k; 5'd6:clk_out<=clk50k; 5'd5:clk_out<=clk25k; 5'd4:clk_out<=clk12_5k; 5'd3:clk_out<=clk5k; 5'd2:clk_out<=clk2_5k; 5'd1:clk_out<=clk1_25k; 5'd0:clk_out<=clk500; default:clk_out<=1'b0; endcase endendmoduleADC_FIFO時鐘輸出模塊Verilog程序moduleADC_FIFO_CLK(clk_50M,rst,ch0,ch1,ch2,ch3,clk_out); inputclk_50M,rst,ch0,ch1,ch2,ch3; outputclk_out; wireclk_50M,clk25M,clk12_5M,clk5M,clk2_5M,clk1_25M,clk500k; wireclk250k,clk125k,clk50k,clk25k,clk12_5k,clk5k,clk2_5k;wireclk1_25k,clk500,clk_out;DIV_MUXu0( .ch0(ch0), .ch1(ch1), .ch2(ch2), .ch3(ch3), .clk_out(clk_out), .clk50M(clk_50M), .clk25M(clk25M), .clk12_5M(clk12_5M), .clk5M(clk5M), .clk2_5M(clk2_5M), .clk1_25M(clk1_25M), .clk500k(clk500k), .clk250k(clk250k), .clk125k(clk125k), .clk50k(clk50k), .clk25k(clk25k), .clk12_5k(clk12_5k), .clk5k(clk5k), .clk2_5k(clk2_5k), .clk1_25k(clk1_25k), .clk500(clk500)); DIV_2u1(.clk(clk_50M),.rst(rst),.clk_out(clk25M)); DIV_2u2(.clk(clk25M),.rst(rst),.clk_out(clk12_5M)); DIV_10u3(.clk(clk_50M),.rst(rst),.clk_out(clk5M)); DIV_10u4(.clk(clk25M),.rst(rst),.clk_out(clk2_5M)); DIV_10u5(.clk(clk12_5M),.rst(rst),.clk_out(clk1_25M)); DIV_10u6(.clk(clk5M),.rst(rst),.clk_out(clk500k)); DIV_2u7(.clk(clk500k),.rst(rst),.clk_out(clk250k)); DIV_10u8(.clk(clk1_25M),.rst(rst),.clk_out(clk125k)); DIV_10u9(.clk(clk500k),.rst(rst),.clk_out(clk50k)); DIV_2u10(.clk(clk50k),.rst(rst),.clk_out(clk25k)); DIV_10u11(.clk(clk125k),.rst(rst),.clk_out(clk12_5k)); DIV_10u12(.clk(clk50k),.rst(rst),.clk_out(clk5k)); DIV_10u13(.clk(clk25k),.rst(rst),.clk_out(clk2_5k)); DIV_10u14(.clk(clk12_5k),.rst(rst),.clk_out(clk1_25k)); DIV_10u15(.clk(clk5k),.rst(rst),.clk_out(clk500));Endmodule串入并出模塊Verilog程序moduleReg595(clk,lck,rst,din,ch0,ch1,ch2,ch3,q); inputclk;//數據輸入時鐘 inputlck;//鎖存信號 inputrst;//復位信號 inputdin; outputch0,ch1,ch2,ch3; output[5:0]q; regch0,ch1,ch2,ch3; reg[5:0]q; reg[9:0]qt; always@(posedgeclkornegedgerst) begin if(!rst) begin qt<=10'd0; end else begin qt<={qt[8:0],din}; end end always@(posedgelckornegedgerst) begin if(!rst) begin {q[5:0],ch3,ch2,ch1,ch0}<=10'd0; end else begin {q[5:0],ch3,ch2,ch1,ch0}<=qt; end endendmoduleFIFOTestbench文件Verilog程序timescale1ns/1ns`defineW_CLK20`defineR_CLK40modulefifo_tb; reg[7:0]data; reg rdclk,rdreq,wrclk,wrreq; wire[7:0]q; wirewrfull; integeri;fifou1(.data(data), .rdclk(rdclk), .rdreq(rdreq), .wrclk(wrclk), .wrreq(wrreq), .q(q), .wrfull(wrfull));initialbegin rdclk=0;wrclk=0; rdreq=0;wrreq=0; i=0;#(`W_CLK); wrreq=1; for(i=0;i<1024;i=i+1)begin data=i;#(`W_CLK*2+1); end wrreq=0;rdreq=1; for(i=0;i<1024;i=i+1)begin rdclk=1;#(`R_CLK*2+1); rdclk=0;#(`R_CLK*2+1); end rdreq=0;wrreq=1; for(i=0;i<1024;i=i+1)begin data=i;#(`W_CLK*2+1); end wrreq=0;rdreq=1; for(i=0;i<1024;i=i+1)begin rdclk=1;#(`R_CLK*2+1); rdclk=0;#(`R_CLK*2+1); end rdreq=0; $stop;endalways#(`W_CLK)wrclk=~wrclk;endmodule附錄三STM32程序main.c#include"stm32f10x.h"#include"delay.h"#include"key.h"#include"display.h"#include"TFTLCD.h"#include"draw.h"#include"fifo.h"#include"TRIG.H"#include"freq.h"u8fifo[FIFO_SIZE];intmain(void){ SystemInit(); key_Init(); w595_init(); TFT_init(); gui(); fifo_init(); Freq_init(); while(1) { if(READ_FIFO(fifo)) { if(Trig(1)) { Signal_Data(); dis_signal(&fifo[TRIG_UNM],YELLOW); } } }}TRIG.C#include"TRIG.H"#include"key.h"#include"draw.h"#include"TFTLCD.h"#include"fifo.h"#include"display.h"u16TRIG_UNM=0;u8FIFO_DATA_TMP[300];//波形數據externu8fifo[FIFO_SIZE];//顯示數據u32V_data;u8min_v,max_v;;externu8v_div;//定義在display.cu16v[12]={5000,2000,1000,500,200,100,50,20,10,5,2,1};//觸發函數:Trig_mode0下降沿觸發1上升沿觸發u8Trig(u8Trig_mode){ u8flag=0; while((TRIG_UNM<(FIFO_SIZE-350))) { if(Trig_mode)//上升沿觸發 { if(fifo[TRIG_UNM]<(TRIG-TRIG_window)&&(flag==0))flag=1; if(fifo[TRIG_UNM]>(TRIG+TRIG_window)&&(flag==1))return1;} else//下降沿觸發 { if(fifo[TRIG_UNM]>(TRIG+TRIG_window)&&(flag==0))flag=1; if(fifo[TRIG_UNM]<(TRIG-TRIG_window)&&(flag==1))return 1; } TRIG_UNM++; } TRIG_UNM=0; return0;}voidSignal_Data(void){ u16i,dat; min_v=fifo[TRIG_UNM]; max_v=fifo[TRIG_UNM]; for(i=TRIG_UNM;i<FIFO_SIZE;i++) { dat=fifo[i]; if(dat>max_v)max_v=dat; elseif(dat<min_v)min_v=dat; dat=(u8)(217-((dat*76/100))); if(dat>MAX_Y)dat=MAX_Y; if(dat<MIN_Y)dat=MIN_Y; fifo[i]=dat; } V_data=(max_v-min_v)*78*v[v_div]/10000; display_Vpp(V_data);}波形顯示函數voiddis_signal(u8*fifo_data,u16color){ u16i,j=0; u8c1,c2,d1,d2; d1=*fifo_data; c1=FIFO_DATA_TMP[0]; for(i=MIN_X;i<MAX_X;i++,j++) { c2=FIFO_DATA_TMP[j+1]; col_line(i,c1,c2,BLACK); c1=c2; d2=*(fifo_data+i+1); col_line(i,d1,d2,color); FIFO_DATA_TMP[j]=d1; d1=d2; } delay_cnt=20;//延時100毫秒 rectangle(10,20,310,220,WHITE); gui_wang_ge(10,20,310,220,WHITE); col_wang_ge(11,20,220,WHITE); col_wang_ge(12,20,220,WHITE); col_wang_ge(308,20,220,WHITE); col_wang_ge(309,20,220,WHITE); col_wang_ge(159,20,220,WHITE); col_wang_ge(160,20,220,WHITE); col_wang_ge(161,20,220,WHITE); row_wang_ge(10,310,21,WHITE); row_wang_ge(10,310,22,WHITE); row_wang_ge(10,310,119,WHITE); row_wang_ge(10,310,120,WHITE); row_wang_ge(10,310,121,WHITE); row_wang_ge(10,310,218,WHITE); row_wang_ge(10,310,219,WHITE);}讀FIFO函數u8READ_FIFO(u8*FIFO_Dat){ u16i=0; if((WRFULL==GPIO_Pin_8)&&(delay_cnt==0)) { SET_RDREQ; for(i=0;i<FIFO_SIZE;i++) { SET_RDCLK; *FIFO_Dat=FIFO_DATA; FIFO_Dat++; CLR_RDCLK; } CLR_RDREQ; return1; } return0;}測頻函數voidTIM1_UP_IRQHandler(void){ if(TIM_GetITStatus(TIM1,TIM_IT_Update)!=RESET) { freq_cnt++; TIM_ClearITPendingBit(TIM1,TIM_IT_Update); }}voidTIM2_IRQHandler(void){ if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET) { TIM1->CR1&=0xfffe; freq_dat=(u32)TIM_GetCounter(TIM1); freq_dat=(freq_cnt<<16)|freq_dat; freq_cnt=0; TIM_SetCounter(TIM1,0x0000); TIM1->CR1|=0x0001; display_freq(freq_dat); TIM_ClearITPendingBit(TIM2,TIM_IT_Update); }}按鍵掃描和服務函數u8Scan_Key(void){ u8key_return=0; //V_DIV加 if(Key_DIV_P==1) { key_p_cnt=0; key_p_flag=0; } else { if(key_p_flag==0) { key_p_cnt++; if(key_p_cnt>KEY_CNT_END) { key_p_flag=1; key_p_cnt=0; key_return=1; } } } //V_DIV減 if(Key_DIV_N==1) { key_n_cnt=0; key_n_flag=0; } else {

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論