文為明德?lián)P原創(chuàng)及錄用文章,轉(zhuǎn)載請(qǐng)注明出處!
1.1 總體設(shè)計(jì)
1.1.1 概述
學(xué)習(xí)了明德?lián)P至簡(jiǎn)設(shè)計(jì)法和明德?lián)P設(shè)計(jì)規(guī)范,本人用FPGA設(shè)計(jì)了一個(gè)測(cè)距系統(tǒng)。該系統(tǒng)采用超聲波進(jìn)行測(cè)量距離再在數(shù)碼管上顯示。在本案例的設(shè)計(jì)過程中包括了超聲波的驅(qū)動(dòng)、三線式數(shù)碼管顯示等技術(shù)。經(jīng)過逐步改進(jìn)、調(diào)試等一系列工作后,最終完成了此設(shè)計(jì),并進(jìn)行上板驗(yàn)證,下面將完整的設(shè)計(jì)記錄與大家分享。
1.1.2 設(shè)計(jì)目標(biāo)
此系統(tǒng)將實(shí)時(shí)顯示前方障礙與裝置之間的距離。
1.1.3 系統(tǒng)結(jié)構(gòu)框圖
系統(tǒng)結(jié)構(gòu)框圖如下所示:

1.1.4 模塊功能
hc_sr04模塊實(shí)現(xiàn)功能:
該模塊通過控制觸發(fā)信號(hào)trig(10us的TTL)使內(nèi)部循環(huán)發(fā)出8個(gè)40KHZ脈沖即驅(qū)動(dòng)超聲波,接收回響信號(hào)echo,通過echo得到距離。
顯示模塊實(shí)現(xiàn)功能:
該模塊完成了對(duì)所測(cè)距離通過數(shù)碼管對(duì)其顯示。
1.1.5頂層信號(hào)

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模塊設(shè)計(jì)
1.2.1 接口信號(hào)

1.2.2 設(shè)計(jì)思路
我們只需要提供一個(gè)短期的10uS脈沖觸發(fā)信號(hào)trig,該模塊內(nèi)部將發(fā)出8個(gè)40kHz周期電平并檢測(cè)回波,一旦檢測(cè)到有回波信號(hào)則輸出回響信號(hào),回響信號(hào)echo是一個(gè)脈沖的寬度成正比的距離變量,可通過發(fā)射信號(hào)到收到的回響信號(hào)時(shí)間間隔可以計(jì)算得到距離。建議測(cè)量周期為60ms以上,以防止發(fā)射信號(hào)對(duì)回響信號(hào)的影響,這里我們采用的是1s測(cè)量一次。
時(shí)鐘計(jì)數(shù)器cnt0:用于計(jì)算 1 秒的時(shí)鐘個(gè)數(shù),加一條件為1,表示一直計(jì)數(shù);結(jié)束條件為數(shù)到 TIME_1S ,表示數(shù)到 1 秒就清零。
距離計(jì)數(shù)器 h_cnt:用于計(jì)算flag為高電平的寬度的時(shí)間,如果flag為1,h_cnt就加一;每完成1秒計(jì)數(shù)后h_cnt就變?yōu)?,此外h_cnt等于h_cnt。
模塊時(shí)序圖

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'b1;
end
end
assign add_cnt0 = 1;
assign end_cnt0 = add_cnt0 && cnt0 == TIME_1S - 1;
assign trig = (cnt0>=500&&cnt0<1000)?1:0;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'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'b0)begin
distance <= 0;
end
else if(add_cnt0 && cnt0 == 45_000_000-1)begin
distance <= h_cnt*34/10000;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'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'b0)begin
s_s <= 0;
end
else begin
s_s <= (distance/10)%10;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'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'b0)begin
s_q <= 0;
end
else begin
s_q <= (distance/1000)%10;
end
end
endmodule
1.3 顯示模塊設(shè)計(jì)
1.3.1接口信號(hào)

