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

这篇具有很好参考价值的文章主要介绍了基于FPGA的超声波测距——UART串口输出。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

环境:
1、Quartus18.0
2、vscode
3、板子型号:EP4CE10F17C8
4、超声波模块:HC_SR04
要求:
使用 EP4CE10F17C8开发板驱动 超声波检测模块(HC_SR04 ),并将所测得数据显示到串口助手上。


一、超声波模块介绍

1、产品特点

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

(1)采用IO口 TRIG触发测距,给最少10us的高电平信呈。
(⑵)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;

基于FPGA的超声波测距——UART串口输出,FPGA,fpga开发

2、超声波模块的时序图

基于FPGA的超声波测距——UART串口输出,FPGA,fpga开发

以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。

二、系统设计

1、系统模块框图

基于FPGA的超声波测距——UART串口输出,FPGA,fpga开发

2、RTL视图

基于FPGA的超声波测距——UART串口输出,FPGA,fpga开发

三、源码

1、div_clk_us(1us的分频)

/**************
芯片晶振为50MHZ,HC_SR04需要一个10us的以上脉冲触发信号
所以这里我们需要对系统时钟进行分频,方便我们产生10us的持续电平
**************/
module div_clk_us (
    input sys_clk,
    input sys_rst_n,

    output wire  clk_us
);

//根据晶振换算,1us只需要计数50次即可

parameter [5:0] MAX_us = 6'd49;
reg [5:0] cnt;
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)begin
        cnt <= 6'd0;
    end
    else if(cnt == MAX_us)begin
        cnt <= 6'd0;
    end
    else begin
        cnt <= cnt + 6'd1;
    end
end
assign clk_us = cnt >= MAX_us;
endmodule

2、产生驱动超声波的信号

/****************
根据分频的1us时钟,产生一个持续10us的电平用于驱动HC_SR04
最好是稍微大于10us,这样稳妥一些
****************/
module trig_driver(
    input       sys_us        ,//1us时钟
    input       sys_rst_n     ,

    output      trig          //驱动超声波的信号
);

parameter T = 19'd29_9999;//设置触发信号的周期,这里设置得越小,其触发越频繁,应该返回的距离更新更频繁

reg [18:0] cnt;

always @(posedge sys_us) begin// or negedge sys_rst_n
    if(!sys_rst_n)begin
        cnt <= 19'd0;
    end
    else if(cnt == T)begin
        cnt <= 19'd0;
    end
    else begin
        cnt <= cnt + 1'd1;
    end
end
//15us的高电平
assign trig = (cnt <15 ) ? 1'b1 : 1'b0;//正确的,只是时间太短,观察不到,目前应该是串口问题
endmodule

3、串口发送模块

