数字电路与逻辑设计实验题目: 简易出租车计价器
学号:
姓名:
班级:
学院:
时间:2013/11/4
一.设计课题的任务要求
设计一台出租车计价器,不同情况具有不同的收费标准。
基本要求:
1、行驶公里:用时钟2 秒钟表示出租车匀速行驶1 公里,在行车5 公里以内,按起步
价13 元收费,超过5 公里部分,以每公里2 元收费。燃油附加费为每运次1 元。
2、途中等待:用按键控制中途等待,等待少于(包括)5 秒不收费,超过5 秒后每等待3 秒钟加收1 元。
3、用数码管分时显示计费金额、行驶里程和等候时间。字母A 表示当前处于显示计费金额状态,字母B 表示当前处于显示行驶里程状态,字母C 表示当前处于显示等候时间状态。
4、用按键控制出租车空驶、载客状态并用点阵显示空驶、载客状态。
二、系统设计(包括设计思路、总体框图、分块设计)
1、设计思路:
将整个计价器分为控制和计费模块,按键及防抖模块,数码管显示模块,点阵显示模块。其中控制和计费模块作为系统核心,负责给出所有控制和对外显示信号。按键及防抖模块提供输入按键信号,用于状态间切换。数码管用于显示计费金额、里程和等待时间信息。点阵模块用于显示出租车载客和空驶状态。
2、设计框图:
3、分块设计
①控制和计费模块:
采用状态机的设计方式,根据计费计时方式的不同,分为了S0、S1、S2、S3四个状态,四个状态的含义和状态转移图如图所示:
②按键防抖模块:
如图:按键防抖模块的原理是利用信号延迟,每个防抖模块都有一个输入时钟,每按下一次按键后输出端将产生一个输入时钟宽度的脉冲,输入时钟频率与主控模块中的状态切换扫描时钟频率相同,使状态能够及时的切换。
③点阵显示模块:
点阵模块主要用于显示出租车的空载和载客状态。空载时显示汉字“空”,载客时显示标志“X”。输出信号lie和com分别连接到点阵控制的行和列。En是由计费控制模块给出的空载/载客信号。
④数码管显示模块
数码管主要用于显示计费、里程、等待时间信息。clk_shu连接1kHz 时钟扫描信号,s0~s6用于接收计费控制模块输出的各个数码管显示
的数字。Weixuan和duanxuan
控制数码管的位选和段选信号。
⑤时钟分频模块
将50MHz片上时钟分频为1Hz、1kHz、200Hz时钟信号,其中1Hz
用于计费和计时。200Hz用于按键防抖和状态切换。1kHz用于数码管和点阵的扫描。
三、仿真波形及波形分析
①数码管显示模块:
下图是固定s0~s6为数字951413后的仿真波形,由于S1位在程序中没有用到,于是将其始终置为高电平(灭),实际输出应为9 1413。
如图所示:weixuan信号每隔6个时钟周期扫描一次,扫描频率为166Hz足以使人眼产生连续显示的感觉。观察duanxuan信号,在圆圈处应显示数字“1”,duanxuan为0000110正是“1”的段选码。说明数码管能将s0~s6传输的数字正确的显示。
②按键防抖模块
如图,keyin输入一个持续时间约为0.1s的按键信号并用高频时钟模拟抖动,keyout输出一个时钟周期(5ms)的高电平。
③时钟分频模块:
由于分频比例太高,仿真到1s需要花费大量时间,故只仿真到20ms,观察1kHz和200Hz信号如下:
④点阵显示模块:
将en置高电平,输出应为X,如图,显示正确。
⑤计费计时模块:
等待模式:如图在2S和3S间分别按start-stop和pause进入s2模式,初始计费为14(起步费+燃油费),2s(即等待3s)后计费变为15。而在切换至s1后outen信号置高电平使点阵显示“X”。
结束和清零:
如图,再次按Start-stop后停止计费,按clear后计时计费清零
行驶状态:
5s内为14元,之后每2s 加2元,计费正常。
四、源程序
计费和控制模块:
Mytaxi.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mytaxi is
port ( signal clk1k,clk1,clk5ms:in std_logic;
--频率为1kHz,1Hz,5ms的信号
start_stop:in std_logic; --开始-结束信号
pause:in std_logic; --等待-重新行驶信号
clear:in std_logic; --清零信号
t0:out integer range 0 to 13; --与数码管连接
t1:out integer range 0 to 13;
t2:out integer range 0 to 9;
t3:out integer range 0 to 9;
t4:out integer range 0 to 9;
t5:out integer range 0 to 9;
outen:out std_logic);--点阵控制信号
end mytaxi;
architecture behav of mytaxi is
signal sec1:integer range 0 to 5; --秒计数十位
signal sec0:integer range 0 to 9; --秒计数个位
signal m1:integer range 0 to 5; --分的十位计数器
signal m0:integer range 0 to 9; --分的个位计数器
signal c2,c1,c0:integer range 0 to 9; --费用计数器
signal k2,k1,k0:integer range 0 to 9; --公里计数器
signal v:integer range 0 to 5:=1; --车速
signal fei:integer range 0 to 999;--费用计数器
signal bai,shi,ge:integer range 0 to 9;--费用计数百位,十位,个位
type state_type is (s0, s1, s2, s3); --状态列表
signal state : state_type;
begin
process(clk5ms,start_stop,pause,clear) --状态切换进程begin
if clear= '1' then
state <= s0;
elsif (rising_edge(clk5ms)) then
case state is
when s0=>
if start_stop = '1' then
state <= s1;
else
state <= s0;
end if;
when s1=>
if start_stop='1' then
state <= s3;
elsif pause = '1' then
state <= s2;
else
state <= s1;
end if;
when s2=>
if start_stop = '1' then
state <= s3;
elsif pause = '1' then
state <= s1;
else
state <= s2;
end if;
when s3=>
if clear= '1' then
state <= s0;
else
state <= s3;
end if;
end case;
end if;
end process;
jishi:process(clk1) --计时,计费进程variable cntk:integer range 0 to 5;
variable cntf1:integer range 0 to 5;
variable cntf11:integer range 0 to 5;
variable cntf2:integer range 0 to 5;
variable cntf22:integer range 0 to 2;
variable cntx:integer range 0 to 6:=0;
begin
if clk1'event and clk1='1' then
case state is
when s2=> --等待模式
outen<='1'; --点阵显示载客
if cntf2>4 then --等待超过5s进行计费
if cntf22=2 then cntf22:=0; --每3s加1元
fei<=fei+1;
else cntf22:=cntf22+1;
end if;
else cntf2 :=cntf2+1;
end if;
if sec0=9 then sec0<=0; --此语句完成秒计数
if sec1=6 then sec1<=0;
if m0=9 then m0<=0; --此语句完成分计数
if m1<=6 then m1<=0;
else m1<=m1+1;
end if;
else m0<=m0+1;
end if;
else sec1<=sec1+1;
end if;
else sec0<=sec0+1;
end if;
bai<=fei/100; --将费用重新计算成三位便于显示shi<=(fei/10) mod 10;
ge<=fei mod 10;
when s1=> --行驶模式
outen<='1';--点阵显示载客
if cntk=v then cntk:=0; --2s一公里
if k0=9 then k0<=0;
if k1=9 then k1<=0;
if k2=9 then k2<=0; --公里计数
else k2<=k2+1;
end if;
else k1<=k1+1;
end if;
else k0<=k0+1;
fei<=fei+2; --每公里2元
end if;
else cntk:=cntk+1;
end if;
if cntf1=v then cntf1:=0;
if cntf11>4 then fei<=fei+2; --超过5公里开始计费
else cntf11:=cntf11+1;
end if;
else cntf1:=cntf1+1;
end if;
bai<=fei/100;
shi<=(fei/10) mod 10;
ge<=fei mod 10;
when s0=> --按下clear后各项数字清零outen<='0';
cntf1:=0;cntf11:=0;cntf2:=0;cntf22:=0;cntk:=0;
fei<=14;
bai<=0;shi<=0;ge<=0;
sec1<=0;sec0<=0;
m1<=0;m0<=0;k1<=0;k0<=0;k2<=0;