FPGA-超声波测距数码管显示系列(包含进制转换、均值滤波)

简介: FPGA-超声波测距数码管显示系列(包含进制转换、均值滤波)

首先在前文已经介绍过了超声波模块的原理和使用,之前没有介绍回响脉冲的计数问题,这次简单说一下吧,每隔一秒发一次触发信号,当触发信号来了后,每隔10Us进行一次脉冲的计数,计算出每秒的脉冲数,这时候就有一个问题,怎么根据回响信号进行计数呢?

1、首先我们可以看到回响信号是根据距离成正比的,而且脉冲计数是每隔10us进行一次脉冲方便进行距离的计算(精度2mm 决定)

2、当本次回响脉冲开始时候可以进行上次的数据的清零,然后进行本次数据的计数,当回响信号结束数据计数终止,将本次的计数值输出,用于距离的测量。

3、计算公式:

如果 距离是m  时间取s:     s=346*t/2;

如果距离是mm  时间取10us: s*0.001=346*t*0.00001/2   即:s=1.73/t    方便计算则取 s=(443 X t )/256

C-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能, 测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。基本工作原理:

(1)采用IO口TRIG触发测距,给至少10us的高电平信号;

(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。

超声波测距模块电路图


image.png

电气参数


image.png

超声波时序图


image.png

原理介绍完毕:

贴代码:(这里的测得的数据是通过均值滤波处理后测得的回响数,然后通过乘法器和除法器进行进制转换后显示具体测得的距离)

 

这里的mul   div进行距离转换用到了IP核)

top.v:


moduletop(clk,rst_n,dtube_cs_n,dtube_data,ultrasound_trig,ultrasound_echo    );
inputclk;
inputrst_n;
outputultrasound_trig;
output [3:0]dtube_cs_n;
output [6:0]dtube_data;
inputultrasound_echo;
wire [15:0] echo_pulse_num;
wireclk_100khz_en;
wire [15:0]cnt;
wire [15:0] out_num;
wirepul_en;
assigncnt={quotient_hund[3:0],quotient_thou[3:0],fractional_ten[3:0],quotient_ten[3:0]};
clk_100khz_enuut_clk_100khz_en(
    .clk(clk),
    .rst_n(rst_n),
    .clk_100khz_en(clk_100khz_en)
    );
chejuuut_cheju(
    .clk(clk),
    .rst_n(rst_n),
    .clk_100khz_en(clk_100khz_en),
    .ultrasound_trig(ultrasound_trig),
    .ultrasound_echo(ultrasound_echo),
    .echo_pulse_en(pul_en),
    .echo_pulse_num(echo_pulse_num)
    );
seg_4uut_seg_4(
    .clk(clk),
    .rst_n(rst_n),
    .dis_data(cnt),
    .dtube_cs_n(dtube_cs_n),
    .dtube_data(dtube_data)
    );
filteruut_filter(
    .clk(clk),
    .rst_n(rst_n),
    .pul_en(pul_en),
    .pulse_num(echo_pulse_num),
    .filter_num(out_num)
    );
