设计一个八层楼房自动电梯控制器,用八个 LED显示电梯行进过程,并有数码管显示电梯当前所在楼层位置,在每层电梯入口处设有请求按钮开关,请求按钮按下则相应楼层的LED 亮。
用 CLK脉冲控制电梯运动,每来一个 CLK脉冲电梯升(降)一层。电梯到达有请求的楼层后,该层次的指示灯灭,电梯门打开(开门指示灯亮),开门 5 秒后,电梯门自动关闭,电梯继续运行。
控制电路应能记忆所有楼层请求信号,并按如下运行规则依次相应:运行过程中先响应最早的请求,再响应后续的请求。如果无请求则停留当前层。如果有两个同时请求信号,则判断请求信号离当偍层的距离,距离近请求的先响应,再响应较远的请求。每个请求信号保留至执行后清除。
设计提示
此设计问题可分为请求信号输入模块、主控模块、移位寄存显示模块和楼层显示几部分。
图 电梯控制器系统框图
在请求信号输入模块中,设置八个开关电平信号 d1,d2,d3,d4,d5,d6,d7,d8 表示 8 个楼层的请求信号,每次最多允许两个信号同时请求。 在主控模块中设置开门指示信号 door,door=1 为开门状态;door=0 为关门状态。
在移位寄存显示模块中设置八个 LED 显示信号 o1,o2,o3,o4,o5,o6,o7,o8,表示当前所在楼层及发出请求信号的楼层用移位寄存模块的 up 表示电梯上行(右移),down 表示电梯下行(左移),电梯初始状态是处在一层,当前楼层经主控模块送数码管显示。
当前楼层信号 A和请求信号 B 在主控模块中进行实时比较,当 AB,则移位寄存模块的 down 信号有效,电梯下行,直到 A=B,电梯开门 5秒,如此反复。若没有请求信号输入,则电梯停在当前楼层不动。若同时有两个请求信号输入,主控模块应能将两个请求信号分别与当前楼层信号比较,使电梯先去距离较近的楼层。
图 电梯控制器硬件系统示意图
电梯控制器主控电路Verilog HDL代码:
//电梯控制器
/*信号定义:
clk:时钟信号
d1,d2,d3,d4,d5,d6,d7,d8:楼层请求信号
o1,o2,o3,o4,o5,o6,o7,o8:楼层与请求信号状态显示
door:开门指示信号
fl:送数码管显示的当前楼层数
*/
module lift(clk,d1,d2,d3,d4,d5,d6,d7,d8,o1,o2,o3,o4,o5,o6,o7,o8,door,fl);
input clk,d1,d2,d3,d4,d5,d6,d7,d8;
output o1,o2,o3,o4,o5,o6,o7,o8,door,fl;
reg o1,o2,o3,o4,o5,o6,o7,o8,door,up,down;
reg[8:1] des;
reg[2:0] count;
reg[3:0] low,high,fl;
always@(posedge clk)
begin
//
if(d1)begin
des[1]<=1;if(low>1||low==4’b0000)low<=1;end
if(d2)begin
des[2]<=1;if(high<2&&{d3,d4,d5,d6,d7,d8}==6’b000000)high<=2;if((low>2||low==4’b0000)&&!d1)low<=1;end
if(d3)begin
des[3]<=1;if(high<3&&{d4,d5,d6,d7,d8}==5’b00000)high<=3;if((low>3||low==4’b0000)&&{d1,d2}==2’b00)low<=3;end
if(d4)begin
des[4]<=1;if(high<4&&{d5,d6,d7,d8}==4’b0000)high<=4;if((low>4||low==4’b0000)&&{d1,d2,d3}==3’b000)low<=4;end
if(d5)begin
des[5]<=1;if(high<5&&{d6,d7,d8}==3’b000)high<=5;if((low>5||low==4’b0000)&&{d1,d2,d3,d4}==4’b0000)low<=5;end
if(d6)begin
des[6]<=1;if(high<6&&{d7,d8}==2’b00)high<=6;if((low>6||low==4’b0000)&&{d1,d2,d3,d4,d5}==5’b00000)low<=6;end
if(d7)begin
des[7]<=1;if(high<7&&!d8)high<=7;if((low>7||low==4’b0000)&&{d1,d2,d3,d4,d5,d6}==6’b000000)low<=7;end
if(d8)begin des[8]<=1;if(high<8)high<=8;end
//
if({o1,o2,o3,o4,o5,o6,o7,o8}==8’b00000000)
begin
{o1,o2,o3,o4,o5,o6,o7,o8}<=8’b10000000;
fl<=1;
end
else if(count==3’b101)
begin
count<=0;
door<=0;
if(low==fl)
low<=4’b0000;
if(high==fl)
high<=4’b0000;
end
else if(count!=0)
begin
count<=count+1;
door<=1;
end
else if(o1&&des[1])
begin
count<=1;
des[1]<=0;
end
else if(o2&&des[2])
begin
count<=1;
des[2]<=0;
end
else if(o3&&des[3])
begin
count<=1;
des[3]<=0;
end
else if(o4&&des[4])
begin
count<=1;
des[4]<=0;
end
else if(o5&&des[5])
begin
count<=1;
des[5]<=0;
end
else if(o6&&des[6])
begin
count<=1;
des[6]<=0;
end
else if(o7&&des[7])
begin
count<=1;
des[7]<=0;
end
else if(o8&&des[8])
begin
count<=1;
des[8]<=0;
end
//
else if(up)
begin
if(fl begin {o1,o2,o3,o4,o5,o6,o7,o8}<={o1,o2,o3,o4,o5,o6,o7,o8}>>1; fl<=fl+1; end else begin if(low!=4’b0000&&low begin if(high>fl&&high-fl up<=1; else down<=1; end else if(high>fl) up<=1; end //************** end end module up<=0; end // else if(down) begin if(fl>low&&low!=4’b0000) begin {o1,o2,o3,o4,o5,o6,o7,o8}<={o1,o2,o3,o4,o5,o6,o7,o8}<<1; fl<=fl-1; end else down<=0; end else //**************