// ultrasonic_sensor_inf2.cpp
// 2016/12/05 by marsee
// count_val は超音波距離センサからのパルス長を示す。単位は 10 ns とする
// 2016/12/07 : パララックス社の超音波距離センサはSIGピンがINOUTなので、自分で出力したトリガパルスを自分で受けてしまう。
// 対策としては、sensor_outのパルスを受けてから、センサのパルス長を測定する。
//
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include <ap_utils.h>
#define COUNT_LIMIT 2000000 // clock = 100MHz, 20ms
void gen_trigger_pulse(volatile ap_uint<1> &sensor_out, volatile ap_uint<1> &sensor_out_en);
int mesure_high_width(hls::stream<ap_uint<1> >& sensor_in, int &cnt);
int mesure_high_width2(hls::stream<ap_uint<1> >& sensor_in, int &cnt);
int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in){
#pragma HLS DATAFLOW
#pragma HLS INTERFACE ap_hs port=sensor_in
#pragma HLS INTERFACE ap_none register port=sensor_out_en
#pragma HLS INTERFACE ap_none register port=sensor_out
#pragma HLS INTERFACE s_axilite port=count_val
#pragma HLS INTERFACE s_axilite port=return
int cnt;
int return_val;
// 5usのトリガパルスを出力
gen_trigger_pulse(sensor_out, sensor_out_en);
// 2回パルスを検出(sensor_out, 距離パルス)
return_val = mesure_high_width2(sensor_in, cnt);
count_val = cnt;
return(return_val);
}
void gen_trigger_pulse(volatile ap_uint<1> &sensor_out, volatile ap_uint<1> &sensor_out_en){
int cnt;
Loop_1out5us: for(cnt=0; cnt<500; cnt++){ // 5 us のパルスを出力
#pragma HLS PIPELINE II=1
sensor_out = 1;
sensor_out_en = 1;
}
sensor_out = 1;
sensor_out_en = 1;
Loop_wait1us: for(cnt=0; cnt<100; cnt++){ // 1 us の間 senser_out に 0 を保持
#pragma HLS PIPELINE II=1
sensor_out = 0;
sensor_out_en = 1;
}
sensor_out = 0;
sensor_out_en = 1;
Loop_wait1us2: for(cnt=0; cnt<100; cnt++){ // 1 us の間 senser_out_en に 0 を保持
#pragma HLS PIPELINE II=1
sensor_out = 0;
sensor_out_en = 0;
}
sensor_out = 0;
sensor_out_en = 0;
}
// mesure_high_widthを2回実行する
int mesure_high_width2(hls::stream<ap_uint<1> >& sensor_in, int &cnt){
int return_val;
// sensor_out のパルスを検出
return_val = mesure_high_width(sensor_in, cnt);
if(return_val)
return(return_val);
// 超音波距離センサのパルスを検出
return_val = mesure_high_width(sensor_in, cnt);
if(return_val)
return(return_val);
return(0);
}
// sensor_in が 1 の間のパルス幅を検出する
int mesure_high_width(hls::stream<ap_uint<1> >& sensor_in, int &cnt){
ap_uint<1> sensor_in_node;
Loop_wait_high: for(cnt=0; cnt<COUNT_LIMIT; cnt++){
#pragma HLS PIPELINE II=1
sensor_in >> sensor_in_node;
if((int)sensor_in_node)
break;
}
if(cnt == COUNT_LIMIT)
return(1); // error, overflow
Loop_mesure_high: for(cnt=1; cnt<COUNT_LIMIT; cnt++){ // リミットは 20 ms
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT min=11500 max=1850000 avg=20000
sensor_in >> sensor_in_node;
if(!(int)sensor_in_node)
break;
}
if (cnt == COUNT_LIMIT)
return(2); // error, overflow
else
return(0); // normal end
}
// ultrasonic_sensor_inf_tb.cpp
// 2016/12/06 by marsee
// 2016/12/07 : パララックス社の超音波距離センサはSIGピンがINOUTなので、自分で出力したトリガパルスを自分で受けてしまう。
// sensor_in にトリガパルスを出力してから、センサが出力するであろうパルスを出力する。
//
// ライセンスは二条項BSDライセンス (2-clause BSD license)とします。
//
#include <ap_int.h>
#include <hls_stream.h>
#define PULSE_WIDTH 20000 // (PULSE_WIDTH/100) us
int ultrasonic_sensor_inf(int &count_val, volatile ap_uint<1> &sensor_out,
volatile ap_uint<1> &sensor_out_en, hls::stream<ap_uint<1> >& sensor_in);
int main(){
using namespace std;
hls::stream<ap_uint<1> > sensor_in;
int count_val;
ap_uint<1> sensor_out, sensor_out_en;
int return_val;
// パララックス社の超音波距離センサは入出力なので、自分の出力に反応しないか?を検証する
// 756 us wait
for(int i=0; i<22; i++){ // 220 ns wait
sensor_in << (ap_uint<1>)0;
}
for(int i=0; i<500; i++){ // 5 us間 1 を入れる
sensor_in << (ap_uint<1>)1;
}
for(int i=0; i<75078; i++){ // 756 us - 5 us - 220 ns
sensor_in << (ap_uint<1>)0;
}
// 測定用に PULSE_WIDTH 間、1 を入れる
for(int i=0; i<PULSE_WIDTH; i++){ // PULSE_WIDTHの間 sensor_in を 1 にする
sensor_in << (ap_uint<1>)1;
}
for(int i=0; i<20000; i++){ // 1 usの間 sensor_in を 0 にする
sensor_in << (ap_uint<1>)0;
}
return_val = ultrasonic_sensor_inf(count_val, sensor_out, sensor_out_en, sensor_in);
printf("Pulse width = %f us\n", (float)count_val/100.0);
if(return_val){
printf("Error: return_val = %d\n");
exit(1);
}
return(0);
}
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | - | - | - | - | - | - |