精华内容
下载资源
问答
  • 出租计费软件

    2015-10-01 16:17:35
    很小的VB6.0综合了EXCEL、DriveListBox、DirListBox、FileListBox等的应用,同时用到了代码模块,分享学习
  • 金帝台球计费软件系统具有灯控设备自动探测,开机自动检测,单路保险,时段调价器、会员限期、禁止手动输卡号、时间监视器、陪打、出租等等功能。Kingd金帝台球计费软件部分功
  • 出租车自动计费

    2011-10-26 21:28:17
    出租车自动计费设计,运用multisim软件
  • 出租计费

    2012-10-25 19:56:28
    基于stc89c51出租软件程序 汇编程序 流程图
  • 出租计费器是一种专用的计量仪器,它安装在出租车上,指示出载客路程数,以及乘客应付费用的总数。  出租车计价系统较多的是利用单片机进行控制,但较易被私自改装,且故障率相对较高,且不易升级;而FPGA具有高...
  • 初始条件:本次设计使用quartus软件编程,最终在FPGA上实现。 要求完成的主要任务: 实现计费功能,计费标准为武汉起步3元,1公里后4元,1.5公里后5元,2公里后6元,2.5公里后7元,车行3公里后跳为8元,以后为1.4...
  • 本设计是使用Verilog实现出租计费器,使用的开发平台是QuartusII开发软件,使用的开发板是DE2开发板
  • 摘要:以现场可编程逻辑器件(FPGA)为设计载体,以硬件描述语言(VHDL)为主要表达方式,以QuartusⅡ开发软件和GW48EDA开发系统为设计工具,给出了一种出租计费器的工作原理和软硬件实现方法。同时对该出租计费器...
  • 为生产可靠、稳定且灵活性好、开发周期短、效率高、维护简单的出租计费器,提出了在QuartusII 9.0 软件平台上,基于FPGA的出租计费器的设计方案。通过VHDL描述出租计费系统的操作流程及控制方案,实现模拟汽车...
  • 出租计费器_VHDL.rar

    2020-03-19 11:37:27
    (1)设一个出租车自动计费器,计费包括起步价、行驶计费和等待计费三个部分,用 2 个数码管显示出金额数目,最大值为 99元,最小计价单位为 1元。行驶里程在 3 公 里范围内且等待时间未超过三分钟时按起步价 8 元...
  • 鸿威台球计费软件允许卡内扣除的费用也可以选择,我们一般也就建议允许扣除桌台费,商品费都不在卡内扣除,对存款奖励现金的卡容易造成亏本。 会员卡还可以选择适用的计费方式,比如这个卡在台球房消费的可以打折,...
  • 出租车自动计费器电路multisim源文件,根据实际路程计算出路费,有设置等候时间,multisim10及以上版本的软件可以正常打开仿真。
  • 出租车的基本计费仿真,89c52单片机仿真,C语言编写,设计思路适用新手,老鸟
  • 该系统利用VHDL语言、PLD设计出租计费系统,以MAX+PLUSⅡ软件作为开发平台,设计了出租计费器系统程序并进行了程序仿真。使其实现计费以及预置和模拟汽车启动、停止、暂停等功能,并动态扫描显示车费数目。
  • 出租计费器是一种专用的计量仪器,它安装在出租车上,指示出载客路程数,以及乘客应付费用的总数。  出租车计价系统较多的是利用单片机进行控制,但较易被私自改装,且故障率相对较高,且不易升级;而FPGA具有高...
  • 该系统利用AVR和FPGA设计出租计费系统,以WinAVR和Quartus II软件作为开发平台,设计了出租计费器系统程序并进行了程序仿真。使其实现计费以及预置和模拟汽车启动、停止、暂停等功能,并用液晶屏显示各种信息和...
  • 该系统利用VHDL语言、PLD设计出租计费系统,以MAX+PLUSⅡ软件作为开发平台,设计了出租计费器系统程序并进行了程序仿真。使其实现计费以及预置和模拟汽车启动、停止、暂停等功能,并动态扫描显示车费数目
  • 出租车计价系统较多的是利用单片机进行控制,但较易被私自改装,且故障率相对较高,且不易升级;...本文正是基于FPGA,设计了一种出租车的计费系统,它可以直观地显示出租车行驶的里程和乘客应付的费用。
  • 功能如下(1)自动计费计费部分应包括行车里程计费、等候时间计费和起步费三部分,三项计费统一用4位数码管显示,并且最大金额为99.99元。 (2)行车里程单价设为1.80元/km,等候时间计费设为1.5元/10分钟,起步费...
  • 本文借助QuartusⅡ9.0软件,基于大规模可编程逻辑器件FPGA,利用Verilog HDL 语言,进行出租计费器设计。该出租计费系统包括计数器分频模块、数码管分频模块、计程模块、计时模块、计费模块、控制模块、数码管...
  • 利用FPGA实现出租计费系统

    千次阅读 多人点赞 2021-01-26 14:38:22
    本文是通过Verilog语言,通过Quartus II平台和FPGA开发板实现的一款出租计费系统的设计。全文对于EDA技术以及Verilog硬件描述语言的概念以及相关特点进行了介绍与论述。对于该计费系统的实现方式以及不同模块功能...

    本文是通过Verilog语言,通过Quartus II平台和FPGA开发板实现的一款出租车计费系统的设计。全文对于EDA技术以及Verilog硬件描述语言的概念以及相关特点进行了介绍与论述。对于该计费系统的实现方式以及不同模块功能的设计也进行了详细具体的介绍。设计过程中考虑了出租车行驶过程中的起步价、里程单价、等候时间等因素来计算总费用。同时,通过设计也能够实现对于计费系统的起步价,单价的设置。此外,在设计过程中,考虑到了出租车在实际的行驶过程中可能遇到的的暂停等待和行驶的不同状态,具有比较强的实用性。完成设计之后首先在Quartus II平台上完成仿真测试,并在最终能够在FPGA开发板上面完成功能验证。

    系统设计与实现

    系统硬件设计

    整个出租车计费器主要分为分频模块、消抖模块、控制模块、计费模块、数码管驱动显示模块、计数器测脉冲模块。
    系统开机时数码管显示的全是0,当按下模式切换按键时,控制模块在调节起步价、单价中进行设置起步价、单价。于是切换模式为显示行程、时间。按下开始,先按行程计费,3km以内按照起步价计费,3km以上,按照1元/km的方式计费。如果选择按照时间等候计费,如果时间在2分钟以内不收取费用,之后每超1分钟收取1元的方式计费。
    当按键切换到显示速度的模式下,数码管显示当前的车速,由于车速是通过类似于霍尔传感器等将速度转化为脉冲信号,因此仅需要个这个测量速度的模块一个1Hz的门限信号,在这1hz的情况下让计数器计数,于是数码管显示的速度为转速。测速度的模块相当于测量外来信号的频率。从设计要求中可以得出出租车计费器的系统整体框图如图1所示。
    在这里插入图片描述

    数码管显示电路

    显示电路采用系统板上的数码管,该数码管为共阳极数码管,数码管的位选接三极管的发射极,基极接引脚,集电极接高电平,通过给基极低电平,控制三极管的导通,于是集电极电流流入发射极,当哪一个数码管的位选打开,哪一个数码管才能亮。数码管的段选也接FPGA的引脚,通过给相应的段码低电平,就会控制数码管亮什么数字。其硬件连接图如图3-4所示。
    在这里插入图片描述
    图3-4 数码管硬件连接图

    按键电路

    按键是控制数码管切换显示以及是否是距离计费还是按照时间计费。按键的靠近引脚的一段接上拉电阻,默认为高电平,按键另一端接低电平,按下则导通为低电平。其硬件连接图如图3-5所示。
    在这里插入图片描述
    5 按键硬件连接图

    LED指示灯与蜂鸣器报警超速电路

    当行程计费与时间计费切换时,需要进行指示灯的显示,当行程计费是指示灯常亮,当速度超过一定转速的时候,蜂鸣器会按照一定频率报警提示。其电路连接图如图3-6和3-7所示。
    在这里插入图片描述
    3-6 显示灯硬件图 3-7 蜂鸣器硬件图

    系统软件设计

    分频模块

    按键消抖模块、1hz信号、数码管驱动显示模块、等待计数等模块都需要相应的频率,因此需要对系统时钟50Mhz分频,消抖模块采用的是1000hz信号,数码管驱动显示模块采用的是500hz信号,等待计数等模块用的是1hz信号。Clk为系统时钟输入端,fs是分频系数,cko是分频得到的频率,也即是说,给fs的数值是多少,输出的频率就是多大。比如fs设置为1000,则输出的cko频率就是1000hz。根据要求分频模块如图3-8所示。
    在这里插入图片描述

    按键消抖模块

    之所以为按键消抖,是因为往往在按键按下的时候不能立刻达到键稳定的状态,因为按键的机械特性,要经历接触-断开-再接触-再断开的过程,最终要稳定在接触位置,也就是说按键虽然只按下一次之后再放掉,在按键稳定前后,会出现不该有的噪声,如图3-9所示。这样会引起电路的误动作。因此消抖是十分必要的。一般软件消抖皆为延迟消抖,在FPGA中也不例外,一般抖动期为5-10ms。
    在这里插入图片描述
    图3-9 按键抖动

    由于分频模块分出1000hz的频率,所以消抖所采用的的频率即为1000hz信号,将按下的按键作为输入,clk选择系统时钟分频得到的1000hz信号,在模块中进行判断,当按键按下时,在1000hz的信号下cnt加1,直到cnt加到100时再次判断输入按键的状态如果仍为0则按键确实按下,于是输出按键按下。这里延时的时间为100×0.001s=10ms。Clk为分频得到时钟,key_in为输入按键值,key_out为消抖输出的按键值。根据要求按键消抖模块如图3-10所示。
    在这里插入图片描述

    数据选择模块

    按键选择模式得到一个标志位,如module_Flag、SPEED_Flag、fee_Flag、price_Flag四个模式,当按键按下一次state加1,然后以此控制标志位,当相应的标志位为1时,数据选择模块中,就将相应模式下的数据给输出段,来控制数码管显示数据。Clk为系统时钟输入,distance[7:0]为行程的两个数据,S[7:0]为秒的两个数据,m[7:0]为分钟的两个数据,q0-q7是显示转速的八个数据,fee[7:0]为费用的两个数据。S_fee和price为设置模式下,显示的设置费用和单价。DH、DL、MH、ML、SH、SL、FH、FL分别对应八个数据送到数码管驱动电路中,驱动显示。根据要求设置的数据选择模块如图3-11所示。
    在这里插入图片描述
    在这里插入图片描述

    数码管显示模块

    将数据选择模块中输出的8个数据送到数码管显示块中,通过3-8译码器选通位选,然后控制数码管亮什么数字。
    3-8译码器的的设计是通过软件实现的,定义3位的scan状态,在500hz上升沿信号下,每来一次上升沿,scan加1,然后通过case语句实现选通位选,在将段码通过assign语句实现。根据要求其数码管显示模块如图3-12所示。
    在这里插入图片描述

    速度测量模块

    速度测量模块又1hz门限信号、计数器、锁存器组成。
    当外围电路,诸如霍尔传感器将车轮的转速转化为脉冲信号之后,可以将转化之后的脉冲信号直接给FPGA的引脚。系统十分分频得到1hz的信号。并且在所存模块中完成赋值所存数据。在1hz下标志位timer在上升沿到来时取反,于是timer是一个1s的门限信号,在1s的门限信号下测量输入的脉冲数据得到脉冲的个数,根据外围电路设计计算出车的转速,转而在计算速度。由于条件有限仅仅只是仿真模拟,并没有真正去检测。
    所采取的测量脉冲是FPGA的简易频率计,由于外围电路能够将转速转化为脉冲,通过测量脉冲的频率即可得到转速。
    所采取的的所存数据是锁存器,这样做的好处是为了能够将1s测得的数据进行保存,以免丢失。
    Clk_in为外围电路输入脉冲信号,timer是1s的门限信号,当timer由1到0发生变化,q将清零,重新一轮计数。这样能够保证每一秒都能够测得新的数据。Q为测得的数据并传送给count_cnt模块,这个锁存器的模块时钟选用的是50Mhz系统分频得到的1Hz 的信号,q0-q7为所存的数据输出给数据选择器。Beep_flag是让蜂鸣器响的标志。当测得脉冲超过一定值时,蜂鸣器会报警。根据要求其测量速度模块如图3-13所示。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    里程计费模块

    由于硬件实物的板子内存有限,乘除运算会占用大量内存,因此本设计假设车速为20m/s,于是50s是1km,在3km之内是起步价,当公里数超过3km之后,按照1km收取1元的计算。
    本模块中cnt在1hz的触发下计数,1hz加一次,当加满50次时,distance加1,实现行程加1km,行程超过3km以上,1km收取1元。
    Clk为1hz信号,flag是选择按里程计费模式,reset为复位,module_flag是选择数码管显示里程模块,distance是输出的形成,distance_enable是一公里到达的标志。根据要求其里程计费模块如图3-14所示。

    在这里插入图片描述
    在这里插入图片描述

    等候时间计费模块

    由于出租车在行驶的过程中,会出现等候乘客、以及等候红绿灯的情况,这种情况仍然需要成本,因此本设计采用的是在2分钟之内不收取任何费用,当时间达到2分钟以上,按超一分钟收1元的方式计费。
    Clk为输入1hz信号,reset为复位按键,flag为选择等候时间计费模式,s为秒的两个数据,m为分的两个数据,time_enable为时间到达1分钟的标志。根据要求其等候时间计费模块如3-15所示。
    在这里插入图片描述
    在这里插入图片描述

    按键切换模式模块

    刚开机时,系统保持默认的0状态,这个状态下没有任何操作,当按下按键key时,此模块的中间变量state实现加1,在state=1的状态下,调节起步价的标志位会置1,这种模式下可以在起步价和单价设置的模块中进行调节。再次按按键key,state会变为2,这种状态下price_Flag为1,这时可以进行单价的设置。当按第三下按键时,状态切换至行程、时间、计价显示模块。第四次按键则会切换至转速显示。
    Key为消抖之后的按键,clk为系统时钟,module_Flag为切换至行程、时间、计价显示的标志,SPEED_Flag为显示速度的模式。Price_Flag和fee_Flag为调节起步价和单价的标志位。根据要求按键切换模式模块如图3-16所示。

    在这里插入图片描述
    在这里插入图片描述

    等候时间与行程计费切换

    在这个模块中,是等候时间与行程计费进行互换,当在等候时间模块中,行程会保持不变,价格随着时间的增加而变化。当在行程计费的模块中时,等候时间不会变化,行程超过3公里以上按照相应的规定收费。
    本模块的使用完全是在按键切换模式模块调到行程、时间、计价模块下才能起作用。当按键切换至行程、时间、计价模块时,默认为时间计费,当按下按键之后,flag置1,如果不按下按键,flag为0,按下之后切换至里程计费模式,时间停止不动,再次按下按键时,切换至时间计费。因此start是里程计费和时间计费的切换。
    Start是另一个按键消抖之后的键值,clk为系统时钟,reset为复位,module_Flag为行程、时间、计价显示模块的标志,flag是切换里程计费和等候时间计费的标志。根据设计其等候时间与行程计费切换模块如图3-17所示。
    在这里插入图片描述
    在这里插入图片描述

    起步价与单价的设置

    起步价与单价的设置,是必须在调节起步价标志位为1或者调节单价标志位为1的情况下才能使用。
    在此模块中,按下数值的加键,会改变单价与起步价,当调节单价的标志位为1,就可以调节单价,当调节起步价的标志位为1,就可以调节起步价。
    Fee_Flag和price_flag为起步价和单价设置的标志位,set为价格加的按键,reset为复位,clk为系统时钟。Fee为调整好的输出按键值,price为调整好的单价输出,fee为调节好的起步价输出。根据要求其起步价与单价设置的模块如图3-18所示。
    在这里插入图片描述

    计费模块

    将设置好的起步价、单价传到计费模块中,以此为基础计费。
    Select_clk为数据选通器也就是说,在控制价格加1的模块中运用assign语句,用作数据选通器。当flag为1时,select_clk选择distance_enable,也就是说当数据选则distance_enable时,距离加1公里就计费,当数据选通器选择time_enable时,就是等候时间计费。
    fee为最后输出的价格,传输到数据切换数据选择模块中。根据设计其计费总体模块如图3-19所示。
    在这里插入图片描述
    在这里插入图片描述

    系统的测试

    系统的硬件调试

    开机时,FPGA系统板状态显示全0,如图4-6所示。于是按下按键到调起步价模式,设置起步价为5元,如图4-7所示。
    在这里插入图片描述
    图4-6 开机状态 图4-7 设置起步价模式
    再次按下按键调单价,设置单价为1元/km,如图4-8所示。于是切换到里程、时间、计价模块显示,并按下reset开始,此时是按时间收费,此时显示的是起步价5元,中间四位显示的是等待时间,由于一开始的状态是时间计费,有时间走动。所以显示为1s。于是按下start切换路程计费模式,,此时初始状态如图4-9所示
    在这里插入图片描述
    当50s时间一过时,路程加1公里,此时数码管显示为行程记1km,而价格没有变化,因为还在三公里以内。如图4-10所示。当行程变化为2公里时,总价还是为5元,知道行程变为4公里,总价加1元。如图4-11所示,达到5公里价格也加1,如图4-12所示。
    在这里插入图片描述
    当计费模式切换至等候时间计费模式下,这时发现,当等候时间比2分钟大的时候,才会收费,并且按照1分钟一块钱的方式收费。如图3-13所示。在时间计费模式下,当时间到达4分钟以上时,费用达到10元,于是切换至行程计费,此时路程继续前行,路程达到6公里时,价格又加1元。如图4-14所示。
    在这里插入图片描述

    总结

    问题与解决办法

    本设计基本达到要求,经过仿真测试与硬件调试,都能够取得良好的效果。但是在设计过程中仍旧有不小的麻烦。
    第一步设计方案时,要设计好系统框图,这是FPGA设计的必要条件,但是对于我而言一个人设计这样一个复杂的系统,是十分困难的,而且FPGA Verilog HDL语言不同于C语言,这又是本次设计的一大难点。
    第二步进行代码编写的时候,由于采用的是顶层模块的编写,模块的输入输出的对应关系也是一大难点,显示生活中的记程可以达到几百公里,而本设计的公里数仅仅只能达到99公里,这是本设计的一大缺陷,为了使得本设计能够真正的投入使用,毕业设计并不是一个终点,因此在今后还需找机会进行完善设计。
    在采用何种方式测量汽车的转速是本设计的另一大难点,于是联想到霍尔传感器可以将轮胎的转速转化为脉冲信号,因此想到运用频率计进行测量脉冲的个数,进而可以测量速度。由于本次实验选择的系统板内存有限,不能进行大量的运算,并没有将车速与行程进行联系。这是本次设计的一大缺陷,但是不妨碍设计完成所有的功能测试。
    车速还需要一个外围电路产生,通过霍尔传感器转化为脉冲信号给FPGA进行测量,但是由于在家条件有限,并不能实现这样的效果,只能进行仿真测试系统的准确性。

    设计总结

    本设计基本达到要求,经过仿真测试与硬件调试,都能够取得良好的效果。但是在设计过程中仍旧有不小的麻烦。
    第一步设计方案时,要设计好系统框图,这是FPGA设计的必要条件,但是对于我而言一个人设计这样一个复杂的系统,是十分困难的,而且FPGA Verilog HDL语言不同于C语言,这又是本次设计的一大难点。
    第二步进行代码编写的时候,由于采用的是顶层模块的编写,模块的输入输出的对应关系也是一大难点,显示生活中的记程可以达到几百公里,而本设计的公里数仅仅只能达到99公里,这是本设计的一大缺陷,为了使得本设计能够真正的投入使用,毕业设计并不是一个终点,因此在今后还需找机会进行完善设计。
    在采用何种方式测量汽车的转速是本设计的另一大难点,于是联想到霍尔传感器可以将轮胎的转速转化为脉冲信号,因此想到运用频率计进行测量脉冲的个数,进而可以测量速度。由于本次实验选择的系统板内存有限,不能进行大量的运算,并没有将车速与行程进行联系。这是本次设计的一大缺陷,但是不妨碍设计完成所有的功能测试。
    车速还需要一个外围电路产生,通过霍尔传感器转化为脉冲信号给FPGA进行测量,但是由于在家条件有限,并不能实现这样的效果,只能进行仿真测试系统的准确性。
    本设计是我帮助别人做的一次毕业设计,时间仓促,但基本功能都已实现,如果能够模拟转速测量频率,去测量速度与距离。效果会更好。另外附上代码。

    代码

    顶层文件

    module taxi(clk_50M, reset,start,a,b,c,d,e,f,g,p,sel,pluse,led,key,set);   // 端口的定义
    
    input clk_50M,reset,start,pluse,key,set;//总的时钟信号,复位信号,开始信号
    output[7:0] sel;//数码管的输出
    output a,b,c,d,e,f,g,p;
    output led;
    wire led;
    
    wire [7:0]distance;//公里
    wire [7:0] s;//秒
    wire [7:0] m;//分
    wire [7:0] fee;//费用
    wire [3:0] rprice;
    wire [7:0]rfee;
    wire [31:0]q;
    wire [3:0]q0,q1,q2,q3,q4,q5,q6,q7;
    wire [3:0]DH,DL,MH,ML,SH,SL,FH,FL;
    wire distance_enable;    //公里控制费用的信号
    wire time_enable;        //时间控制费用的信号
    wire select_clk;         //控制信号
    wire hz1,hz2;            //数码管的时钟
    wire hz;                 //计数时钟
    wire clk_key;
    wire timer;
    wire key_reg,rkey_reg,rkey_set;
    wire module_Flag,SPEED_Flag,flag,price_Flag,fee_Flag,beep_flag;
    
    //*模块的调用*//
    div_clk         u0(.clk(clk_50M),.fs(1),.cko(hz));//调用计数分频模块
    div_clk         u1(.clk(clk_50M),.fs(500),.cko(hz1));//调用数码管分频模块
    div_clk         u2(.clk(clk_50M),.fs(1000),.cko(clk_key));//调用时钟消抖分频模块
    control         u3(.flag(flag),.distance_enable(distance_enable),.time_enable(time_enable),
                       .select_clk(select_clk));
    distancemokuai  u4(.clk(hz),.flag(flag),.reset(reset),.distance(distance),
                       .distance_enable(distance_enable),.module_Flag(module_Flag));//调用计程模块
    timemokuai      u5(.clk(hz),.reset(reset),.flag(flag),.s(s),.m(m), 
                       .time_enable(time_enable));//调用计时模块
    feemokuai       u6(.reset(reset),.price(rprice),.fee(fee),.s_fee(rfee),.select_clk(select_clk),.clk(hz));//调用计费模块
    feeprice_set    u7(.fee_Flag(fee_Flag),.price_Flag(price_Flag),.set(rkey_set),.reset(reset),
                       .clk(clk_50M),.fee(rfee),.price(rprice));
    scan_led        u8
    (
    	.clk(hz1),  
    	.DA(DH),  .DB(DL),  .DC(MH), .DD(ML), .DE(SH), .DF(SL), .DG(FH), .DH(FL), 
    	.a(a), .b(b), .c(c), .d(d), .e(e), .f(f), .g(g), .p(p), .sel(sel)
    );  
    count_in        u9(.clk_in(pluse),.q(q),.timer(timer));
    count_cnt       u10(.clk(hz),.q(q),.q0(q0),.q1(q1),.q2(q2),.q3(q3),.q4(q4),.q5(q5),.q6(q6),.q7(q7),
                        .timer(timer),.led(led),.beep_flag(beep_flag));
    key_shake 	    u11(.clk(clk_key),  .key_in(key),  .key_out(key_reg));
    key_shake 	    u12(.clk(clk_key),  .key_in(start),  .key_out(rkey_reg));
    key_shake 	    u13(.clk(clk_key),  .key_in(set),  .key_out(rkey_set));
    
    key_control     u14(.key(key_reg),.clk(clk_50M),.module_Flag(module_Flag),.SPEED_Flag(SPEED_Flag),
                        .price_Flag(price_Flag),.fee_Flag(fee_Flag));
    key_control2    u15(.start(rkey_reg),.clk(clk_50M),.flag(flag),.reset(reset),.module_Flag(module_Flag));
    switch          u16(.clk(clk_50M),.distance(distance),.s(s),.m(m),
                        .q0(q0),.q1(q1),.q2(q2),.q3(q3),.q4(q4),.q5(q5),.q6(q6),.q7(q7),
                        .fee(fee),.s_fee(rfee),.price(rprice),.module_Flag(module_Flag),
    						  .SPEED_Flag(SPEED_Flag),.fee_Flag(fee_Flag),.price_Flag(price_Flag),
    						  .DH(DH),.DL(DL),.MH(MH),.ML(ML),.SH(SH),.SL(SL),.FH(FH),.FL(FL));
    endmodule//结束顶层模块
    
    

    分频

    module  div_clk(clk,fs,cko);
    input  clk;    //输入时钟频率clk=50M
    input [31:0]fs;
    output  cko;  //输出时钟cko 
    reg cko;
    parameter  N=50_000_000;  //定义累加器上限,需要与基准频率f0相等
    reg  [31:0]ACC;  //定义32位累加器ACC
    always  @(posedge clk) begin //累加器在clk上升沿触发完成累加
    	if(ACC<N/2-1) ACC = ACC + fs;  //累加器按参数步进值累加,注意不是+1
    	else begin //满足累加器溢出条件
    		ACC=0;
    		cko=!cko;  //这里cko自身二分频,所以上一句N需要除以2
    	end
    end
    endmodule
    

    控制

    module control(flag,distance_enable,time_enable,select_clk);
    
    input flag,distance_enable,time_enable;
    output select_clk;//输出选择的时钟信号
    
    wire  select_clk;
    
    //*当start高电平的时候选择公里计费,输出的时钟信号为distance_enable,当start低电平的时候选择时间计费,输出的时钟信号为time_enable*//
    
    assign select_clk=flag?time_enable:distance_enable; 
    
    endmodule//结束控制模块
    

    距离模块

    module distancemokuai(clk,flag,reset,distance,distance_enable,module_Flag);     //端口的定义
    input clk,flag,reset,module_Flag;
    output [7:0] distance;        // 输出的公里
    reg [7:0] distance;
    output distance_enable;       // 控制计费的公里信号
    wire distance_enable;
    reg [7:0]cnt;
    
    always@(posedge clk or negedge reset)      //异步复位
    begin
         if(!reset)                //低电平复位
         begin
             distance<=8'H00;
         end
         else if((flag==1'b0)&&(module_Flag==1'b1)) 
    	  begin 
    		  if(cnt>8'd50) 
    		  begin 
    				 cnt=0;
    				 if(distance[3:0]==4'B1001)        //判断distance的低四位计到了9没有
    					  begin
    						  distance[3:0]<=4'B0000;  //计到9清零
    					  if(distance[7:4]==4'B1001)     //判断distance的高四位计到了9没有
    						  distance[7:4]<=4'B0000;  // //计到9清零
    					  else  
    						  distance[7:4]<= distance[7:4]+4'B0001; // distance的高四位没有计到9的时候加一
    					  end   
    				 else 
    					 begin
    					  distance[3:0]<=distance[3:0]+4'B0001;     // distance的低四位没有计到9的时候加一
    					 end
    		  end				 
    	     else begin cnt=cnt+1; end
         end         
    end             
    
    
    /*
    always@(posedge clk or negedge reset)
    begin
    if(!reset)
    begin
     distance_enable<=1'b0;     //复位
    end
    else
        if(distance[7:0]>8'H01)       
        begin
            distance_enable=1'b1;    //输出distance_enable信号
        end   
    end
    */
    assign distance_enable=((distance[7:0]>8'H02)&&(cnt==8'd50))?1'b1:1'b0;
    
    endmodule 
    

    时间

    module timemokuai(clk,reset,flag,s,m,time_enable);// 端口的定义
    input clk,reset,flag;
    output [7:0] s;       //输出的秒
    output [7:0] m;       //输出的分
    output time_enable;   //输出的控制计费的信号
    reg [7:0] s;
    reg [7:0] m;
    wire time_enable; 
    
    always@(posedge clk or negedge reset)    //异步复位
    	begin
    		if(!reset)            //低电平有效
    			begin                 //复位
    			s<=8'H00;
    			m<=8'H00;
    			end
    		else if(flag==1'b1)      
    		begin
    			if(s[3:0]==4'B1001)         // 秒的低四位是9
    				 begin
    				 s[3:0]<=4'B0000;     //清零
    					 if(s[7:4]==4'B0101)        // 秒的高四位是5
    					     begin
    					     s[7:4]<=4'B0000;     //清零
    							  if(m[3:0]==4'B1001)      // 分的低四位是9
    								  begin
    									  m[3:0]<=4'B0000;     //清零
    									  if(m[7:4]==4'B1001)     // 分的高四位是9
    									  m[7:4]<=4'B0000;     //清零
    									  else 
    									  m[7:4]<=m[7:4]+4'B0001;    // 分的高四位不是9加一
    								  end
    					        else 
    						        m[3:0]<=m[3:0]+4'B0001;        //分的低四位不是9加一
    					     end
    			       else s[7:4]<=s[7:4]+4'B0001;        // 秒的高四位不是5加一
    			    end
    		   else s[3:0]<=s[3:0]+4'B0001;        //秒的低四位不是9加一
    		   end
    	end
    	
    assign time_enable=((m[7:0]>8'H01)&&(s[7:0]==8'H00))?1'b1:1'b0;
    
    endmodule
    

    计费

    module feemokuai(price,s_fee,select_clk,reset,fee,clk);
    
    input select_clk,reset,clk;
    input [3:0]price;
    input [7:0]s_fee;
    output[7:0] fee;//输出的费用
    reg [7:0] fee;
    
    always@(posedge clk or negedge reset) //异步复位
    begin
    	 if(!reset) //低电平有效
    		 begin
    			  fee<=s_fee;   //设置的起步价
    		 end
    		 else if(select_clk==1'b1)
    		 begin
    		 if(fee[3:0]>=4'B1001)//费用的低四位是不是计到了9
    			 begin
    				 fee[3:0]<=4'B0000;//计到9清零
    				 if(fee[7:4]==4'B1001)// 费用的高四位是不是计到了9
    					 fee[7:4]<=4'B0000; //计到9清零
    				 else fee[7:4]<=fee[7:4]+1'B1;// 费用的高四位没有计到9加1
    			 end
    	    else fee[3:0]<=fee[3:0]+price[3:0];// 费用的低四位没有计到9加1
    	    end
    end
    
    endmodule //结束计费模块
    

    费用设置

    module feeprice_set(fee_Flag,price_Flag,set,reset,clk,fee,price);
    
    input fee_Flag,price_Flag,set,reset,clk;
    output[7:0]fee;
    output[3:0]price;
    reg[7:0]fee;
    reg[3:0]price;
    reg set_f;
    
    always@(posedge clk or negedge reset)
    begin
    if(!reset)begin set_f=0; end
    else if(fee_Flag==1'b1)
    	begin
    		if(set==0)
    			begin
    			if(set_f==1)
    				begin
    					if(fee[7:0]==8'H99) fee=8'H00;
    					else if(fee[3:0]==4'H9) fee=fee+8'H07;
    					else fee=fee+8'H01;
    					set_f=0;
    				end
    			end
    		else begin set_f=1;end
    	end
    else if(price_Flag==1'b1)
    	begin
    		if(set==0)
    			begin
    			if(set_f==1)
    				begin
    					if(price[3:0]==4'H9) price=0;
    					else price=price+4'H1;
    					set_f=0;
    				end
    			end
    		else begin set_f=1;end
    	end
    end
    
    endmodule
    

    数码管扫描

    module  scan_led(clk,DA,DB,DC,DD,DE,DF,DG,DH,a,b,c,d,e,f,g,p,sel);  
    input clk;//数码管扫描时钟
    input [3:0]DA,DB,DC,DD,DE,DF,DG,DH;
    output a,b,c,d,e,f,g,p;
    output [7:0]sel;
    
    reg [2:0]scan;
    reg[7:0]sel;
    reg [3:0]num;
    always @(posedge clk) begin
       begin
       scan=scan+1;
       end
    	case(scan) //3-8译码器 和 数据选择器
    		0: begin sel=8'b1111_1110; num=DA; end
    		1: begin sel=8'b1111_1101; num=DB; end
    		2: begin sel=8'b1111_1011; num=DC; end
    		3: begin sel=8'b1111_0111; num=DD; end
    		4: begin sel=8'b1110_1111; num=DE; end
    		5: begin sel=8'b1101_1111; num=DF; end
    		6: begin sel=8'b1011_1111; num=DG; end
    		7: begin sel=8'b0111_1111; num=DH; end
    	endcase
    end
    
    assign  {a,b,c,d,e,f,g,p} =	//字符译码器
    	(num==0)?  8'B0000_0011:		//"0"
    	(num ==1)?  8'B1001_1111:		//"1"
    	(num ==2)?  8'B0010_0101:		//"2"
    	(num ==3)?  8'B0000_1101:		//"3"
    	(num ==4)?  8'B1001_1001:		//"4"
    	(num ==5)?  8'B0100_1001:		//"5"
    	(num ==6)?  8'B0100_0001:		//"6"
    	(num ==7)?  8'B0001_1111:		//"7"
    	(num ==8)?  8'B0000_0001:		//"8"
    	(num ==9)?  8'B0000_1001:		//"9"
    	(num==10)?  8'B1111_1101:	//"-"
    	8'B1111_1111;	//熄灭
    
    endmodule
    

    计数

    module count_in(clk_in,q,timer);
    
    input clk_in,timer;
    
    output [31:0]q;
    
    reg[31:0]q;
    reg led;
    
    
    always @(posedge clk_in or negedge timer) begin
    if(!timer) begin q=0; end
    else begin
        if((q[15:0]==16'H9999)&&(q[31:16]==16'H9999)) q=0;
        else if(q[27:0]==28'H9999999) q=q+32'H6666667;
        else if(q[23:0]==24'H999999) q=q+32'H666667;
        else if(q[19:0]==20'H99999) q=q+32'H66667;
        else if(q[15:0]==16'H9999) q=q+32'H6667;
        else if(q[11:0]==12'H999) q=q+32'H667;
        else if(q[7:0]== 8'H99) q=q+32'H67;
        else if(q[3:0]== 4'H9) q=q+32'H7;
        else q=q+32'H1; 
        end
    end
    
    
    endmodule
    

    计数输出

    module count_cnt(clk,q,q0,q1,q2,q3,q4,q5,q6,q7,timer,led,beep_flag);
    
    input clk;
    input [31:0]q;
    output timer,led,beep_flag;
    reg timer,beep_flag;
    reg led;
    output [3:0]q0,q1,q2,q3,q4,q5,q6,q7;
    reg [3:0]q0,q1,q2,q3,q4,q5,q6,q7;
    
    always @(posedge clk)
    begin
    	if((q[31:28]>0)||(q[27:24]>0)||(q[23:20]>0)||(q[19:16]>0)||(q[15:12]>0)||(q[11:8]>0)||(q[7:4]>0)||(q[3:0]>0))
    	begin
    		q0=q[3:0];
    		q1=q[7:4];
    		q2=q[11:8];
    		q3=q[15:12];
    		q4=q[19:16];
    		q5=q[23:20];
    		q6=q[27:24];
    		q7=q[31:28];
    	end
    	else if(q[15:12]>4'd4)
    	begin
    	beep_flag=1'b1;
    	end
    	timer = !timer;
    	led=!led;
    end
    
    endmodule
    

    按键消抖

    module key_shake(clk,key_in,key_out);
    input clk;		//1000Hz时钟
    input key_in;	//物理按键输入
    output key_out; //去抖之后输出
    reg [6:0]c;	//计数变量
    reg key_out;
    always @(posedge clk) begin
    	if(!key_in)
    		c=c+1; //计数延迟消抖		
    	else c=0;
    	if(c==100) 
    	   key_out=0;
    	else key_out=1;
    end
    endmodule
    

    按键控制

    module key_control(key,clk,module_Flag,SPEED_Flag,price_Flag,fee_Flag);
    
    input  clk, key;
    output module_Flag,SPEED_Flag,price_Flag,fee_Flag;
    reg  key_f;//合理利用标志位,实现单次加减1操作
    reg module_Flag,SPEED_Flag,price_Flag,fee_Flag;
    reg [2:0]state;
    
    
    always @(posedge clk) begin
    	if(key==0) 
    	  begin
    	     if(key_f) 
    		    begin
    			 state_add();
    			 key_f=0;
    			 end
    	  end
    	else 
    	  begin
    	     state=state;
    	     key_f=1;
    	  end
    end
    
    always @(posedge clk) 
    begin
    	case(state) 
    		0: begin module_Flag=1'b0; SPEED_Flag=1'b0; price_Flag=1'b0; fee_Flag=1'b0;end
    		1: begin module_Flag=1'b0; SPEED_Flag=1'b0; price_Flag=1'b0; fee_Flag=1'b1;end
    		2: begin module_Flag=1'b0; SPEED_Flag=1'b0; price_Flag=1'b1; fee_Flag=1'b0;end
    		3: begin module_Flag=1'b1; SPEED_Flag=1'b0; price_Flag=1'b0; fee_Flag=1'b0;end
    		4: begin module_Flag=1'b0; SPEED_Flag=1'b1; price_Flag=1'b0; fee_Flag=1'b0;end
    		default: begin module_Flag=1'b0; SPEED_Flag=1'b0; price_Flag=1'b0; fee_Flag=1'b0;end 
    	endcase
    end
    
    task state_add();
    begin
    if(state==3'B100) state=3'B000;    
    else state=state+1;
    end
    endtask
    
    endmodule
    

    按键控制2

    module key_control2(start,clk,flag,reset,module_Flag);
    
    input start,clk,reset,module_Flag;
    output flag;
    reg flag;
    reg  key_f;
    reg state;
    
    always@(posedge clk or negedge reset)
    begin
      if(!reset) begin key_f=1;state=0;end
      else if(module_Flag==1'B1)
       begin
       if(start==1)
        begin
    	   if(key_f) 
    		  begin
    		   state=state+1'b1;
    			key_f=0;
    		  end
    	   end
    	else 
    	 begin
    	   state=state;
    	   key_f=1;
    	 end
    	end
    end
    
    always@(posedge clk)
    begin
    case(state)
         0:begin flag=0;end
    	  1:begin flag=1;end
    	  default:begin flag=0;end
    endcase
    end
    
    endmodule
    

    模式选择

    module switch(clk,distance,s,m,q0,q1,q2,q3,q4,q5,q6,q7,fee,s_fee,price,module_Flag,SPEED_Flag,fee_Flag,price_Flag,DH,DL,MH,ML,SH,SL,FH,FL);
    
    input clk;
    input module_Flag,SPEED_Flag,fee_Flag,price_Flag;
    input[7:0] distance,fee;//输入的公里,费用
    input[7:0]  s;//输入的秒
    input[7:0]  m;//输入的分
    input[7:0] s_fee;
    input [3:0]price;
    input [3:0]q0,q1,q2,q3,q4,q5,q6,q7;
    output [3:0]DH,DL,MH,ML,SH,SL,FH,FL;
    reg [3:0]DH,DL,MH,ML,SH,SL,FH,FL;
    
    always @(posedge clk)
    begin
    if(module_Flag)
    	begin
    	DH[3:0]<=distance[7:4];
    	DL[3:0]<=distance[3:0];
       MH[3:0]<=m[7:4];
       ML[3:0]<=m[3:0];
       SH[3:0]<=s[7:4];
       SL[3:0]<=s[3:0];
    	FH[3:0]<=fee[7:4];
       FL[3:0]<=fee[3:0];
    	end	
    	else if(SPEED_Flag)
    	begin
    	DH[3:0]<=q7[3:0];
    	DL[3:0]<=q6[3:0];
       MH[3:0]<=q5[3:0];
       ML[3:0]<=q4[3:0];
       SH[3:0]<=q3[3:0];
       SL[3:0]<=q2[3:0];
    	FH[3:0]<=q1[3:0];
       FL[3:0]<=q0[3:0];
    	end
    	else if(fee_Flag)
    	begin
    	DH[3:0]<=0;
    	DL[3:0]<=0;
       MH[3:0]<=0;
       ML[3:0]<=0;
       SH[3:0]<=0;
       SL[3:0]<=0;
    	FH[3:0]<=s_fee[7:4];
       FL[3:0]<=s_fee[3:0];	
    	end
    	else if(price_Flag)
    	begin
    	DH[3:0]<=0;
    	DL[3:0]<=0;
       MH[3:0]<=0;
       ML[3:0]<=0;
       SH[3:0]<=0;
       SL[3:0]<=0;
    	FH[3:0]<=0;
       FL[3:0]<=price[3:0];	
    	end
    	else 
    	begin
    	DH[3:0]<=distance[7:4];
    	DL[3:0]<=distance[3:0];
       MH[3:0]<=m[7:4];
       ML[3:0]<=m[3:0];
       SH[3:0]<=s[7:4];
       SL[3:0]<=s[3:0];
    	FH[3:0]<=fee[7:4];
       FL[3:0]<=fee[3:0];
    	end
    end
    endmodule
    

    quartus代码其实很难理解的,如果大家想采用这样的思路,希望大家把顶层文件看懂,才好下手,代码全都附上去了,没有任何隐藏。如果大家对利用FPGA设计TAXI计费有需求,大家可以参考我的思路。谢谢!

    展开全文
  • 介绍应用VHDL语言设计的出租计费器的一种新的方案, 使其具有模拟出租车起动、停止、暂停和加速等功能, 并用动态扫描电路显示出租车所走的里程, 显示所走路程需要的费用。所有源程序经Altrera 公司的软件Max+ Plus2...
  • 摘要:介绍了基于μPD78F0034单片机和模块式结构的出租计费器的硬件和软件设计方法,讨论了μPD78F0034单片机的主要特点;介绍了该单片机和PC机串行通信的硬件连接方法;同时给出了采用单、双信号防作弊技术来防止...
  • 出租计费器一般采用以单片机为核心的设计方法,设计不够灵活方便。为此,在此介绍了采用EDA技术的层次化设计方法设计出租计费器的方法。即用VHDL编写各个功能模块,实现低层设计;用原理图输入方式描述各模块...
  • 根据预定的设计要求和设计思路,采用VHDL硬件描述语言作为设计手段,采用自顶向下的设计思路设计了一个实际的基于AheraFPGA芯片的出租车计价系统,通过在QuartusⅡ6.0软件下进行模拟仿真,并进行相应的硬件下载调试...
  • 引言EDA使用户在无需实际芯片、电路板和仪器仪表的情况下进行电路设计和分析...采用在系统编程技术,在现场对系统进行逻辑重构和升级,实现硬件设计软件化。EDA技术以可编程逻辑器件FPGA和CPLD及其开发系统为硬件平台,
  • 基于FPGA的出租计费器的设计 1 概述 EDA(Electronic Design Automation)即电子设计自动化,是电子设计技术的核心,它的系统级高层次电子设计方法,对整个系统进行方案设计和功能划分,无须通过门级原理图描述电路...

    基于FPGA的出租车计费器的设计

    1 概述

    EDA(Electronic Design
    Automation)即电子设计自动化,是电子设计技术的核心,它的系统级高层次电子设计方法,对整个系统进行方案设计和功能划分,无须通过门级原理图描述电路,而是针对设计目标进行功能描述,。

    FPGA
    是现场可编程门阵列的简称。它结合了微电子技术、电路技术和EDA技术,使设计者可以集中精力进行所需逻辑功能的设计,缩短设计周期,提高设计质量。FPGA的开发系统包括软件和硬件两个部分,开发系统软件指专用的编程语言和相应的汇编程序或编译程序。开发系统硬件部分包括计算机和编程器。编程器是对FPGA进行写入和擦除的专用装置,能够供写入或擦除操作所需要的电源电压和控制信号,并通过串行接口从计算机接收编程数据,最终写进FPGA之中。

    基于FPGA的计费器系统利用Verilog
    HDL语言,采用模块化程序设计,自顶向下、由粗到细、逐步求精的方法,将基于FPGA的计费器系统的整体逐步分解各个模块。它不需要专门的硬件,只通过软件编程即可实现计费器系统的逻辑功能、电路结构和连接形式。Verilog
    HDL语言类似C语言,可读性强、更易理解,这种语言几乎覆盖了以往各种硬件描述语言的功能,在编程的过程中一般采用自顶向下的电路设计过程。

    本设计利用Verilog
    HDL语言,在QuartusⅡ13.0软件中将出租车计费器基本结构分成6个模块对其进行程序汇编。将各块程序生成的.v文件组合在一起,生成数字钟源代码的.bdf
    图形文件,最后下载到CycloneⅡ系列芯片EP20C8Q208C8N中,验证试验结果。

    1.1 设计要求

    1.1.1 设计任务

    设计并制作一台出租车计费器。

    1.1.2 性能指标要求

    ① 用EDA实训仪的I/O设备和PLD芯片实现出租车计费器的设计。


    出租车起步开始计程和计费,计程系统按实际公里数计程,计费系统首先显示起步价(如7.0),车行驶2km以内,只收起步价7元。

    ③ 出租车行驶超过2km后,按每公里1.6元在7.0元的基础上增加。


    出租车行驶超过10km后(或超过20元路费),每公里加收50%的车费,即车费变为每公里2.4元。

    ⑤ 出租车达到目的地后,(用一个按钮)计程和计费数据清零,为下一次计费开始。

    1.2 总体设计基本原理及框图

    1.2.1 基本原理

    该出租车计费器的基本原理方框图如图1所示,由时钟模块、控制模块、计程模块、音乐模块、LCD显示模块、计费模块6部分组成。该计费系统通过分频模块将20MHz的时钟信号通过分频器变成1Hz的时钟信号和50Hz的显示输出信号。该出租车计费的标准是起步价是6元,2公里之内费用不变,当超过2公里时,每行驶1公里,费用加收50%元;由peo信号来控制有人或者没人,高电平有人,低电平显示空车,出租车计费显示模块显示相应的费用和行驶的里程。当res为低电平时,计费系统复位。该计费系统的显示费用是0~999.9元

    1.2.2 总体框图

    ![C:\Users\Home\Documents\Tencent
    Files\1120572057\Image\C2C\Y[}1L5]CNPLAM@@]JI254WK.png](media/924498901234891f75b5b1eb34710397.png)
    在这里插入图片描述

    图1 总体框图

    2 系统软件设计分析

    整个系统由6个模块组成:

    2.1时钟模块

    时钟模块,提供实时时间,并可以通过按键调节分钟和小时并由其qs、qm、qh分别输出秒、分、时,clk20m输入20Mhz,clrn清零,fj和hj为调分和调时。用于区分白天与夜间计费,白天时间6:00~00:00、夜间时间00:00~6:00,由两个60进制计数器和一个24进制计数器组成,生成一个元件符号。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pl4hVYoX-1619189226876)(media/ce142d58869d07f6e5e0c9d80abace7a.png)]
    在这里插入图片描述

    图2-1 时钟模块元件符号图

    60进制计数器程序:

    module cont60(clk,clrn,q,cout,j);

    input j,clrn,clk;

    output reg [7:0] q;

    output reg cout;

    always @( posedge clk^j or posedge clrn )

    begin

    if(clrn) q=0;

    else

    begin

    q = q+1; if(q[3:0] >= 10)

    begin q[3:0] = 0;q[7:4] = q[7:4]+1;

    if(q[7:4] >= 6) q[7:4] = 0;

    end

    if( q == 'h00 ) cout = 1;else cout = 0;

    end

    end

    endmodule

    24进制计数器程序:

    module cont24(clk,clrn,q,cout,j);

    input j,clk,clrn;

    output reg [7:0] q;

    output reg cout;

    always@( posedge clk^j or posedge clrn )

    begin

    if(clrn)begin q=0;cout = 0;end

    else

    begin

    q = q+1; if(q[3:0] >= 10)

    begin q[3:0] = 0; q[7:4] = q[7:4]+1;

    end

    if( q >= 'h24 )

    begin q = 0; cout = 1; end

    else cout = 0; end end endmodule

    在这里插入图片描述

    图2-2 时钟仿真图

    2.2控制模块

    控制模块是用于控制车速的模块clk输入20Mhz,res清零作用,key_up是加速、key_down是减速,对应速度有0km/h、20km/h、40km/h——260km/h、280km/h、300km/h共15个速度调节来产生不同的频率由clk_speed输出,20km/h即11.1m每秒,所以20km/h要产生一秒为11100个上升沿,20Mhz/(2*11100),而gear输出不同的档位,通过对20MHz分频来产生不同的频率对应不同的速度,1秒内10000个上升沿表示1秒行驶了1m,改变频率即改变了1秒内上升沿的个数,就改变了速度。

    在这里插入图片描述

    图2-3 按键控制模块元件符号图

    控制模块程序:

    module key(clk,

    key_up,

    gear,

    res,

    key_down,

    clk_speed,

    people);

    input res,people;

    input key_up,clk,key_down;

    output reg clk_speed;

    reg [29:0] clk_sp_reg;

    output reg[3:0]gear;

    reg [29:0]up_c,down_c,n;

    initial begin

    gear='b1000;up_c=0;down_c=0;n=0;

    clk_sp_reg=0;

    end

    always@( posedge clk or posedge res)//加速减速控制

    begin

    if(res) begin down_c=0;up_c=0;end

    else if(!people)begin up_c=0; down_c =0; end else

    begin

    if(key_up)

    begin

    up_c=up_c+1’b1;

    end

    else

    begin

    up_c=0;

    end

    if(key_down)

    begin

    down_c=down_c+1’b1;

    end

    else

    begin

    down_c=0;

    end

    end

    end

    always @(posedge clk or posedge res)//速度对应的分频数,

    begin

    if(res) begin gear=0; end

    else if(!people)begin gear=0; clk_sp_reg=0; end else

    begin

    if(key_up ^ key_down )

    begin

    if(key_up==1)

    begin

    if(up_c==5 && gear<='b1110)//200000)

    gear=gear+1;

    if(gear>='b1111)

    gear='b1111;

    end

    if(key_down==1)

    begin

    if(down_c==5)//200000)

    if(gear=='b0)

    gear='b0;else gear=gear-1;

    end

    end

    case (gear)

    0 : ; //速度为0

    1 : clk_sp_reg=909;

    2 : clk_sp_reg=454;

    3 : clk_sp_reg=303;

    4 : clk_sp_reg=227;

    5 : clk_sp_reg=181;

    6 : clk_sp_reg=151;

    7 : clk_sp_reg=129;

    8 : clk_sp_reg=113;

    9 : clk_sp_reg=101;

    10 : clk_sp_reg=90;

    11 : clk_sp_reg=82;

    12 : clk_sp_reg=75;

    13 : clk_sp_reg=69;

    14 : clk_sp_reg=64;

    15 : clk_sp_reg=60;

    endcase

    end

    end

    always @( posedge clk or posedge res) //把20MHz分频,产生相对应速度的频率

    begin

    if(res)begin n<=0;clk_speed<=0;end

    else if(!people)begin n<=0;clk_speed<=0; end else

    begin

    if (n>=clk_sp_reg && gear!=0)

    begin n<=0;clk_speed<=~clk_speed; end

    else

    begin n<=n+1; clk_speed<=clk_speed;end

    end

    end

    endmodule

    在这里插入图片描述

    图2-4 控制模块仿真图

    2.3计程模块

    计程模块由五个100进制的计数器组成,clk输入控制模块分频出来的频率,然后在计程模块进行计数,只显示qshiwan到qshiyi的计程其中qshiwan[7:4]是百米计程,这样能使计费精确到分以下,所以计程用1000个上升沿记为1米,
    在这里插入图片描述

    图2-5 计程模块元件符号图

    计程模块程序:

    module counter0_99(clk,clr,q,cout,people);

    input clk,clr,people;

    output reg [7:0] q;

    output reg cout;

    reg one='b1;

    initial q='h99;

    always@( posedge clk or posedge clr or negedge people )

    begin

    if(clr ) q=0;

    else

    begin if(!people) q=0;

    else

    begin

    q = q+1;

    if(q[3:0] >= 10)

    begin

    q[3:0] = 0;

    q[7:4] = q[7:4]+one;

    if(q[7:4] >= 10)

    q[7:4] = 0;

    end

    if( q == 0 )

    cout = 1;

    else

    cout = 0;

    end end end endmodule

    在这里插入图片描述

    图2-6 计程模块仿真图

    2.4音乐模块

    音乐模块的clk是时钟输入,people是有人和没人的状态标志,beep外接蜂鸣器,并设定了两个音乐《送别》和《起风了》,作为乘客上车下车时播放的音乐,播放音乐的原理是通过改变频率来改变音高,改变延时时间来确定一小节拍的时间是240ms,通过分频产生。

    //音高与频率的对应关系

    //| | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

    //|低音 |261.6Hz |293.7Hz |329.6Hz |349.2Hz | 392Hz | 440Hz |493.9Hz |

    //|中音 |523.3Hz |587.3Hz |659.3Hz |698.5Hz | 784Hz | 880Hz |987.8Hz |

    //|高音 |1045.5Hz|1174.7Hz|1318.5Hz|1396.9Hz| 1568Hz | 1760Hz
    |1975.5Hz|

    //乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)
    在这里插入图片描述

    图2-7 音乐模块元件符号图

    音乐模块程序:

    module music( clk,people, beep);

    input clk,people;

    output reg beep;

    reg flag ,flag1;

    reg[7:0] state,state1; //乐谱状态机

    reg[16:0]count,count_end;

    reg[23:0]count1,count2; //乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)

    parameter S_0=8’d20000000,

    L_1 = 17’d38226, M_1 = 17’d19109, H_1 = 17’d09564, //音1

    L_2 = 17’d34048, M_2 = 17’d17027, H_2 = 17’d08512, //音2

    L_3 = 17’d30339, M_3 = 17’d15167, H_3 = 17’d07584, //音3

    L_4 = 17’d28636, M_4 = 17’d14316, H_4 = 17’d07158, //音4

    L_5 = 17’d25510, M_5 = 17’d13368, H_5 = 17’d06377, //音5

    L_6 = 17’d22727, M_6 = 17’d11363, H_6 = 17’d05681, //音6

    L_7 = 17’d20247, M_7 = 17’d10123, H_7 = 17’d05062; //音7

    parameter TIME = 2400000; //控制每一个音的长短(480ms)

    parameter TIME1 = 4800000; //控制每一个音的长短(240ms)

    always @(posedge clk)

    begin

    if(people==0)

    begin

    flag=1; state1 =0;count2=0;

    if(flag1==1)

    begin

    count = count + 1’b1; //计数器加1

    if(count == count_end && count_end!=S_0)

    begin count = 17’h0; //计数器清零

    beep = !beep;end //输出取反

    if(count1 < TIME) count1 = count1 + 1’b1;

    //一个节拍240mS data=F/2/ms T=2*N*Tc

    else begin count1 = 24’d0;

    if(state == 8’d127)

    begin flag = 0;state=8’d0; end

    else state = state + 1’b1;

    case(state)

    8’d0,8’d1,8’d2,8’d3: count_end = M_5;//低音"3",4个节拍

    8’d4,8’d5: count_end = M_3;//低音"5",持续2个节拍

    8’d6,8’d7: count_end = M_5;//低音"6",持续2个节拍

    8’d8,8’d9,8’d10,8’d11,

    8’d12,8’d13,8’d14,8’d15: count_end = H_1;//高音"1",8拍

    8’d16,8’d17,8’d18,8’d19: count_end = M_6;//中音"6",4拍

    8’d20,8’d21,8’d22,8’d23: count_end = H_1;//高音"1",4拍

    8’d24,8’d25,8’d26,8’d27,

    8’d28,8’d29,8’d30,8’d31,

    8’d32,8’d33,8’d34,8’d35: count_end = M_5;//中音"5",8拍

    8’d36,8’d37: flag1=0;//count_end = M_1;//低音"5",2拍

    endcase

    end

    end

    end

    else

    if(people==1)

    begin

    flag1=1; state =0;count1=0;

    if(flag==1)

    begin

    count = count + 1’b1; //计数器加1

    if(count == count_end)

    begin count = 17’h0; //计数器清零

    beep = !beep;end //输出取反

    if(count2 < TIME1) count2 = count2 + 1’b1;

    //一个节拍240mS data=F/2/ms T=2*N*Tc

    else begin count2 = 24’d0;

    if(state1 == 8’d229)

    begin flag = 0;state1=8’d0; end

    else state1 = state1 + 1’b1;

    case(state1)

    8’d0,8’d1 : count_end = M_1;

    8’d2,8’d3 : count_end = M_2;

    8’d4,8’d5 : count_end = M_3;

    8’d6,8’d7 : count_end = M_1;//

    8’d8,8’d9 : count_end = M_6;

    8’d10 : count_end = M_5;

    8’d11 : count_end = M_6;

    8’d12 : count_end = M_6;

    8’d13,8’d14 : flag=0;//count_end = S_0;

    endcase

    end

    end

    end

    end

    endmodul

    2.5 LCD显示模块

    显示模块是使用LCD1602液晶屏,其中clk是时钟,people是有人和没人的状态为rstn是清零,in_data是档位输入,q0到q4是公里数输入,qs、qm、qh是时钟输入,cost_lcd_in是费用输入,显示界面可以显示时间、行驶路程、速度、费用,由于程序数据转换太多,这里只给出一部分程序,后面的程序在附录。

    LCD1602主要技术参数:显示容量:16×2个字符、芯片工作电压:4.5—5.5V、工作电流:2.0mA(5.0V)、模块最佳工作电压:5.0V、字符尺寸:2.95×4.35(W×H)mm。
    在这里插入图片描述

    图2-8 LCD1602模型图

    编号符号引脚说明编号符号引脚说明
    1VSS电源地9D2数据
    2VDD电源正极10D3数据
    3VL液晶显示偏压11D4数据
    4RS数据/命令选择12D5数据
    5R/W读/写选择13D6数据
    6E使能信号14D7数据
    7D0数据15BLA背光源正极
    8D1数据16BLK背光源负极

    表1 引脚接口说明表

    序号指令RSR/WD7D6D5D4D3D2D1D0
    1清显示0000000001
    2光标返回000000001*
    3置输入模式00000001I/DS
    4显示开/关控制0000001DCB
    5光标或字符移位000001S/CR/L**
    6置功能00001DLNF**
    7置字符发生存贮器地址0001字符发生存贮器地址
    8置数据存贮器地址001显示数据存贮器地址
    9读忙标志或地址01BF计数器地址
    10写数到CGRAM或DDRAM)10要写的数据内容
    11从CGRAM或DDRAM读数11读出的数据内容

    表2 控制指令表

    1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。(说明1为高电平,0为低电平)

    指令1:清显示,指令码01H,光标复位到地址00H位置

    指令2:光标复位,光标返回到地址00H

    指令3:光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,S:屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。

    指令4:显示开关控制。D:控制整体的显示开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标
    B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。

    指令5:光标或显示移位 S/C :高电平时显示移动的文字,低电平时移动光标

    指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线
    N:低电平时为单行显示,高电平时为双行显示,F:低电平时显示5X7的点阵字符,高电平时显示5X10的显示字符。

    指令7:字符发生器RAM地址设置。

    指令8:DDRAM地址设置。

    指令9:读忙信号和光标地址
    BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。

    在这里插入图片描述

    图2-9 LCD显示模块元件符号图

    LCD显示模块程序:

    module lcd1602(sys_clk ,

    sys_rstn ,

    lcd_rs ,

    lcd_rw ,

    lcd_en ,

    lcd_data ,

    in_data,

    q0,q1,q2,q3,q4,qs,qm,qh,people,

    cost_lcd_in

    ); //输入输出信号定义

    input [31:0] cost_lcd_in;

    input [7:0] q0,q1,q2,q3,q4,qs,qm,qh;

    input sys_clk ;//系统时钟输入

    input people, sys_rstn ;//系统复位信号,低电平有效

    input [3:0] in_data;

    output lcd_rs ;//lcd的寄存器选择输出信号

    output lcd_rw ;//lcd的读、写操作选择输出信号

    output lcd_en ;//lcd使能信号

    output [7:0] lcd_data ;//lcd的数据总线(不进行读操作,故为输出)

    reg lcd_rs ;

    reg clk_div ;

    reg [7:0] q1h,q1l,q2h,q2l,q3h,q3l,q4l;

    reg [7:0] sp_reg1,sp_reg2,sp_reg3;

    reg [7:0] qsl,qsh,qml,qmh,qhl,qhh;

    reg [7:0] in_data_reg;

    reg [7:0] cost_reg0,cost_reg1,cost_reg2,cost_reg3;

    reg [17:0] delay_cnt ;

    reg [7:0] lcd_data ;

    reg [4:0] char_cnt ;

    reg [7:0] data_disp ;

    reg [9:0] state ;

    parameter

    idle = 10’b000000000, //初始状态,下一个状态为CLEAR

    clear = 10’b000000001, //清屏

    set_function = 10’b000000010,

    switch_mode = 10’b000000100,

    set_mode = 10’b000001000,

    shift = 10’b000010000,

    //光标、画面位移设置:光标向左平移一个字符位

    set_ddram1 = 10’b000100000,

    //设置DDRAM的地址:第一行起始为0x00(注意输出时DB7一定要为1)

    set_ddram2 = 10’b001000000, //设置DDRAM的地址:第二行为0x40 write_ram1 =
    10’b010000000, //数据写入DDRAM相应的地址

    write_ram2 = 10’b100000000; //数据写入DDRAM相应的地址

    assign lcd_rw = 1’b0; //没有读操作,R/W信号始终为低电平

    assign lcd_en = clk_div; //E信号出现高电平以及下降沿的时刻与LCD时钟相同
    always@(posedge sys_clk or posedge sys_rstn) /分频

    begin if(sys_rstn) begin delay_cnt<=18’d0; clk_div<=1’b0;

    end else if(delay_cnt==18’d200000)

    begin

    delay_cnt<=18’d0; clk_div<=~clk_div; end else

    begin delay_cnt<=delay_cnt+1’b1; clk_div<=clk_div;

    end end

    always@(posedge clk_div or posedge sys_rstn) //State Machine

    begin if(sys_rstn)

    begin state <= idle; lcd_data <= 8’b0; char_cnt <= 5’d0;

    lcd_rs<=1’b0;//地址\数据

    end else begin

    case(state)

    idle: begin //初始状态

    state <= clear; lcd_data <= 8’b0; end

    clear: begin //清屏

    state <= set_function;

    lcd_rs<=1’b0;

    lcd_data <= 8’b00000001;

    end

    set_function: //功能设置(38H):8位数据接口/2行显示/5*8点阵字符

    begin state <= switch_mode; lcd_rs<=1’b0;

    lcd_data <= 8’b00111000; end

    switch_mode: //显示开关控制(0CH):开显示,光标和闪烁关闭

    begin state <= set_mode; lcd_rs<=1’b0;

    lcd_data <= 8’b00001110; end

    set_mode:begin //输入方式设置(06H):数据读写操作后,地址自动加一/画面不动

    state <= shift; lcd_rs<=1’b0;

    lcd_data <= 8’b00000110; end

    shift: begin //光标、画面位移设置(10H):光标向左平移一个字符位

    //(光标显示是关闭的,所以实际上设置是看不出效果的)

    state <= set_ddram1; lcd_rs<=1’b0;

    lcd_data <= 8’b0001_0000; end

    set_ddram1: //设置DDRAM的地址:第一行起始为00H(注意输出时DB7一定要为1)

    begin state <= write_ram1;

    lcd_rs<=1’b0; lcd_data <= 8’b1000_0000;//Line1

    end

    set_ddram2: //设置DDRAM的地址:第二行为40H(DB7一定要为1)

    begin state <= write_ram2;

    lcd_rs<=1’b0; lcd_data <= 8’b1100_0000;//Line2

    end

    write_ram1:

    begin

    if(char_cnt <=5’d15)

    begin char_cnt <= char_cnt + 1’b1;

    lcd_rs<=1’b1; lcd_data <= data_disp;

    state <= write_ram1; end

    else begin state <= set_ddram2; end

    end

    write_ram2:

    begin

    if(char_cnt <=5’d30)

    begin char_cnt <= char_cnt + 1’b1;

    lcd_rs<=1’b1; lcd_data <= data_disp;

    state <= write_ram2; end

    else begin char_cnt <=5’d0; state <= shift; end

    end

    default: state <= idle;

    endcase

    end

    end

    2.6计费模块

    计费模块其中clk是20MHz输入,clrn清零,people是有人没人的状态位,q0到q4为里程输入,qh为小时输入,用于判断白天计程和夜间计费,其中又分0~2km不计程,2~10km加20%费用,且白天和夜间的四个计费阶段都有相对应的指示灯闪烁(L12到L15),白天:7元2km内7元,2km-10km每公里收费1.6元,10km以上每公里收费2.4元;夜间:起步价8元2km内8元,2km-10km每公里收费2元,10km以上每公里收费3元。cost_q输出费用。10km以上加收费用,1000个上升沿即为1米,则1km——1.6元,1000000个上升沿对应160分,1分即6250个上升沿,由于程序数据转换太多,这里只给出一部分程序,后面的程序在附录。

    在这里插入图片描述

    图2-10 计费模块元件符号图

    计费模块程序:

    module counter0_99_16(

    clk,clr,cost_q,people,

    q0,q1,q2,q3,q4,qh,

    l12,l13,l14,l15

    );

    input clk,clr,people;

    output reg l12,l13,l14,l15;

    input [7:0] q0,q1,q2,q3,q4,qh;

    output reg [31:0] cost_q;

    reg [13:0] n;

    reg one='b1;

    initial n=0;

    initial cost_q='b0000_0000_0000_0000_0000_1000_0000_0000;

    always@( posedge clk or posedge clr or negedge people )

    begin

    if(clr ) begin l12=0;l13=0;l14=0;l15=0;cost_q=0;end

    else

    begin if(!people) begin l12=0;l13=0;l14=0;l15=0;

    if(qh>'b00000110)cost_q='b0000_0000_0000_0000_0000_0111_0000_0000;

    else if(qh<='b00000110)cost_q='b0000_0000_0000_0000_0000_1000_0000_0000; end

    else

    begin

    if(qh>8’b00000110)

    begin

    if({q4,q3,q2,q0}<=32’b0000_0000_0001_0000_0000_0000_0000_0000

    && {q4,q3,q2,q0}>32’b0000_0000_0000_0010_0000_0000_0000_0000 ) begin

    //1000000电平除以160分,得出一分6250个上升沿

    if(n < 'd6250) //1.6元

    begin n=n+'d1; end

    if(n >= 'd6250)

    begin

    n<=0;

    begin

    l12=~l12;l13=0;l14=0;l15=0;

    cost_q = cost_q+1;

    if(cost_q[3:0] >= 10)

    begin cost_q[3:0] = 0;

    cost_q[7:4] = cost_q[7:4]+one;end

    if(cost_q[7:4] >= 10)

    begin cost_q[7:4] = 0;

    cost_q[11:8] = cost_q[11:8]+one;end

    if(cost_q[11:8] >= 10)

    begin cost_q[11:8] = 0;

    cost_q[15:12] = cost_q[15:12]+one;end

    if(cost_q[15:12] >= 10)

    begin cost_q[15:12] = 0;

    cost_q[19:16] = cost_q[19:16]+one;end

    if(cost_q[19:16] >= 10)

    begin cost_q[19:16] = 0;

    cost_q[23:20] = cost_q[23:20]+one;end

    if(cost_q[23:20] >= 10)

    begin cost_q[23:20] = 0;

    cost_q[27:24] = cost_q[27:24]+one;end

    if(cost_q[27:24] >= 10)

    begin cost_q[27:24] = 0;

    cost_q[31:28] = cost_q[31:28]+one;end

    end

    end

    end else

    end

    end

    end

    end

    endmodule

    在这里插入图片描述

    图2-11 计费模块仿真图

    3 系统测试(调试)

    3.1 测试仪器与设备

    ① EDA实验仪一台。

    ② 计算机一台(装有Quartus Ⅱ软件)

    3.2 性能指标测试

    把程序下载进实验箱,按键控制有人和没人的状态,蜂鸣器能正常播放音乐,然后运行计费器,通过计算的出的费用和路程相符合,白天和夜间的起步价、2km到10km计费标准和10km以上的计费标准都正确,且能显示正确的速度,时间,路程,四个收费阶段都有相对应的指示灯闪烁提示,速度的各档速也有相对应的灯点亮。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34JtQeYN-1619189226885)(media/024cb6b92b850231a7fd4fa75f86ccfb.png)]
    在这里插入图片描述

    图3-1 引脚锁定

    在这里插入图片描述

    3.3 结果分析

    达到了所要完成的基本功能,并在此功能上扩展出来,一些额外功能,在显示方面使用了LCD1602的液晶显示屏显示时间、速度、里程和费用,并有一个一天的计时器,且能够分为白天和夜间计费,并在人上车下车的时候能够用蜂鸣器播放音乐。

    4 波形发生器设计

    波形发生器设计,能够产生锯齿波、三角波、方波和正弦波,采用LPM_ROM,储存四个波形的数字,然后直接输出波形的数据即可,并在此基础上采用两个按键控制四个频率的转换。

    锯齿波ROM数据,从0自加到255。

    三角波ROM数据:从0到127自加,每次加2,从128到255自减每次减2。

    正弦波ROM数据:用正弦波发生函数。

    正弦波数据C语言程序:

    #include <stdio.h>

    #include “math.h”

    main()

    {

    int i,k;

    for(i=0;i<256;i++)

    {

    k=128+128*sin(360.0*i/256.0*3.1415926/180);

    printf("%d : %d\n",i,k);

    }

    return 0;

    }

    方波ROM数据:从0到127自加,为255,从128到255为0。

    计数模块:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R83iS7hq-1619189226886)(media/227d232942c6eef01da61cb2e680f6be.png)]

    图4-1 计数器元件符号图

    LPM_ROM模块:

    在这里插入图片描述
    在这里插入图片描述

    图4-3 选择波形元件符号图

    选择波形的程序:

    module data_selector4_1 (A,B,C,D,s0,s1,z);

    input s0;

    input s1;

    input [7:0] A;

    input [7:0] B;

    input [7:0] C;

    input [7:0] D;

    output reg [7:0] z;

    always@( s0 or s1 or A or B or C or D)

    begin

    case ( {s1,s0} )

    'b00 : z=A;

    'b01 : z=B;

    'b10 : z=C;

    'b11 : z=D;

    default : z='bz;

    endcase

    end

    endmodule

    分频选择部分:

    在这里插入图片描述

    图4-4 选择频率元件符号图

    分频选择程序:

    module clk_ch (key1,key2,clk,clk_c);

    input clk;

    input key1;

    input key2;

    output reg clk_c;

    reg [7:0]h;

    reg [7:0]y;

    always@( posedge clk )

    begin

    case ({key2,key1})

    'b00:y=0;

    'b01:y=2;

    'b10:y=4;

    'b11:y=6;

    endcase

    if(h == y)

    begin h<=0;clk_c<=~clk_c; end

    else begin h<=h+1;clk_c<=clk_c;end

    end endmodule

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    图4-8 频率转换结果图

    5 实训总结

    在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。另外,这次课程设计让我感到了团队合作的重要性。在团队中,我们互帮互助,对整个课程设计来说,这是至关重要的,缺少每一个人都会对我们的设计产生影响。还有要感谢指导老师在我们遇到困难时,给予我们的建议与鼓励。一周的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。
    为期一个星期的课程实训,在覃老师的亲切指导和同学的帮助下,此次设计才得以完成,在此向所有给予我此次课程设计指导和帮助的老师和同学表示最诚挚的感谢!

    6 参考文献

    [1] 江国强,覃琴.EDA技术与应用(第5版):电子工业出版社,2017

    [2]赵倩,叶波,林丽萍,周多,王晓华.Verilog数字系统设计与FPGA应用[M].北京:清华大学出版社,2012

    [3]吴迪,杨梅,严飞.EDA与数字系统实验教程[M].大连:大连海事大学出版社,2011

    附录

    总体原理图

    在这里插入图片描述

    总仿真图

    在这里插入图片描述

    展开全文
  • **用jAVA写一个出租计费小程序** 那天上街坐出租车坐在副驾驶,看着收费标准就随手拍下来了。 主要思路是写四个计费方法:非空车方法,空驾驶方法,行驶等待方法,夜行方法,主函数中键入一个Scanner类作为输入...
            **用jAVA写一个出租车计费小程序**
      那天上街坐出租车坐在副驾驶,看着收费标准就随手拍下来了。
    

    随手拍的

    主要思路是写四个计费方法:非空车方法,空驾驶方法,行驶等待方法,夜行方法,主函数中键入一个Scanner类作为输入量,然后在主函数中写判断语句交互式操作,根据用户的需求再具体调用方法。

    代码如下:

    
    import java.util.Scanner;
    
    import org.omg.CORBA.PUBLIC_MEMBER;
    
    /**
     * @author 结哥
     *出租基价:5元/2km
     *出租公里基价;超过基价2km,每公里2元
     *出租车空驾驶费:单行六公里为限,超过部分0.5元/公里加收空驾驶费
     *出租车等候费:3min内免费,超过3min按每0.5元/min收取
     *出租车夜行费:当日21:00-次日6:00期间,基价和车公里租价加收20%
     */
    public class CarPaySyst {
    	
    	private static double n;
    	public static void unEmptyPay(double b)
    	{
    					if (b<=2) {
    					System.out.println("	收费"+(5+WaitPay()  )+"元");
    			   		}else {
    			   			System.out.println("收费"+(  (5+(b-2)*2)+WaitPay() )+"元");
    					         }     
    				}
    	public static void isEmpty(double b)
    	{                                 
    				if (b<=6) {
    							 if (b<=2) {
    									System.out.println("	收费"+(5+WaitPay())+"元");
    					 	}	else {
    									System.out.println("收费"+( (5+(b-2)*2)+WaitPay())+"元");
    								}      
    						  	} else {   System.out.println("收费:"+( (9+(b-6)*0.5)+WaitPay() )+"元");		
    										}
    								}
    	public static double WaitPay()
    	{    if (n<=3) {
    		return 0;
    	}else {
    		return 0+((n-3)*0.5);
    	}
    		
    	}
    	public static void NightDrive(double b) {
    		if (b<=2) {
    			System.out.println("	收费"+(6+WaitPay())+"元");
    	   		}else {
    	   			System.out.println("收费"+(  (6+(b-2)*2.4)+WaitPay()   )+"元");
    			         }   
    	}
    	public static void main(String[] args) {	
    		double b=0;
    	     boolean c,k ;  
    	     System.out.println("请输入行驶公里  ");
    	    Scanner a=new Scanner(System.in);
    	       b=a.nextDouble(); 
    	       System.out.println("请输入等待时间(min>0)");
    	       n=a.nextDouble();
    	       System.out.println("正常载人收费吗?  请输入true(代表是)或false(代表否)");
    	     c=a.nextBoolean();
    	            if (c) {
    	    	   unEmptyPay(b);
    		   }else {
    			System.out.println("是否空车驾驶  请输入true(代表是)或false(代表否)");
    			   k=a.nextBoolean();
    			   if (k) {
    				   isEmpty(b);	
    			}else {
    				System.out.println("夜间行车:");
    			        NightDrive(b) ;  
    			}	 
    		}	
    	}
    
    

    下面看运行结果,nice,很流畅,结果也正确:
    在这里插入图片描述

    经验总结

     作者在写代码的时候,犯了这几个错误,后来改正了
     1.没有注意到返回值会返回负值,导致输出时,前三分钟等待的价格出错    
     2.静态方法可以直接调用,调用静态类则用 :类名.方法名。
     3.看清数据类型,if()里面放布尔值
    

    在这里插入图片描述

    作者的话

    碍于作者能力有限,可能写的还有不合理的地方,希望路过的朋友多多指点,将来我也会尽力写出更好的内容!
    呀,快开学了,这学期学python,很期待呢!

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,470
精华内容 588
关键字:

出租计费软件