基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上

这篇具有很好参考价值的文章主要介绍了基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验现象

将MAX-10小脚丫FPGA和超声波模块HC_SR04插在面包板上,用杜邦线将对应的引脚连接好,烧录程序,小脚丫自带的数码管显示距离数据(单位是厘米)。
基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上,fpga开发基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上,fpga开发这张图拍花了,数码管显示的数据是18CM

简单介绍超声波测距模块HC_SR04

HC-SR04是一种基于超声波的测距模块。该模块向前15度内发送超声波并接收回响,通过发出超声波到收到回响的这个时间间隔计算前方的障碍物距离,可以用来给智能小车做障碍物监测。可提供2cm- 400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。

该模块的时序图如下:

基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上,fpga开发该模块的引脚图如下:
基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上,fpga开发
我们在编写代码的时候,想要发出测距命令,需要先保持触发信号输入(trig引脚)为低电平,然后保持大于10us的高电平,再变成低电平即可(时序图第一行所示)。

发出测距命令后,回响信号输出(echo引脚)会保持一段时间的高电平,这个高电平的持续时间与距离有关。我们在FPGA编写代码测量高电平持续时间,然后将时间转化为距离即可。

经过测试,得到以下结论:
1、发送测距的时候,每个脉冲之间的间隔不要过近,我用的间隔是300ms,即每300ms测一次距离,也可以根据需要修改。
2、接收端高电平时间与距离的关系式是:距离(cm)= 高电平持续时间(us)x 0.034cm / 2 (除以2是因为持续时间是往返时间,除以2才是单程时间)

模块框图

我们需要设计以下模块:
1、测距信号源模块,输入时钟与复位,每隔300ms输出15us高电平。

2、距离计算模块,输入时钟、复位与回响信号echo,输出距离(cm)

3、数据显示模块,将得到的距离可视化,我用的是2个1位数码管模块(小脚丫自带两个1位共阴极数码管)

4、顶层模块

框图如下:

基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上,fpga开发

模块编写

测距信号源

在此模块,写一个计时周期为300us的循环计数器,当计数器值小于15时输出高电平,其他时候输出低电平即可。
代码如下:

module trigger_send #(
    parameter TIME_1S = 12_000_000
) (
    input   clk ,
    input   rst_n   ,
    output  trigger
);

//1us生成
wire clk_1us;
PLL UPLL(
	.inclk0 (clk),
	.c0 (clk_1us)
);

reg [25:0] cnt_1us;
always @(posedge clk_1us or negedge rst_n) begin
    if (!rst_n) begin
        cnt_1us <= 20'd0;
    end
    else if (cnt_1us == 20'd300_000 - 1)begin
        cnt_1us <= 20'd0;
    end
	 else begin
        cnt_1us <= cnt_1us + 1'b1;
    end
end

assign trigger = cnt_1us < 15 ? 1'b1 : 1'b0;

endmodule

我懒得自己写1us的计数器,用锁相环生成了一个1MHZ(1us)的时钟,让它驱动计时,你可以不用锁相环自己写1us比特计数,不知道怎么用锁相环可以搜一下,很简单。

距离计算

这个模块输入了HC_SR04的回响引脚,要做的就是计算它的高电平持续时间,并转化为距离数据输出。

这里持续时间的单位用us最合适,因此同样生成一个1us时钟,用这个时钟监测回响信号的上升沿与下降沿。检测到上升沿,就每过一个时钟周期就把计时器数值加1(可以自己设置上限,表示最大检测距离);等检测到下降沿,就把计时器的数据保存起来,然后把计时器清空准备下次计时。

拿到保存好的计时后,使用上文提到的公式计算出距离输出。

代码如下:

module data_rec #(
    parameter TIME_1S = 12_000_000
) (
    input   clk ,//系统时钟
    input   rst_n   ,//复位
    input   rec_data    ,//回响,早知道取名echo了
    output  [11:0] distance	//计算好的距离
);
//锁相环生成1us周期时钟,因为后面的计时单位全是1us,这样方便
wire clk_1us;
PLL UPLL(
	.inclk0 (clk),
	.c0 (clk_1us)
);

//给回响信号打拍,检测上升沿下降沿
reg rec_data2;
reg rec_data3;
wire rec_negedge;
wire rec_posedge;
assign rec_negedge = (!rec_data2) && rec_data3;
assign rec_posedge = rec_data2 && (!rec_data3);
always @(posedge clk_1us or negedge rst_n) begin
    if (!rst_n) begin
        rec_data2 <= 1'b0;
    end
    else begin
        rec_data2 <= rec_data;
    end
end
always @(posedge clk_1us or negedge rst_n) begin
    if (!rst_n) begin
        rec_data3 <= 1'b0;
    end
    else begin
        rec_data3 <= rec_data2;
    end
