本文共 5070 字,大约阅读时间需要 16 分钟。
题目九:出租车计价器设计(平台实现)★★
完成简易出租车计价器设计,选做停车等待计价功能。 基本功能: (1)起步8元/3公里,此后2元/公里; (2)里程指示信号为每前进50米一个高电平脉冲,上升沿有效;显示行公里数,精确到0.1公里。(模拟时速40KM/h) (3)前进里程开始之前显示价钱,精确到0.1元; (4)用两个按键分别表示开始行程和结束行程。 选做功能: (1)增加一个停车等待/恢复行程按钮,用2个数码管显示等待时间,精确到0.1分钟。 (2)等候费1元/分钟,计价精度为0.1元。1.实现步骤:分频得到一秒,将一秒的频率作为输入,传入计时模块。在计时模块的行驶模块中:当汽车行驶时,如果km大于3km,那么每9s,km加上0.1km,即小数位加1,价钱加0.2元。
在计时模块的等待模块中:当汽车等待时,每6s即0.1min,等待时间加上0.1min,价钱加上0.1元。2.VHDL代码
library IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity taxi isport(clk_100:in std_logic; clk_scan:in std_logic; start:in std_logic; --开始 stop:in std_logic; --停车与恢复行驶 reset:in std_logic; --重置键 ended:in std_logic; --结束 op,led:out std_logic_vector(7 downto 0));--数码管位选与段选end taxi;architecture one of taxi is signal f_1:std_logic; --1Hz频率 signal q_1:integer range 0 to 99; signal c2,c1,c0:std_logic_vector(3 downto 0);--费用cost signal k2,k1,k0:std_logic_vector(3 downto 0);--km signal m1,m0:std_logic_vector(3 downto 0); --min signal bit_2:integer range 9 downto 0; --op signal num:std_logic_vector(3 downto 0); --ledbeginfeipin:process(clk_100,start) --分频得1sbegin if (clk_100'event and clk_100='1') then if start='0' then q_1<=0;f_1<='0'; else if q_1=99 then q_1<=0;f_1<='1'; else q_1<=q_1+1;f_1<='0'; end if; end if; end if;end process;jishi:process(f_1,start) --计时模块variable x:integer range 9 downto 0:=0;variable w:integer range 9 downto 0:=0;begin if f_1'event and f_1='1' then if reset='1' then --重置 k2<="0000";k1<="0000";k0<="0000"; m1<="0000";m0<="0000"; c2<="0000";c1<="1000";c0<="0000"; --行驶状态,3km以内8元 elsif (start='1' and stop='0' and ended='0') then --行驶状态 if x=8 then x:=0; --9s行程加0.1km,即0.2元 if k0="1001" then k0<="0000"; if k1="1001" then k1<="0000"; if k2="1001" then k2<="0000"; else k2<=k2+1; end if; else k1<=k1+1; end if; else k0<=k0+1; end if; if (k2&k1&k0>="000000110000") then --大于3km,开始行驶计费 if c0>="1001" then c0<=c0-"1000"; --行驶计费 if c1="1001" then c1<="0000"; if c2="1001" then c2<="0000"; else c2<=c2+1; end if; else c1<=c1+1; end if; else c0<=c0+2; --9s行程加0.1km,即0.2元 end if; end if; else x:=x+1; end if; elsif (start='1' and stop='1' and ended='0') then --等待停车状态 if w=5 then w:=0; --计时0.1分钟即6s,即0.1元 if m0="1001" then m0<="0000"; if m1="1001" then m1<="0000"; else m1<=m1+1; end if; else m0<=m0+1; end if; if c0="1001" then c0<="0000"; --等待计费 if c1="1001" then c1<="0000"; if c2="1001" then c2<="0000"; else c2<=c2+1; end if; else c1<=c1+1; end if; else c0<=c0+1; end if; else w:=w+1; end if; end if; end if;end process;xiangshi:process(clk_scan,c0,k0,m0) --显示模块variable a:integer range 9 downto 0:=0;begin if clk_scan'event and clk_scan='1' then if start='1' then bit_2<=a; a:=a+1; a:=a rem 8; case bit_2 is when 0=>num<=k0;op<="11111110"; when 1=>num<=k1;op<="11111101"; when 2=>num<=k2;op<="11111011"; when 3=>num<=c0;op<="11110111"; when 4=>num<=c1;op<="11101111"; when 5=>num<=c2;op<="11011111"; when 6=>num<=m0;op<="10111111"; when 7=>num<=m1;op<="01111111"; when others=>null; end case; end if; end if;end process;shumaguan:process(num)variable y:std_logic_vector(6 downto 0);begin case num is when "0000" =>y:="1111110"; when "0001" =>y:="0110000"; when "0010" =>y:="1101101"; when "0011" =>y:="1111001"; when "0100" =>y:="0110011"; when "0101" =>y:="1011011"; when "0110" =>y:="1011111"; when "0111" =>y:="1110000"; when "1000" =>y:="1111111"; when "1001" =>y:="1111011"; when others =>null; end case; if (bit_2=2 or bit_2=5 or bit_2=0) then --添加小数点 led<=y&'1'; else led<=y&'0'; end if;end process; end one;
管脚编号:
3.仿真:
4.板载测试 上图为:等待3.9min,总费用为23.9元,行驶里程为9.0km. 23.9=3.9*1+8+(9-3)*2,符合题意。 多次测试各种情况也符合题意。 测试成功!1.系统测试结论: 通过反复地测试工作情况,得出本次实验的设计满足题意,并且只要输入的为标准100Hz的时钟信号,那么就能正确计算出行驶路程、等待时间、总费用,能精确到0.1。
2.性能特点: ①优点:计费、计时、计程很准确,达到40km/h的效果。功能全部实现。
3.可扩展性分析: 可以在加上几个模式:比如把模式分为:白天、黑夜、雨天等,不同的环境下实现计时、计程、计费。
1.设计过程中的困难和解决方法:
问题一:一个信号量只能在一个进程中赋值。解决:想办法在一个进程中赋值。 问题二:需要1500多个单元,但是只有1150个。解决:这个时候是用整形做的,然后把整形换为位矢量,并且优化过程,因为此时有六个进程process. 有的问题解决了,有的没解决,就换了思路。 当然还有一些小问题。2.经验与收获体会、对EDA的认识
刚开始的时候感觉这一题还挺简单的,因为思路真的是异常清晰(之前习惯软件思维的我,把它当软件看),然后感觉用C语言写,分分钟的事情。一写起来,到处报错,才发现一些语法的细节不是很了解,在不断摸索中,终于对VHDL的越来越熟悉,通过不断地认识,从刚开始的数码管显示的有点乱七八糟,最后终于达到了自己的一点点要求,最后不断完善程序,终于达到了自己的要求。 发现VHDL这种硬件语言真的和之前学过的很不一样,有的时候编译通过,逻辑没问题,但是到了物理层次,还是出了问题。于是,在写VHDL的时候把它看出是一个物理盒子,写代码就是在连线一样,把变量尽量用二进制表示,成功率会提升许多。转载地址:http://kqvwb.baihongyu.com/