記事ディレクトリ
序文
環境
- ハードウェア
DE2-115
HC-SR04 超音波センサー - ソフトウェア
Quartus 18.1
目標の結果
DE2-115 開発ボードを使用して HC-SR04 モジュールを駆動し、測定データを開発ボード上のデジタル管に表示します。
1 実験原理
1.1 超音波の原理
HC-SR04
超音波測距モジュールは、2cm~400cmの非接触距離感知機能を提供でき、測距精度は3mmに達することができ、モジュールには超音波送信機、受信機、制御回路が含まれています。図1にHC-SR04
外観を示しますが、基本的な動作原理は、超音波測距モジュールにトリガ信号を与えると超音波を発し、超音波が物体に照射され反射されるとエコー信号を出力します。トリガ信号とエコー信号の時間差によって判断され、物体の距離がわかります。
モジュールの動作原理は次のとおりです。
- メイン制御デバイスは、10us のパルス信号を Trig ピンに提供します。
- HC-SR04は信号を受信して超音波の送信を開始し、Echoをハイレベルにして戻ってくる超音波の受信準備をします。
- HC-SR04は戻ってきた超音波を受信し、Echoをローレベルに設定します。
- エコーの高レベルの継続時間は、超音波が戻ってくるまでの時間間隔です。
超音波モジュールの前方約 4 メートル以内に障害物がない場合、Trig ピンに 10μs 以上のパルストリガー信号が供給されると、モジュールは内部で 8 つの 40kHz 超音波パルスを送信し、エコーを検出します。エコーピンが受信する信号がハイレベルに達し、それが 38 ミリ秒続くとローレベル状態になるため、38 ミリ秒の値を取得すると、前方に障害物が検出されていないことがわかります。
前方に障害物がある場合、超音波パルスの送信後に信号が反射され、信号を受信するとすぐにエコーピンがローレベル状態に切り替わり、エコーピンがハイレベルに留まる時間が長くなります。レベル状態 信号が送信されて戻ってくるまでにかかる時間です。
1.2 ハードウェアモジュールのタイミング図
上のタイミング図は、10uS を超えるパルス トリガー信号を提供するだけで、モジュールが内部で 8 つの 40kHz サイクル レベルを送信し、エコーを検出することを示しています。エコー信号が検出されると、エコー信号が出力されます。エコー信号のパルス幅は測定された距離に比例します。したがって、信号を送信してからエコー信号を受信するまでの時間間隔から距離を計算できます。計算式: uS/58 = cm または uS/148= = インチ; または: 距離 = 高レベル時間 * 音速 (340M/S) /2; 送信信号の影響を防ぐため、推奨測定期間は 60ms 以上です。エコー信号上で。
1.3 モジュールの説明
DE2-115 のピン割り当ては次のとおりです:
HC-SR04 超音波測距モジュールには 5V の電源が必要で、残りのトリガーとエコーは自由に接続できます。この記事では GPIO[0] と GPIO[1] を使用します。
超音波モジュールの 4 つのピンの機能は次のとおりです。
ピン | 効果 |
---|---|
VCC | 電源ピン、超音波モジュールの動作電圧は 5V です。 |
トリガー | Trigger(トリガー)という言葉の略で、超音波パルスをトリガーするために使用されるピンです。 |
エコー | この端子はハイレベルとローレベルを切り替え、障害物を検知したときに信号が発信されて反射されるまでの時間を示します。 |
GND | アースピン。 |
2つのデザインファイル
2.1 クロックの分周
1us
周期のクロック信号を生成するクロック分周モジュールを定義します。
module clk_div(
input wire Clk , //system clock 50MHz
input wire Rst_n , //reset ,low valid
output wire clk_us //
);
//Parameter Declarations
parameter CNT_MAX = 19'd50;//1us的计数值为 50 * Tclk(20ns)
//Interrnal wire/reg declarations
reg [5:00] cnt ; //Counter
wire add_cnt ; //Counter Enable
wire end_cnt ; //Counter Reset
//Logic Description
always @(posedge Clk or negedge Rst_n)begin
if(!Rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin
cnt <= cnt;
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt >= CNT_MAX - 19'd1;
assign clk_us = end_cnt;
endmodule
2.2 超音波測距
HC-SR04
トリガー測距信号 (trig) を生成するための超音波センサーのトリガー モジュールを実装します。
module hc_sr_trig(
input wire clk_us , //system clock 1MHz
input wire Rst_n , //reset ,low valid
output wire trig //触发测距信号
);
//Parameter Declarations
parameter CYCLE_MAX = 19'd300_000;
//Interrnal wire/reg declarations
reg [18:00] cnt ; //Counter
wire add_cnt ; //Counter Enable
wire end_cnt ; //Counter Reset
//Logic Description
always @(posedge clk_us or negedge Rst_n)begin
if(!Rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin
cnt <= cnt;
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt >= CYCLE_MAX - 9'd1;
assign trig = cnt < 15 ? 1'b1 : 1'b0;
endmodule
HC-SR04
距離を測定し、検出距離データを出力するために使用される超音波センサーのエコー モジュールを定義します(data_o)
module hc_sr_echo(
input wire Clk , //clock 50MHz
input wire clk_us , //system clock 1MHz
input wire Rst_n , //reset ,low valid
input wire echo , //
output wire [18:00] data_o //检测距离,保留3位小数,*1000实现
);
/* S(um) = 17 * t --> x.abc cm */
//Parameter Declarations
parameter T_MAX = 16'd60_000;//510cm 对应计数值
//Interrnal wire/reg declarations
reg r1_echo,r2_echo; //边沿检测
wire echo_pos,echo_neg; //
reg [15:00] cnt ; //Counter
wire add_cnt ; //Counter Enable
wire end_cnt ; //Counter Reset
reg [18:00] data_r ;
//Logic Description
//如果使用clk_us 检测边沿,延时2us,差值过大
always @(posedge Clk or negedge Rst_n)begin
if(!Rst_n)begin
r1_echo <= 1'b0;
r2_echo <= 1'b0;
end
else begin
r1_echo <= echo;
r2_echo <= r1_echo;
end
end
assign echo_pos = r1_echo & ~r2_echo;
assign echo_neg = ~r1_echo & r2_echo;
always @(posedge clk_us or negedge Rst_n)begin
if(!Rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= cnt;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin //echo 低电平 归零
cnt <= 'd0;
end
end
assign add_cnt = echo;
assign end_cnt = add_cnt && cnt >= T_MAX - 1; //超出最大测量范围则保持不变,极限
always @(posedge Clk or negedge Rst_n)begin
if(!Rst_n)begin
data_r <= 'd2;
end
else if(echo_neg)begin
data_r <= (cnt << 4) + cnt;
end
else begin
data_r <= data_r;
end
end //always end
assign data_o = data_r >> 1;
endmodule
2.3 超音波駆動
プラットフォームのマニュアルを確認すると、DE2-115
開発ボードにはビット選択信号が含まれておらず、各セグメント選択信号には個別のピンがあることがわかります。
デジタル チューブ ドライバー モジュールのコードは次のとおりで、入力データ (data_o) を対応するデジタル チューブ ディスプレイに変換するために使用されます。
module seg_driver(
input wire Clk ,
input wire Rst_n ,
input wire [18:0] data_o ,
output wire [6:0] hex1 ,
output wire [6:0] hex2 ,
output wire [6:0] hex3 ,
output wire [6:0] hex4 ,
output wire [6:0] hex5 ,
output wire [6:0] hex6 ,
output wire [6:0] hex7 ,
output wire [6:0] hex8
);
parameter NOTION = 4'd10,
FUSHU = 4'd11;
parameter MAX20us = 10'd1000;
reg [9:0] cnt_20us;
reg [7:0] sel_r;
reg [3:0] number;
reg [6:0] seg_r;
reg [6:0] hex1_r;
reg [6:0] hex2_r;
reg [6:0] hex3_r;
reg [6:0] hex4_r;
reg [6:0] hex5_r;
reg [6:0] hex6_r;
reg [6:0] hex7_r;
reg [6:0] hex8_r;
//20微妙计数器
always @(posedge Clk or negedge Rst_n) begin
if (!Rst_n) begin
cnt_20us <= 10'd0;
end
else if (cnt_20us == MAX20us - 1'd1) begin
cnt_20us <= 10'd0;
end
else begin
cnt_20us <= cnt_20us + 1'd1;
end
end
//单个信号sel_r位拼接约束
always @(posedge Clk or negedge Rst_n) begin
if (!Rst_n) begin
sel_r <= 8'b11_11_11_10;
end
else if (cnt_20us == MAX20us - 1'd1) begin
sel_r <= {
sel_r[6:0],sel_r[7]};
end
else begin
sel_r <= sel_r;
end
end
/*拿到数字*/
always @(*) begin
case (sel_r)
8'b11_11_11_10: number = NOTION ;
8'b11_11_11_01: number = data_o/10_0000 ;
8'b11_11_10_11: number = (data_o%10_0000)/1_0000 ;
8'b11_11_01_11: number = ((data_o%10_0000)%1_0000)/1000 ;
8'b11_10_11_11: number = FUSHU ;
8'b11_01_11_11: number = (((data_o%10_0000)%1_0000)%1000)/100 ;
8'b10_11_11_11: number = ((((data_o%10_0000)%1_0000)%1000)%100)/10 ;
8'b01_11_11_11: number = ((((data_o%10_0000)%1_0000)%1000)%100)%10 ;
default: number = 4'd0 ;
endcase
end
/*通过数字解析出seg值*/
always @(*) begin
case (number)
4'd0 : seg_r = 7'b100_0000;
4'd1 : seg_r = 7'b111_1001;
4'd2 : seg_r = 7'b010_0100;
4'd3 : seg_r = 7'b011_0000;
4'd4 : seg_r = 7'b001_1001;
4'd5 : seg_r = 7'b001_0010;
4'd6 : seg_r = 7'b000_0010;
4'd7 : seg_r = 7'b111_1000;
4'd8 : seg_r = 7'b000_0000;
4'd9 : seg_r = 7'b001_0000;
NOTION : seg_r = 7'b111_1111;
FUSHU : seg_r = 7'b011_1111;
default : seg_r = 7'b111_1111;
endcase
end
always @(*) begin
case (sel_r)
8'b11_11_11_10: hex1_r = seg_r;
8'b11_11_11_01: hex2_r = seg_r;
8'b11_11_10_11: hex3_r = seg_r;
8'b11_11_01_11: hex4_r = seg_r;
8'b11_10_11_11: hex5_r = seg_r;
8'b11_01_11_11: hex6_r = seg_r;
8'b10_11_11_11: hex7_r = seg_r;
8'b01_11_11_11: hex8_r = seg_r;
default: seg_r = seg_r;
endcase
end
assign hex1 = hex1_r;
assign hex2 = hex2_r;
assign hex3 = hex3_r;
assign hex4 = hex4_r;
assign hex5 = hex5_r;
assign hex6 = hex6_r;
assign hex7 = hex7_r;
assign hex8 = hex8_r;
endmodule
3 実験による検証
3.1 コンパイル
以下に示すように、RTL ゲート レベルの回路を表示します。
3.3 ハードウェアテスト
ピンバインディング:
package require ::quartus::project
set_location_assignment PIN_Y2 -to Clk
set_location_assignment PIN_M23 -to Rst_n
set_location_assignment PIN_AC15 -to echo
set_location_assignment PIN_AB22 -to trig
set_location_assignment PIN_AA14 -to hex1[6]
set_location_assignment PIN_AG18 -to hex1[5]
set_location_assignment PIN_AF17 -to hex1[4]
set_location_assignment PIN_AH17 -to hex1[3]
set_location_assignment PIN_AG17 -to hex1[2]
set_location_assignment PIN_AE17 -to hex1[1]
set_location_assignment PIN_AD17 -to hex1[0]
set_location_assignment PIN_AC17 -to hex2[6]
set_location_assignment PIN_AA15 -to hex2[5]
set_location_assignment PIN_AB15 -to hex2[4]
set_location_assignment PIN_AB17 -to hex2[3]
set_location_assignment PIN_AA16 -to hex2[2]
set_location_assignment PIN_AB16 -to hex2[1]
set_location_assignment PIN_AA17 -to hex2[0]
set_location_assignment PIN_AH18 -to hex3[6]
set_location_assignment PIN_AF18 -to hex3[5]
set_location_assignment PIN_AG19 -to hex3[4]
set_location_assignment PIN_AH19 -to hex3[3]
set_location_assignment PIN_AB18 -to hex3[2]
set_location_assignment PIN_AC18 -to hex3[1]
set_location_assignment PIN_AD18 -to hex3[0]
set_location_assignment PIN_AE18 -to hex4[6]
set_location_assignment PIN_AF19 -to hex4[5]
set_location_assignment PIN_AE19 -to hex4[4]
set_location_assignment PIN_AH21 -to hex4[3]
set_location_assignment PIN_AG21 -to hex4[2]
set_location_assignment PIN_AA19 -to hex4[1]
set_location_assignment PIN_AB19 -to hex4[0]
set_location_assignment PIN_Y19 -to hex5[6]
set_location_assignment PIN_AF23 -to hex5[5]
set_location_assignment PIN_AD24 -to hex5[4]
set_location_assignment PIN_AA21 -to hex5[3]
set_location_assignment PIN_AB20 -to hex5[2]
set_location_assignment PIN_U21 -to hex5[1]
set_location_assignment PIN_V21 -to hex5[0]
set_location_assignment PIN_W28 -to hex6[6]
set_location_assignment PIN_W27 -to hex6[5]
set_location_assignment PIN_Y26 -to hex6[4]
set_location_assignment PIN_W26 -to hex6[3]
set_location_assignment PIN_Y25 -to hex6[2]
set_location_assignment PIN_AA26 -to hex6[1]
set_location_assignment PIN_AA25 -to hex6[0]
set_location_assignment PIN_U24 -to hex7[6]
set_location_assignment PIN_U23 -to hex7[5]
set_location_assignment PIN_W25 -to hex7[4]
set_location_assignment PIN_W22 -to hex7[3]
set_location_assignment PIN_W21 -to hex7[2]
set_location_assignment PIN_Y22 -to hex7[1]
set_location_assignment PIN_M24 -to hex7[0]
set_location_assignment PIN_H22 -to hex8[6]
set_location_assignment PIN_J22 -to hex8[5]
set_location_assignment PIN_L25 -to hex8[4]
set_location_assignment PIN_L26 -to hex8[3]
set_location_assignment PIN_E17 -to hex8[2]
set_location_assignment PIN_F22 -to hex8[1]
set_location_assignment PIN_G18 -to hex8[0]
set_location_assignment PIN_E21 -to led[0]
set_location_assignment PIN_E22 -to led[1]
set_location_assignment PIN_E25 -to led[2]
set_location_assignment PIN_E24 -to led[3]
set_location_assignment PIN_AG26 -to beep
ダウンロードテスト:
バックレーダーをシミュレートするために、ブザーインジケーターも同時に追加されます。20cm 未満の場合は 1 秒に 1 回、10cm 未満の場合は 0.5 秒に 1 回鳴ります。
このプロジェクトのソースコードを参照してください:
https://github.com/MiaOuyang/ultrasound_waves
要約する
実際の基板テストを通じて、超音波距離測定は基本的に実現されており、測定された距離は実際の距離と基本的に一致しています。ただし、コード内に設計されたレジスタの数が限られているため、コードは約 4 ~ 247cm の距離までしかテストできません。同時に、距離測定に HC-SR04 超音波測距モジュールを使用すると、多少の干渉やエラーが発生します。センサー自体のノイズ、エコーのマルチパス伝播、環境の干渉など、多くの場合に遭遇する要因により、不正確な測距結果や誤った距離値が発生する可能性があります。測距結果に干渉やエラーがある場合は、信号がフィルタリングされます。
参考記事:
https://blog.csdn.net/qq_43546203/article/details/125281386
https://blog.csdn.net/qq_45659777/article/details/124717655
https://blog.csdn.net/AM0R_/article /詳細/119303815