例として超音波距離センサーを使用して、周辺モジュールをMIPSfpgaに接続する

良い一日。 この記事では、2つの超音波センサーHC-SR04とPmod MAXSONARの例を使用して、MIPSfpgaに基づくチップベースのシステムにモジュールを統合する方法を説明します。 また、接続されたモジュールを管理するためのプログラムの作成方法についても説明します。



私の例に基づいて、独自のモジュールを接続し、プログラムを使用してそれらを管理できます。 MIPSfpgaに基づいて、独自の周辺機器のセットでシステムを作成します。







ここにそのようなセンサーを接続します:





そのためのドキュメントはここにあります 。 データは、ボード上の7セグメントインジケーターに表示されます。 また、ピエゾダイナミクスを使用して、さまざまな持続時間の音声信号を生成します。



まず第一に、MIPSfpgaソースが必要です。



ダウンロード手順:



www.silicon-russia.com/2015/12/11/mipsfpga-download-instructions



次に、MIPSfpga-plusアドインをダウンロードする必要があります。これにより、UARTでプログラムを記録できます。



github.com/MIPSfpga/mipsfpga-plus



スクリプトを実行してプロジェクトを組み立てるには、簡単に説明とインストール手順が必要です。



MIPSfpgaソースをフォルダーに配置します。



C:\MIPSfpga
      
      





MIPSfpga-plusの場合:



 C:\github\mipsfpga-plus
      
      





次に、フォルダーC:\ github \ mipsfpga-plus \ boardで、 ボードを選択します。de0_cvがあり、 make_projectスクリプトを実行します。 起動するプロジェクトは、 C:\ github \ mipsfpga-plus \ boards \ de0_cv \ projectにあります。



ボードがそこにない場合は、論理セルの数に応じて最適なボードを選択し、宛先を変更できます。



コンパイラーであるCodescapeリンカーも必要です 。 そして、USB UARTコンバーター。 たとえば、pl2303hxまたはch340。



センサーにはアナログ出力、パルス幅変調出力、シリアルUARTインターフェイスがあり、センサーをMIPSfpgaに接続するために使用します。 接続は、センサーからのデータを表示するレジスタを、プロセッサがメモリと通信するバスに接続することにより行われます。



センサーからデータを受信して​​処理するモジュールについて説明します。



既に説明したUARTレシーバーを使用します。これはプログラムのフラッシュに使用され、baud_rateパラメーターのみを9600に変更します。このような伝送速度はセンサーによって使用されます。



Uartレシーバーモジュール
 module uart_receiver ( input clock, input reset_n, input rx, output reg [7:0] byte_data, output byte_ready ); parameter clock_frequency = 50000000; parameter baud_rate = 9600; localparam clock_cycles_in_symbol = clock_frequency / baud_rate; // Synchronize rx input to clock reg rx_sync1, rx_sync; always @(posedge clock or negedge reset_n) begin if (! reset_n) begin rx_sync1 <= 1; rx_sync <= 1; end else begin rx_sync1 <= rx; rx_sync <= rx_sync1; end end // Finding edge for start bit reg prev_rx_sync; always @(posedge clock or negedge reset_n) begin if (! reset_n) prev_rx_sync <= 1; else prev_rx_sync <= rx_sync; end wire start_bit_edge = prev_rx_sync & ! rx_sync; // Counter to measure distance between symbols reg [31:0] counter; reg load_counter; reg [31:0] load_counter_value; always @(posedge clock or negedge reset_n) begin if (! reset_n) counter <= 0; else if (load_counter) counter <= load_counter_value; else if (counter != 0) counter <= counter - 1; end wire counter_done = counter == 1; // Shift register to accumulate data reg shift; reg [7:0] shifted_1; assign byte_ready = shifted_1 [0]; always @ (posedge clock or negedge reset_n) begin if (! reset_n) begin shifted_1 <= 0; end else if (shift) begin if (shifted_1 == 0) shifted_1 <= 8'b10000000; else shifted_1 <= shifted_1 >> 1; byte_data <= { rx, byte_data [7:1] }; end else if (byte_ready) begin shifted_1 <= 0; end end reg idle, idle_r; always @* begin idle = idle_r; shift = 0; load_counter = 0; load_counter_value = 0; if (idle) begin if (start_bit_edge) begin load_counter = 1; load_counter_value = clock_cycles_in_symbol * 3 / 2; idle = 0; end end else if (counter_done) begin shift = 1; load_counter = 1; load_counter_value = clock_cycles_in_symbol; end else if (byte_ready) begin idle = 1; end end always @ (posedge clock or negedge reset_n) begin if (! reset_n) idle_r <= 1; else idle_r <= idle; end endmodule
      
      







