自动售货机设计Verilog.docx
《自动售货机设计Verilog.docx》由会员分享,可在线阅读,更多相关《自动售货机设计Verilog.docx(16页珍藏版)》请在冰豆网上搜索。
自动售货机设计Verilog
自动售货机设计
一、实验目的
1、实现自动售货机的功能;
2、运用状态机原理设计。
二、实验容
⏹这种自动售货机只销售听装与瓶装两种罐装可乐,售价均为1.5元。
顾客只能通过两个不同的投币口分别投入五角的硬币或者一元硬币。
一次交易可以买多罐,且自动找零。
若钱不够,则自动退币。
并且在购买之前只要一按下取消键cancel就马上无条件退币。
⏹此机器的硬件示电路,以二個按键电路代替二個投币孔,以两个八段数码管显示投币数量,再以4hz闪烁之led來显示退币,以两个八段数码管显示退币数量。
此机器就采用1024hz的系统clock信号同步所有的买卖行为,并且作为弹跳消除电路的基准参考脉冲。
这个电路虽然是纯数位电路但是可作为一个自动售货机的控制核心电路加上驱动器就可以用来驱动机械装置。
⏹下图为自动售货机的操作盘,有两个投币按钮,分別为五角硬币与一元硬币。
每投入一个硬币就将下方的LED指示灯号点亮到具体数额,并且最高上限只能接受9.5元的金额。
另外,每一种饮料商品都配置3个灯号(分别显示存货、选择数量与出货等三个信息)与一个选择购买的按钮。
每按一次选择购买按钮,选择数量显示加1,并且存货自动计算,若没有货存,则货存灯灭,一旦选择商品与投币金额足够,就需要按下确定要购买的按键;当然也可以后悔不买而按下取消键,让机器退回已经投入的硬币。
如若投入的钱币不足以购所有的饮料,则退币。
退币时货存更改为原状态。
三、程序设计
moduleauto_vending(clk,cel_cola,cel_diet,reset,coin_ten,coin_five,ok_buy,cancel_buy,//输入
led_cola_ok,led_diet_ok,led_buy,led_cancel,led_cola_out,led_diet_out,shu_cola_sel,shu_diet_sel,
led_display,shu_money_return,Hex);//输出
inputclk,cel_cola,cel_diet,reset,coin_ten,coin_five,ok_buy,cancel_buy;
outputled_cola_ok,led_diet_ok,//表示还有存货
led_buy,led_cancel,//表示选择购买和取消购买
led_cola_out,led_diet_out;//显示表示已出货
//led_return;//每四秒闪烁一次代表被退之硬币
wire[10:
0]led_cola_sel,led_diet_sel;////选中饮料的数量
output[6:
0]shu_cola_sel,shu_diet_sel;
output[13:
0]led_display;//表示投币的金额
output[13:
0]shu_money_return;
wireok,cancel,money_ok;//在ok_or_cancel出来的
//wire[10:
0]no_diet,no_cola;//售货机的饮料数量
wire[10:
0]money_return;
//reg[10:
0]no_sock_cola,no_sock_diet;
wire[10:
0]total_count,total_consum;
output[13:
0]Hex;
assignHex=14'b111_111_111_11111;
parameterIdle=2'd0,
S1=2'd1,
S2=2'd2;
reg[1:
0]state;
regclk_1;
regrst;
reg[29:
0]count;
always(posedgeclk)//shengcheng1sdeshizhong
begin
if(count==30'd25000000)
begin
clk_1<=~clk_1;
count<=0;
end
else
count<=count+1;
end
always(posedgeclk_1ornegedgereset)
if(!
reset)
begin
state<=Idle;
rst<=0;
end
else
case(state)
Idle:
begin
rst<=0;
state<=S1;
end
S1:
begin
rst<=1;
if(ok_buy||cancel_buy)
state<=Idle;
end
endcase
wirebuyok;
toubiu1(rst,clk,coin_five,coin_ten,led_display,total_count);
select_drinku2(clk,rst,cel_cola,cel_diet,/*no_cola,no_diet,*/
led_cola_sel,led_diet_sel,/*led_cola_ok,led_diet_ok,*/total_consum);
ok_or_cancelu3(clk,rst,ok_buy,cancel_buy,ok,cancel,led_buy,led_cancel);
give_checku4(reset,buyok,clk,ok,money_ok,rst,led_cola_out,led_diet_out,
led_cola_sel,led_diet_sel,led_cola_ok,led_diet_ok/*no_cola,no_diet*/);
coin_returnu5(clk,rst,ok_buy,money_return,total_count,total_consum,money_ok,cancel_buy,cancel);
xianshiq1(led_cola_sel,shu_cola_sel);
xianshiq2(led_diet_sel,shu_diet_sel);
xianshi2w2(money_return,shu_money_return);
endmodule
///显示数量的
modulexianshi(a,b);//用来显示
input[10:
0]a;
outputreg[6:
0]b;
always(a)
case(a)
11'd0:
b<=7'b1000000;
11'd1:
b<=7'b1111001;
11'd2:
b<=7'b0100100;
11'd3:
b<=7'b0110000;
11'd4:
b<=7'b0011001;
11'd5:
b<=7'b0010010;
11'd6:
b<=7'b0000010;
11'd7:
b<=7'b1111000;
11'd8:
b<=7'b0000000;
11'd9:
b<=7'b0010000;
endcase
endmodule
//钱数显示
modulexianshi2(total_count,led_display);
input[10:
0]total_count;
outputreg[13:
0]led_display;
always(total_count)
case(total_count)
11'd0:
led_display<=14'b1000000_1000000;
11'd1:
led_display<=14'b1000000_0010010;
11'd2:
led_display<=14'b1111001_1000000;
11'd3:
led_display<=14'b1111001_0010010;
11'd4:
led_display<=14'b0100100_1000000;
11'd5:
led_display<=14'b0100100_0010010;
11'd6:
led_display<=14'b0110000_1000000;
11'd7:
led_display<=14'b0110000_0010010;
11'd8:
led_display<=14'b0011001_1000000;
11'd9:
led_display<=14'b0011001_0010010;
11'd10:
led_display<=14'b0010010_1000000;
11'd11:
led_display<=14'b0010010_0010010;
11'd12:
led_display<=14'b0000010_1000000;
11'd13:
led_display<=14'b0000010_0010010;
11'd14:
led_display<=14'b1111000_1000000;
11'd15:
led_display<=14'b1111000_0010010;
11'd16:
led_display<=14'b0000000_1000000;
11'd17:
led_display<=14'b0000000_0010010;
11'd18:
led_display<=14'b0010000_1000000;
11'd19:
led_display<=14'b0010000_0010010;
endcase
endmodule
//去抖模块
modulequdou(clk,reset,k,key);
inputk,reset,clk;
outputregkey;
reg[10:
0]clock;
always(posedgeclk)
if(!
reset)
clock<=11'd0;
else
begin
if(k)
begin
key<=1;
clock<=0;
end
else
begin
clock<=clock+1;
if(clock==1000)
begin
clock<=11'b0;
key=0;
end
end
end
endmodule
/////投币电路
moduletoubi(reset,clk,coin_05,coin_10,led_display,total_count);//加一个去抖模块
inputreset,clk,coin_05,coin_10;
output[13:
0]led_display;
outputreg[10:
0]total_count;//统计投入里面的金币
wirequ_coin_05,qu_coin_10;
qudoua1(clk,reset,coin_05,qu_coin_05);
qudoua2(clk,reset,coin_10,qu_coin_10);
reg[10:
0]count_1,count_2;
always(negedgequ_coin_05ornegedgereset)
beginif(!
reset)
begin
count_1<=11'd0;
end
elseif(!
qu_coin_05)
begin
count_1<=count_1+11'd1;
end
end
always(negedgequ_coin_10ornegedgereset)
if(!
reset)
begin
count_2<=11'd0;
end
elseif(!
coin_10)
begin
count_2<=count_2+11'd2;
end
always(count_1orcount_2)
total_count<=count_2+count_1;
xianshi2a4(total_count,led_display);
endmodule
//饮料选择处理模块
moduleselect_drink(clk,reset,select_cola,select_diet/*,sock_cola,sock_diet*/,
cola_sel,diet_sel,/*led_cola_ok,led_diet_ok,*/total_consum);
inputclk,reset,select_cola,select_diet;
//input[10:
0]sock_cola,sock_diet;//系统部库存数量
output[10:
0]cola_sel,diet_sel;//选中的饮料数量
reg[10:
0]cola,diet;
//outputled_cola_ok,led_diet_ok;//除去选中的饮料外,是否还有余量
output[10:
0]total_consum;//消费金额
reg[10:
0]cola_sel,diet_sel;
//regled_cola_ok,led_diet_ok;
wireselect_cola_out,select_diet_out;
qudoua3(clk,reset,select_cola,select_cola_out);
qudoua4(clk,reset,select_diet,select_diet_out);
reg[10:
0]total_consum_2,total_consum_1,total_consum;
always(total_consum_2ortotal_consum_1)
total_consum<=total_consum_2+total_consum_1;
always(negedgeresetornegedgeselect_cola_out)
if(!
reset)
begin
cola_sel<=0;
total_consum_1<=0;
end
elseif(!
select_cola_out)
begin
cola_sel<=cola_sel+1;
total_consum_1<=total_consum_1+11'd3;
end
always(negedgeresetornegedgeselect_diet_out)
if(!
reset)
begin
diet_sel<=0;
total_consum_2<=0;
end
elseif(!
select_diet_out)
begin
diet_sel<=diet_sel+1;
total_consum_2<=total_consum_2+11'd3;
end
/*
always(posedgeclkornegedgereset)
if(!
reset)
begin
led_cola_ok<=1;
led_diet_ok<=1;
end
else
begin
cola<=sock_cola;
diet<=sock_diet;
if(cola_sel>=cola)
led_cola_ok<=0;
if(diet_sel>=diet)
led_diet_ok<=0;
end
*/
Endmodule
//确认与取消电路模块
moduleok_or_cancel(clk,reset,ok_buy,cancel_buy,
ok,cancel,//给其他模块使用
led_buy,led_cancel);//对外显示
inputclk,reset,ok_buy,cancel_buy;
outputregok,cancel;
outputregled_buy,led_cancel;
always(posedgeclkornegedgereset)
if(!
reset)
begin
ok<=0;
cancel<=0;
led_buy<=0;
led_cancel<=0;
end
else
if(ok_buy)
begin
ok<=1;
led_buy<=1;
cancel<=0;
led_cancel<=0;
end
else
if(cancel_buy)
begin
ok<=0;
cancel<=1;
led_buy<=0;
led_cancel<=1;
end
endmodule
//出货并计算存货模块
modulegive_check(reset,buyok,clk,ok,money_ok,rst,led_cola_out,led_diet_out,
cola_out,diet_out,led_cola_ok,led_diet_ok/*no_cola,no_diet*/);
inputreset,clk,ok,rst,money_ok;
input[10:
0]cola_out,diet_out;//从售货机取出的饮料数量
outputregled_cola_ok,led_diet_ok;//显示是否还有饮料
reg[10:
0]no_cola,no_diet,sock_cola,sock_diet;//输出的饮料之后售货机部剩余数量
outputled_cola_out,led_diet_out;//售货机输出饮料时led亮
regled_cola_out,led_diet_out;
reg[1:
0]state;
parameterS1=2'd0,
S2=2'd1,
S3=2'd2;
regs1,s2;
outputregbuyok;
always(posedgeclkornegedgereset)
if(!
reset)
begin
sock_cola<=11'd5;
sock_diet<=11'd5;
end
else
if(!
rst)
begin
led_cola_out<=0;
led_diet_out<=0;
state<=S1;
s1<=0;
s2<=0;
no_cola<=sock_cola;
no_diet<=sock_diet;
buyok<=0;
end
else
case(state)
S1:
if(ok&&money_ok)
begin
if(cola_out>0)
begin
led_cola_out<=1;
no_cola<=no_cola-cola_out;
s1<=1;
end
if(diet_out>0)
begin
led_diet_out<=1;
no_diet<=no_diet-diet_out;
s2<=1;
end
state<=S2;
end
S2:
begin
state<=S2;
buyok<=1;
sock_cola<=no_cola;
sock_diet<=no_diet;
end
endcase
always(posedgeclkornegedgerst)
if(!
rst)
begin
led_cola_ok<=1;
led_diet_ok<=1;
end
else
begin
if(cola_out>=no_cola)
led_cola_ok<=0;
if(diet_out>=no_diet)
led_diet_ok<=0;
end
endmodule
//退币处理电路模块
modulecoin_return(clk,reset,ok_buy,led_return,total_count,total_consum,money_ok,cancel_buy,cancel);
inputclk,ok_buy,reset,cancel_buy,cancel;//return_clk来指定给退币闪烁警示灯
input[10:
0]total_count,total_consum;
outputreg[10:
0]led_return;//用来显示退出货币的总数
outputregmoney_ok;
always(posedgeclkornegedgereset)
if(!
reset)
begin
led_return<=0;
money_ok<=0;
end
else
if(cancel_buy)
begin
led_return<=total_count;
money_ok<=0;
end
else
if(total_count>=total_consum)
if(ok_buy)
begin
led_return<=total_count-total_consum;
money_ok<=1;
end
else
begin
money_ok<=0;
end
endmodule
四、实验结果
在DE2开发板上实现了自动售货机的功能。