我们是模拟电梯的运行情况,处理里面的上行下行及开关门的逻辑,最简单的情况就是按键输入楼层信号电梯运动到楼层的时候开门关门,led灯来表示或者数码管来表示电梯位置;再复杂一点,做电梯剩余楼层的遍历,假如我目前在三楼电梯上行,二楼有人需要电梯开门,这个时候电梯就应该直接去到二楼,而不是继续上行到顶楼再做下行计算,单部电梯就应该这样,这也是生活中的现象,那再增加一点外设电机正转表示电梯上行,反转表示电梯下行,语言播报来做一些情况的提示,于是有了下图的结构:
shake_top是按键消抖模块,设计中使用的按键比较多,所以用一个模块封装整个按键的消抖,使用了10个独立按键和16个矩阵按键,把消抖信号进行区分给到主控模块
control是电梯运行的主控模块,主要功能是检测按键信号寄存上下行的需求以及什么时候开关门,同时把一些信息输出
control_uart_send是串口输出控制模块,串口连接的语音设备,驱动这个设备就需要串口按照一定要求发送数据,这个模块收到主控过来的三个flag信号判断是“电梯上行”、“电梯下行”、还是“关门请注意”然后处理发送串口数据
UartSend是串口发送模块,在收到使能和发送数据便会根据串口格式发送这个数据,Tx外接的就是语音设备的输入
moster的四相五线步进电机的控制,这个步进电机是四根线进行驱动,按照一定的要求,我把正转和反转的输出都分别写上,再根据主控过来的信号判断是否有效来输出对应的控制
digital是动态扫描模块,用以显示楼层数以及时间显示
设计的难点在于电梯的控制下面列出电梯逻辑的控制代码
//********状态机********
//0:根据上行、下行方向判断电梯所处楼层是否开门
//1:4秒开门计时
//2:4秒开着计时
//3:3秒关门计时
//4:延时
//5:根据上行、下行方向赋遍历地址起始值
//6:遍历该方向上是否还有预开门状态
//7:下一楼计时
always@(posedge clk or negedge rstn)
begin
if(!rstn)begin
state <= 0;
direction <= 1;
count <= 0;
lift_floor <= 0;
c_time <= 0;
reg_state4 <= 0;
end else begin
case(state)
0:begin
if(direction)begin//判断方向,再判断当前楼层是否开门
if(upbusy[lift_floor] || lift_busy[lift_floor])begin
state <= 1;
end else begin
state <= 5;
end
end else begin
if(downbusy[lift_floor] || lift_busy[lift_floor])begin
state <= 1;
end else begin
state <= 5;
end
end
reg_state4 <= 0;
end
1:begin//开门
if(c_time == 4 && flag_1s)begin
c_time <= 0;
state <= 2;
end else if(flag_1s)begin
c_time <= c_time+1;
end
end
2:begin//门开着
if(c_time == 8 && flag_1s)begin
c_time <= 0;
state <= 3;
end else if(quicken)begin
c_time <= 0;
state <= 3;
end else if(flag_1s)begin
c_time <= c_time+1;
end
end
3:begin//关门
if(c_time >= 4 && flag_1s)begin
c_time <= 0;
state <= 4;
end else if(suspend)begin
c_time <= 0;
end else if(flag_1s)begin
c_time <= c_time+1;
end
end
4:begin
state <= 5;
reg_state4 <= 1;
end
5:begin
state <= 6;
if(direction)begin//遍历楼层赋值
count <= 7;
end else begin
count <= 0;
end
end
6:begin
if(direction)begin
if(count == lift_floor)begin//楼层遍历到当前层,表示电梯不需要上行
direction <= 0;
count <= 0;
state <= 0;
end else if(upbusy[count] || lift_busy[count] || downbusy[count])begin//电梯需要上行
state <= 7;
count <= 7;
end else begin
count <= count-1;
end
end else begin
if(count == lift_floor)begin
direction <= 1;
count <= 7;
state <= 0;
end else if(upbusy[count] || lift_busy[count] || downbusy[count])begin
state <= 7;
count <= 0;
end else begin
count <= count+1;
end
end
end
7:begin
if(c_time == 2 && flag_1s)begin//next楼层计数
c_time <= 0;
state <= 0;
if(direction)begin
lift_floor <= lift_floor+1;
end else begin
lift_floor <= lift_floor-1;
end
end else if(flag_1s)begin
c_time <= c_time+1;
end
end
default:
state <= 0;
endcase
end
end
B站视频效果https://www.bilibili.com/video/BV1Ep4y177TR/实物展示(开发板和电梯模块都是自己DIY的,有需要的可以找我购买)