end

//计时启动标志,上升沿启动,下降沿结束
reg flag;
always @(posedge clk_1us or negedge rst_n) begin
    if (!rst_n) begin
        flag <= 1'b0;
    end
    else if (rec_posedge)begin
        flag <= 1'b1;
    end
    else if (rec_negedge)begin
        flag <= 1'b0;
    end
    else begin
        flag <= flag;
    end
end

//计时器数值,flag期间计数,有下降沿就清0,急了多少数就是保持了多少us,因为是用1us时钟驱动的
reg [14:0] cnt_1us;
always @(posedge clk_1us or negedge rst_n) begin
    if (!rst_n) begin
        cnt_1us <= 15'd0;
    end
    else if (rec_negedge)begin
        cnt_1us <= 15'd0;
    end
    else if (flag && cnt_1us < 15'd15_000)begin
        cnt_1us <= cnt_1us + 1'b1;
    end
    else begin
        cnt_1us <= cnt_1us;
    end
end

//因为计时器结束计时会变0,因此要用另外的变量,在它清0的时候把值保存下来
reg [14:0] high_time;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        high_time <= 15'd0;
    end
    else if (rec_negedge)begin
        high_time <= cnt_1us ;
    end
    else begin
        high_time <= high_time;
    end
end

//计算距离,Verilog不能直接用浮点数,就这样实现乘以0.017
//为什么不是0.034看前面
reg [11:0] distance_buf;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        distance_buf <= 12'd0;
    end
    else begin
        distance_buf <= high_time * 17 / 1000;
    end
end
assign distance = distance_buf;

endmodule

数码管模块

距离模块的distance就是测到的距离,你拿去数码管输出,串口打印都可以。我的小脚丫自带两个1位的共阴极数码管,就用它们来显示,毕竟自己在面包板上给数码管插线插电阻还是挺麻烦的。

用的时候取出测的距离的十位个位分别给两个模块就行。

1位七段式共阴极数码管十进制显示模块如下:

module nixietube_1 (
    input   clk,
    input   rst_n,
    input   [3:0]   din, //输入0-9
    output  drive_out, //使能
    output  [6:0]   _dig, //输出数码管
    output  dot_out //小数点要亮吗
);
//dot小数点输出
assign dot_out = 1'b0;

//使能,阴极为0
assign drive_out = 1'b0;

//dig段选输出
parameter   ZER = 7'b0111111,
            ONE = 7'b0000110,
            TWO = 7'b1011011,
            THR = 7'b1001111,
            FOU = 7'b1100110,
            FIV = 7'b1101101,
            SIX = 7'b1111101,
            SEV = 7'b0000111,
            EIG = 7'b1111111,
            NIN = 7'b1101111;
            
reg [6:0]   dig;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        dig <= ZER;
    end
    else begin
        case (din)
            0 : dig <= ZER;
            1 : dig <= ONE;
            2 : dig <= TWO;
            3 : dig <= THR;
            4 : dig <= FOU;
            5 : dig <= FIV;
            6 : dig <= SIX;
            7 : dig <= SEV;
            8 : dig <= EIG;
            9 : dig <= NIN;
            default : dig <= ZER;
        endcase
    end
end

assign _dig = dig;

endmodule

顶层模块

连起来就可以了,没什么好说的。

module Ultrasound  (
    input   clk,
    input   rst_n,
    input   rec_data    ,
    output  trigger ,
    output  [6:0]   dig1,
	 output  [6:0]   dig2,
    output  dot1,
	 output  dot2,
	 output  drive1,
	 output  drive2
); 
    trigger_send u_trigger_send(
        .clk (clk),
        .rst_n (rst_n),
        .trigger (trigger)
    );

    wire [11:0] distance;
    data_rec u_data_rec(
        .clk (clk),
        .rst_n (rst_n),
        .rec_data (rec_data),
        .distance (distance)
    );
		
	 nixietube_1 u_nixietube_1(
        .clk (clk),
        .rst_n (rst_n),
        .din    ((distance/10)%10),
        ._dig (dig1),
        .dot_out (dot1),
		  .drive_out (drive1)
    );
	 
	 nixietube_1 u_nixietube_2(
        .clk (clk),
        .rst_n (rst_n),
        .din    ((distance/1)%10),
        ._dig (dig2),
        .dot_out (dot2),
		  .drive_out (drive2)
    );

endmodule  

引脚设置的时候,两个数码管,时钟按照小脚丫的原理图来设置,trig与echo自己设置,复位键可以用它自带的按钮。

总结

本次实验实现了使用FPGA驱动超声波模块HC_SR04,以前在小车比赛见过,但当时用的官方提供好的示例代码。现在自己也知道如何使用了,可以拿去做很多东西,收获很大。文章来源地址https://www.toymoban.com/news/detail-633324.html

到了这里,关于基于MAX-10 FPGA 读取超声波模块HC_SR04距离数据到数码管上的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的超声波测距——UART串口输出

    环境: 1、Quartus18.0 2、vscode 3、板子型号:EP4CE10F17C8 4、超声波模块:HC_SR04 要求: 使用 EP4CE10F17C8开发板驱动 超声波检测模块(HC_SR04 ),并将所测得数据显示到串口助手上。 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发

    2024年02月14日
    浏览(45)
  • 基于FPGA的超声波测距——数码管显示

    环境: 1、Quartus18.1 2、vscode 3、板子型号:EP4CE6F17C8N 4、超声波模块:HC_SR04 要求: 使用 EP4CE6F17C8开发板驱动 超声波检测模块(HC_SR04 ),并将所测得数据显示到开发板上的数码管上 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超

    2024年02月06日
    浏览(40)
  • 基于FPGA的蓝牙遥控,超声波避障,红外循迹的智能小车

            闲来无事整个小车玩玩,设想的小车可以有蓝牙模块来控制模式切换,通过发送指令来更改相对应的功能,当避障的时候可以自动规避障碍物,当处于红外循迹时,可以跟随规划的轨迹前线,当手动遥控时可以控制前进后退左右转向停止等功能。         先介绍一下

    2024年02月07日
    浏览(50)
  • 超声波测距模块HC-SR04详解(基于51单片机)

    本篇文章是个人整理的包含超声波测距模块HC-SR04的基本介绍与基本工作原理以及分别通过LCD1602、数码管和串口显示距离的实例讲解与代码的笔记,部分内容来自《HC-SR04超声波测距模块说明书》,代码使用模块化编辑,部分模块来自江科大自化协的51单片机教学视频。 希望大

    2023年04月16日
    浏览(52)
  • 【嵌入式系统应用开发】FPGA——基于HC-SR04超声波测距

    硬件 DE2-115 HC-SR04超声波传感器 软件 Quartus 18.1 使用DE2-115开发板驱动HC-SR04模块,并将所测得数据显示到开发板上的数码管。 HC-SR04 超声波测距模块可提供 2cm-400cm的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。图1为 HC-SR04 外观,

    2024年02月08日
    浏览(62)
  • 基于STM32的HC_SR04模块实现超声波测距(附源码)

    本次实验需要通过STM32与HC_SR04模块实现实时测距,并将测距信息通过串口显示在电脑上 原理 超声波测距原理是在超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时

    2024年02月11日
    浏览(49)
  • 基于51单片机驱动HC-SR04超声波模块(LCD1602显示)

    点击图片购买 HC- SR04+是一款宽电压工作的超声波测距模块。模块外形尺寸及软件与老版本 HC- SR04完全兼容;可以与老版本HC SR04无缝切换。低至3V的低工作电压, 使其与3.3V供电的MCU可以直接连接。 特点 探测角度: 15° 采用工业级MCU,工作温度:-20C~80C 探测距离:5V:2cm-- 450cm;3.3V: 2c

    2024年02月02日
    浏览(61)
  • 基于STM32的超声波HC-SR04和红外测距模块测量距离的实验对比(HAL库)

            前言: 本文主要是为了 日常普通场合 下测距做的 对比实验 ,本实验主要包含 2种模块 : 超声波测距模块 (HC-SR04)和 红外测距模块 (SHARP GP2Y0A21YK0F)。两种模块不管是测距原理和编程实验方式都是不相同的,其测距效果也存在很大差异。感兴趣的读者朋友,

    2023年04月27日
    浏览(68)
  • 输入捕获模块的使用–超声波测距

    @(MSP432P401R) 输入捕获的配置 基本默认即可 输入捕获的API的使用 参数 Capture_Mode即捕获模式,经实际测试,MSP432P401R只能使用前三种模式 Capture_CallBackFxn即回调函数 Capture_PeriodUnits即捕获周期单位 函数表 全局配置,在ti_drivers_config.c文件中生成 功能函数 文档链接:file:///D:/MSP%

    2024年02月15日
    浏览(80)
  • 13.STM32超声波模块讲解与实战

    目录 1.超声波模块讲解 2.超声波时序图 3.超声波测距步骤 4.项目实战   超声波传感器模块上面通常有两个超声波元器件,一个用于发射,一个用于接收。电路板上有4个引脚:VCC GND Trig(触发),Echo(回应)主要参数: 工作电压与电流:5V,15ma 感应距离:2-400cm 感测角度:不

    2023年04月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包