FPGA入门实验-基于状态机实现超声波避障小车

任务目标

基于状态机实现超声波避障小车。最近生产实习的FPGA培训课程内容,还是挺简单的。具体原理其他文章应该都烂大街了,重点是状态机的写法,还是很少博主写,没怎么看到,基本上都是时序机写的模块功能。

电机驱动用的L298N,默认全速拉满,没用PWM调制速度。

实现代码

整改TOP逻辑涉及电机控制,超声波测距,数码管显示超声波读数。后面两个模块之前的文章都写了代码的。这里我就直接引用吧,不做过多篇幅了。

数码管显示seg.v和超声波测距trasonic.v:

FPGA入门实验-基于状态机实现4位共阴极数码管显示超声波模块读数_星羽空间的博客-CSDN博客FPGA基于状态机实现4位共阴极数码管显示超声波模块读数https://blog.csdn.net/qq_25662827/article/details/125213391这里增添了L298N电机驱动代码:

module MOTOR(
    input sysclk,
    input rst_n,
	input ENA,
	input ENB,
	input	[1:0]	ATRUN,
	input	[1:0]	BTRUN,
	output	reg	[1:0]	EN,
	output	reg	[1:0]	AIN,
	output	reg	[1:0]	BIN
);

always@(posedge sysclk)	begin
    if(!rst_n) begin
        EN <= 2'b00;
        AIN <= 2'b00;
        BIN <= 2'b00;
        end
    else
        begin
        EN <= {ENB ,ENA};
        AIN <= ATRUN;
        BIN <= BTRUN;
        end
	end

endmodule

最后就剩顶层逻辑了。也是状态机实现的。并且做了二阶均值滤波,让超声波读数平滑一点,减少噪声,TOP.v:

module top(
    input           sysclk      ,
    input           rst_n       ,
    input           Echo        ,
    output          Trig        ,
    output  [7:0]   SEG         ,
    output  [3:0]   DIG         ,
    output  [1:0]   AIN         ,
    output  [1:0]   BIN
    );

wire    [15:0]  numtemp ;
reg     [15:0]  num     ;
reg     [1:0]   ATRUN   ;
reg     [1:0]   BTRUN   ;
wire    [1:0]   MOTOREN ;

reg     [31:0]  cnt     ;
reg     [1:0]   cur_state, next_state;
parameter   IDLE    =   2'b00;
parameter   GO      =   2'b01;
parameter   STOP    =   2'b10;
parameter   TRUN    =   2'b11;
parameter   DELAY   =   32'd62_500_000;
parameter   THRESHHOLD   =   15'd25;
reg             goflag;

seg
#(
     .SYSCLK    (125_000_000)   ,
     .TIME      (1000)          ,
     .MODE      (0)
)a(
       .sysclk  (sysclk)    ,
       .rst_n   (rst_n)     ,
       .set     (10)        ,
       .number  (num)       ,
       .DIG     (DIG)       ,
       .SEG     (SEG)
    );

trasonic
#(
    .SYSCLK  (125_000_000)      ,
    .TIME1   (5000       )      ,
    .TIME2   (20_000_000 )
)b(
    .sysclk  (sysclk)  ,
    .rst_n   (rst_n)   ,
    .Echo    (Echo)    ,
    .Trig    (Trig)    ,
    .distence(numtemp)
    );

