【Verilog HDL】状态机 - 停车场管理系统

本文介绍了设计一个基于光感应器的停车场出入口车辆自动检测计数电路的方法,使用FSM状态机处理车辆进出状态,并处理行人干扰。通过LED输入、计数器和状态转换逻辑实现车辆数量的实时监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 【2023.11西南交大 数电实验】

具体要求

        设计一个停车场出入口车辆自动检测计数电路。如图 1 所示,用两对光感应器 a
和 b 监测车辆的行动,车身长度大于 a 与 b 之间的距离。当一个物体出现在光感应发
射器和接收器之间时,光被阻断,相应的输出被置位为 1 。通过检测传感器 a 和 b 的
信号,确定是否有车辆进入或驶出停车场。(西南交通大学数电实验,笔者实验已被验收)

设计思路

         FSM状态机思考过程:

(1)输入: 检测传感器a,b

(2)输出:是否有车出或入,变量设为Y

(3)状态:状态的设计方法比较多样,可以采用Moore也可以用Mearly,笔者将以后者进行介绍。状态分为7种

S0:a,b都没有反应 0 0

(进入状态)S1:a,b显示为1 0   S2:1 1    S3:0 1

(出去状态)S4:0 1       S5:1 1     S6:1 0

代码实现

       这道题目本身不难,笔者认为考点在于如何将两种状况分开考虑并且建立在同一个FSM中以及如何判断干扰。

如何将两组状态分开考虑

       二者状态的分歧点在于初始状态S0之后的输入,如果是10就是进入,如果是01就是出(不考虑干扰)所以在cs == 00 时把状态进行划分,进入S1就意味着是进车,S4就是出车,这样就将两组状态连接在了一起。

如何判断干扰

        这边要先申明一下,因为这仅仅只是一个简化的管理系统,所以不能做到比较完善的去干扰能力,思维比较严谨的小伙伴们可以先不去想太深。这边只考虑一辆车子的前进、停住不动和倒退,以及一个人的经过。

 行人的经过

        以进入为例,行人经过时,信号是这样的:00 10  00  01  00

        而对比车子的进入:00  10  11  01  00,中间存在 00的情况,那么只要判断处在状态10  01的时候,如果下一次出现的是00(处在状态10  01的时候),就可以判断是行人而退回到S0的状态。

 车子的进与不进

        因为处在不同的状态(前进属于正常状态就暂且不说)后退与停滞所需要做的操作其实是一样的,所以以进车时的S2 (11)状态为例,如果此时我检测到是 11说明车子没有发生移动,那么ns = S2(不变);如果我检测到是10说明车子回退了,那么ns = S1(回到上一个状态)。其他的情况下都是同理的。

以上便是我们对干扰的讨论,代码奉上

module test6_2022116384(ledin,cnter,clk,dout,seg,clr);
input [1:0]ledin;
input clk,clr;
output reg [3:0]cnter;//用来计数当前车库的车辆数
output reg [6:0]dout;//控制7段数码管内的7个管子
output [7:0] seg = 8'b00000001;// 控制8个7段数码管的显示
reg [2:0] ns,cs; // 次态和现态
parameter s0 = 3'b000,s1 = 3'b001,s2 = 3'b010,s3 = 3'b011,s4 = 3'b100,s5 = 3'b101,s6 = 3'b110;//7个状态

always @(posedge clk,negedge clr)
begin
       if(~clr) //对当前的状态置零
		 cs <= s0;
		 else
       cs <= ns;//更新状态
end

always @(*)
begin
       case(cs)
	s0: if(ledin == 2'b10) ns = s1;//进了车
		 else if(ledin == 2'b01) ns = s4;//出了车
		 else ns = s0;//其他情况的都是干扰
		 
	s1: if(ledin == 2'b11) ns = s2;//如果车身把两个信号都挡到了就是前进了一个状态
	    else if(ledin == 2'b10) ns = s1;//不动
	    else ns = s0;//00有两种情况,行人干扰和汽车回退 01也可能是行人因为车身长
		 
   s2: if(ledin == 2'b01) ns = s3;//车尾到b,要前进一个状态
	    else if(ledin == 2'b10) ns = s1;//车子往回退
		 else if(ledin == 2'b11) ns = s2;//不动 
		 else ns = s0;//00,基本上就是行人的干扰了(从11 -> 00车子肯定做不到)
		 
	s3: if(ledin == 2'b00) ns = s0;//车身全部过去,要计数了
	    else if(ledin == 2'b11) ns = s2;//往回退 **也可能是后方又来了一辆车,同时挡信号
		 else if(ledin == 2'b01) ns = s3;//不动
		 else ns =s0;//10,车子做不到,肯定是干扰
		 
	s4: if(ledin == 2'b11) ns = s5;
	    else if(ledin == 2'b01) ns = s4;//不动
	    else ns = s0;
		 
	s5: if(ledin == 2'b10) ns = s6;
	    else if(ledin == 2'b01) ns = s4;//回退
		 else if(ledin == 2'b11) ns = s5;//不动
		 else ns = s0;
		 
	s6: if(ledin == 2'b00) ns = s0;
	    else if(ledin == 2'b10) ns = s6;//不动
		 else if(ledin == 2'b11) ns = s5;//车子往回走
		 else ns = s0;
		 
	default: ns = s0;
		 endcase
end

always @(posedge clk)
begin
       if(ledin == 2'b00 && cs == s3) //如果是进车状态下,到了s3并且下一次的输入是00
		 begin
		        if(cnter < 4'd9)//不超过10
			     cnter <= cnter + 1;//车库车辆加一
				  else cnter = 0;
		 end
		 else if(ledin == 2'b00 && cs == s6)
		 begin
		        if(cnter > 0)//在车库不空的情况下就减一
				  cnter <= cnter - 1;
		 end
end
			 
always @(*)//控制7段数码管
begin
       case(cnter)
		 4'd0: dout = 7'b0111111;
		 4'd1: dout = 7'b0000110;
		 4'd2: dout = 7'b1011011;
		 4'd3: dout = 7'b1001111;
		 4'd4: dout = 7'b1100110;
		 4'd5: dout = 7'b1101101;
		 4'd6: dout = 7'b1111101;
		 4'd7: dout = 7'b0000111;
		 4'd8: dout = 7'b1111111;
		 4'd9: dout = 7'b1101111;
		 endcase
end

endmodule
		      

上板子!

以下视频是笔者在实验室实录的,感兴趣的小伙伴可以看看哦!

车辆管理系统

感谢观看!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

忆阁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值