×

出租车计价器课程设计,EDA课程设计,用VHDL编程做出租车计费器

admin admin 发表于2024-04-03 02:12:14 浏览19 评论0

抢沙发发表评论

本文目录一览:

EDA课程设计,用VHDL编程做出租车计费器

目录
第一章 引言 1
1.1 设计背景 1
1.2 设计任务与要求 1
1.21 设计任务 1
1.22 设计要求 1
第二章 系统方案设计 2
2.1 出租车计费器工作原理 2
2.2 基本设计思想 2
第三章 主要功能的实现 3
3.1 具体模块功能设计 3
3.2 具体模块实现 4
3.21 车速控制模块 4
3.22 里程计数模块 4
3.23 计费计数模块 4
3.24 动态扫描模块 4
3.3 总模块 4
第四章 程序调试及局部仿真结果 6
4.1 车速控制模块仿真结果 6
4.2 测试结果展示 6
第五章 结束语 8
参考资料 9
附件 10



第一章 引言
1.1 设计背景
随着出租车行业的发展,对出租车计费器的要求也越来越高。最近几年出租车行业发展迅速,在全国有几千家出租车公司。因此出租车计费器市场是庞大的。而出租车计费器成为不可缺少的一部分。
信息社会的现代电子产品,性能越来越高,复杂度越来越大,更新步伐也越来越快。实现这种进步的主要原因就是微电子技术和电子技术的发展。而电子技术的发展后者的核心就是电子设计自动化EDA(Electronic?Design?Automatic)技术。EDA是指以计算机为工作平台,融合了应用电子技术、计算机技术、智能化技术的最新成果而开发出的电子CAD通用软件包,它根据硬件描述语言HDL完成的设计文件,自动完成逻辑编译、化简、分割、综合、优化、布局布线及仿真,直至完成对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。没有EDA技术的支持,想要完成超大规模集成电路的设计制造是不可想象的;反过来,生产制造技术的不断进步又必将对EDA技术提出新的要求。
由美国国防部提出的VHDL(Very High Speed Integrated CIRCUIT HARDWARE DESCRIPTION Language)即超高速集成电路硬件描述语言,采用高层次的、自顶向下的设计方法来描述硬件,非常适合当前集成化、大规模的需要。
MAX+PLUSⅡ(Multiple Array MATRIX And Programmable Logic User Systems)是电子设计不可缺少的工具,他可以接受多种方式的输入:原理图输入、文本输入(硬件描述语言)、第三方EDA工具提供的接口等。MAX+PLUSⅡ的仿真器具有很强灵活性,可以控制对单器件或多器件的仿真。MAX+PLUSⅡ还提供了丰富的帮助库。  本文采用VHDL语言来设计实现出租车计费系统,源程序经美国ALTERA公司的MAX+PLUSⅡ软件调试优化,下载到特定芯片(MAX系列之一)后,可应用于实际的出租车计费系统中。
1.2 设计任务与要求
1.21 设计任务
设计一个出租车自动计费器,计费包括起步价、行车里程计费、停止和暂停不计费三部分。现场模拟汽车的启动、停止、暂停和换挡状态。分别用四位数码管显示金额和里程,各有两位小数,行程 3公里内,起步费为6元,超过3公里,以每公里1.2元计费。
1.22 设计要求
1、设计正确,方案合理。界面友好,使用方便。程序精炼,结构清晰。
2、有详细的文档。包括设计思路、设计仿真程序、仿真结果及相应的分析与结论。



第二章 系统方案设计
2.1 出租车计费器工作原理  实际中出租车的计费工作原理一般分成3个阶段:
  (1)车起步开始计费。首先显示起步价(本次设计起步费为6.00元),车在行驶3 km以内,只收起步价6.00元。
  (2)车行驶超过3 km后,按每公里1.2元计费(在7.00元基础上每行驶1 km车费加1.2元),车费依次累加。
  (3)行驶路程达到或超过10.5 km后(车费达到20元)?,每公里加收50%的车费,车费变成按每公里1.8元?开始计费。车暂时停止(行驶中遇红灯或中途暂时停车)不计费,车费保持不变。若停止则车费清零,等待下一次计费的开始。
2.2 基本设计思想  (1)根据出租车计费原理,将出租车计费部分由5个计数器来完成分别为counterA,counterB,counterC,counterD,counterE。①计数器A完成车费百位。②计数器B完成车费十位和个位。③计数器C完成车费角和分。④计数器D完成计数到30(完成车费的起步价)。⑤计数器E完成模拟实现车行驶100 m的功能。  (2)行驶过程中车费附加50%的功能:由比较器实现。  (3)车费的显示:由动态扫描电路来完成。用专用模块来实现,完成数据的输入即动态数据的显示。  (4)根据层次化设计理论,该设计问题自顶向下可分为车速控制模块、计数模块、译码和动态扫描显示模块,其系统框图如下图所示:
图1.1 出租车系统框图
第三章 主要功能的实现
3.1 具体模块功能设计
计费器按里程收费,每100 m开始一次计费.图3.1为原理结构图,各模块功能如下:
   图3.1 出租车计费器的结构框图
  (1)计数器E为带预置的可变步长的模100计数器,预置端为车速(每秒),如果预置端接入车速表,就可以实现计费了,这里用于模拟行车速度。例如:假设当计数器E计数到100则E的“CO”端输出一个高电平。此脉冲信号送给计数器D,使D完成车起步里程3 km的功能。在以后的时间里E的“CO”端的脉冲信号送给计数器C,使其完成按每公里收取费用的功能。
  (2)计数器D为带预置模的十进制加法计数器,预置数为车起步里程3 km,计数脉冲为计数器E的进位信号。这样当计数器D计数达到30后,进位输出将为一个高电平,控制计数器A,B,C开始计数,这样就能实现超过3 km后计费器再按每公里加收车费。
  (3)与门为2个8输入的8与门,一端用于预置,一端输入当前计费器收费情况,当计费器计费达到或超过一定收费(如20元)时,每公里加收50%的车费,此时该与门输出一个片选信号送MUX。  (4)MUX为16选8的2选1MUX,2个选择输入端分别为每100 m收费和50%的每100 m收费,片选信号由与门控制。
(5)计数器C为可变步长的模100十进制计数器,带预置端,预置数为计数步长。计数器C主要用于累加,当车行驶达到100 m时,计数器计数一次,计数步长为每100 m的行车收费。进位脉冲信号送到计数器B的“CLK”端,控制计数器B的计数步调。
  (6)计数器B为带预置的模100十进制计数器,预置数为出租车起步价,车费的个位,与数码管的第2位和第3位相连。计数时钟为计数器C的进位脉冲信号。
(7)计数器A为十进制计数器,其结果为车费的十,与4位数码管的最高位相连,计数时钟为进位脉冲。
(8)动态扫描电路将计数器A、B、C的计费状态用数码管显示出来,所连接的数码管共用一个数据端,由片选信号依次选择输出,轮流显示。
3.2 具体模块实现
3.21 车速控制模块
当启停键为启动状态(高电平时),模块根据车速选择和基本车速发出响应频率的脉冲驱动计费器和里程显示模块进行计数;当处于停止状态时,暂停发出脉冲,此时计费器和里程显示模块相应的停止计数。
3.22 里程计数模块
里程计数模块实现对于出租车在行驶过程的里程计数功能;当行驶里程大于3KM时,本模块中信号变为1;clk每来一个上升沿,里程计数模块实现一次计数,里程数加1。
计数车速控制模块发出的脉冲,并将计数显示动态显示出来,每来一个脉冲里程值加0.1(控制器每发一个脉冲代表运行了0.1公里)。
3.23 计费计数模块
计费模块启动reset信号,根据输入的clk信号变化,调节费用的计数,用c0、c1、c2、c3显示费用。
其初值为6,当里程数超过3公里后,才接受计数车速控制模块发出的脉冲的驱动,并且将计数显示动态显示出来,每一个脉冲其数值加0.12,当收费超过20时数值加0.18当启停键为启动状态(高电平时),模块根据车速选择和基本车速发出响应频率的脉冲驱动计费器和里程显示模块进行计数;当处于停止状态时,暂停发出脉冲,此时计费器和里程显示模块相应的停止计数。
3.24 动态扫描模块
动态扫描电路将计数器A、B、C的计费状态用数码管显示出来,所连接的数码管共用一个数据端,由片选信号依次选择输出,轮流显示。该模块经过8选1选择器将计费数据(4位BCD码)、计程数据(4位BCD码)动态选择输出。其中计费数据送入显示译码模块进行译码,最后送至百元、十元、元、角为单位对应的数码管上显示;计程数据送入显示译码模块进行译码,最后送至以公里为单位的数码管上显示。
3.3 总模块
taxi的计费器的原理图:将各模块的原理图对应的端口连接。
图3.2 出租车计数器原理图
第四章 程序调试及局部仿真结果
4.1 车速控制模块仿真结果
图4.1 车速控制模块时序仿真结果
图4.1
clk为基本输入时钟即(基本车速);k为可调车速,通过改变k来模拟车速变化;start为启停开关,当start为‘1’时内部计数器开始计数;reset为复位开关,用于复位车速控制模块中定义的count2计数器;clkout为脉冲输出,当输入车速越大,脉冲输出频率越高,计数周期变短,而clkout输出脉冲的意义为,参照于基本车速所反映的一个相对时间量,一个脉冲代表在该车速下行进了0.1km;
仿真出现的问题:
该车速控制模块中的reset复位端作为整个系统复位的一个环节,配合其他模块的的复位一起使用,做到对计数模块和显示模块的清零和归位。但是在该模块中单独时,效果不能体现,因为在该模块中,它复位的是内部定义的计数器count2,在脉冲输出clkout中不能体现使其为‘0’,只是不在出现状态变换,在全体仿真和硬件测试中,reset可以体现复位和清零。
4.2 测试结果展示