MOTOR c(
    .sysclk(sysclk),
    .rst_n(rst_n),
	.ENA(1'b1),
	.ENB(1'b1),
	.ATRUN(ATRUN),
	.BTRUN(BTRUN),
	.EN(MOTOREN),
	.AIN(AIN),
	.BIN(BIN)
);

//____________________state1______________________//
always@(posedge sysclk)
    if(!rst_n)
        cur_state <= IDLE;
    else
        cur_state <= next_state;

//____________________state2______________________//
always@(*)begin
    next_state = IDLE;
    case(cur_state)
        IDLE:begin
            next_state = GO;
        end
        GO:begin
            if(num < THRESHHOLD)
                next_state = STOP;
            else
                next_state = GO;
        end
        STOP:begin
            if(cnt >= DELAY - 1)
                if(goflag)
                    next_state = TRUN;
                else if(num >= THRESHHOLD)
                    next_state = GO;
                else
                    next_state = TRUN;
            else
                next_state = STOP;
        end
        TRUN:begin
            if(num>= THRESHHOLD)
                next_state = STOP;
            else
                next_state = TRUN;
        end
    endcase
    end

//________________________state3______________________//
always@(posedge sysclk)
    if(!rst_n)begin
        cnt <= 32'd0;
        ATRUN <= 2'b00;
        BTRUN <= 2'b00;
        goflag <= 1'b0;
        num <=  numtemp;
    end
    else begin
        case(cur_state)
        IDLE:begin
            cnt <= 32'd0;
            ATRUN <= 2'b00;
            BTRUN <= 2'b00;
            goflag <= 1'b0;
            num <=  numtemp;
            end
        GO:begin
            cnt <= 32'd0;
            ATRUN <= 2'b01;
            BTRUN <= 2'b01;
            goflag <= 1'b1;
            num <=  (num + numtemp)/2;
            end
        STOP:begin
            cnt <= cnt + 1;
            ATRUN <= 2'b00;
            BTRUN <= 2'b00;
            goflag <= goflag;
            num <=  (num + numtemp)/2;
            end
        TRUN:begin
            goflag <= 1'b0;
            ATRUN <= 2'b01;
            BTRUN <= 2'b10;
            cnt <= 32'd0;
            num <=  (num + numtemp)/2;
            end
        endcase
    end


endmodule

结语

这个代码量对于新手来说还是有点吃不消的吧。不过反反复复踏踏实实地去理解每个模块的实现方法,和代码逻辑,也就能通透许多了。

在装车过程中,尽量装得标准一点。单侧车轮正反转方向一致,方向前后设定明确(以超声波一侧为车头,除非将此模块作为倒车检测),布线尽量简约一点。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: d37-基于单片机的智能寻迹避障小车设计是一项科技创新,它利用现代电子技术和编程技术,集成了多种传感器和控制器,可以实现智能化的寻迹和避障功能。 首先,d37小车的寻迹功能通过光线传感器和红外传感器进行检测,可以识别出黑色轨迹,并按照轨迹行驶,同时,通过检测到的光信号来判断物体是否在前方,从而实现避障功能。 其次,d37小车的运行还可以通过编程来实现复杂的控制,比如控制小车速度、方向和行程等参数。这些参数可以根据不同的需求进行调整。 最后,d37小车还具备多项先进的技术,比如使用快速电机控制技术和高精度测距技术,对小车的运行过程进行监控和调整,实现精确的行驶。 总体而言,d37-基于单片机的智能寻迹避障小车设计是一项创新性的科技产品,它具备多种高科技技术的集成与应用,可以实现高效的寻迹和避障功能,并且具备灵活性和可编程性,在未来的实际应用中具有广泛的应用前景和市场价值。 ### 回答2: d37-基于单片机的智能寻迹避障小车是一款结合了多种技术的智能机器人车辆。它主要采用的技术包括单片机、红外线、超声波、直流电机及其驱动模块等,通过这些技术,将车辆变得更加智能化,实现了自主寻迹、避障、巡线等功能。 该小车由两个驱动轮和一个转向轮组成,结构简单、灵活。车体上部设有两个红外线传感器,用于检测车辆前方路面状况,判断是否有障碍物需要避开。此外,小车下方还安装了一个超声波传感器,可以检测到车辆周围的障碍物距离,并根据距离自动避开。 为了保证小车的稳定性和可靠性,智能寻迹避障小车还采用了直流电机及其驱动模块。直流电机可以让小车高速运转,同时,通过驱动模块可以灵活控制车速和方向。此外,该小车还配备了单片机,通过编程实现了自主巡线、寻迹、避障等功能。 总之,d37-基于单片机的智能寻迹避障小车结合了多种技术,可以自主控制运动方向,并根据传感器检测到的信息,自动避开障碍物。其结构简单,操作灵活,可以有效提高工作效率和安全性,是一种非常有价值的智能机器人车辆。 ### 回答3: d37-基于单片机的智能寻迹避障小车是一款智能化的车辆设计。整个小车的核心是一块单片机,它通过对外部传感器的感知和处理,实现车辆的自主控制。该小车主要应用于需要自主行驶、智能避障和寻迹的场合,如物流输送、监控巡逻、智能家居等。 该小车的主要组成部分包括:单片机模块、驱动模块、传感器模块、车体模块及电源模块。单片机模块是整个小车的核心,它通过接收传感器信号,控制马达实现转向和控制速度。驱动模块采用直流电机控制模块,通过控制电机实现小车的前后移动。传感器模块包括寻迹传感器和超声波测距传感器,分别用于寻找路径和避障。车体模块采用轻质材料制造,保证小车的机动性和速度,同时还能提供较好的载重能力和稳定性。电源模块则为整个小车提供电能来源,可选用锂电池或干电池。 小车的控制算法包括寻迹算法和避障算法。寻迹算法通过寻找一定宽度的黑线,实现自动跟踪和转向。避障算法通过超声波传感器实现对前方障碍物的探测和距离测量,一旦发现障碍物,小车会自动停车或避开障碍物。当然,这些算法需要在单片机上进行编程,程序设计的好坏将直接影响小车的性能表现。 总之,d37-基于单片机的智能寻迹避障小车设计是应用于人工智能和自动化技术的一项创新产品,将为工业、商业、家庭带来更多的便利和效益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星羽空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值