データシート[1]によると、ソナーは49msごとに、ASCII形式の4バイト、「R」文字、測定された距離の3文字を、上位ビットを先に送信します。



ソナーモジュール
 module sonn ( input clock, input reset_n, input rx, output reg [15:0] hword ); reg [1:0] count2; wire [7:0] byte_data; reg [31:0] wordd; always @(posedge clock) if (! reset_n) wordd <= 32'b0; else if (byte_ready) case(count2) 2'd0:begin wordd[31:24]<=byte_data; if(byte_data==8'h52) count2<=2'd1; end 2'd1:begin wordd[23:16]<=byte_data; count2<=2'd2;end 2'd2:begin wordd[15:8]<=byte_data; count2<=2'd3;end 2'd3:begin wordd[7:0]<=byte_data; count2<=2'd0; hword={4'b0000,wordd[19:16],wordd[11:8],wordd[3:0]};end default begin wordd[31:24]<=byte_data; if(byte_data==8'h52) count2<=count2+1'b1; end endcase uart_receiver uart(clock,reset_n,rx,byte_data,byte_ready); endmodule
      
      





各クロックサイクルとフラグbyte_ready(バイトの受信時にコック)に対して、文字 "R"-16進数の52が予想され、次の3文字の受信に進みます。 3バイトを受信すると、下位ニブルを出力レジスタに書き込み、ASCIIからバイナリ10進形式に変換します。



ピエゾダイナミクスを制御するモジュールは2つで構成されます。最初のモジュールでは、周波数を選択してパルスが実際に生成されます。



トーンモジュール
 module note(clk,reset_n,notein,noteout); input clk,reset_n; input [6:0]notein; output reg noteout; reg [19:0]div; reg [19:0]cnt; reg eocnt; always @* begin case (notein) 0: div = 191114; // C 1: div = 180385; // C# 2: div = 170262; // D 3: div = 160705; // D# 4: div = 151686; // E 5: div = 143173; // F 6: div = 135136; // F# 7: div = 127552; // G 8: div = 120389; // G# 9: div = 113636; // A 10:div = 107259; // A# 11:div = 101239; // H 12:div = 95558; // C 13:div = 90194; // C# 14:div = 85132; // D 15:div = 80354; // D# 16:div = 75845; // E 17:div = 71558; // F 18:div = 67567; // F# 19:div = 63775; // G 20:div = 60197; // G# 21:div = 28403; // A 22:div = 53629; // A# 23:div = 50619; // H 24:div = 47777; // C 25:div = 45097; // C# 26:div = 42566; // D 27:div = 40176; // D# 28:div = 37921; // E default: div = 1; // endcase end always @(posedge clk) begin if(~reset_n) begin noteout<=0; cnt <= 0; end if(cnt == div) begin cnt <= 0; noteout <= ~noteout; end else cnt <= cnt + 1'b1; end endmodule
      
      







divにカウントして、出力信号を反転します。 Divは入力メモによって選択されます。



Div = Fclk / Fnote / 2



Fclkはクロック周波数、Fnoteは目的の出力周波数です。



そして、音のパルスの持続時間が調整されるモジュール:



バズモジュール
 module buzz(clk,reset_n,en,tim,tone); input clk,reset_n,en; input [1:0]tim; output reg tone; wire [6:0]notein; wire noteout; assign notein=21; reg [27:0]counter,div,div1; reg ene; note note1(clk,reset_n,notein,noteout); always@(posedge clk) if(~reset_n) begin counter<=28'b0; ene<=1'b0; end else begin case(tim) 0:begin div<=28'd 5_000_000; div1<=28'd 12_000_000; end 1:begin div<=28'd 10_000_000; div1<=28'd 20_000_000; end 2:begin div<=28'd 25_000_000; div1<=28'd 35_000_000; end 3:begin div<=28'd 50_000_000; div1<=28'd 60_000_000; end default begin div<=28'd 10_000_000; div1<=28'd 20_000_000; end endcase counter<=counter+1; if(counter==div) ene<=1'b1; if(counter==div1 | counter>60_000_000) begin counter<=28'b0; ene<=1'b0; end end always@(posedge clk) tone<=en¬eout&ene; endmodule
      
      







各クロックサイクルでは、div値に達すると、オーディオ信号が許可され、div1値に達すると、カウンターがインクリメントされます。 したがって、音声信号の持続時間と周波数が設定されます。 また、カウンター値がdivとdiv1の間にあるときにdiv1が変化したときに発生する可能性のある長いパルスを防ぐため、カウンターは60,000,000に制限されています。



上記のモジュールを含むファイルをプロジェクトに接続します。





C:\ github \ mipsfpga-plusフォルダーにあるmfp_ahb_lite_matrix_config.vhファイル。



次の行を追加します。



 `define MFP_SONAR_SENSOR_IONUM 4'h6 `define MFP_CONTROL_IONUM 4'h9 `define MFP_SONAR_SENSOR_ADDR 32'h1f800018 `define MFP_CONTROL_ADDR 32'h1f800024
      
      





実際には、これらはレジスタが利用できるアドレスです。



モジュールのソースと変更されたファイルはここから入手できます。



github.com/Denis-Kingit/UltraSonicToMIPSfpga



次に、プロジェクトをコンパイルし、ボードをフラッシュします。 センサー、トランスデューサー、ピエゾダイナミックを接続します。



コンバータのGNDピンをGPIO_1 [26]にTXピンをGPIO_1 [31]にピンで接続します。 GPIO_0 [34]GPIO_0 [35]へのピエゾダイナミック 。 センサーのGNDピンをGPIO_0 [3]VCC-GPIO_0 [1]、TX-GPIO_0 [7]に接続します。 次のようになります:







ソフトウェア部



C:\ github \ mipsfpga-plus \ Programs \ 01_light_sensorフォルダーの内容をコピーするか、単にそのフォルダーで作業します。 レジスタアドレスをmfp_memory_mapped_registers.hファイルに追加します。



 #define MFP_SONAR_SENSOR_ADDR 0xBF800018 #define MFP_CONTROL_ADDR 0xBF800024 #define MFP_SONAR_SENSOR (* (volatile unsigned *) MFP_SONAR_SENSOR_ADDR ) #define MFP_CONTROL (* (volatile unsigned *) MFP_CONTROL_ADDR )
      
      





次に、レジスタから値を読み取り、7セグメントインジケーターに表示するプログラムを作成します。 そして、読み取り値に応じて、音声信号を制御します。 main.cを変更します。



プログラム
 #include "mfp_memory_mapped_registers.h" int main () { MFP_CONTROL = 1; for (;;) { MFP_7_SEGMENT_HEX = MFP_SONAR_SENSOR; if(MFP_SONAR_SENSOR<0x10) MFP_CONTROL = 1; else if (MFP_SONAR_SENSOR<0x12) MFP_CONTROL = 3; else if (MFP_SONAR_SENSOR<0x14) MFP_CONTROL = 5; else if (MFP_SONAR_SENSOR<0x16) MFP_CONTROL = 7; else MFP_CONTROL = 0; } return 0; }
      
      







スクリプトを実行してコンパイルします。



  02_compile_and_link
      
      





motorola_s_recordファイルを生成します。



  08_generate_motorola_s_record_file
      
      





USB UARTコンバーターが接続されているCOMポートを確認します。



  11_check_which_com_port_is_used
      
      





ファイル12_upload_to_the_board_using_uartを変更します。



 set a=7 mode com%a% baud=115200 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off type program.rec >\.\COM%a%
      
      





ここで、aはUSB UARTコンバーターが接続されているCOMポート番号です。



最後に、プログラムをダウンロードします。



  12_upload_to_the_board_using_uart
      
      









次に、超音波HC-SR04を差し込みます









接続の考え方は同じです;バスに接続されたレジスタにセンサーからのデータを表示します。



距離を測定するには、Trig信号ピンに10μsのパルスを印加する必要があります。その後、超音波モジュールは40 kHzの周波数の超音波信号の8パックを放出し、エコーを検出します。









物体までの測定距離は、エコーの幅に比例します。これは、センサーの出力での電気信号の持続時間(エコー)によってエンコードされます。 推奨される測定間隔は、少なくとも50msです。 距離を計算するには、マイクロ秒単位のパルス(エコー)持続時間を、センチメートル単位の距離では58で、インチ単位の距離では148で割る必要があります。 障害物が見つからない場合、出力は持続時間が38ミリ秒の信号になります[2]。



ソニックモジュール
 module sonic(clk,trig,reset_n,en,echo,out); input clk,echo,reset_n,en; output reg trig; output reg[23:0]out; reg [23:0]count; reg [23:0]countp; always@(posedge clk) if(~reset_n) begin countp<=24'b0; count<=24'b0; end else if(en) begin if(countp==0) trig<=1'b1; if(echo) count<=count+1'b1; if(countp==500) trig<=1'b0; if(countp==2500000) begin if (count>1800000) out<=24'hfff; else out<=count/2900; countp<=24'b0; count<=24'b0; end countp<=countp+1'b1; end endmodule
      
      







2500000サイクル(50ミリ秒)の周期で、500サイクル(10μs)の持続時間でトリガーの出力にパルスを作成し、エコーの持続時間を考慮して、2900(マイクロ秒単位の転送では50、センチメートル単位の転送では58)で除算し、結果をレジスタに書き込みます(何のために)追加の仕切りを作成しないように、プログラムでそれを変換できます)パルスの持続時間が36msを超える場合、0xFFFを書き込みます。これは、障害物が検出されなかったことを意味します。



プロジェクトの最上位ファイル( de0_cv.v )でモジュールを接続します。



 wire [23:0] usonic; sonic sonica ( .clk ( CLOCK_50 ), .trig ( GPIO_0[33] ), .reset_n ( RESET_N ), .en ( control[3] ), .echo ( GPIO_0[32] ), .out ( usonic ) );
      
      





同様に、フォルダーC:\ github plus mのファイルmfp_ahb_gpio_slave.v、mfp_ahb_lite_matrix.v、mfp_ahb_lite_matrix_with_loader.v、mfp_ahb_lite_matrix_config.vh、mfp_system.vを変更します。



センサーを接続するには、5Vの電源が必要です。トリガーピンはGPIO_0 [33]に接続されます。センサーは5Vで動作するため、エコーピンは分圧器を介してGPIO_0 [32]に接続する必要があります。共通のソース、センサー、ボードワイヤを接続します。



プログラムを作成します。



プログラム
 #include "mfp_memory_mapped_registers.h" int main () { int k = 0; for (;;) { //MFP_RED_LEDS = MFP_SONICR_SENSOR >> 4; k=MFP_SONIC_SENSOR/58/50; MFP_7_SEGMENT_HEX = k; if(k<0x10) MFP_CONTROL = 1; else if (k<0x12) MFP_CONTROL = 3; else if (k<0x14) MFP_CONTROL = 5; else if (k<0x16) MFP_CONTROL = 7; else MFP_CONTROL = 0; } return 0; }
      
      







レジスタから値を読み取り、取得した値に応じて、音の持続時間を制御し、7セグメントインジケーターに距離値を表示します。



また、 mfp_memory_mapped_registers.hファイルに新しいアドレスを追加する必要があります



 #define MFP_SONIC_SENSOR_ADDR 0xBF800020 #define MFP_SONIC_SENSOR (* (volatile unsigned *) MFP_SONIC_SENSOR_ADDR )
      
      









上記の方法で、独自のモジュールを接続し、それらをプログラムで管理できます。



便利なリンク
[1] LV-MaxSonar-maxbotix.com/documents/LV-MaxSonar-EZ_Datasheet.pdf

[2]超音波HC SR04-robocraft.ru/blog/electronics/772.html

ソースMIPSfpga-plus github.com/MIPSfpga/mipsfpga-plus

Codescape- Codescape

Mipsfpgaダウンロード手順-手順

モジュール、プログラム、および変更されたファイルのソース:

github.com/Denis-Kingit/UltraSonicToMIPSfpga

役に立つ本-デビッドハリスとサラハリス「デジタル回路とコンピューターアーキテクチャ」



All Articles