1.3.2設(shè)計(jì)思路
該模塊對(duì)數(shù)碼管的位選信號(hào)sel每隔1ms的時(shí)間移位一次,也就是1ms循環(huán)亮一個(gè)燈,由于1ms的頻率肉眼觀察不出,我們看到的就是4個(gè)燈全亮。
對(duì)輸入距離distance進(jìn)行求余處理,得到每一位的數(shù)據(jù),通過case語句,讓每一位數(shù)據(jù)形成段選信號(hào),通過位選信號(hào)的控制顯示在對(duì)應(yīng)的數(shù)碼管上。
1.3.3參考代碼
module seg_disp(
clk ,
rst_n ,
segment_data,
segment ,
seg_sel
);
parameter ZERO = 8'b1100_0000 ;
parameter ONE = 8'b1111_1001 ;
parameter TWO = 8'b1010_0100 ;
parameter THREE = 8'b1011_0000 ;
parameter FOUR = 8'b1001_1001 ;
parameter FIVE = 8'b1001_0010 ;
parameter SIX = 8'b1000_0010 ;
parameter SEVEN = 8'b1111_1000 ;
parameter EIGHT = 8'b1000_0000 ;
parameter NINE = 8'b1001_0000 ;
input clk ;
input rst_n ;
input [31:0] segment_data ;
output [7:0 ] segment ;
output [7:0 ] seg_sel ;
reg [7:0 ] segment ;
reg [7:0 ] seg_sel ;
reg [10:0] delay ;
reg [3:0 ] delay_time ;
wire add_delay_time ;
wire end_delay_time ;
wire add_delay ;
wire end_delay ;
wire [3:0 ] segment_tmp ;
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
delay <= 0;
end
else if(add_delay) begin
if(end_delay)
delay <= 0;
else
delay <= delay+1 ;
end
end
assign add_delay = 1;
assign end_delay = add_delay && delay == 2000-1 ;
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
delay_time <= 0;
end
else if(add_delay_time) begin
if(end_delay_time)
delay_time <= 0;
else
delay_time <= delay_time+1 ;
end
end
assign add_delay_time = end_delay;
assign end_delay_time = add_delay_time && delay_time == 8-1 ;
assign segment_tmp = segment_data[(1+delay_time)*4-1 -:4];
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
segment <= ZERO;
end
else begin
case(segment_tmp)
4'd0:segment <= ZERO;
4'd1:segment <= ONE ;
4'd2:segment <= TWO ;
4'd3:segment <= THREE;
4'd4:segment <= FOUR ;
4'd5:segment <= FIVE ;
4'd6:segment <= SIX ;
4'd7:segment <= SEVEN;
4'd8:segment <= EIGHT;
4'd9:segment <= NINE ;
default:begin
segment <= segment;
end
endcase
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
seg_sel <= 8'b1111_1111;
end
else begin
seg_sel <= ~(8'b1<<delay_time);
end
end
endmodule
1.4 效果和總結(jié)
上板驗(yàn)證效果



在這個(gè)設(shè)計(jì)中,使用明德?lián)P的至簡(jiǎn)設(shè)計(jì)法,讓我的思路非常清晰,邏輯非常嚴(yán)謹(jǐn),雖然沒有做到一遍成功,但在調(diào)試過程中我都比較快速的找到問題,并快速解決。對(duì)于學(xué)習(xí)FPGA的同學(xué),我非常推薦使用明德?lián)P至簡(jiǎn)設(shè)計(jì)法和明德?lián)P模塊進(jìn)行學(xué)習(xí)和設(shè)計(jì)。
教學(xué)視頻和工程源代碼請(qǐng)移步明德?lián)P論壇學(xué)習(xí)!
溫馨提示:明德?lián)P2023推出了全新課程——邏輯設(shè)計(jì)基本功修煉課,降低學(xué)習(xí)FPGA門檻的同時(shí),增加了學(xué)習(xí)的趣味性,并組織了考試贏積分活動(dòng)
http://www.cqqtmy.cn/ffkc/415.html
(點(diǎn)擊→了解課程詳情?)感興趣請(qǐng)聯(lián)系易老師:13112063618(微信同步)