a:起步价格 b:开始行使未超过三公里

c:超过三公里后 d:超过20元后

图4.2 计费和里程测试结果显示
图4.2中a为起始起步价格,6元。b为出租车开始行使,未超出三公里保持起始价格不变。c为超过三公里后按每公里加1.2元计算。d为超出20元后按每公里原价的150%计算,即每公里1.8元。
第五章 结束语
短短一周的EDA课程设计已经接近尾声了,我们从挑选课设题目,查阅资料,到研究出总体设计,详细设计,然后分工合作,再到最后的编程上机调试,修改程序,完善程序,收获颇多。出租车计费器系统的设计已全部完成,能按预期的效果进行模拟汽车启动,停止、暂停等功能,并设计动态扫描电路显示车费数目。车暂停时停止计费。若停止清零,等待下一次计费的开始。出租车计费系统设计中体现了VHDL覆盖面广,描述能力强,是一个多层次的硬件描述语言及PLD器件速度快,使用方便,便于修改等特点。本设计在使用方面居庸一点的价值。由于时间有限和经验是平的欠缺,不足之处还望老师予以指正。
在这一周里我们再次熟悉和增强了对VHDL语言的基本知识,熟悉利用VHDL语言对常用的的组合逻辑电路和时序逻辑电路编程,把编程和实际结合起来。VHDL硬件描述语言打破了硬件和软件设计人员之间互不干涉的界限,可以使用语言的形式来进行数字系统的硬件结构、行为的描述,直接设计数字电路硬件系统。通过编程、下载后,该芯片已经具备了原来需要使用复杂的数字电路实现的功能;更加了解和加深了对编制和调试程序的技巧,进一步提高了上机动手能力,培养了使用设计综合电路的能力,养成了提供文档资料的习惯和规范编程的思想。
本次的课程设计将各个单一的模块实现其功能后,学会通过原理图或顶层文件把各模块连接,从而实现对出租车自动计费。课设注重的不仅是把理论知识巩固,而且应把理论和实际相结合,把知识应用到生活中。在课设过程中,遇到了不少问题,数码管无法正常显示,计费不按要求等。通过的对源代码的修改,发现了一些易忽略的细节。课设考验的是思维逻辑能力,对知识的灵活应用,当然,合作精神是不可或缺的。课设时间不长,要在短时间内完成绝不是个人力量能达到的,要学会集众人之精华,还要善于利用已有的工具为自己服务,开拓思维。课设让我们认识到所学本科知识的真正实用性,只是这门课开始研究的第一步。
在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常的,但应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。最后,我们衷心的感谢课设期间一直指导和陪伴着我们的老师。
参考资料
[1] 候伯亨,顾新. VHDL硬件描述语言与数字逻辑电路设计.修订版。西安电子科技大学出版社,1999?[2] 张昌凡,等.可编程逻辑器件及VHDL设计技术.广州:华南理工大学出版社,2001 [3] 曾繁泰,陈美金.VHDL程序设计 .北京:清华大学出版社,2001 [4] 潘松,等.VHDL实用教程 .成都:电子科技大学出版社,2000
附件
1、车速控制模块源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SPEED IS
PORT(
CLK,RESET,START: IN STD_LOGIC;
K : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
CLKOUT : OUT STD_LOGIC
);
END SPEED;
ARCHITECTURE A OF SPEED IS
SIGNAL COUNT1 :STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL TEMPCLK,CLKS:STD_LOGIC;
SIGNAL KINSIDE :STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
KINSIDE<="00000"-K;
CLKS_LABEL:
PROCESS(RESET,CLK)
VARIABLE COUNT2: STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
IF RESET = '1' THEN
COUNT2:="00000";
ELSIF CLK'EVENT AND CLK='1' THEN
IF START='1' THEN
IF COUNT2=KINSIDE THEN COUNT2:="00000";
END IF;
IF NOT (K="00000") THEN COUNT2:= COUNT2+1;
END IF;
IF COUNT2="00001" THEN TEMPCLK <= NOT TEMPCLK;
END IF;
END IF;
END IF;
END PROCESS CLKS_LABEL;
CLKOUT <= TEMPCLK;
END A;
2、计程源程序如下
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CDU99 IS
PORT (CLK,RESET: IN STD_LOGIC;
COUNT1:OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
COUNT2:OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
COUNT3:OUT STD_LOGIC_VECTOR (3 DOWNTO 0));
END CDU99;
ARCHITECTURE AA OF CDU99 IS
BEGIN
PROCESS(CLK,RESET)
VARIABLE MM: STD_LOGIC_VECTOR (11 DOWNTO 0);
BEGIN
IF RESET ='1' THEN
MM:="000000000000";
ELSIF CLK'EVENT AND CLK='1' THEN
IF MM(3 DOWNTO 0)="1001" THEN
MM:=MM+7; ELSE MM:=MM+1; END IF;
IF MM(7 DOWNTO 4)="1010" THEN
MM:=MM+"01100000"; END IF;
END IF;
COUNT1 <=MM(3 DOWNTO 0);
COUNT2 <=MM(7 DOWNTO 4);
COUNT3 <=MM(11 DOWNTO 8);
END PROCESS;
END AA;
4、计费模块源程序如下
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY COUNT99 IS
PORT(CLK,RESET:IN STD_LOGIC;
JUDGE2:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
JUDGE3:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT2:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT3:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT4:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COUNT99;
ARCHITECTURE AA OF COUNT99 IS
SIGNAL EN :STD_LOGIC;
SIGNAL MONEY :STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL MCOUNT :STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
MONEY<="00011000" WHEN ((MCOUNT(15)='1') OR (MCOUNT(14)='1') OR (MCOUNT(13)='1')) ELSE "00010010";
EN<='0' WHEN JUDGE3="0000" AND JUDGE2(3 DOWNTO 2)="00" AND((JUDGE2(1)='0') OR (JUDGE2(1)='1' AND JUDGE2(0)='0')) ELSE '1';
PROCESS(CLK,RESET)
VARIABLE MM: STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
IF RESET='1' THEN
MM:="0000011000000000";
ELSIF CLK'EVENT AND CLK='1' THEN
IF EN='1' THEN MM:=MM+MONEY;END IF;
IF MM(3)='1' AND (NOT(MM(2 DOWNTO 1)="00"))THEN
MM:=MM+6;END IF;
IF MM(7)='1' AND (NOT(MM(6 DOWNTO 5)="00"))THEN
MM:=MM+"01100000";END IF;
IF MM(11)='1' AND (NOT(MM(10 DOWNTO 9)="00"))THEN
MM:=MM+"011000000000";END IF;
END IF;
COUNT1<=MM(3 DOWNTO 0);
COUNT2<=MM(7 DOWNTO 4);
COUNT3<=MM(11 DOWNTO 8);
COUNT4<=MM(15 DOWNTO 12);
MCOUNT<=MM;
END PROCESS;
END AA;
5、 译码管片选信号源程序:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SE IS
PORT(CLK: IN STD_LOGIC;
A: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END SE;
ARCHITECTURE RT1 OF SE IS
BEGIN
PROCESS(CLK)
VARIABLE B:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF(B="111")THEN
B:="000";
ELSE
B:=B+1;
END IF;
END IF;
A<=B;
END PROCESS;
END RT1;
6、八选一模块程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY XXX1 IS
PORT(C:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
DP: OUT STD_LOGIC;
A1,A2,A3,A4,B1,B2,B3,B4:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
D:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END XXX1;
ARCHITECTURE RT1 OF XXX1 IS
BEGIN
PROCESS(C,A1,A2,A3,A4,B1,B2,B3,B4)
VARIABLE COMB:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
COMB:=C;
CASE COMB IS
WHEN"000"=>D<=A1;
DP<='0';
WHEN"001"=>D<=A2;
DP<='0';
WHEN"010"=>D<=A3;
DP<='1';
WHEN"011"=>D<=A4;
DP<='0';
WHEN"100"=>D<=B1;
DP<='0';
WHEN"101"=>D<=B2;
DP<='0';
WHEN"110"=>D<=B3;
DP<='1';
WHEN"111"=>D<=B4;
DP<='0';
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
END RT1;
7、译码模块源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DI IS
PORT(D:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Q:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END DI;
ARCHITECTURE RT1 OF DI IS
BEGIN
PROCESS(D)
BEGIN
CASE D IS
WHEN"0000"=>Q<="0111111";
WHEN"0001"=>Q<="0000110";
WHEN"0010"=>Q<="1011011";
WHEN"0011"=>Q<="1001111";
WHEN"0100"=>Q<="1100110";
WHEN"0101"=>Q<="1101101";
WHEN"0110"=>Q<="1111101";
WHEN"0111"=>Q<="0100111";
WHEN"1000"=>Q<="1111111";
WHEN OTHERS=>Q<="1101111";
END CASE;
END PROCESS;
END RT1;
课程设计内容与要求
1,用开关按键表示脉冲,每个脉冲代表100米,10个脉冲1公里,每公里1.4元,能同步显示里程和费用;
2,低于2公里5元计费,高于2公里总费用=起步费用+(里程-2公里)*里程单价+
等候时间*等后单价;
3,等候时间大于2分钟,按每分钟1.3元计费;
4,可以设定起步价和里程单价。
一、设计原理与技术方法:
包括:电路工作原理分析与原理图、元器件选择与参数计算、电路调试方法与结果说明;
软件设计说明书与流程图、软件源程序代码、软件调试方法与运行结果说明。
根据设计要求,系统的输入信号clk,计价开始信号start,等待信号stop,里程脉冲信号fin。系统的输出信号有:总费用数C0—c3,行驶距离k0—k1,等待时间m0—m1等。系统有两个脉冲输入信号clk_750k,fin,其中clk_750k将根据设计要求分频成14hz,15hz和1hz分别作为公里计费和超时计费的脉冲。两个控制输入开关start,stop;控制过程为:start作为计费开始的开关,当start为高电平时,系统开始根据输入的情况计费。当有乘客上车并开始行驶时,fin脉冲到来,进行行驶计费,此时的stop需要置为0;如需停车等待,就把stop变为高电平,
并去除fin输入脉冲,进行等待计费;当乘客下车且不等待时,直接将start置为0,系统停止工作;价格开始归为起步价5.0元。
整个设计由分频模块,计量模块,计费模块,控制模块和显示模块五个部分组成。
其中计量模块是整个系统实现里程计数和时间计数的重要部分;控制模块是实现不同计费方式的选择部分,根据所设计的使能端选择是根据里程计费还是根据等待时间计费,同时设计通过分频模块产生不同频率的脉冲信号来实现系统的计费。计量模块采用1hz的驱动信号,计费模块采用14hz,13hz的驱动信号;计量模块每计数一次,计量模块就实现14次或者13次计数,即为实现计时的1.3元/min,计程时的1.4元/km的收费。组成框图如下所示:
1.百进制模块:
实现百米脉冲的驱动信号,元件框图如图3所示:

图3 百进制模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity baijinzhi is
port(start,clk2: in std_logic; --秒脉冲
a: out std_logic_vector(3 downto 0));
end baijinzhi;
architecture rt1 of baijinzhi is
signal count_1:std_logic_vector(3 downto 0);
begin
a<=count_1;
process(start,clk2)
begin
if(start='0')then
count_1<="0000";
elsif(clk2'event and clk2='1')then
if(count_1="0111")then
count_1<="0000";
else
count_1<=count_1+'1';
end if;
end if;
end process;
end rt1
2.计费模块
; 实现里程和等候时间的计费并输出到显示,元件框图4如下:
图4 计费模块框图
源程序如下:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity jifei is
port(clk2:in std_logic; --计费驱动信号
start:in std_logic; --计费开始信号
c0,c1,c2,c3:buffer std_logic_vector(3 downto 0));
end jifei;
architecture rt1 of jifei is
begin
process(clk2,start)
begin
if start='0'then c3<="0000";c2<="0000";c1<="0101";c0<="0000"; --起步价5元
elsif clk2'event and clk2='1'then
if c0="1001" then c0<="0000";
if c1="1001" then c1<="0000";
if c2="1001" then c2<="0000";
if c3="1001" then c3<="0000";
else c3<=c3+1;
end if;
else c2<=c2+1;
end if;
else c1<=c1+1;
end if;
else c0<=c0+1;
end if;
end if;
end process;
end rt1;
3.公里模块
实现历程的计数和输出计费脉冲,元件框图5如下:

图5 公里模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity gongli is
port(clk1,start: in std_logic; --百米脉冲
k1,k2,k3,k4: out std_logic_vector(3 downto 0); --里程显示
temp2 : out std_logic);
end gongli;
architecture rt1 of gongli is
signal count_1: std_logic_vector(3 downto 0);
signal count_2: std_logic_vector(3 downto 0);
signal count_3: std_logic_vector(3 downto 0);
signal count_4: std_logic_vector(3 downto 0);
begin
k1<=count_1;
k2<=count_2;
k3<=count_3;
k4<=count_4;
process(start,clk1)
begin
if(start='0')then
count_1<="0000";
count_2<="0000";
count_3<="0000";
count_4<="0000"; ---公里清零
elsif(clk1'event and clk1='1')then
if(count_1="1001")then --公里计数器
count_1<="0000";count_2<=count_2+1;temp2<='1';
if(count_2="1001")then
count_2<="0000";count_3<=count_3+'1';
if(count_3="1001")then
count_3<="0000";count_4<=count_4+'1';
end if;
end if;
else
count_1<=count_1+'1';temp2<='0';
end if;
end if;
end process;
end rt1;
4.输出模块
实现所有数据的输出,元件框图6如下:

图6 输出模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity shuchu is
port(y: in std_logic_vector(3 downto 0);
e: out std_logic_vector(6 downto 0));
end shuchu;
architecture rt1of shuchu is
begin
process
begin
case y is
when"0000"=>e<="0111111";
when"0001"=>e<="0000110";
when"0010"=>e<="1011011";
when"0011"=>e<="1001111";
when"0100"=>e<="1100110";
when"0101"=>e<="1101101";
when"0110"=>e<="1111101";
when"0111"=>e<="0000111";
when"1000"=>e<="1111111";
when"1001"=>e<="1100111";
when others=>e<="0000000";
end case;
end process;
end rt1;
5.显示模块
实现所有数据的显示,元件框图7如下:

图7 显示模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xianshi is
port(start: in std_logic;
a:in std_logic_vector(3 downto 0); --选择信号
c1,c2,c3,c4,out1,out2,out3,out4:in std_logic_vector(3 downto 0); --里程显示,时间显示输入
y:out std_logic_vector(3 downto 0)); --里程显示,时间显示输出
end xianshi;
architecture rt1 of xianshi is
begin
process
begin
if(start='0')then
y<="0000";
else case a is
when "0000"=> y<=c1 ;
when "0001"=> y<=c2 ;
when "0010"=> y<=c3 ;
when "0011"=> y<=c4 ;
when "0100"=> y<=out1 ;
when "0101"=> y<=out2;
when "0110"=> y<=out3 ;
when "0111"=> y<=out4;
when others =>y<= "0000";
end case;
end if;
end process;
end rt1;
6.dian模块

图8 dian模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dian is
port(a: in std_logic_vector(3 downto 0);
e: out std_logic);
end dian;
architecture rt1 of dian is
begin
process
begin
case a is
when "0001"=>e<='1';
when "0101"=>e<='1';
when others=>e<='0';
end case;
end process;
end rt1;
三、中各个模块设计分析
系统总体顶层框图如下:
系统总体顶层框图
程序最终功能实现波形仿真
1. 分频模块
由于实验箱上没有14hz和13hz的整数倍时钟信号,因此采用频率较大的750khz进行分频,以近似得到14hz,13hz和1hz的时钟频率。通过以上三种不同频率的脉冲信号实行出租车行驶,等待两种情况下的不同计费。模块元件如下:

分频模块框图
源程序如下:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity fenpin is
port(clk_750k:in std_logic; --系统时钟
clk_14:buffer std_logic; --14分频
clk_13:buffer std_logic; --13分频
clk_1 : buffer std_logic); --1分频
end fenpin ;
architecture rt1 of fenpin is
signal q_14:integer range 0 to 53570; --定义中间信号量
signal q_13:integer range 0 to 57691;
signal q_1:integer range 0 to 749999;
begin
process(clk_750k)
begin
If(clk_750k' event and clk_750k='1')then
If q_14=53570 then q_14<=0;clk_14<=not clk_14;
else q_14<=q_14+1;
end if; --得14hz频率信号
If q_13=57691 then q_13<=0;clk_13<=not clk_13;
else q_13<=q_13+1;
end if; --得13hz频率信号
If q_1=749999 then q_1<=0;clk_1<=not clk_1;
else q_1<=q_1+1;
end if; --得1hz频率信号
end if;
end process;
end rt1;
2. 计量模块
计量模块主要完成计时和计程功能。
计时部分:计算乘客的等待累积时间,当等待时间大于2min时,本模块中en1使能信号变为1;当clk1每来一个上升沿,计时器就自增1,计时器的量程为59min,满量程后自动归零。
计程部分:计算乘客所行驶的公里数,当行驶里程大于2km时,本模块中en0使能信号变为1;当clk每来一个上升沿,计程器就自增1,计程器的量程为99km,满量程后自动归零。
元件框图为:

计量模块框图
计量模块仿真波形为:
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity jiliang is
port(start:in std_logic; --计费开始信号
fin:in std_logic; --里程脉冲信号
stop:in std_logic; --行驶中途等待信号
clk1:in std_logic; --驱动脉冲
en1,en0:buffer std_logic; --计费单价使能信号
k1,k0:buffer std_logic_vector(3 downto 0); --行驶公里计数
m1,m0:buffer std_logic_vector(3 downto 0)); --等待时间计数
end jiliang;
architecture rt2 of jiliang is
signal w:integer range 0 to 59; --计时范围0~59
begin
process(clk1)
begin
if(clk1'event and clk1='1')then
if start='0' then
w<=0;en1<='0';en0<='0';m1<="0000";
m0<="0000";k1<="0000";k0<="0000";
elsif stop='1' then --计时开始信号
if w=59 then
w<=0;
else w<=w+1;
end if;
if m0="1001" then
m0<="0000";
if m1="0101" then
m1<="0000";
else m1<=m1+1;
end if;
else m0<=m0+1;
end if;
if stop='1' then en0<='0';
if m1&m0>"00000001" then en1<='1'; --若等待时间大于2min则en1置1
else en1<='0';
end if;
end if;
elsif fin='1' then --里程计数开始
if k0="1001" then k0<="0000";
if k1="1001" then k1<="0000"; --计程范围0~99
else k1<=k1+1;
end if;
else k0<=k0+1;
end if;
if stop='0' then
en1<='0';
if k1&k0>"00000001" then
en0<='1'; --若行使里程大于2km,则en0置1
else en0<='0';
end if;
end if;
end if;
end if;
end process;
end rt2;
3. 控制模块
本模块主要是通过计量模块产生的两个不同的输入使能信号en0,en1,对每个分频模块输出的14hz,13hz的脉冲进行选择输出的过程;本模块实现了双脉冲的二选一;最终目的为了计费模块中对行驶过程中不同的时段进行计价。
模块元件如下:

控制模块框图
控制模块仿真波形为:
源程序如下:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity kongzhi is
port(en0,en1:in std_logic; --使能选择信号
clk_in1:in std_logic; --14分频输入信号
clk_in2:in std_logic; --13分频输入信号
clk_out:out std_logic); --输出信号
end kongzhi;
architecture rt3 of kongzhi is
begin
process(en0,en1)
begin
if en0='1' then --实现二选一功能
clk_out<=clk_in1;
elsif en1='1' then
clk_out<=clk_in2;
end if;
end process;
end rt3;
4.计费模块
当计费信号start一直处于高电平即计费状态时,本模块根据控制模块选择出的信号从而对不同的单价时段进行计费。即行程在2km内,而且等待累计时间小于2min则为起步价5元;2km外以每公里1.4.元计费,等待累积时间超过2min则按每分钟1.3元计费。c0,c1,c2,c3分别表示费用的显示。
模块元件为:

计费模块框图
计费模块仿真波形为:
源程序如下:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity jifei is
port(clk2:in std_logic; --计费驱动信号
start:in std_logic; --计费开始信号
c0,c1,c2,c3:buffer std_logic_vector(3 downto 0));
end jifei;
architecture rt4 of jifei is
begin
process(clk2,start)
begin
if start='0'then c3<="0000";c2<="0000";c1<="0101";c0<="0000"; --起步价5元
elsif clk2'event and clk2='1'then
if c0="1001" then c0<="0000";
if c1="1001" then c1<="0000";
if c2="1001" then c2<="0000";
if c3="1001" then c3<="0000"; --计价范围0~999.9
else c3<=c3+1;
end if;
else c2<=c2+1;
end if;
else c1<=c1+1;
end if;
else c0<=c0+1;
end if;
end if;
end process;
end rt4;
5.显示模块
显示模块完成计价,计时和计程数据显示。计费数据送入显示模块进行译码,最后送至以百元,十元,元,角为单位对应的数码管上显示。计时数据送入显示模块进行译码,最后送至以分为单位对应的数码管上显示。计程数据送入显示模块进行译码,最后送至以km为单位的数码管上显示。
模块元件为:

显示模块框图
源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; --定义库包
entity xianshi is --定义实体
port(
clk_scan:in std_logic; --扫描时钟信号端口设置
c3,c2,c1,c0:in std_logic_vector(3 downto 0); --总费用输入端口
k0,k1:in std_logic_vector(3 downto 0); --里程输入端口
m0,m1:in std_logic_vector(3 downto 0); --等待时间输入端口
sel:out std_logic_vector(2 downto 0); --控制数码管位选信号的扫描信号输出端口
led:out std_logic_vector(6 downto 0); --数码管的控制端口
led_dp:out std_logic --数码管的小数点输出端口
);
end xianshi;
architecture rt5 of xianshi is
signal duan:std_logic_vector(6 downto 0); --数码显示管中间变量
signal shuju:std_logic_vector(3 downto 0); --选择输入端的中间变量
signal cnt:std_logic_vector(2 downto 0); --控制数码管的中间变量
signal xiaodian:std_logic; --小数点的中间变量
begin
process(clk_scan) --开始进程
begin
if clk_scan'event and clk_scan='1' then
cnt<=cnt+1; --每有一个扫描信号上升沿实现加1扫描
end if;
end process; --结束进程
process(cnt) --开始进程(选择扫描显示数码管)
begin
case cnt is --扫描时给每个数码管赋值
when "000"=>shuju<=c0;
when "001"=>shuju<=c1;
when "010"=>shuju<=c2;
when "011"=>shuju<=c3;
when "100"=>shuju<=k0;
when "101"=>shuju<=k1;
when "110"=>shuju<=m0;
when "111"=>shuju<=m1;
when others=> null;
end case;
if (cnt="001" or cnt="110")
then xiaodian<='1'; --在里程和总费用的个位处显示小数点
else xiaodian<='0';
end if;
end process; --结束进程
process(shuju) --开始进程(译码显示)
begin
case shuju is
when "0000"=>duan<="0111111"; --0
when "0001"=>duan<="0000110"; --1
when "0010"=>duan<="1011011"; --2
when "0011"=>duan<="1001111"; --3
when "0100"=>duan<="1100110"; --4
when "0101"=>duan<="1101101"; --5
when "0110"=>duan<="1111101"; --6
when "0111"=>duan<="0000111"; --7
when "1000"=>duan<="1111111"; --8
when "1001"=>duan<="1101111"; --9
when others=>null;
end case;
end process;
sel<=cnt;
led<=duan;
led_dp<=xiaodian;
end rt5;
二、课程设计工作记录:
包括:设计步骤与时间安排、调试步骤与时间安排、课题完成结果说明
2.课题完成结果说明:
此计费器能实现起步价是5元;实现实验要求的1公里计费一次单价,行驶公里大于2km时每公里按1.4元计费并能显示里程和总共的费用。当行驶了6公里,等待了4分钟时,费用显示为15.8元。与计算公式总费用=起步费用+(里程-2公里)*里程单价+等候时间*等后单价;即15.8=5+(6-2)*1.4+4*1.3。实验结果与理论结果完全一致,实验设计成功。

出租车计价器程序设计与原理图

用单片机好做,但如果用模拟电路和数字电路来搭建这样复杂的功能,恐怕做出来要比现有的成本计价器大几十倍,而且耗电巨大,成本更高,何必要这样做呢?只因为没有学到就要这样不计成本的浪费吗?
如果是急求的话,可以花钱招一个懂单片机的人来搞,没有人能提供不用单片机的电路的,太复杂了,不可能实现。
首先要看里程传感器的输出是模拟的还是数字的。
无论何种里程传感器,
可以用数字积分器,简单些;也可以用模拟积分器,这样设计和调试的难度就很大。

EDA 出租车计费器 求大神帮忙 谢谢了 很急啊!!!

以前做的设计,参考一下,记得给分啊
粘过来时图形好像没显示啊
一、设计目的
1、 熟悉和增强对VHDL语言的基本知识,熟悉利用VHDL语言对常用的的组合逻辑电路和时序逻辑电路编程,把编程和实际结合起来。
2、加深对编制和调试程序的技巧.
3、提高上机动手能力,培养使用设计综合电路的能力。
二、设计要求
1、出租车启动和停驶由司机控制;
2、行程小于基本里程时,显示起步价,基本里程设3公里,起步价设5元;
3、行程大于基本里程时,每多行一公里,在起步价上加2元;
4、当出租车等待时,由司机按下等候键,每等待一分钟加1元,不足一分钟的按一分钟计算;
5、此处用脉冲信号模拟轮胎的转数,设每计一个脉冲汽车前进1米,系统中所需脉冲均由实验箱的50MHz晶振分频提供。
三、总体设计原理与内容(四号字、宋体、加粗)
1、设计的总体原理(比如算法及其流程框图等)
出租车计价器按功能主要分为:速度模块、计程模块、计时模块、计费模块。


2、设计内容
首先根据start信号判断是否开始计费,然后根据sp判断,确定1米所需要的时钟数,每前进一米,输出一个clkout,同时由cnt对clk进行计数。
通过对clkout信号的计数,可计算形式的距离kmcount,一个clkout相当于行驶一米,所以只要记录clkout的脉冲数,即可确定行驶距离。
通过对sp信号的判断,确定是否开始计时。Sp= 0时,开始记录时间。当时间足够长时,产生timecount脉冲。
计费模块分为kmmoney1和kmmoney2两个进程。kmmoney1用于产生enable和price信号。当记录距离达到3km后,enable信号为1,开始进行每千米的计费。
kmmoney2用于判断timecount和clkout的值,当其为1时,总费用加1。最终输出为总费用。
四、EDA设计及仿真(四号字、宋体、加粗)
1、出租车计价器的设计源程序
速度模块的VHDL代码如下:
library ieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;

entity speed is
port(
clk : in std_logic;
reset: instd_logic;
start:instd_logic;
stop:in std_logic;
sp:in std_logic;
clkout:out std_logic
);
end speed;
architecture rt1of speed is
begin
process(clk,reset,stop,start) -----敏感信号变化时,启动进程
type state_typeis(s0,s1); ------枚举类型
variables_state:state_type;
variablecnt:integer range 0 to 100;
begin

ifreset='1'then ----复位清
s_state:=s0;
elsif clk'eventand clk='1'then
case s_state is
when s0=>
cnt:=0;
clkout<='0';
if start='1'then
s_state:=s1;
else
s_state:=s0;
end if;
when s1=>
clkout<='0';
if stop='1'then
s_state:=s0; ----无客上车
elsif sp='0'then
s_state:=s1;
elsif cnt=100 then
cnt:=0;
clkout<='1';
s_state:=s1;
else
cnt:=cnt+1;
s_state:=s1;
end if;
end case;
end if;
end process;
end rt1;
计程模块的VHDL代码如下:
LIBRARY IEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY km IS
PORT (
CLKOUT,RESET: IN STD_LOGIC;
kmcnt1:OUT STD_LOGIC_VECTOR (3 DOWNTO0);
kmcnt2:OUT STD_LOGIC_VECTOR (3 DOWNTO0);
kmcnt3:OUT STD_LOGIC_VECTOR (3 DOWNTO0));
END km;
ARCHITECTURE rtlOF km IS
BEGIN
PROCESS(CLKOUT,RESET) ----启动进程
VARIABLE kM_reg: STD_LOGIC_VECTOR (11DOWNTO 0);
BEGIN
IF RESET ='1' THEN ---复位清零
kM_reg:="000000000000";
ELSIF CLKOUT'EVENT AND CLKOUT='1' THEN ---------时钟上升沿到达时进行计程
IF kM_reg(3 DOWNTO 0)="1001"THEN ---------对应里程十分位
kM_reg:=kM_reg+"0111"; ---------十分位向个位进位
ELSE
kM_reg(3 DOWNTO 0):=kM_reg(3 DOWNTO0)+"0001";
END IF;
IF kM_reg(7 DOWNTO 4)="1010"THEN
kM_reg:=kM_reg+"01100000"; ---------个位向十位进位
END IF;
END IF;
kmcnt1<=kM_reg(3 DOWNTO 0);
kmcnt2<=kM_reg(7 DOWNTO 4);
kmcnt3<=kM_reg(11 DOWNTO 8);
END PROCESS;
END rtl;

计时模块的VHDL代码如下:
library ieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;

entity times is
port(
clk : in std_logic;
reset: in std_logic;
start:in std_logic;
stop:in std_logic;
sp :in std_logic;
timecount:out std_logic
);
end times;
architecture rt1of times is
begin
process(clk,reset,stop,start,sp) -----启动进程
type state_type is(t0,t1,t2);
variable t_state:state_type;
variable cnt:integer range 0 to 28;
variable waittime:integer range 0 to 255;
begin
if reset='1'then ----复位清零
t_state:=t0;
elsif clk'event and clk='1'then
case t_state is
when t0=>
waittime:=0;
timecount<='0';
if start='1'then
t_state:=t1;
else
t_state:=t0;
end if;

when t1=>
if sp='0'then
t_state:=t2;
else
waittime:=0;
t_state:=t1;
end if;
when t2=>
waittime:=waittime+1;------等待时间加1
timecount<='0';
if waittime=255 then
timecount<='1'; -------产生一个时间计费脉冲
waittime:=0;
elsif stop='1'then
t_state:=t0;

else
timecount<='0';
t_state:=t1;
end if;
end case;
end if;
end process;
end rt1;

计费模块的VHDL代码如下:
LIBRARY IEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY kmmoney IS
PORT(
CLK :IN STD_LOGIC;
RESET:IN STD_LOGIC;
timecount:IN STD_LOGIC;
clkout:IN STD_LOGIC;
kmcnt2:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
kmcnt3:in STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT2:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT3:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END kmmoney ;
ARCHITECTURE rtlOF kmmoney IS
SIGNAL cash :STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL price :STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL enable :STD_LOGIC;
BEGIN
kmmoney1:process(cash,kmcnt2) -------------此进程产生下一进程的敏感信号
BEGIN
price<="0010";
if kmcnt2>="0010" then
enable<='1';
else
enable<='0';
END IF;
END PROCESS;

kmmoney2:process(reset,clkout,clk,enable,price,kmcnt2)
variablereg2:std_logic_vector(11 DOWNTO 0);
variableclkout_cnt:integer range 0 to 10;
begin
if reset='1'then

cash<="000000000101";
-------起步费用设为5元
elsif clk'eventand clk='1'then
----判断是否需要时间计费,每60s加1元
if timecount='1'then
reg2:=cash;
if (reg2(3 downto
0)+"0001")>"1001" then
------产生进位------
reg2(7 downto 0):=reg2(7 downto0)+"00000111";
if reg2(7 downto4)>"1001"then
cash<=reg2+"000001100000";
else
cash<=reg2;

END IF;
else
cash<=reg2+"0001";

END IF;
---里程计费

elsif clkout='1'and enable='1'then
if clkout_cnt=10 then
clkout_cnt:=0;
reg2:=cash;
if
"0000"®2(3 downto 0)+price(3 downto 0)
>"00001001"then
reg2(7 downto 0):=reg2(7downto 0)+"00000110"+price; ----十位进位
if reg2(7 downto4)>"1001"then ----百位进位
cash<=reg2+"000001100000";
else
cash<=reg2;
END IF;
else
cash<=reg2+price;
END IF;
else -----------------------对时钟计数
clkout_cnt:=clkout_cnt+1;
END IF;
END IF;
END IF;
END process;
COUNT1<=cash(3 DOWNTO 0); -----总费用的个位
COUNT2<=cash(7 DOWNTO 4); -----总费用的十位
COUNT3<=cash(11 DOWNTO 8); -----总费用的百位
END rtl;
顶层模块的VHDL代码如下:
library ieee;
use ieee.std_logic_1164.all;
entity top is
port(
clk : in std_logic;
reset: in std_logic;
start:in std_logic;
stop:in std_logic;
sp :in std_logic;
kmcnt1:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0);
kmcnt2:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0);
kmcnt3:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0);
COUNT1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT2:OUTSTD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT3:OUTSTD_LOGIC_VECTOR(3 DOWNTO 0)
);
end top;
ARCHITECTURE rtl OF top IS
------- 对上述电路模块进行元件定义--------
COMPONENT SPEED IS------------定义速度模块
port(
clk : in std_logic;
reset: in std_logic;
stop:in std_logic;
start:in std_logic;
sp :in std_logic;
clkout:out std_logic
);
end COMPONENT speed;
COMPONENT km is ---定义计程模块
PORT (
CLKOUT,RESET: INSTD_LOGIC;
kmcnt1:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0);
kmcnt2:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0);
kmcnt3:OUTSTD_LOGIC_VECTOR (3 DOWNTO 0)
);
end COMPONENT km;
COMPONENT kmmoney is--------定义计费模?------
PORT(
CLK :IN STD_LOGIC;
RESET:IN STD_LOGIC;
timecount:INSTD_LOGIC;
clkout:IN STD_LOGIC;
kmcnt2:INSTD_LOGIC_VECTOR(3 DOWNTO 0);
kmcnt3:inSTD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT1:OUTSTD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT2:OUTSTD_LOGIC_VECTOR(3 DOWNTO 0);
COUNT3:OUTSTD_LOGIC_VECTOR(3 DOWNTO 0)
);

end COMPONENT kmmoney;

component times is
port( clk:in std_logic;
reset:instd_logic;
stop:in std_logic;
start:instd_logic;
sp:in std_logic;
timecount:outstd_logic
);
end component times;
signal clktmp:STD_LOGIC;
signal timetmp:STD_LOGIC;
signal kmtmp2:STD_LOGIC_VECTOR (3 DOWNTO 0);
signal kmtmp3:STD_LOGIC_VECTOR (3 DOWNTO 0);
begin

U1:speed PORTMAP(clk,reset,stop,start,sp,clktmp);
U2: times PORTMAP(clk,reset,stop,start,sp,timetmp);
U3:km PORTMAP(clktmp,reset,kmcnt1,kmtmp2,kmtmp3);
U4:kmmoney PORTMAP(clk,reset,timetmp,clktmp,kmtmp2,kmtmp3,COUNT1,COUNT2,COUNT3);
kmcnt2<=kmtmp2;
kmcnt3<=kmtmp3;
end rtl;
2、出租车计价器的设计
仿真结果及数据分析
出租车计费器的电路图如图:
上图中当reset为高电平时,系统所有寄存器、计数器都清零;当开始记费信号start信号有效时,计费器开始计费,根据出租车行驶的速度sp的取值计算所用花费和行驶里程;当停止计费信号有效时,计费器停止工作。
对上图构成的系统进行仿真,得到的仿真波形为:

五、硬件实现
1、给出硬件实现(步骤及引脚锁定等说明等)
主要模块中包括输入时钟脉冲clk,时钟上升沿有效;复位信号reset,开始计费信号start,停止计费信号stop,均为高电平有效;出租车状态sp。
2、硬件实现照片
该照片为超过基本行程的的照片,显示为行驶5.5公里,费用为11元。等待1分钟,共计12元。
该照片为基本行程内的的照片,显示为行驶2.6公里,收费5元,显示正确。
该图片显示,行驶7.9公里,费用为15元,显示正确。
等待计费,行驶5.5公里,攻击11元,等待8分钟,共计19元。
六、设计总结
1、设计过程中遇到的问题及解决方法
设计中遇到了数码管无法正常显示,计费不按要求等问题。通过的对源代码的修改,发现易忽略了一些细节。
2、设计体会
从挑选课设题目,查阅资料,到研究出总体设计,详细设计,然后分工合作,再到最后的编程上机调试,修改程序,完善程序,收获颇多。出租车计费器系统的设计已全部完成,能按预期的效果进行模拟汽车启动,停止、暂停等功能,并设计动态扫描电路显示车费数目。车暂停时停止计费。若停止清零,等待下一次计费的开始。由于时间有限,经验欠缺,还存在很多不足之处。
在这一周里我们再次熟悉和增强了对VHDL语言的基本知识,熟悉利用VHDL语言对常用的的组合逻辑电路和时序逻辑电路编程,把编程和实际结合起来。加深了对编制和调试程序的技巧,进一步提高了上机动手能力,培养了使用设计综合电路的能力,养成了提供文档资料的习惯和规范编程的思想。
本次的课程设计将各个单一的模块实现其功能后,学会通过原理图或顶层文件把各模块连接,从而实现对出租车自动计费。课程设计注重的不仅是把理论知识巩固,而且应把理论和实际相结合,把知识应用到生活中。在课程设计过程中,遇到了不少问题,数码管无法正常显示,计费不按要求等。通过的对源代码的修改,发现了一些易忽略的细节。课程设计考验的是思维逻辑能力,对知识的灵活应用,当然,合作精神是不可或缺的。
在设计程序时,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常的,但应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
3、对设计的建议
本设计为出租车计费器的VHDL设计,利用软件仿真和硬件测试实现了其计费功能、预制功能、模拟功能等,建议时间延长,不拘于用VHDL一种语言,而且要求创造出实物。这样可以让学生自由发挥,拓宽思路,提高动手能力。
七、设计生成的电路图

这是单片机课程设计 ---出租车计价器。。这个模拟脉冲的大概原理是什么?那个电阻什么作用?跪求。

那叫 “上拉电阻”,1K, 3.3K, 4.7K 都是可以的。51系列单片机,有的通道必须要加上拉电阻,这是手册里面介绍的,我的印象是这样。我以前设计过键盘扫描电路,有一个通到就连接了上拉电阻,那是根据手册的要求。另外,国外有些电路为了抗干扰,也加上拉电阻。例如,日本的 fanuc 数控系统,所有的输入端点都有上拉电阻。
用一只按钮开关来模拟脉冲,按钮断开时输入低电平,按下时输入高电平。电阻是下拉电阻。
P0口内部无上啦电阻因此使用P0 口均需要上啦电阻。另外P3.3是单片机的一个外部中断1 接口 可以满足实时采集计数脉冲的需要!希望能帮到你

基于单片机的出租车计价器的课程设计怎么写?


#51单片机 #计价器 #计轮胎圈数 #时钟芯片 #中断 #LCD显示 #累加 #按键 #reset键 #LCD #数码管 #车辆速度

出租车计价器

saSASQSSSASSXSA大圣等待丶
一、题目:A题 设计并制作一个用于出租车的计费系统。
二、设计要求
1、基本要求:
(1)制作一个模拟车轮用直流电动机(或步进电机)驱动,现场模拟以下运行情况的收费情况:
u 假设车轮的周长为一米。
u 起步价为三公里五元,白天每公里三元,晚上每公里四元。
u 运行五公里之后,停三分钟,再运行五公里之后乘客下车,由于演示的时间的需要,途中停车超过一分钟开始收费,超过的时间每分钟一元。
(2)能够手动修改单价。
(3)具有数据的复位功能。
(5)数据输出
u 单价输出 至少2位
u 路程输出 至少2位
u 总金额输出 至少3位
2、发挥部分:
(1)能够在掉电的情况下存储单价等数据。
(2)能够显示、调节当前的系统时间,并根据当前的系统时间进行计费(6时至18时为白天,18时至第二天6时为晚上)。
(3)有语音报价功能。
1.2 方案比较与论证
1.2.1控制器模块
方案一:采用可编程逻辑器件CPLD 作为控制器。CPLD可以实现各种复杂的逻辑功能、规模大、密度高、体积小、稳定性高、IO资源丰富、易于进行功能扩展。采用并行的输入输出方式,提高了系统的处理速度,适合作为大规模控制系统的控制核心。但本系统不需要复杂的逻辑功能,对数据的处理速度的要求也不是非常高。且从使用及经济的角度考虑我们放弃了此方案。
方案二:采用凌阳公司的16位单片机,它是16位控制器,具有体积小、驱动能力高、集成度高、易扩展、可靠性高、功耗低、结构简单、中断处理能力强等特点。处理速度高,尤其适用于语音处理和识别等领域,采用此单片机能够很方便的实现发挥部分的语音报价功能,但此单片机较难买到,而且价格稍贵,故放弃了此方案。
方案三:采用Atmel公司的AT89S52单片机作为主控制器,此单片机是51内核的CMOS 8位单片机,片内含8k空间的可反复擦些1000次的Flash读写存储器,具有256 bytes的随机存取数据存储器(RAM),32个IO口,你知道厂房装修合同样板。2个16位可编程定时计数器。其价格低廉,非常适合用于小系统的开发,开采用ISP在线编程,程序的下载和修改也很方便。题目所要求的系统对控制器的要求不高,我们综合多方面考虑选用了此方案。
1.2.2车轮转速探测模块
方案一:用光敏电阻组成光敏探测器。光敏电阻的阻值可以跟随周围环境光线的变化而变化。当光线照射到车轮码盘的白色部分时,光线发射强烈,光线照射到车轮码盘的黑色部分时,光线发射较弱。因此光敏电阻在白色部分和黑色部分上方时,阻值会发生明显的变化。将阻值的变化值经过比较器就可以输出高低电平。此方案易受外界光线的干扰。
方案二:采用霍尔传感器最为探测器件,霍尔传感器的两部分分别安装在车轮和固定电路板上,根据车轮转动时将变化的磁场强度转换为脉冲电信号,此方案能够使对车轮计数精确,工作稳定,但成本较高。
方案三:采用红外对管,当红外发射管发射出的红外线照到码盘的白色部分和黑色部分时,其反射的红外线强度不同,通过红外接收管接收后经电压比较器LM311比较后即可输出高低电平。此方案成本低,容易实现,且灵敏度较高。
根据本系统的设计要求,对车轮转速的探测受外界的干扰较小,而采用采用红外对管工作电路简单,调试方便,所以我们选择此方案。
1.2.3时钟控制模块
方案一:采用32.768MHz的晶振产生震荡后经多个74LS161进行15次2分频,产生精确的秒信号,自行搭建时间电路。此方案具有较好的原创性,但电路搭建起来较为复杂,工作不够稳定,也不方便调节。
方案二:直接采用单片机内部的时钟信号。这样能够大大简化硬件的设计,但断电后不能工作,而且大量占用单片机有限的内存资源。
方案三:采用DS专用时钟芯片。DS是功能强大的实时时钟芯片,内置锂电池,内置晶振。提供二进制数和BCD码两种数据表示方式。可切换24小时制和12小时制时间表示。具有闹钟功能。可编程方波输出。提供114字节非易失存储空间,用于断电保存数据。
由于本系统的很多功能都是基于时间的基础上实现的,因此对时钟的要求较高,故我们选择方案三。
1.2.4显示模块
方案一:用数码管进行显示。数码管由于显示速度快,使用简单,显示效果简洁明了而得到了广泛应用,但显示的内容仅仅局限于数字,人机界面不够友好因此我们放弃了此方案。
方案二:用LCD液晶1602进行显示。LCD由于其显示清晰,显示内容丰富、清晰,显示信息量大,使用方便,显示快速而得到了广泛的应用。由于本此系统需要显示的内容较多,为达到较好的人机交互界面,我们选择了此方案。
1.3最终选择方案
u 采用AT89S52单片机作为主控制器。
u 采用红外对管+LM311作为车轮转速探测模块。
u 采用DS作为实时时钟控制芯片。
u 采用1602LCD液晶作为显示模块。
u 采用普通的直流电机和自制的车轮及码盘作为模拟车轮。
1.4系统结构图
按键:

红外感应模块

MCU
AT89S52

DS系统时间,断电保存数据

LCD液晶显示

模拟车轮

图1 系统结构框架
第二章:各部分电路原理与设计
2.1单片机主控模块的设计
Atmel公司的AT89S52是51内核的单片机。不用烧写器而只用串口或者并口就可以往单片机中下载程序。
我们所设计的单片机最小系统板采用的双龙公司的并口下载标准,且在板上留有下载线插座,这样可以非常方便的实现通过PC机的并口往单片机中下载程序。同时将稳压电源部分也附在其上,经过7805稳压后的+5V电源为除电机外的其他系统模块提供工作电源。
单片机控制模块的示意图如图9所示:
图2 单片机主控模块
单片机的I/O口分配如下:
P0,P2.5~P2.7 LCD模块
P1,P2.0~P2.3,P3.3 实时时钟模块
P3.0~P3.1,P3.5~P3.7 按键开关
P3.2 红外探测模块
2.2红外探测模块的设计
我们通过将红外接收二极管的不同压降与基准电压送入电压比较器LM311进行比较,输出对应的高低电平信号,送到单片机进行处理。其电路原理图如下:
图3 红外探测模块
在图3中,可调电阻RW可以调节比较器的门限电压,经示波器观察,输出波形相当规则,可以直接够单片机查询使用。
由于我们的码盘采用二分法进行设计,黑白两种颜色各占原周的一半,因此单片机每接收到一个高电平信号则模拟车轮转了一圈,通过计算每秒钟单片机接收到的高电平信号个数即可方便的计算出车轮的速度和所走的里程。
2.3模拟车轮的设计
小车的速度和里程的测量是通过光电对管检测码盘实现的。我们采用普通的直流电机和玩具车的车轮,自制码盘,做成模拟车轮,供测量用。
考虑到电机运行时对电压的干扰,电机的电源直接由输入的未经过稳压的电源提供,试用期解除劳动合同。并设立独立的开关,有人工控制,这样更符合实际的工作情况。
为防止光电管产生误动作,我们将光电码盘分为2份黑白相间的圆盘,每份各占圆周的一半,如图4:
图4 模拟车轮码盘
将其紧贴在车轮的内侧。在封装盒右侧打一个方孔,红外对管通过方孔对光电码盘进行检测就可以得到车轮转过的圈数。从而计算出小车前进的路程。
本系统假设车轮的周长为1米,假设单片机每秒检测到黑白信号的变化为n,共走了k秒则小车走过的路程为S=nk米。
2.4实时时钟控制模块的设计
我们采用的DS功能强大,内置锂电池,内置晶振,可以作为实时电子钟,为整个系统提供时钟,很好地解决了题目发挥部分“能够显示、调节当前的系统时间,并根据当前的系统时间进行计费(6时至18时为白天,18时至第二天6时为晚上)”的要求。同时利用其闹钟功能对探测信号进行采样,精确的计算出车速。由于芯片还提供114字节非易失存储空间,因此我们将题目要求的各种价格的设置方便的保存在里面,达到断电保存数据的功能。
图5 时钟模块电路图
2.5人机交互界面的设计
为使系统有更良好的人机交互界面,我们将LCD液晶显示模块,操作按键,系统复位开关和车轮控制开关集中于封装盒的面板上,方便用户操作,如下图:
图6 人机交互界面
2.6系统总体电路图
图7 系统总电路图
图8 系统装箱后的内部实物图
第三章:系统程序设计
3.1系统程序所实现的功能
u 实时显示总金额,总里程,车速,已走过时间,系统时间。
u 可在线修改系统时间。
u 可修改起步价及起步距离。
u 可修改每超过一公里加收费用。
u 可修改途中停车超过时间开始收费的时间及单价。
3.2程序任务分配
表1 程序任务分配
外部中断0(来自车轮)

外部中断1(来自时钟)

主函数

更新路程,加总价,复位计时器,如果显示屏使用权在INT0,就更新显示。
显示屏使用权用screen变量表示。

计算速度,计算行车时间,计时并在停车超时后加钱。根据显示屏使用权判断是否更新显示。
根据real_time变量的值决定是否把系统时间更新到屏幕上。

读取按键。决定控制逻辑。

3.3主程序流程图
开始

初始化LCD、实时时钟

从存储器读出单价等数据

显示logo

任意键

空闲状态,显示系统时间

有键按下

空闲状态

计费状态

设置键?

N

Y

设置

等待按键

是2键?

N

Y

初始化计费屏幕,进入计费状态

是3键

Y

查看系统时间,延时4秒

N

是4键?

Y

停止计费,进入空闲状态

N

按下2键复位

3.4各数据在中存储地址
表2 各数据在中存储地址
地址

变量

功能

0x0e

d

//起步价 d 公里 p 角

0x0f

p

0x10

day_price

//白天每公里价格,单位:角

0x11

night_price

//夜晚每公里价格,单位:角

0x12

x

//中途停车超过y分钟之后按x角每分钟计价

0x13

y

3.5中断服务0程序流程图
触发中断

路程加一米

允许使用显示屏?

计时器复位

路程==起步路程?

路程>起步路程?

Y

N

Y

更新路程显示

向总金额加上公里价

N

更新总金额显示

Y

N

Y

公里计程器复位

中断2服务程序的timer_state和timer_count变量

counter_1000变量

公里计程器加1

公里计程器==1000?

结束

N

Y

向总金额加上公里价

允许使用显示屏?

更新总金额显示

Y

N

公里计程器复位

0号中断服务程序:
车轮转动一圈触发一次

3.6 中断服务2程序流程图
触发中断

系统在计费状态?

Y

N

需要同步时间?

Y

N

结束

速度=现在的路程—一秒之前的路程

行车时间加一秒

计时器加一秒

计时等于最大停车时间?

N

总金额加每分钟价

进入停车超时状态

Y

停车超时状态?

Y

每分钟加钱

N

将系统时间和日期同步到屏幕上

2号中断服务程序:
每秒钟触发一次

第四章:系统调试结果与分析
4.1调试方法与仪器
表3 测试仪器设备清单
仪器名称

型号

用途

数量

PC机

联想

调试及下载程序

1

数字万用表

UNI-T10A

测量各电路工作情况

1

秒表

记录时间

1

直流稳压电源

ALKIMIA

提供电源

1

4.2调试步骤与测试数据
4.2.1系统时间与秒表实际时间测量
开机后按“开始”键进入计时工作状态,同时启动秒表进行及时对比,分别对工作时间为1分钟,2分钟,3分钟,4分钟,5分钟进行测量比较,结果如表2
表4 系统时间测试比较
测试时间

系统显示时间

秒表测量时间

60s

60s

59.61s

120s

120s

121.02s

180s

180s

180.66s

240s

240s

238.58s

300s

300s

300.40s

4.2..2车轮转速测试
本系统的设计对探测信号的下降沿进行触发,因此当红外对管探测到的码盘从白色转为黑色时,单片机中断触发,计数器加一。
启动计费系统,同时手工转动车轮一周,显示屏上路程显示1m,在转动车轮几圈,LCD的显示数值均与实际相符。
4.2.3计费系统测试
表5 不同情况下的计费结果测试
计费时间段

行驶里程

行驶时间

中途停车时间

计费价格

白天

2781m

61s

0

5.0元

白天

9532m

198s

0

26.0元

晚上

9682m

202s

0

33.0元

晚上

9529m

385s

182s

36.0元

4.2.4数据设定及断电储存功能
在待机状态下按“设置”键,分别修改起步价4km内8元,白天每公里5元,晚上每公里7元,修改系统时间,然后保存,关机,断开电源,等待5分钟之后重新开机,发现数据为修改后的数据,即数据的设定及断电储存功能有效。
4.3测试结果分析
通过调试和系统测试,发现系统能很好地实现预期的目的,实现了除语音功能外的其他所有功能,工作性能稳定,计费精确。系统时间实时运行,准确,里程的显示误差在1m以内。很好的完成了赛题的要求。
第五章:系统性能总结及特点
5.1 实现基本要求功能
表4 基本功能的实现情况
基本要求功能

功能实现情况

基本要求第(1)项

实现

基本要求第(2)项

实现

基本要求第(3)项

实现

基本要求第(4)项

实现

基本要求第(5)项

实现

5.2 实现发挥部分功能
表5 发挥功能的实现情况
发挥要求功能

功能实现情况

发挥要求第(1)项

实现

发挥要求第(2)项

实现

发挥要求第(3)项

未实现

5.3 增加的其他功能
u 与计费系统相关的所有参数用户均可修改并储存。
u 兼有万年历和数字电子钟功能。
u 一体化人机交互界面控制面板,硬件系装箱,提高机械强度,安全性能和美观度。
第六章:附录
附录一 系统程序源代码
/******************************************************************************/
// 华南理工大学自动控制大赛高级组A题:出租车计费系统
// 参赛队:Dragonfly
// 成员:翁新钎
// 曾 泽
// 罗桂波
// 文件名称:main.c
// 文件功能:提供包括主函数、中断服务、LCD显示及按键操作等功能函数,
// 实现对红外探测到的信号进行处理、显示功能和系统设置。
// 建立时间:2008.4.28
// 更新时间:2008.5.10
// 文件版本:V1.5
/******************************************************************************/
#include"test_.c"
#define SYSTEM_STATE_IDLE 0
#define SYSTEM_STATE_RUN 1
#define INT0 1
#define INT1 2
#define MAIN 4
/***** 按键定义 *****/
sbit Key1=P3^5;
sbit Key2=P3^6;
sbit Key3=P3^7;
sbit Key4=P3^0;
sbit Key5=P3^1;
/*** 全局变量 ***/
char code *day[]={"Sun","Mon","Tue","Wen","Thu","Fri","Sat"}; //显示星期几对应的字符串
int distance=0,min_distance=3000;
char min_price=50; //3000m,50角
char price=30; //角/km
int sum=0; //分
char speed; //(m/s)
int counter_1000=0;
int last_distance=0;
char max_stop_time=1; //minute
char price_per_minute=10; //角
char hh,mm,ss; //time
bit timer_state=0; //Free
int timer_count=0;
char system_state=SYSTEM_STATE_IDLE; //系统状态
char screen=MAIN; //把LCD显示屏的使用权分配给MAIN
bit real_time=0; //控制外部中断2是否要把系统时间和日期
//更新到LCD屏幕上
/* 函数声明 */
char getkey(); //等待一个按键按下,返回键码
void logo(); //开机logo
void init_prices(); //从的数据存储区读出数据
void update_distance(); //计价过程中负责更新屏幕上显示的路程
void LCD_write_int(int i); //向LCD写一个整数
void update_time(); //计价过程中负责更新屏幕上显示的行车时间
void update_speed(); //计价过程中负责更新屏幕上显示的速度
void update_sum(); //计价过程中负责更新屏幕上显示的总金额
void set(); //设置
void display_time(); //显示系统时间 hh:mm:ss
void display_date(); //显示日期 20xx-xx-xx
void idle_state_screen_init(); //进入空闲状态屏幕初始化
void run_screen_init(); //进入计费状态屏幕初始化
void set_time(); //设置系统时间
void set_start_price(); //设置起步价
void set_price(); //设置行车价格
void set_wait_price(); //设置中途停车的价钱
附录二 系统说明书
一、 人机交互界面
图9 人机交互界面
LCD显示屏

2 4
1 3 5

二、按键功能
2:开始计费,停止计费后用来复位。
4:停止计费。
1:进入设置界面。
3:设置过程中用来切换设置项,计费过程中查看系统时间和日期。
5:改变数字大小。
三、系统描述:
1、开机首先显示LOGO,如图10。按任意键继续。
图10 开机Logo
2、系统空闲,显示时间、日期和星期几。
图11 空闲时显示电子钟
3、按2键开始计费。或者按1键进入设置。
4、计费:界面显示总金额,路程,速度,行车时间。
图12 开始计费界面
按3查看系统时间,4秒钟后自动返回计费界面。
按1进入设置界面。
四、系统设置:
无论系统工作状态,按下1键进入设置界面。设置界面有4个。
a. 设置系统时间和日期。(SET-T)用3键移动闪烁的光标到要进行设置的位,按5键改变数值大小。按1转入下一个设置界面。
图13设置系统时间和日期
b. 设置起步价。(SET START PRICE)操作同a。
图14设置起步价
c. 设置价格。(SET PRICE)包括白天的价格和夜晚的价格。操作同a。
图15设置价格

《计算机组成原理》课程设计--出租车计价器

第三方第三方第三方斯蒂芬斯蒂芬
问题是什么?
单片机课程设计出租车计价器资料全(程序、论文、proteus仿真图)