阳光保险网站温州平阳县网站建设兼职

当前位置: 首页 > news >正文

阳光保险网站,温州平阳县网站建设兼职,石家庄学做网站建设培训学校,公司网站建站收费文章目录 前言一、超声波模块介绍1、产品特点2、超声波模块的时序图 二、系统设计1、系统模块框图2、RTL视图 三、源码1、div_clk_us(1us的分频)2、产生驱动超声波的信号3、串口发送模块4、HC_SR04_uart(顶层文件) 四、效果五、总结六、参考资料 前言 环境#xff1a; 1、Quar… 文章目录 前言一、超声波模块介绍1、产品特点2、超声波模块的时序图 二、系统设计1、系统模块框图2、RTL视图 三、源码1、div_clk_us(1us的分频)2、产生驱动超声波的信号3、串口发送模块4、HC_SR04_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; 2、超声波模块的时序图 以上时序图表明你只需要提供一个10uS 以上脉冲触发信号该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。 二、系统设计 1、系统模块框图 2、RTL视图 三、源码 1、div_clk_us(1us的分频) /************** 芯片晶振为50MHZHC_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 6d49; reg [5:0] cnt; always (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)begincnt 6d0;endelse if(cnt MAX_us)begincnt 6d0;endelse begincnt cnt 6d1;end end assign clk_us cnt MAX_us; endmodule2、产生驱动超声波的信号 /************* 根据分频的1us时钟产生一个持续10us的电平用于驱动HC_SR04 最好是稍微大于10us这样稳妥一些 ****************/ module trig_driver(input sys_us ,//1us时钟input sys_rst_n ,output trig //驱动超声波的信号 );parameter T 19d29_9999;//设置触发信号的周期这里设置得越小其触发越频繁应该返回的距离更新更频繁reg [18:0] cnt;always (posedge sys_us) begin// or negedge sys_rst_nif(!sys_rst_n)begincnt 19d0;endelse if(cnt T)begincnt 19d0;endelse begincnt cnt 1d1;end end //15us的高电平 assign trig (cnt 15 ) ? 1b1 : 1b0;//正确的只是时间太短观察不到目前应该是串口问题 endmodule3、串口发送模块 module uart_send #(parameter CLK 26d50000000 , // 时钟频率parameter BAUD 17d115200 // 波特率 ) (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 4d9 flag_bit 1b1;// 发送使能always (posedge clk or negedge rstn) beginif(!rstn) begintx_en 1b0;end// 已经发送了十位 bit 并且到达下一个下降沿输入只需要判断到数据位最后一位输出则需要判断完整输出else if(cnt_bit 4d9 flag_bit 1b1) begintx_en 1b0;endelse if(flag_in 1b1) begintx_en 1b1;endend// 波特计数器always (posedge clk or negedge rstn) beginif(!rstn) begincnt_baud 9d0;end// 传输完成所有波特或者使能失效表示发送结束else if(cnt_baud Baud_Clk - 1b1 || tx_en 1b0) begincnt_baud 9d0;endelse begincnt_baud cnt_baud 9d1;endendalways (posedge clk or negedge rstn) beginif(!rstn) beginflag_bit 1b0;end// 只有刚开始发送的一瞬间会产生一个时钟周期上升沿和下降沿else if(cnt_baud 9d1) beginflag_bit 1b1;endelse beginflag_bit 1b0;endend// 计数10分有效数据位always (posedge clk or negedge rstn) beginif(!rstn) begincnt_bit 4d0;end// 已经发送了十位 bit 并且到达下一个下降沿else if(cnt_bit 4d9 flag_bit 1b1) begincnt_bit 4d0;end// 使能有效下降沿发送数据else if(flag_bit 1b1 tx_en 1b1) begincnt_bit cnt_bit 4d1;endelse begincnt_bit cnt_bit;endend// 满足 RS232 协议 起始位为 0停止位为 1并按位输出always (posedge clk or negedge rstn) beginif(!rstn) beginUART_tx 1d1;end// 下降沿发送数据else if(flag_bit 1b1) begincase (cnt_bit)0: UART_tx 1d0 ;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 1d1 ;default: UART_tx 1d1 ;endcaseendend endmodule //UART_send4、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