北邮vhdl自动售货机实验报告(含代码)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《自动售货机》实验报告
一.设计课程的任务要求
基本要求:
1.用2个数码管(disp5,disp4)显示钱数,以元为单位。
用3个按键(btn0,
btn1,btn2)分别表示一元、五元、十元,每按一次按键,增加一次相应的
钱数,上限99元。
2.再用3个按键(btn3,btn4,btn5)分别对应3种商品,其中,商品甲售价
3元、商品乙售价8元、商品丙售价12元;
3.买东西时,先输入钱币,再按对应的商品键。
每按一次商品键,钱数要相应
地减少,同时有声光(蜂鸣器或发光二极管)提示购买成功。
剩余钱数大于
3元可继续按商品键再次购买;当剩余钱数少于3元时,表示钱数的数码管
disp5,disp4显示为零,同时用数码管disp0显示退出的钱数。
4.买东西时,按下商品键,若输入的钱数少于商品的价格,表示钱数的数码管
disp5,disp4显示为零,同时用数码管(disp1、disp0)显示退出的钱数,
并用蜂鸣器或发光二极管闪烁表示购买失败。
5.按下商品键时,用数码管disp2表示当前购买的商品,1代表商品甲,2代
表商品乙,3代表商品丙。
6.用btn7做为退出功能键,退出键可以随时按下,按下后,数码管(disp5,
disp4)显示为零,同时数码管(disp1、disp0)显示退出的钱数,表示结
束购买,钱款全部退出。
提高要求:
7.用点阵设计显示投币动画、出货动画,购买成功/失败动画;
8.允许随时输入钱币,购买时,钱款不足有声光报警并等待追加钱币或选择别
的商品;
9.商品数量管理,有缺货提示;
10.用点阵动态显示商品名称和库存数量等。
自拟其它功能
二.系统设计(包括设计思路、总体框图、分块设计)
1.设计思路:
本实验为设计一个自动售货机。
由于本实验题目逻辑不太复杂,所以有两种设计思路可以选择。
第一种是用顺序结构和if when逻辑判断来实现。
第二种是用状态机来实现。
我选择的使用第一种。
总体来说可以将其分为两个大块。
第一个是接受键盘命令并通过逻辑判断向LED灯和数码管发出命令。
第二个是显示模块,通过接收命令控制灯亮与数码管显示。
2.总体框图:
结构框图:
逻辑划分框图:
ASM图:
MDS图:
分块设计:
防抖:本程序防抖功能采取延时防抖,即在按键按下后若持续时间超过一定时长才计数。
计价器:计价器分为十位和个位分别计数,由两个信号控制。
加减时根据补码计算的思想,先判断十位是否进位或退位,若有则对各位进行反向计算,若没有则直接修改个位。
充值模块:此模块与计价器加法思想一样。
并设有99的最高限。
消费模块:此模块与计价器减法一样。
在做减法前先判断是否减钱后余额大于零。
显示模块:此模块分为两步。
第一步由充值消费后的价钱通过信号赋给显示输出管脚。
第二步为通过循环用cat控制数码管关与开。
三.仿真波形及波形分析
由于程序加入了大量防抖与分频器,所以无法直接进行仿真。
以下仿真为拆除了防抖、分频,并且将钱数两位分别输出观察结果。
Money11为十位,money00为个位。
1.充值1元仿真:
当bn0按下后,十位不变,个位加一。
2.充值五元仿真
当bn1按下后,十位不变,个位加五。
3.充值十元仿真
当bn2按下后,个位不变,十位加一。
4.充值超过99仿真
充值超过九十九时,个位十位均不变保持九十九。
5.消费三元仿真
总钱数为十元时,当bn3按下后,十位减一,个位加七。
6.消费八元仿真
总钱数为十元,当bn4按下后,十位减一,个位加二。
7.消费十二元仿真
总钱数为二十元,当bn5按下后,十位减2,个位加8。
8.消费超出总额仿真
当消费超过总额时,钱数全部置零。
四.源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_unsigned.all;
ENTITY cxz IS
PORT(bn0,bn1,bn2,bn3,bn4,bn5,bn7:IN STD_LOGIC;
clk_50M,reset:IN STD_LOGIC;
DOUT7: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
CatL: OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
led1,led2,led3,led4:OUT STD_LOGIC
);
END cxz;
ARCHITECTURE behave OF cxz IS
SIGNAL disp0,disp1,disp2,disp4,disp5:STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL btn0,btn1,btn2,btn3,btn4,btn5,btn7 :STD_LOGIC:='0';
SIGNAL clk_1,clk_1k:STD_LOGIC;
SIGNAL Q:STD_LOGIC_VECTOR(3 downto 0);
SIGNAL temp1:INTEGER RANGE 0 TO 499;
SIGNAL temp:INTEGER RANGE 0 TO 24999;
SIGNAL money0,money1:STD_LOGIC_VECTOR(3 downto 0):="0000";
SIGNAL count_BTN0:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN1:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN2:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN3:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN4:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN5:INTEGER RANGE 0 TO 20;
SIGNAL count_BTN7:INTEGER RANGE 0 TO 20;
BEGIN
p1:PROCESS(clk_50M,reset)---------------------------------分频模块
BEGIN
IF reset='0' THEN
temp<=0;
ELSIF clk_50M'event AND clk_50M='1' THEN
IF temp=24999 THEN
temp<=0;clk_1k<=NOT clk_1k;
ELSE
temp<=temp+1;
END IF;
END IF;
END PROCESS p1;------------------------------------------分频结束
p2:PROCESS(clk_1k,bn0)-------------------------------------------------按键防抖模块开始BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn0 = '1') THEN
IF count_BTN0 = 20 THEN
count_BTN0 <= count_BTN0;
ELSE
count_BTN0 <= count_BTN0+ 1;
END IF;
IF count_BTN0= 19 THEN
btn0<= '1';
ELSE
btn0<= '0';
END IF;
ELSE
count_BTN0<= 0;------------------------输出变量启动判断进程END IF;
ELSE
END IF;
END PROCESS p2;
p3:PROCESS(clk_1k,bn1)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn1= '1') THEN
IF count_BTN1 = 20 THEN
count_BTN1 <= count_BTN1;
ELSE
count_BTN1 <= count_BTN1+ 1;
END IF;
IF count_BTN1= 19 THEN
btn1<= '1';
ELSE
btn1<= '0';
END IF;
ELSE
count_BTN1<= 0;
END IF;
ELSE
END IF;
END PROCESS p3;
p4:PROCESS(clk_1k,bn2)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn2= '1') THEN
IF count_BTN2= 20 THEN
count_BTN2 <= count_BTN2;
ELSE
count_BTN2 <= count_BTN2 + 1;
END IF;
IF count_BTN2= 19 THEN
btn2<= '1';
ELSE
btn2<= '0';
END IF;
ELSE
count_BTN2<= 0;
END IF;
ELSE
END IF;
END PROCESS p4;
p5:PROCESS(clk_1k,bn3)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn3 = '1') THEN
IF count_BTN3= 20 THEN
count_BTN3 <= count_BTN3;
ELSE
count_BTN3 <= count_BTN3 + 1;
END IF;
IF count_BTN3= 19 THEN
btn3<= '1';
ELSE
btn3<= '0';
END IF;
ELSE
count_BTN3<= 0;
END IF;
ELSE
END IF;
END PROCESS p5;
p6:PROCESS(clk_1k,bn4)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn4 = '1') THEN
IF count_BTN4 = 20 THEN
count_BTN4 <= count_BTN4;
ELSE
count_BTN4 <= count_BTN4 + 1;
END IF;
IF count_BTN4= 19 THEN
btn4<= '1';
ELSE
btn4<= '0';
END IF;
ELSE
count_BTN4<= 0;
END IF;
ELSE
END IF;
END PROCESS p6;
p7:PROCESS(clk_1k,bn5)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn5 = '1') THEN
IF count_BTN5 = 20 THEN
count_BTN5 <= count_BTN5;
ELSE
count_BTN5 <= count_BTN5 + 1;
END IF;
IF count_BTN5= 19 THEN
btn5<= '1';
ELSE
btn5<= '0';
END IF;
ELSE
count_BTN5<= 0;
END IF;
ELSE
END IF;
END PROCESS p7;
p8:PROCESS(clk_1k,bn7)
BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN
IF(bn7 = '1') THEN
IF count_BTN7 = 20 THEN
count_BTN7 <= count_BTN7;
ELSE
count_BTN7<= count_BTN7 + 1;
END IF;
IF count_BTN7= 19 THEN
btn7<= '1';
ELSE
btn7<= '0';
END IF;
ELSE
count_BTN7<= 0;
END IF;
ELSE
END IF;
END PROCESS p8;--------------------------------------------------------按键防抖模块结束
P9:process(clk_1k,btn0,btn1,btn2,btn3,btn4,btn5,btn7)------------------逻辑判断模块BEGIN
IF(clk_1k'event AND clk_1k = '1') THEN--------------------------------购买模块IF btn0='1' THEN
IF money0 >"1000" THEN--------------------------------十位有进位情况money0<="0000";money1<=money1+1;
ELSE money0<=money0+1;--------------------------------十位不进位情况
END IF;
IF money1>"1001"THEN----------------------------------超出99封顶
money1<="1001";money0<="1001";
ELSE NULL;
END IF;
ELSIF btn1='1'THEN
IF money0>"0100" THEN
money0<=money0-5;money1<=money1+1;
ELSE money0<=money0+5;
END IF;
IF money1>"1001"THEN
money1<="1001";money0<="1001";
ELSE NULL;
END IF;
ELSIF btn2='1'THEN
IF money1>"1000" THEN
money0<="1001";money1<="1001";
ELSE money1<=money1+1;
END IF;------------------------------------------购买模块结束
ELSIF btn3='1'THEN-------------------------------------消费模块
IF money1>"0000" or money0>"0010" THEN-----------钱数大于够买物品钱数led1<='1';led2<='0';led3<='0';
disp2<="0110000";-----------------------------显示够买物品种类
IF money0>"0010"THEN
money0<=money0-3;
ELSE money1<=money1-1;
money0<=money0+7;
END IF;
IF money1="0000" and money0<"0011"THEN--------------钱数小于三的情况
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money0<="0000";
ELSE NULL;
END IF;
ELSE---------------------------------------------钱数不够
led4<='1';
CASE money1 IS
WHEN "0000"=>disp1<="1111110";
WHEN "0001"=>disp1<="0110000";
WHEN "0010"=>disp1<="1101101";
WHEN "0011"=>disp1<="1111001";
WHEN "0100"=>disp1<="0110011";
WHEN "0101"=>disp1<="1011011";
WHEN "0110"=>disp1<="1011111";
WHEN "0111"=>disp1<="1110000";
WHEN "1000"=>disp1<="1111111";
WHEN "1001"=>disp1<="1111011";
WHEN OTHERS=>disp1<="0000000";
END CASE;
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN "0011"=>disp0<="1111001";
WHEN "0100"=>disp0<="0110011";
WHEN "0101"=>disp0<="1011011";
WHEN "0110"=>disp0<="1011111";
WHEN "0111"=>disp0<="1110000";
WHEN "1000"=>disp0<="1111111";
WHEN "1001"=>disp0<="1111011";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money1<="0000";
money0<="0000";
disp2<="1111110";
END IF;
ELSIF btn4='1'THEN
IF money1>"0000" or money0>"1000" THEN
led2<='1';led1<='0';led3<='0';
disp2<="1101101";
IF money0>="1000"THEN
money0<=money0-8;
ELSE money1<=money1-1;
money0<=money0+2;
END IF;
IF money1="0000" and money0<"0011"THEN
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money0<="0000";
ELSE NULL;
END IF;
ELSE
led4<='1';
CASE money1 IS
WHEN "0000"=>disp1<="1111110";
WHEN "0001"=>disp1<="0110000";
WHEN "0010"=>disp1<="1101101";
WHEN "0011"=>disp1<="1111001";
WHEN "0100"=>disp1<="0110011";
WHEN "0101"=>disp1<="1011011";
WHEN "0110"=>disp1<="1011111";
WHEN "0111"=>disp1<="1110000";
WHEN "1000"=>disp1<="1111111";
WHEN "1001"=>disp1<="1111011";
WHEN OTHERS=>disp1<="0000000";
END CASE;
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN "0011"=>disp0<="1111001";
WHEN "0100"=>disp0<="0110011";
WHEN "0101"=>disp0<="1011011";
WHEN "0110"=>disp0<="1011111";
WHEN "0111"=>disp0<="1110000";
WHEN "1000"=>disp0<="1111111";
WHEN "1001"=>disp0<="1111011";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money1<="0000";
money0<="0000";
disp2<="1111110";
END IF;
ELSIF btn5='1'THEN
IF money1>"0001" or (money1="0001" and money0>"0001") THEN led3<='1';led1<='0';led2<='0';
disp2<="1111001";
IF money0>"0001"THEN
money0<=money0-2;
money1<=money1-1;
ELSE money1<=money1-2;
money0<=money0+8;
END IF;
IF money1="0000" and money0<"0011"THEN
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money0<="0000";
ELSE NULL;
END IF;
ELSE
led4<='1';
CASE money1 IS
WHEN "0000"=>disp1<="1111110";
WHEN "0001"=>disp1<="0110000";
WHEN "0010"=>disp1<="1101101";
WHEN "0011"=>disp1<="1111001";
WHEN "0100"=>disp1<="0110011";
WHEN "0101"=>disp1<="1011011";
WHEN "0110"=>disp1<="1011111";
WHEN "0111"=>disp1<="1110000";
WHEN "1000"=>disp1<="1111111";
WHEN "1001"=>disp1<="1111011";
WHEN OTHERS=>disp1<="0000000";
END CASE;
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN "0011"=>disp0<="1111001";
WHEN "0100"=>disp0<="0110011";
WHEN "0101"=>disp0<="1011011";
WHEN "0110"=>disp0<="1011111";
WHEN "0111"=>disp0<="1110000";
WHEN "1000"=>disp0<="1111111";
WHEN "1001"=>disp0<="1111011";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money1<="0000";
money0<="0000";
disp2<="1111110";
END IF;------------------------------------------消费模块结束ELSIF btn7='1'THEN-------------------------------------结束模块
led1<='0';
led2<='0';
led3<='0';
led4<='0';
CASE money1 IS------------------------------------将余额输出
WHEN "0000"=>disp1<="1111110";
WHEN "0001"=>disp1<="0110000";
WHEN "0010"=>disp1<="1101101";
WHEN "0011"=>disp1<="1111001";
WHEN "0100"=>disp1<="0110011";
WHEN "0101"=>disp1<="1011011";
WHEN "0110"=>disp1<="1011111";
WHEN "0111"=>disp1<="1110000";
WHEN "1000"=>disp1<="1111111";
WHEN "1001"=>disp1<="1111011";
WHEN OTHERS=>disp1<="0000000";
END CASE;
CASE money0 IS
WHEN "0000"=>disp0<="1111110";
WHEN "0001"=>disp0<="0110000";
WHEN "0010"=>disp0<="1101101";
WHEN "0011"=>disp0<="1111001";
WHEN "0100"=>disp0<="0110011";
WHEN "0101"=>disp0<="1011011";
WHEN "0110"=>disp0<="1011111";
WHEN "0111"=>disp0<="1110000";
WHEN "1000"=>disp0<="1111111";
WHEN "1001"=>disp0<="1111011";
WHEN OTHERS=>disp0<="0000000";
END CASE;
money1<="0000";
money0<="0000";
disp2<="1111110";
ELSE null;
END IF;
CASE money0 IS------------------------------------------------显示模块
WHEN "0000"=>disp5<="1111110";
WHEN "0001"=>disp5<="0110000";
WHEN "0010"=>disp5<="1101101";
WHEN "0011"=>disp5<="1111001";
WHEN "0100"=>disp5<="0110011";
WHEN "0101"=>disp5<="1011011";
WHEN "0110"=>disp5<="1011111";
WHEN "0111"=>disp5<="1110000";
WHEN "1000"=>disp5<="1111111";
WHEN "1001"=>disp5<="1111011";
WHEN OTHERS=>disp5<="0000000";
END CASE;
CASE money1 IS
WHEN "0000"=>disp4<="1111110";
WHEN "0001"=>disp4<="0110000";
WHEN "0010"=>disp4<="1101101";
WHEN "0011"=>disp4<="1111001";
WHEN "0100"=>disp4<="0110011";
WHEN "0101"=>disp4<="1011011";
WHEN "0110"=>disp4<="1011111";
WHEN "0111"=>disp4<="1110000";
WHEN "1000"=>disp4<="1111111";
WHEN "1001"=>disp4<="1111011";
WHEN OTHERS=>disp4<="0000000";
END CASE;
ELSE NULL;
END IF;
END PROCESS p9;
p10:PROCESS(clk_50M,reset)
BEGIN
IF reset='0' THEN
temp1<=0;
ELSIF clk_50M'event AND clk_50M='1' THEN
IF temp1=499 THEN
temp1<=0;clk_1<=NOT clk_1;
ELSE
temp1<=temp1+1;
END IF;
END IF;
END PROCESS p10;
p11:PROCESS(clk_1,reset)-------------------------------------------为扫描数码管计数BEGIN
IF reset='0' THEN
Q <= "1111";
ELSIF(clk_1'event and clk_1='1')THEN
IF Q = "0100" THEN
Q <= "0000";
ELSE
Q <= Q+1;
END IF;
END IF;
END PROCESS p11;
p12:PROCESS(Q)----------------------------------------------------扫描数码管
BEGIN
CASE Q IS
WHEN "0000"=>DOUT7<=disp0;CatL<="111110";
WHEN "0001"=>DOUT7<=disp1;CatL<="111101";
WHEN "0010"=>DOUT7<=disp2;CatL<="111011";
WHEN "0011"=>DOUT7<=disp4;CatL<="011111";
WHEN "0100"=>DOUT7<=disp5;CatL<="101111";
WHEN OTHERS=>DOUT7<="1111111";CatL<="111111";
END CASE;
END PROCESS p12;
END behave;
五.功能说明及资源利用情况
资源利用情况:
功能说明:
本品为自动售货机,可实现自动充值与购买的功能。
通过btn0、btn1、btn2三个键分别代表一元、五元、十元充值,通过btn3、btn4、btn5三个键可以实现3元、八元、十二元三种商品的购买。
在充值和购买时相应的总金额会时时显示在disp4、disp5上。
充值封顶九十九元,如若超过则保持在九十九元。
购买时钱数会相应的减小,并将相应的产品序号显示在disp2上。
当钱数扣到小于零时,自动将推出的钱数显示在disp0、disp1上。
六.故障及问题分析
七.总结和结论。