module uart_send
#(
    parameter  CLK        =   26'd50000000    ,    // 时钟频率
    parameter  BAUD        =   17'd115200           // 波特率
)
(
    input   wire            clk         ,
    input   wire            rstn        ,   
    input   wire    [7 : 0] data_in     ,   // 需要发送的数据
    input   wire            flag_in     ,   // 数据接收标志位,既发送标志位

    output  wire            tx_done     , 
    output  reg             UART_tx         // 串口输出位         
);

    localparam Baud_Clk     =   CLK/BAUD       ;    // 传输每个 Baud 需要的时钟数

    reg             tx_en       ;   // 发送使能
    reg             flag_bit    ;   // 比特标志位,采用下降沿发送
    reg [8 : 0]     cnt_baud    ;   // 波特率计数器
    reg [3 : 0]     cnt_bit     ;   // 比特计数器

    assign tx_done = cnt_bit == 4'd9 && flag_bit == 1'b1;

    // 发送使能
    always @(posedge clk or negedge rstn) begin
        if(!rstn) begin
            tx_en <= 1'b0;
        end
        // 已经发送了十位 bit 并且到达下一个下降沿,输入只需要判断到数据位最后一位,输出则需要判断完整输出
        else if(cnt_bit == 4'd9 && flag_bit == 1'b1) begin
            tx_en <= 1'b0;
        end
        else if(flag_in == 1'b1) begin
            tx_en <= 1'b1;
        end
    end

    // 波特计数器
    always @(posedge clk or negedge rstn) begin
        if(!rstn) begin
            cnt_baud <= 9'd0;
        end
        // 传输完成所有波特或者使能失效,表示发送结束
        else if(cnt_baud == Baud_Clk - 1'b1 || tx_en == 1'b0) begin
            cnt_baud <= 9'd0;
        end
        else begin
            cnt_baud <= cnt_baud + 9'd1;
        end
    end

    always @(posedge clk or negedge rstn) begin
        if(!rstn) begin
            flag_bit <= 1'b0;
        end
        // 只有刚开始发送的一瞬间会产生一个时钟周期上升沿和下降沿
        else if(cnt_baud == 9'd1) begin
            flag_bit <= 1'b1;
        end
        else begin
            flag_bit <= 1'b0;
        end
    end

    // 计数10分有效数据位
    always @(posedge clk or negedge rstn) begin
        if(!rstn) begin
            cnt_bit <= 4'd0;
        end
        // 已经发送了十位 bit 并且到达下一个下降沿
        else if(cnt_bit == 4'd9 && flag_bit == 1'b1) begin
            cnt_bit <= 4'd0;
        end
        // 使能有效,下降沿发送数据
        else if(flag_bit == 1'b1 && tx_en == 1'b1) begin
            cnt_bit <= cnt_bit + 4'd1;
        end
        else begin
            cnt_bit <= cnt_bit;
        end
    end

    // 满足 RS232 协议 起始位为 0,停止位为 1,并按位输出
    always @(posedge clk or negedge rstn) begin
        if(!rstn) begin
            UART_tx <= 1'd1;
        end
        // 下降沿发送数据
        else if(flag_bit == 1'b1) begin
            case (cnt_bit)
                0:       UART_tx <= 1'd0        ;
                1:       UART_tx <= data_in[0]  ;
                2:       UART_tx <= data_in[1]  ;
                3:       UART_tx <= data_in[2]  ;
                4:       UART_tx <= data_in[3]  ;
                5:       UART_tx <= data_in[4]  ;
                6:       UART_tx <= data_in[5]  ;
                7:       UART_tx <= data_in[6]  ;
                8:       UART_tx <= data_in[7]  ;
                9:       UART_tx <= 1'd1        ;
                default: UART_tx <= 1'd1        ;
            endcase
        end
    end
endmodule //UART_send

4、HC_SR04_uart(顶层文件)

module HC_SR04_uart(
    input               sys_clk       ,
    input               sys_rst_n     ,
    input               echo          ,
    input        		uart_rx		  , // 串口输入 

    output              trig          ,         
    output              uart_tx       //串口发送端口
);
wire             clk_us;
wire [18:0]      data_o_r;//待发送的数据
//时钟分频
div_clk_us div_clk_us_inst(
    /*input */      .sys_clk         (sys_clk  ),
    /*input */      .sys_rst_n       (sys_rst_n),

    /*output*/      .clk_us          (clk_us)
);
//产生驱动超声波信号
trig_driver trig_driver_inst(
    /*input */      .sys_us        (clk_us),//1us时钟
    /*input */      .sys_rst_n     (sys_rst_n),

    /*output*/      .trig          (trig)//驱动超声波的信号
);
//对返回来的echo信号进行计算得出距离
echo_driver echo_driver_inst(
    /*input        */   .sys_clk         (sys_clk),
    /*input        */   .sys_us          (clk_us),
    /*input        */   .sys_rst_n       (sys_rst_n),
    /*input        */   .echo            (echo),

    /*output [18:0]*/   .data_o          (data_o_r)//检测距离,保留三位小数,*1000实现
);
//初步想法是使用串口发送模块直接操作,不需要串口回环,否则需要发送到接收,接收模块再发送给发送模块,发送模块再发送给PC
uart_driver2 uart_driver2_inst(
	.clk         (sys_clk  ),
	.rstn        (sys_rst_n),
	.data_in	 (data_o_r	),
    .UART_rx     (uart_rx),

	.UART_tx     (uart_tx	)
);
endmodule

四、效果

FPGA串口输出测距信息


五、总结

前面写过FPGA测距的数码管显示,STM32的测距串口输出,其实这篇文章的内容之前完成过。由于前面又学习了一边串口回环,所以又敲了一遍,实现一下FPGA的串口输出。虽然做过,但是还是折腾了一天,仿真、SignalTap II 抓了一下午的信号。但这次比上一次的理解更加深刻,收获更多。

六、参考资料

1、基于FPGA的超声波测距——数码管显示
2、源码:https://github.com/no1jiangjiang/HC-SR04_uart_FPGA文章来源地址https://www.toymoban.com/news/detail-622865.html

到了这里,关于基于FPGA的超声波测距——UART串口输出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【嵌入式系统应用开发】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)
  • FPGA一键测距仪之超声波模块篇

    FPGA一键测距仪之数码管篇 FPGA一键测距仪之[按键+控制+蜂鸣器]篇 FPGA一键测距仪之终篇 第一个FPGA小项目:基于BASYS3的超声波一键测距仪 本篇会对超声波测距模块进行详细的讲解,包括测距原理、各模块的时序图构思以及代码实现。 所用到的软件工具: Vivado 2019.1 Modelsim SE

    2024年02月02日
    浏览(51)
  • 基于STM32的超声波测距

    一、HC-SR04模块介绍 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可高达3mm;模块包括超声波发射器、接收器、与控制电路。 模块的基本工作原理为: (1)采用 IO口 TRIG触发测距,给最少 10us的高电平信呈。 (2)模块自动发送 8个 40khz的方波,自动检测是

    2024年02月13日
    浏览(47)
  • 基于单片机超声波测距语音播放

    一、系统方案 本设计采用52单片机作为主控器,HC-SR04测距,液晶1602显示,按键设置报警阀值,语音报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 uint dist; // 保存超声波模块测量到的结果 2、液晶显示程序 / / // 1602液晶写命令函数,cmd就是要写

    2024年02月09日
    浏览(51)
  • 基于STM32超声波测距系统设计

    随着社会的发展和科技的进步,人们对测距的要求越来越高,特别是在一些要求实时测距的场合,传统的测距方式已经无法满足人们的需求,而超声波测距由于其非接触和实时反馈的特点在生活中得到广泛应用。 本系统硬件部分由电源模块、控制模块、显示模块、报警模块、

    2024年02月04日
    浏览(55)
  • 基于单片机的超声波语音测距系统

    一、系统方案 超声波具有指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的

    2024年02月10日
    浏览(54)
  • 基于STM32_HAL库实现超声波测距

    核心板               : STM32F103C8T6。 超声波测距模块 : HC-SR04超声波测距模块 实验目的            : 利用超声波测距,将测量的距离打印在串口并输出。 HC-SR04超声波测距模块介绍         接口定义:Vcc、 Trig(控制端——PA2)、 Echo(接收端——PA11)、 Gnd        

    2024年02月16日
    浏览(52)
  • 基于51单片机的超声波测距及温度显示

    (仿真+程序+PCB+原理图+设计报告) 功能介绍 具体功能: 1.超声波测距传感器HC-SR04、温度传感器DS18B20将检测的数据传给51单片机; 2.LCD1602实时显示测得的距离和温度; 3.按键可以设置距离的上下限; 4.距离超过设定范围,蜂鸣器+LED产生声光报警; ​演示视频: 基于5

    2024年04月24日
    浏览(51)
  • 基于c51单片机超声波测距仪

            整个系统由AT89C51,超声波电路,显示电路和报警电路,按键控制组成,系统复位后,首先对各模块进行初始化,初始化后根据超声波模块返回的回波进行数据计算,把数据显示到LMO16L液晶显示器上,并与设定的报警值相比较,小于报警值则蜂鸣器响起、指示灯亮

    2024年02月04日
    浏览(54)
  • 基于Arduino单片机超声波测距仪设计

    文章目录 摘  要 1.课程设计任务 1.1课程设计题目 1.2设计的要求 2.设计总体方案 2.1初步设计方案 2.2各个单元电路的设计要求 2.3主要性能指标 2.4总体方案 3.单元模块设计 3.1显示模块 3.2超声波测距模块 3.3蜂鸣器模块 3.4电机模块 3.5 LED二极管模块 4.软件流程图 5.设计代码 5.1核

    2024年02月11日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包