ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【案例】超声波测距系统设计

【案例】超声波测距系统设计 1.1 总体设计1.1.1 概述学习了明德扬至简设计法和明德扬设计规范本人用FPGA设计了一个测距系统。该系统采用超声波进行测量距离再在数码管上显示。在本案例的设计过程中包括了超声波的驱动、三线式数码管显示等技术。经过逐步改进、调试等一系列工作后最终完成了此设计并进行上板验证下面将完整的设计记录与大家分享。1.1.2 设计目标此系统将实时显示前方障碍与装置之间的距离。1.1.3 系统结构框图系统结构框图如下所示1.1.4 模块功能hc_sr04模块实现功能该模块通过控制触发信号trig10us的TTL使内部循环发出8个40KHZ脉冲即驱动超声波接收回响信号echo通过echo得到距离。显示模块实现功能该模块完成了对所测距离通过数码管对其显示。1.1.5顶层信号1.1.6顶层代码module top(clk ,rst_n ,echo ,trig , sel, seg ); input clk ; input rst_n ; input echo ; output trig ; wire [3:0] s_g ; wire [3:0] s_s ; wire [3:0] s_b ; wire [3:0] s_q ; output [7:0] sel ; output [7:0] seg ; hc_sr04 hc_sr04_1( .clk (clk) , .rst_n (rst_n) , .echo (echo) , .trig (trig) , .s_g (s_g ), .s_s (s_s ), .s_b (s_b ), .s_q (s_q ) ); seg_disp u_seg_disp( .clk (clk ), .rst_n (rst_n), .segment_data({s_q,s_b,s_s,s_g}), .segment (seg ), .seg_sel (sel ) ); endmodule1.2 hc_sr04模块设计1.2.1 接口信号1.2.2 设计思路我们只需要提供一个短期的10uS脉冲触发信号trig该模块内部将发出8个40kHz周期电平并检测回波一旦检测到有回波信号则输出回响信号回响信号echo是一个脉冲的宽度成正比的距离变量可通过发射信号到收到的回响信号时间间隔可以计算得到距离。建议测量周期为60ms以上以防止发射信号对回响信号的影响这里我们采用的是1s测量一次。时钟计数器cnt0用于计算 1 秒的时钟个数加一条件为1表示一直计数结束条件为数到 TIME_1S 表示数到 1 秒就清零。距离计数器 h_cnt用于计算flag为高电平的宽度的时间如果flag为1h_cnt就加一每完成1秒计数后h_cnt就变为0此外h_cnt等于h_cnt。模块时序图1.2.3 参考代码module hc_sr04(clk ,rst_n ,echo ,trig , s_g , s_s , s_b , s_q ); parameter DATA_W 14 ; parameter TIME_1S 50_000_000; input clk ; input rst_n ; input echo ; output trig ; output[ 3:0] s_g ; output[ 3:0] s_s ; output[ 3:0] s_b ; output[ 3:0] s_q ; wire trig ; reg [ 3:0] s_g ; reg [ 3:0] s_s ; reg [ 3:0] s_b ; reg [ 3:0] s_q ; reg [DATA_W-1:0] distance; reg [25:0] cnt0 ; reg [20:0] h_cnt ; reg echo_2 ; reg echo_1 ; wire add_cnt0; wire end_cnt0; wire flag_h ; wire flag_l ; always (posedge clk or negedge rst_n)begin if(!rst_n)begin cnt0 0; end else if(add_cnt0)begin if(end_cnt0) cnt0 0; else cnt0 cnt0 1b1; end end assign add_cnt0 1; assign end_cnt0 add_cnt0 cnt0 TIME_1S - 1; assign trig (cnt0500cnt01000)?1:0; always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin echo_1 0; echo_2 0; end else begin echo_1 echo ; echo_2 echo_1; end end always (posedge clk or negedge rst_n)begin if(!rst_n)begin h_cnt 0; end else if(add_h_cnt)begin if(end_h_cnt) h_cnt 0; else h_cnt h_cnt 1; end else if(end_cnt0)begin h_cnt 0; end end assign add_h_cnt echo_2; assign end_h_cnt 0 ; always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin distance 0; end else if(add_cnt0 cnt0 45_000_000-1)begin distance h_cnt*34/10000; end end always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin s_g 0; end else begin s_g distance%10; end end always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin s_s 0; end else begin s_s (distance/10)%10; end end always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin s_b 0; end else begin s_b (distance/100)%10; end end always (posedge clk or negedge rst_n)begin if(rst_n1b0)begin s_q 0; end else begin s_q (distance/1000)%10; end endendmodule1.3 显示模块设计1.3.1接口信号1.3.2设计思路该模块对数码管的位选信号sel每隔1ms的时间移位一次也就是1ms循环亮一个灯由于1ms的频率肉眼观察不出我们看到的就是4个灯全亮。对输入距离distance进行求余处理得到每一位的数据通过case语句让每一位数据形成段选信号通过位选信号的控制显示在对应的数码管上。1.3.3参考代码module seg_disp(clk ,rst_n ,segment_data,segment ,seg_sel);parameter ZERO 8’b1100_0000 ;parameter ONE 8’b1111_1001 ;parameter TWO 8’b1010_0100 ;parameter THREE 8’b1011_0000 ;parameter FOUR 8’b1001_1001 ;parameter FIVE 8’b1001_0010 ;parameter SIX 8’b1000_0010 ;parameter SEVEN 8’b1111_1000 ;parameter EIGHT 8’b1000_0000 ;parameter NINE 8’b1001_0000 ;input clk ;input rst_n ;input [31:0] segment_data ;output [7:0 ] segment ;output [7:0 ] seg_sel ;reg [7:0 ] segment ;reg [7:0 ] seg_sel ;reg [10:0] delay ;reg [3:0 ] delay_time ;wire add_delay_time ;wire end_delay_time ;wire add_delay ;wire end_delay ;wire [3:0 ] segment_tmp ;always (posedge clk or negedge rst_n) beginif (rst_n0) begindelay 0;endelse if(add_delay) beginif(end_delay)delay 0;elsedelay delay1 ;endendassign add_delay 1;assign end_delay add_delay delay 2000-1 ;always (posedge clk or negedge rst_n) beginif (rst_n0) begindelay_time 0;endelse if(add_delay_time) beginif(end_delay_time)delay_time 0;elsedelay_time delay_time1 ;endendassign add_delay_time end_delay;assign end_delay_time add_delay_time delay_time 8-1 ;assign segment_tmp segment_data[(1delay_time)*4-1 -:4];always (posedge clk or negedge rst_n)beginif(rst_n1’b0)beginsegment ZERO;endelse begincase(segment_tmp)4’d0:segment ZERO;4’d1:segment ONE ;4’d2:segment TWO ;4’d3:segment THREE;4’d4:segment FOUR ;4’d5:segment FIVE ;4’d6:segment SIX ;4’d7:segment SEVEN;4’d8:segment EIGHT;4’d9:segment NINE ;default:beginsegment segment;endendcaseendendalways (posedge clk or negedge rst_n)beginif(rst_n1’b0)beginseg_sel 8’b1111_1111;endelse beginseg_sel ~(8’b1delay_time);endendendmodule1.4 效果和总结上板验证效果在这个设计中使用明德扬的至简设计法让我的思路非常清晰逻辑非常严谨虽然没有做到一遍成功但在调试过程中我都比较快速的找到问题并快速解决。对于学习FPGA的同学我非常推荐使用明德扬至简设计法和明德扬模块进行学习和设计。教学视频和工程源代码请移步明德扬论坛学习好消息FPGA至简设计200例已更新学习链接https://pan.baidu.com/s/181l9fKI8BXwR7HuAF-ok0w 提取码yt5p【FPGA至简设计200例】毕业设计案例由浅入深步骤性教学明德扬温馨提示明德扬2023推出了全新课程——逻辑设计基本功修炼课降低学习FPGA门槛的同时增加了学习的趣味性并组织了考试赢积分活动http://www.mdy-edu.com/ffkc/415.html点击→了解课程详情☝明德扬 FPGA 产品官网https://www.mdyfpga.cn/
返回列表