大实验:基于赛灵思csg324100T,pmodMAXsonar的危险距离警报

实验五 危险距离报警器实验报告

目录

  1. 实验目的
  2. 实验内容
  3. 实验体会
  4. 实验照片

实验目的

利用NEXYS A7及verilog代码制作危险距离报警器,借助pmod模块MaxSonar实现测距功能。应用场景包括:倒车入库刮蹭警示、汽车盲区检测防误伤、极端天气水位警报等。


实验内容

原理描述

1. 流水灯实现
  • 通过计数器cnt和led_control,实现0.2s为周期的循环流水灯。每到一个周期,流水灯向下移动一位,用case语句实现不同LED的点亮。
  • 舍弃reset端,确保流水灯通电后自动循环。
2. 三色灯原理
  • Nexys A7三色LED每种颜色高电平点亮,紫色由红蓝同时高电平实现。
  • 本实验让三色灯在距离小于10英寸时闪烁(紫色),用计数器count_1调节闪烁频率。
  • 通过判断距离的BCD码(two0&&three0)来判定是否小于10英寸。
3. CLOSE显示
  • reset为0时,调用close模块显示"CLOSE",reset为1时进行测距。
  • close模块通过数码管动态扫描显示CLOSE。
4. Pmod MaxSonar测距模块
  • 超声波测距,有效范围6255英寸(15648cm),1英寸分辨率。
  • 输出方式:UART、模拟、PWM。实验采用PWM测脉冲宽度,1英寸对应147us高电平。
  • 每49ms输出一次测距结果。
  • 与FPGA连接后,Verilog检测高电平时间,计算距离,并显示在数码管上。

Verilog HDL设计源代码

module 复制代码
 input clk,
  input reset,//控制信号,控制选择工作模式还是关闭模式
  input ultra_sound_signal,  //接受超声波的信号
  output reg rx,//与MaxSonar的RX端口连接
  output reg [6:0] sseg,//控制每段LED的亮灭
  output reg [7:0] an,//控制哪一个八位数码管工作
  output reg [15:0]led,//控制流水灯
  output reg [1:0]color_1,//控制第一个三色灯
  output reg [1:0]color_2//控制第二个三色灯
);

reg [23:0] time_; // 反射波的传播时间,23bits足够存储
wire[3:0]one,two,three; //所测量的英寸数的个位、十位、百位
reg [32:0]count;//计clk的周期,每加一就计一个周期
reg [7:0]distance; //所测的距离
wire [7:0]an_distance;//由子模块scan_seg_disp传入的,用于控制哪一个八位数码管工作
wire [6:0]sseg_distance;//由子模块scan_seg_disp传入的,用于控制每段LED的亮灭
wire [7:0]an_close;//由子模块close传入的,用于控制哪一个八位数码管工作
wire [6:0]sseg_close;//由子模块close传入的,用于控制每段LED的亮灭

///用于得到distance的代码块///
always@(posedge clk,negedge reset)  
begin
if(!reset)
    begin
        rx <= 0;
    end
else if(time_ >= 0 &&time_ <=2000)
    begin
    rx <= 1;
    time_ <= time_ + 1;
    end
else if(time_ == 4900000)
    begin
        distance <= count *255 / 3750000;
        time_ <= time_ + 1;
    end
else if(time_ == 5000000)
    begin
        time_ <= 0;
    end
else 
    begin
        time_ <= time_ + 1;
        rx <= 0;
     end
end

always@(posedge clk)
begin
    if(time_ >=2000 && time_ <= 3850000 && ultra_sound_signal == 1)
            count <= count + 1;            
    if(time_ == 4900000)
        count <= 0;
