本文為明德揚原創及錄用文章,轉載請註明出處!
1.1 總體設計
1.1.1 概述
學習了明德揚至簡設計法和明德揚設計規範,本人用FPGA設計了一個測距系統。該系統採用超聲波進行測量距離再在數碼管上顯示。在本案例的設計過程中包括了超聲波的驅動、三線式數碼管顯示等技術。經過逐步改進、調試等一系列工作後,最終完成了此設計,並進行上板驗證,下面將完整的設計記錄與大家分享。
1.1.2 設計目標
此系統將實時顯示前方障礙與裝置之間的距離。
1.1.3 系統結構框圖
系統結構框圖如下所示:
1.1.4 模塊功能
hc_sr04模塊實現功能:
該模塊通過控制觸發信號trig(10us的TTL)使內部循環發出8個40KHZ脈衝即驅動超聲波,接收回響信號echo,通過echo得到距離。
顯示模塊實現功能:
該模塊完成了對所測距離通過數碼管對其顯示。
1.1.5頂層信號
1.1.6頂層代碼
module top( clk , rst_n , echo , trig , sel, seg ); input clk ; input rst_n ; input echo ; output trig ; wire [3:0] s_g ; wire [3:0] s_s ; wire [3:0] s_b ; wire [3:0] s_q ; output [7:0] sel ; output [7:0] seg ; hc_sr04 hc_sr04_1( .clk (clk) , .rst_n (rst_n) , .echo (echo) , .trig (trig) , .s_g (s_g ), .s_s (s_s ), .s_b (s_b ), .s_q (s_q ) ); seg_disp u_seg_disp( .clk (clk ), .rst_n (rst_n), .segment_data({s_q,s_b,s_s,s_g}), .segment (seg ), .seg_sel (sel ) ); endmodule
1.2 hc_sr04模塊設計
1.2.1 接口信號
1.2.2 設計思路
我們只需要提供一個短期的10uS脈衝觸發信號trig,該模塊內部將發出8個40kHz周期電平並檢測回波,一旦檢測到有回波信號則輸出迴響信號,迴響信號echo是一個脈衝的寬度成正比的距離變量,可通過發射信號到收到的迴響信號時間間隔可以計算得到距離。建議測量周期為60ms以上,以防止發射信號對迴響信號的影響,這裡我們採用的是1s測量一次。
時鐘計數器cnt0:用於計算 1 秒的時鐘個數,加一條件為1,表示一直計數;結束條件為數到 TIME_1S ,表示數到 1 秒就清零。
距離計數器 h_cnt:用於計算flag為高電平的寬度的時間,如果flag為1,h_cnt就加一;每完成1秒計數後h_cnt就變為0,此外h_cnt等於h_cnt。
模塊時序圖
1.2.3 參考代碼
module hc_sr04( clk , rst_n , echo , trig , s_g , s_s , s_b , s_q ); parameter DATA_W = 14 ; parameter TIME_1S = 50_000_000; input clk ; input rst_n ; input echo ; output trig ; output[ 3:0] s_g ; output[ 3:0] s_s ; output[ 3:0] s_b ; output[ 3:0] s_q ; wire trig ; reg [ 3:0] s_g ; reg [ 3:0] s_s ; reg [ 3:0] s_b ; reg [ 3:0] s_q ; reg [DATA_W-1:0] distance; reg [25:0] cnt0 ; reg [20:0] h_cnt ; reg echo_2 ; reg echo_1 ; wire add_cnt0; wire end_cnt0; wire flag_h ; wire flag_l ; always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt0 <= 0; end else if(add_cnt0)begin if(end_cnt0) cnt0 <= 0; else cnt0 <= cnt0 + 1&39;b0)begin echo_1 <= 0; echo_2 <= 0; end else begin echo_1 <= echo ; echo_2 <= echo_1; end end always @(posedge clk or negedge rst_n)begin if(!rst_n)begin h_cnt <= 0; end else if(add_h_cnt)begin if(end_h_cnt) h_cnt <= 0; else h_cnt <= h_cnt + 1; end else if(end_cnt0)begin h_cnt <= 0; end end assign add_h_cnt = echo_2; assign end_h_cnt = 0 ; always @(posedge clk or negedge rst_n)begin if(rst_n==1&39;b0)begin s_g <= 0; end else begin s_g <= distance%10; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1&39;b0)begin s_b <= 0; end else begin s_b <= (distance/100)%10; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1&39;b1100_0000 ;parameter ONE = 8&39;b1010_0100 ;parameter THREE = 8&39;b1001_1001 ;parameter FIVE = 8&39;b1000_0010 ;parameter SEVEN = 8&39;b1000_0000 ;parameter NINE = 8&39;b0)begin segment <= ZERO; end else begin case(segment_tmp) 4&39;d1:segment <= ONE ; 4&39;d3:segment <= THREE; 4&39;d5:segment <= FIVE ; 4&39;d7:segment <= SEVEN; 4&39;d9:segment <= NINE ; default:begin segment <= segment; end endcase endendalways @(posedge clk or negedge rst_n)begin if(rst_n==1&39;b1111_1111; end else begin seg_sel <= ~(8'b1<<delay_time); endendendmodule
1.4 效果和總結
上板驗證效果
在FPGA實驗箱上的效果
在MP801開發板上的效果
在點撥開發板上的效果
在這個設計中,使用明德揚的至簡設計法,讓我的思路非常清晰,邏輯非常嚴謹,雖然沒有做到一遍成功,但在調試過程中我都比較快速的找到問題,並快速解決。對於學習FPGA的同學,我非常推薦使用明德揚至簡設計法和明德揚模塊進行學習和設計。
詳細的教學視頻和工程原始碼請移步明德揚論壇學習!
感興趣的朋友也可以訪問明德揚論壇(http://www.fpgabbs.cn/)進行FPGA相關工程設計學習,也歡迎大家在評論與我進行討論!
也可以看一下我們往期的文章:
《基於FPGA的密碼鎖設計》
《波形相位頻率可調DDS信號發生器》
《基於FPGA的曼徹斯特編碼解碼設計》
《基於FPGA的計程車計費系統》
《數電基礎與Verilog設計》《基於FPGA的頻率、電壓測量》
《基於FPGA的漢明碼編碼解碼設計》
《關於鎖存器問題的討論》
《阻塞賦值與非阻塞賦值》
《參數例化時自動計算位寬的解決辦法》
1.15公司簡介
明德揚是一家專注於FPGA領域的專業性公司,公司主要業務包括開發板、教育培訓、項目承接、人才服務等多個方向。
點撥開發板——學習FPGA的入門之選。
MP801開發板——千兆網、ADDA、大容量SDRAM等,學習和項目需求一步到位。
網絡培訓班——不管時間和空間,明德揚隨時在你身邊,助你快速學習FPGA。
周末培訓班——明天的你會感激現在的努力進取,升職加薪明德揚來助你。
就業培訓班——七大企業級項目實訓,獲得豐富的項目經驗,高薪就業。
專題課程——高手修煉課:提升設計能力;
實用調試技巧課:提升定位和解決問題能力;
FIFO架構設計課:助你快速成為架構設計師;
時序約束、數位訊號處理、PCIE、綜合項目實踐課等你來選。
項目承接——承接企業FPGA研發項目。人才服務——提供人才推薦、人才代培、人才派遣等服務。