//距离换算wire[31:0]mul_dout;
mul_outuut_mul_out(
    .clk(clk), //inputclk    .a(16'd443), // input [15 : 0] a    .b(out_num), //input [15 : 0] b    .p(mul_dout) //output [31 : 0] p    );
//利用除法器进行进制转换wire [15:0]quotient_thou,fractional_thou;
div_outuut_div_out1(
    .clk(clk), //inputclk    .rfd(), //outputrfd    .dividend(mul_dout[23:8]), //input [15 : 0] dividend    .divisor(16'd1000), // input [15 : 0] divisor    .quotient(quotient_thou), //output [15 : 0] quotient    .fractional(fractional_thou)
    ); //output [15 : 0] fractionalwire [15:0]quotient_hund,fractional_hund;
div_outuut_div_out2(
    .clk(clk), //inputclk    .rfd(), //outputrfd    .dividend(fractional_thou), //input [15 : 0] dividend    .divisor(16'd100), // input [15 : 0] divisor    .quotient(quotient_hund), //output [15 : 0] quotient    .fractional(fractional_hund)
    ); //output [15 : 0] fractionalwire [15:0]quotient_ten,fractional_ten;
div_outuut_div_out3(
    .clk(clk), //inputclk    .rfd(), //outputrfd    .dividend(fractional_hund), //input [15 : 0] dividend    .divisor(16'd10), // input [15 : 0] divisor    .quotient(quotient_ten), //output [15 : 0] quotient    .fractional(fractional_ten)
    ); //output [15 : 0] fractionalendmodule

clk_100khz_en.v:


moduleclk_100khz_en(clk,rst_n,clk_100khz_en    );
inputclk;
inputrst_n;
outputclk_100khz_en;
reg [7:0] cnt;
always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)begincnt<=1'b0;endelseif(cnt==8'd249)begincnt<=1'b0;endelsebegincnt<=cnt+1'b1;endendassignclk_100khz_en=(cnt==8'd249);endmodule

seg.v:


moduleseg_4(clk,rst_n,dis_data,dtube_cs_n,dtube_data    );
inputclk;      //时钟信号25MHzinputrst_n;            //复位信号input [15:0] dis_data;//outputreg[3:0] dtube_cs_n; //段选数据位outputreg[6:0] dtube_data;//位选数据位reg [3:0]TimeH;         //两位输入高位  [0]
reg [3:0]TimeL;         //两位输入低位  [1]
reg [3:0]TimeH1;        //两位输入高位  [2]
reg [3:0]TimeL1;        //两位输入低位  [3]   
reg [3:0] display_num;  //当前显示数据reg [16:0] div_cnt; //延时计数器计数位always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginTimeH<=1'b0;    TimeL<=1'b0;    TimeH1<=1'b0;TimeL1<=1'b0;endelsebeginTimeH<=dis_data[3:0];  
TimeL<=dis_data[7:4];  
TimeH1<=dis_data[11:8];
TimeL1<=dis_data[15:12];
endendinitialdiv_cnt=0;//赋初值为0//延时计数器模块always@ (posedgeclkornegedgerst_n)
beginif(!rst_n) 
div_cnt<=8'd0;elseif(div_cnt==17'd80000)div_cnt<=8'd0;        elsediv_cnt<=div_cnt+1'b1;end//显示当前的数据模块always@(posedgeclkornegedgerst_n)
beginif(!rst_n) 
display_num<=4'h0;elseif(div_cnt<17'd20000)display_num<=TimeL;
elseif((div_cnt>17'd20000)&(div_cnt <17'd40000))
display_num<=TimeH;
elseif((div_cnt>17'd40000)&(div_cnt < 17'd60000))
display_num<=TimeL1;
elsedisplay_num<=TimeH1;
end//段选数据译码模块(共阴数码管)
always@(*)
beginif(!rst_n) 
dtube_data<=8'h00;elsebegincase(display_num) 
4'h0: dtube_data <= 8'h3f;
4'h1: dtube_data <= 8'h06;
4'h2: dtube_data <= 8'h5b;
4'h3: dtube_data <= 8'h4f;
4'h4: dtube_data <= 8'h66;
4'h5: dtube_data <= 8'h6d;
4'h6: dtube_data <= 8'h7d;
4'h7: dtube_data <= 8'h07;
4'h8: dtube_data <= 8'h7f;
4'h9: dtube_data <= 8'h6f;
default:dtube_data<=8'h00;endcaseendend//位选选译模块always@(posedgeclkornegedgerst_n)  
beginif(!rst_n) 
dtube_cs_n<=4'b1111;elseif(div_cnt<=17'd20000)dtube_cs_n<=4'b1110;elseif((div_cnt>17'd20000)&(div_cnt <=17'd40000))
dtube_cs_n<=4'b1101;elseif((div_cnt>17'd40000)&(div_cnt <=17'd60000))
dtube_cs_n<=4'b1011;elsedtube_cs_n<=4'b0111;endendmodule

filter.v:


modulefilter(clk,rst_n,pul_en,pulse_num,filter_num    );
inputclk;
inputrst_n;
inputpul_en;
input [15:0]pulse_num;
output [15:0]filter_num;
reg[15:0]pul_buf[7:0];
always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginpul_buf[0]<=1'b0;pul_buf[1]<=1'b0;pul_buf[2]<=1'b0;pul_buf[3]<=1'b0;pul_buf[4]<=1'b0;pul_buf[5]<=1'b0;pul_buf[6]<=1'b0;pul_buf[7]<=1'b0;endelseif(pul_en==1'b1)beginpul_buf[0]<=pulse_num;
pul_buf[1]<=pul_buf[0];
pul_buf[2]<=pul_buf[1];
pul_buf[3]<=pul_buf[2];
pul_buf[4]<=pul_buf[3];
pul_buf[5]<=pul_buf[4];
pul_buf[6]<=pul_buf[5];
pul_buf[7]<=pul_buf[6];
endendreg [15:0]sum_pul;
always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginsum_pul<=1'b0;endelsebeginsum_pul<=pul_buf[0]+pul_buf[1]+pul_buf[2]+pul_buf[3]+pul_buf[4]+pul_buf[5]+pul_buf[6]+pul_buf[7];
endendassignfilter_num={3'b0,sum_pul[15:3]};endmodule

cheju.v:


modulecheju(clk,rst_n,clk_100khz_en,ultrasound_trig,ultrasound_echo,echo_pulse_en,echo_pulse_num    );
inputclk;
inputrst_n;
inputclk_100khz_en;
inputultrasound_echo;//回响信号outputultrasound_trig;//脉冲激励信号outputregecho_pulse_en;       //超声波测距模块回响信号计数值有效信号outputreg[15:0] echo_pulse_num;    //以10us为单位对超声波测距模块回响信号高脉冲进行计数的最终值reg [16:0]timer_cnt;
always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)begintimer_cnt<=1'b0;endelseif(clk_100khz_en==1'b1)beginif(timer_cnt<17'd99_999)begintimer_cnt<=timer_cnt+1'b1;endelsebegintimer_cnt<=1'b0;endendelsebegintimer_cnt<=timer_cnt;
endendassignultrasound_trig=(timer_cnt==1'b1)?1'b1:1'b0;//每隔一秒产生一次脉冲                 //超声波测距模块的回响信号echo打两拍,产生上升沿和下降沿标志位reg[1:0] ultrasound_echo_r;
always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginultrasound_echo_r<=2'b00;endelsebeginultrasound_echo_r<= {ultrasound_echo_r[0],ultrasound_echo};
endendwirepos_echo=~ultrasound_echo_r[1] &ultrasound_echo_r[0];   //echo信号上升沿标志位,高电平有效一个时钟周期wireneg_echo=ultrasound_echo_r[1] &~ultrasound_echo_r[0];   //echo信号下降沿标志位,高电平有效一个时钟周期//以10us为单位对超声波测距模块回响信号高脉冲进行计数reg[15:0] echo_cnt;     //回响高脉冲计数器always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginecho_cnt<=16'd0;endelseif(pos_echo==1'b1)beginecho_cnt<=16'd0;  //计数清零endelseif(clk_100khz_en==1'b1 && ultrasound_echo_r[0]==1'b1)beginecho_cnt<=echo_cnt+1'b1;endend//计数脉冲数锁存always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginecho_pulse_num<=16'd0;    endelseif(neg_echo==1'b1)beginecho_pulse_num<=echo_cnt;
endend//计数脉冲有效使能信号锁存always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginecho_pulse_en<=1'b0;endelsebeginecho_pulse_en<=neg_echo;
endendendmodule
目录
相关文章
|
8月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(一)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
254 2
|
8月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(三)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
189 4
|
6月前
|
异构计算
FPGA入门(6):数码管静态/动态显示(二)
FPGA入门(6):数码管静态/动态显示(二)
88 10
|
6月前
|
异构计算
FPGA入门(6):数码管静态/动态显示(一)
FPGA入门(6):数码管静态/动态显示
70 0
|
8月前
|
存储 芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(二)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
219 4
|
异构计算
实验三 基于FPGA的数码管动态扫描电路设计 quartus/数码管/电路模块设计(上)
实验三 基于FPGA的数码管动态扫描电路设计 quartus/数码管/电路模块设计(上)
933 0
实验三 基于FPGA的数码管动态扫描电路设计 quartus/数码管/电路模块设计(上)
|
异构计算
FPGA项目五:数码管动态扫描(下)
FPGA项目五:数码管动态扫描
230 0
FPGA项目五:数码管动态扫描(下)

热门文章

最新文章