end         
///选择使用close还是scan_seg_disp传入的控制数码管的信号///
always@(posedge clk)
begin
    if(reset==1'b0)
    begin
        an<=an_close;
        sseg<=sseg_close;
    end
    else if(reset==1'b1)
    begin
        an<=an_distance;
        sseg<=sseg_distance;
    end
end
实现流水灯的代码块
reg [23:0] cnt; 
    always@(posedge clk )
    begin
        if(cnt<24'd999_9999)
        cnt<=cnt+1'b1;
        else
        cnt<=0;
    end
    reg [4:0] led_control;
    //状态切换和状态赋值
    always@(posedge clk)
    begin
        if(cnt==24'd999_9999)
            led_control<=led_control+1'b1;
        else
            led_control<=led_control;
    end
    always@(posedge clk)
    begin
        case(led_control)
            5'b00000:led<=16'b1000000000000000;
            5'b00001:led<=16'b0100000000000000;
            5'b00010:led<=16'b0010000000000000;
            5'b00011:led<=16'b0001000000000000;
            5'b00100:led<=16'b0000100000000000;
            5'b00101:led<=16'b0000010000000000;
            5'b00110:led<=16'b0000001000000000;
            5'b00111:led<=16'b0000000100000000;
            5'b01000:led<=16'b0000000010000000;
            5'b01001:led<=16'b0000000001000000;
            5'b01010:led<=16'b0000000000100000;
            5'b01011:led<=16'b0000000000010000;
            5'b01100:led<=16'b0000000000001000;
            5'b01101:led<=16'b0000000000000100;
            5'b01110:led<=16'b0000000000000010;
            5'b01111:led<=16'b0000000000000001;
            5'b10000:led<=16'b0000000000000001;
            5'b10001:led<=16'b0000000000000010;
            5'b10010:led<=16'b0000000000000100;
            5'b10011:led<=16'b0000000000001000;
            5'b10100:led<=16'b0000000000010000;
            5'b10101:led<=16'b0000000000100000;
            5'b10110:led<=16'b0000000001000000;
            5'b10111:led<=16'b0000000010000000;
            5'b11000:led<=16'b0000000100000000;
            5'b11001:led<=16'b0000001000000000;
            5'b11010:led<=16'b0000010000000000;
            5'b11011:led<=16'b0000100000000000;
            5'b11100:led<=16'b0001000000000000;
            5'b11101:led<=16'b0010000000000000;
            5'b11110:led<=16'b0100000000000000;
            5'b11111:led<=16'b1000000000000000;
        endcase
    end
//用于实现三色灯的代码块/
reg [23:0]count_1;
always@(posedge clk)
begin
    if(count_1<24'd10000001)
        count_1<=count_1+1;
    else if(count_1==24'd10000001)
        count_1<=1'b0;
end    

always@(posedge clk)
begin
    if(count_1<24'd10000000&&count_1>24'd6000000&&two==3'd0&&three==3'd0&&reset==1'b1)
        begin
            color_1<=2'b11;
            color_2<=2'b11;    
        end
    else 
        begin
            color_1<=2'b00;
            color_2<=2'b00;    
        end
end
//三个子模块的实例化/
bintobcd8 bintobcd_1(
.clk(clk),
.rst(reset),
.bin(distance),
.one(one),
.ten(two),
.hun(three)
);
scan_seg_disp scan_seg_disp_1(
.clk(clk),
.rst(reset),
.one(one),
.ten(two),
.hun(three),
.an_d(an_distance),
.sseg_d(sseg_distance)
);    
close close1(
.clk(clk),
.sseg_c(sseg_close),
.an_c(an_close)
);
endmodule
///将二进制表示的distance转化为十进制数(左移加三法)///
module bintobcd8(
    input clk, rst,
    input [7:0] bin,
    output reg [3:0]one,ten,hun);
    reg [17:0] shift_reg;
    reg [3:0] count;//这里count是用来表示移位次数的

    always@(posedge clk, negedge rst)
    if(!rst) begin//复位
        one=0;
        ten=0;
        hun=0;
        shift_reg=0;
        count=0;
        end
	else begin
	 	if (count == 0)
        shift_reg = {10'd0, bin};
        if (count < 4'd8) begin
            count = count+1;
            if (shift_reg[11:8]>4)//[11:8]与[15:12]是移位的8位
                shift_reg[11:8]= shift_reg[11:8]+2'b11;
            if (shift_reg[15:12]>4)
                shift_reg[15:12] = shift_reg[15:12]+2'b11;
        shift_reg[17:1] = shift_reg[16:0];
        end
        else if (count==4'd8)  begin
            one= shift_reg[11:8];
            ten = shift_reg[15:12];
            hun= {2'b00,shift_reg[17:16]};
            count = count+1;
            end
            else 
            count = count-9;
        end
endmodule

///将得到的距离的BCD码转换为数码管显示
module scan_seg_disp (
    input clk, rst,
    input [3:0] one, ten, hun,
    output reg [7:0] an_d,//控制8位数码管
    output reg [6:0] sseg_d//控制8位数码管的每一段,这里不包含小数
    );

    localparam N=20;
    reg [N-1:0] cnt;
    reg [3:0] hex;

    always @(posedge clk , negedge rst)//敏感列表里应该与计数器里的保持一致,这样才能同时激活运行
    begin
        if(!rst) begin//复位
            cnt = 0;  
            hex = 4'd10;
        end
    else begin//分频
        cnt = cnt + 1;
        case (cnt[N-1:N-2])
        2'b00:begin
         hex = one;
        an_d = 8'b11111110;
        end
        2'b01:begin
        hex = ten;
        an_d = 8'b11111101;
        end
        2'b11:begin
        hex = hun;
        an_d = 8'b11111011;
        end
        endcase
       end
	end

    always@ (*)
        case(hex)当相应的管脚为低电平0时,点亮该段Led。
        4'h0:sseg_d[6:0] = 7'b0000001;
        4'h1:sseg_d[6:0] = 7'b1001111;
        4'h2:sseg_d[6:0] = 7'b0010010;
        4'h3:sseg_d[6:0] = 7'b0000110;
        4'h4:sseg_d[6:0] = 7'b1001100;
        4'h5:sseg_d[6:0] = 7'b0100100;
        4'h6:sseg_d[6:0] = 7'b0100000;
        4'h7:sseg_d[6:0] = 7'b0001111;
        4'h8:sseg_d[6:0] = 7'b0000000;
        4'h9:sseg_d[6:0] = 7'b0000100;
        default:
        sseg_d[6:0] = 7'b1111111;
        endcase
endmodule
///当reset置为0时,用于显示close的模块//
module close(
        input clk,
        output [6:0]sseg_c,
        output [7:0]an_c
    );
wire [25:0]slow_clk;

//模块的实例化,close模块的功能由这两个子模块承担
slow_clk slow_clk1(
    .clk(clk),
    .slow_clk(slow_clk)
);
LED LED1(
       .clk(clk),
       .slow_clk(slow_clk),
       .control(sseg_c),
       .an_LED(an_c)
);

endmodule
/close模块让数码管显示的功能由此模块承担/
module LED(
        input clk,
        input [25:0]slow_clk,
        output reg [6:0]control,
        output reg [7:0]an_LED
);
wire [6:0]controlE=7'b0110000;
wire [6:0]controlS=7'b0100100;   
wire [6:0]controlO=7'b0000001;
wire [6:0]controlL=7'b1110001;
wire [6:0]controlC=7'b0110001;

always@(posedge clk)//控制三段数码管的亮灭,使人眼看到的三段数码管常亮
        begin
        if(slow_clk[19:17]==3'b000)
        begin
            an_LED<=8'b11111110;
            control<=controlE;
        end
        else if(slow_clk[19:17]==3'b010)
        begin
            an_LED<=8'b11111101;
            control<=controlS;
        end
        else if(slow_clk[19:17]==3'b100)
        begin
            an_LED<=8'b11111011;
            control<=controlO;
        end
        else if(slow_clk[19:17]==3'b110)
        begin
            an_LED<=8'b11110111;
            control<=controlL;
        end    
        else if(slow_clk[19:17]==3'b111)
        begin
            an_LED<=8'b11101111;
            control<=controlC;
        end
    end
endmodule
//close模块的分频工作由这个模块承担
module slow_clk(//分频
    input clk,
    output reg [25:0]slow_clk
);

always@(posedge clk)
    slow_clk<=slow_clk+1;
endmodule

XDC文件配置



(4)下板测试

Ps:流水灯不便使用单张照片演示,以下图片的拍摄过程中流水灯在一直运行,作装饰用。

①当reset(v10端口)置为0时,不工作,显示CLOSE

②当reset(v10端口)置为1时,开始工作,显示距离,单位为英寸

③当reset(v10端口)置为1时,开始工作,显示距离,且当距离小于10英寸时三色灯闪烁(紫光)

3.实验体会

①.通过对pmod模块MaxSonar的使用,我们更深刻的理解了FPGA的可扩展性------通过连接不同的pmod模块可以实现各种各样的功能。

复制代码
 ②.搞清楚硬件的工作原理是重中之重,最初我们认为MaxSonar与老式的测距仪器相同------即发送超声波与接受超声波,之后经过查资料发现它的原理与老式的不同。经过这次教训,后来我们便更注重硬件的工作原理,少走了很多弯路。

 ③.经过这次实验,我们对verilog语言的认识更进了一步,解决了实验过程中很多的代码问题,诸如并行驱动问题、数据截断问题、模块调用问题,等等。

 ④.硬件的使用应与现实生活紧密结合起来,最好可以提供一些解决现实问题的思路,将硬件功能与硬件应用结合起来,例如本实验的硬件实现的功能便是测距,在此基础上,结合现实问题,我们联想到了这个功能可能用于水位检测,车辆盲区检测等场景。

⑤.两个人的实验我们合理分工,各自攻坚,遇到问题时共同思考交流学习,认识到团队协作的重要性。

⑥.学会查找资料并耐心阅读,有很多外文的,需要我们运用翻译工具,之前一直不知道WPS里PDF可以划词翻译,发现以后效率提高了不少。

相关推荐
Hello-FPGA17 小时前
基于RFSOC FPGA ZCU216 的CoaXPress 采集demo
fpga开发
9527华安19 小时前
FPGA基于ADV7182解码PAL视频,Video Processing Subsystem去隔行,提供6套工程源码和技术支持
fpga开发·音视频·pal·adv7182
hahaha601619 小时前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
GateWorld19 小时前
Xilinx 7系列FPGA时钟网络详解
fpga开发·时钟网络·xilinx 7系列
szxinmai主板定制专家1 天前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
szxinmai主板定制专家2 天前
AMR 项目落地:机器人控制器硬件定制化需求复盘
arm开发·单片机·fpga开发·系统架构·机器人·am62x
FPGA小迷弟3 天前
FPGA 与卫星:从星载硬件到在轨智能的完整技术解析
fpga开发·架构·fpga·1024程序员节·无线电
NamoAmitabha1283 天前
CPU 内部结构是什么?---deepseek
fpga开发
abc light3 天前
ARM 裸机开发(6)——时钟树与定时器
arm开发·单片机·fpga开发
156082072193 天前
JFMZQ28DR、JFMZQ68DR、RFsoc XCZU47DR、XCZU48DR 信号处理板
fpga开发·信号处理