自动售货机vhdl.docx
《自动售货机vhdl.docx》由会员分享,可在线阅读,更多相关《自动售货机vhdl.docx(16页珍藏版)》请在冰豆网上搜索。
自动售货机vhdl
EDA课程设计
李畅
硬件描述语言VHDL程序设计
————自动售货机
一.设计内容
本次设计的自动售货机只销售cola与pepsi两种饮料,售价均为1.5元。
顾客可以由两个不同投币孔分别投入5角硬币或1元硬币。
一次交易只能购买一瓶,且自动找零。
只要按下取消键就会马上无条件退币。
二.设计说明
用两个按键电路代替两种币值的投币孔,以LED点亮的数量显示各投币种类的投入数量,在以4Hz闪烁的LED来显示退币种类与数量。
本设计采用1024Hz的系统时钟信号来控制所有买卖行为。
三.自动售货机外观示意图
Led_cola_out
Led_pepsi_out
Led_ten_return
Led_five_return
Led_ten
Led_five
Led_cancel
Cancel_buy
Led_buy
Ok_buy
Led_pepsi
Select_pepsi
Select_cola
Led_pepsi_sel
四.自动售货机构成模块:
●产生退币闪烁信号的电路模块
●投入壹圆硬币的处理电路模块
●投入五角硬币的处理电路模块
●饮料选择处理电路模块
●确认与取消处理电路模块
●退币处理电路模块
●出货并计算存货电路模块
实体定义了系统的输入输出端口信号,顾客由4种操作行为,即投币、选择、确定与取消。
结构体定义功能模块之间整体共享的传递信号,以整合所有块的功能。
这些信号将成为各个功能块外部输入或输出信号。
五.设计程序及注释如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;
entityvendoris
port(
reset:
instd_logic;--系统内部给其他顾客重新操作的复位信号
clk:
instd_logic;
--由外接信号发生器提供的1024Hz系统时钟信号
ok_buy:
instd_logic;--购买确认的按键信号
cancel_buy:
instd_logic;--购买取消的按键信号
coin_5:
instd_logic;--投入五角硬币的动作按键
coin_10:
instd_logic;--投入壹圆硬币的动作按键
select_cola:
instd_logic;--选择可口可乐的按键信号
select_pepsi:
instd_logic;--选择百事可乐的按键信号
led_cola_ok:
outstd_logic;--灯亮显示还有可口可乐
led_pepsi_ok:
outstd_logic;--灯亮显示还有百事可乐
led_cola_sel:
outstd_logic;--灯亮显示可口可乐选择键被按
led_pepsi_sel:
outstd_logic;--灯亮显示百事可乐选择键被按
led_buy:
outstd_logic;--灯亮显示按了购买确认键
led_cancel:
outstd_logic;--灯亮显示按了购买取消键
led_five:
outstd_logic_vector(2downto0);
--3个LED,投入1个五角硬币亮一个LED
led_ten:
outstd_logic_vector(1downto0);
--2个LED,投入1个壹圆硬币亮一个LED
led_five_return:
outstd_logic_vector(2downto0);
--3个LED,以每秒4次的闪烁代表退出的硬币
led_ten_return:
outstd_logic_vector(2downto0);
--2个LED,以每秒4次的闪烁代表退出的硬币
led_cola_out:
outstd_logic;--灯亮显示可口可乐已出货
led_pepsi_out:
outstd_logic--灯亮显示百事可乐已出货
);
end;
architecturearchofvendoris
signalok:
std_logic;--用来维持ok_buy的状态
signalcancel:
std_logic;--用来维持cancel_buy的状态
signalmoney_ok:
std_logic;--投入金额正确
signalreturn_clk:
std_logic;--退币的闪烁信号4Hz
signalcola_choice:
std_logic;--用来维持select_cola的状态
signalpepsi_choice:
std_logic;--用来维持select_pepsi的状态
signaltotal_amount_five:
integerrange0to15;--五角硬币的累计投入金额
signaltotal_amount_ten:
integerrange0to20;--壹圆硬币的累计投入金额
signalcola_out:
std_logic;--可口可乐已经出货的信号
signalpepsi_out:
std_logic;--百事可乐已经出货的信号
begin
return_clock:
block--产生退币闪烁信号的电路模块
signalcount:
std_logic_vector(7downto0);
begin
process(reset,clk)
begin
ifreset='1'thencount<="00000000";--高电平复位
return_clk<='0';
elsifrising_edge(clk)then--时钟上升沿有效
count<=count+"00000001";
ifcount(7)='1'thenreturn_clk<='1';--退币
elsereturn_clk<='0';
endif;
endif;
endprocess;
endblock;
coin_10_counting:
block--投入壹圆硬币的处理电路模块
signalno_coin_ten:
integerrange0to2;
begin
process(reset,coin_10)
begin
ifreset='1'thentotal_amount_ten<=0;--复位
no_coin_ten<=0;
led_ten<="00";
elsifrising_edge(coin_10)then--按下投入一元硬币的按钮
total_amount_ten<=total_amount_ten+10;
ifno_coin_ten<2then--投入一元钱
led_ten(no_coin_ten)<='1';--灯亮几盏表示投入多少个硬币
no_coin_ten<=no_coin_ten+1;
elseno_coin_ten<=2;--投入两元钱
endif;
endif;
endprocess;
endblock;
coin_5_counting:
block--投入五角硬币的处理电路模块
signalno_coin_five:
integerrange0to3;
begin
process(reset,coin_5)
begin
ifreset='1'thentotal_amount_five<=0;--复位
no_coin_five<=0;
led_five<="000";
elsifrising_edge(coin_5)then--按下投入五角钱硬币的按钮
total_amount_five<=total_amount_five+5;
ifno_coin_five<3then--投入0.5—1元钱
led_five(no_coin_five)<='1';
no_coin_five<=no_coin_five+1;
elseno_coin_five<=3;--投入多与1.5元
endif;
endif;
endprocess;
endblock;
select_drink:
block--饮料选择处理电路模块
begin
process(reset,clk)
begin
ifreset='1'thenled_cola_sel<='0';--复位
led_pepsi_sel<='0';
elsifrising_edge(clk)then--时钟上升沿
ifselect_cola='1'then--选择可乐
led_cola_sel<='1';--相应的信号灯亮
cola_choice<='1';--维持选择状态
led_pepsi_sel<='0';
endif;
ifselect_pepsi='1'then--选择百事
led_cola_sel<='0';
pepsi_choice<='1';--维持选择状态
led_pepsi_sel<='1';--相应的灯亮
endif;
endif;
endprocess;
endblock;
ok_or_cancel:
block--确认与取消处理电路模块
begin
p1:
process(reset,ok_buy)
begin
ifreset='1'thenok<='0';--复位
led_buy<='0';
elsifrising_edge(ok_buy)then--按确认按钮
ok<='1';--维持状态
led_buy<='1';--确认灯亮
endif;
endprocess;
p2:
process(reset,cancel_buy)
begin
ifreset='1'thencancel<='0';--复位
led_cancel<='0';
elsifrising_edge(cancel_buy)then--按取消键
cancel<='1';--维持状态
led_cancel<='1';--取消灯亮
endif;
endprocess;
endblock;
coin_returned:
block--退币处理电路模块
signaltotal_amount:
integerrange0to35;
begin
process(reset,clk)
begin
ifreset='1'then--复位
total_amount<=0;
money_ok<='0';
led_five_return<=(others=>'0');
led_ten_return<=(others=>'0');
elsifrising_edge(clk)then--时钟上升沿
total_amount<=total_amount_ten+total_amount_five;
--投入总钱数,十进制,单位角
iftotal_amount>=15thenmoney_ok<='1';--投入1.5元,正确
elsemoney_ok<='0';
endif;
if(cancel='1')then--取消购买
foriin0to2loop
led_five_return(i)<=return_clk;--退五角钱
endloop;
foriin0to1loop
led_ten_return(i)<=return_clk;--退一元
endloop;
elsif(pepsi_out='1'orcola_out='1')then
casetotal_amountis
when0to14=>foriin0to2loop--钱数不够1.5元,退钱
led_five_return(i)<=return_clk;
endloop;
foriin0to1loop
led_ten_return(i)<=return_clk;
endloop;
when15=>null;--投入等于1.5元
when20=>led_five_return
(2)<=return_clk;
--投入两元,退回一个0.5元硬币
when25=>led_ten_return(0)<=return_clk;
--投入2.5元,退回一个一元硬币
when30=>led_ten_return
(1)<=return_clk;
--投入3元,退回一个一元硬币
led_five_return
(1)<=return_clk;--一个0.5元硬币
whenothers=>led_ten_return(0)<=return_clk;
led_ten_return
(1)<=return_clk;
endcase;
endif;
endif;
endprocess;
endblock;
give_check:
block--出货并计算存货电路模块
signalno_cola:
integerrange0to20;
signalno_pepsi:
integerrange0to20;
begin
cola_out<='1'when(money_ok='1'andok='1'andcola_choice='1')
else'0';
led_cola_out<=cola_out;--可乐出货灯亮
pepsi_out<='1'when(money_ok='1'andok='1'andpepsi_choice='1')
else'0';
led_pepsi_out<=pepsi_out;--百事出货灯亮
cola:
process(reset,cola_out)
begin
ifreset='1'thenno_cola<=20;--复位
led_cola_ok<='1';
elsifrising_edge(cola_out)then--可乐卖出
no_cola<=no_cola-1;--卖出一个计一次数
ifno_cola=0thenled_cola_ok<='0';--可乐全部售出
elseled_cola_ok<='1';--还有存货
endif;
endif;
endprocess;
pepsi:
process(reset,pepsi_out)
begin
ifreset='1'thenno_pepsi<=20;--复位
led_pepsi_ok<='1';
elsifrising_edge(pepsi_out)then--百事卖出
no_pepsi<=no_pepsi-1;--卖出一个计一次数
ifno_pepsi=0thenled_pepsi_ok<='0';--百事全部售出
elseled_pepsi_ok<='1';--还有存货
endif;
endif;
endprocess;
endblock;
endarch;
六.结果:
上图所示为本次实验的部分仿真结果,所演示的是假设cola不缺货,用户第一次购买的是cola,继续购买投入两枚五角钱硬币,发现钱不够要求退币的过程。
对上图要说明几点:
1)本次设计的售货机是由主时钟clk控制的,而且上升沿有效,所以当用户按下Select_cola按钮之后,在clk的上升沿到来之前,led_cola_sel灯不亮,在下一个clk上升沿到来时才亮。
2)用户按下ok_buy按钮的同时,clk上升沿到来,由于上图为设计仿真,不考虑机器的反应时间,所以灯led_ok同一时刻亮起。
3)该设计采用的主时钟频率为1024Hz,而设计中执行退币操作时,灯led_cancel的闪烁频率为4Hz,所以在上图中不予以体现。
七.原理图
1)顶层设计图
2)内部结构图
八.设计总结
这个设计实现了一个简单的自动售货机的功能,程序由硬件描述语言vhdl编写。
程序中采用分块编写的方式,将一个本来复杂的体系用简单的逻辑表述出来。
主时钟配合各个模块产生不同的信号,以这些信号为桥梁分别控制各个模块,这样做设计显得很流畅,每个成员都不是独立存在的。
九.附录
设计开发环境:
XilinxISE6.2
参考资料:
《可编程逻辑器件与EDA技术》主编:
李景华,杜玉远
2005年全国大学生电子设计大赛EDA培训课件,主讲:
栾峰