多功能出租车运营控制器.docx

上传人:b****6 文档编号:3604905 上传时间:2022-11-24 格式:DOCX 页数:44 大小:87.87KB
下载 相关 举报
多功能出租车运营控制器.docx_第1页
第1页 / 共44页
多功能出租车运营控制器.docx_第2页
第2页 / 共44页
多功能出租车运营控制器.docx_第3页
第3页 / 共44页
多功能出租车运营控制器.docx_第4页
第4页 / 共44页
多功能出租车运营控制器.docx_第5页
第5页 / 共44页
点击查看更多>>
下载资源
资源描述

多功能出租车运营控制器.docx

《多功能出租车运营控制器.docx》由会员分享,可在线阅读,更多相关《多功能出租车运营控制器.docx(44页珍藏版)》请在冰豆网上搜索。

多功能出租车运营控制器.docx

多功能出租车运营控制器

多功能出租车运营控制器

学号:

61007211

姓名:

洪立俊

1、申请题目:

多功能出租车运营控制器

这是一个以出租车计费为主要功能的基于FPGA的全数字系统,同时此系统还附加有一些相关的其他功能,比如计时,自动收费,管理员操作等。

2、课题背景:

出租车是人们日常生活中不可或缺的交通工具,但就目前的出租车运营状况来看,仍存在许多问题,比如司机乱收费,不打表现象较多,出租车公司对于运营信息的管理不到位,另外在客运安全方面仍存在较大漏洞,针对以上提到的问题,我觉得开发一个能够高效管理出租车运营的系统。

3、项目规划:

⏹系统功能:

此系统的功能主要有计时(附有闹钟和日期),运营计价,自动收费,运营信息保存,管理员操作等。

⏹指标及规模:

时间显示包括时,分,秒,日期显示包括日,月(分大小月,二月假设为29天),闹钟设置精确到秒,闹铃长达30s。

收费标准:

白天(6时到夜间23点)起步价为9元,3~15公里每公里1元,15公里以上每公里1.5元,每等待1分钟加收2元,夜间起步价10元,超过3公里每公里1.8元,每等待1分钟3元。

计价按每100米计价,里程增加。

里程最大为99公里,收费最大999.99元,自动收费接受10,5元,1元,自动找零找都是1元。

系统涉及密码为6位。

⏹面板(显示):

6个8段数码管,4×4小键盘,开关若干,LED灯

⏹操作及规则:

复位后进入计时,按C修改时间,中途按B可退出,完成六位修改后按E确认,按6进入设置闹钟状态,类似于时间的修改。

闹钟时间到或者按0关闭,或者30s后自动关闭。

按4显示日期,按C修改日期,类似时间修改。

按B回到时间显示。

按A进入登陆过程,输入6为密码,登录成功进入,管理员操作程序,按D修改里程分配参数,按F可阅读运营记录。

按B退出管理员操作,按F键进入运营过程,按方向键可切换里程和费用的显示,按2进入等待。

按3保存记录,进入自动收费,通过拨开关进行收费。

收完费进入自动找零至零。

按E回到时间显示。

⏹输入、输出接口:

键盘有扫描译码模块,数码管有译码模块及显示驱动模块,相当于数据选择器。

4、实现方案:

⏹核心问题:

状态的控制及转移,数据处理模块的设计,以及若干显示的分时显示模块的设计。

⏹解决方案:

FPGA设计顶层文件采用图形化设计,状态机及相关数据处理单元,附加模块部分采用VHDL语言设计,部分采用图形化设计。

由于显示部分也是比较复杂的,所以也引进状态的概念对显示内容进行控制。

存储器采用数组的形式存储二进制信息,数组元素即为逻辑值向量。

5、系统结构:

⏹系统框图:

⏹模块功能描述:

输入接口用于译码产生相关的控制信号,状态机用于控制不同时刻的相关操作,数据处理单元用来处理相关信号,包括计时模块,相关寄存模块,计费,收费,计程模块,存储器模块等,输出驱动模块用于控制不同时候的输出。

⏹模块接口标注:

输入模块接口有4位键盘码keyvalue输出,握手信号pressed,以及一些经消抖同步的外部输入,如复位reset,闹钟开关控制alarm_on,收费脉冲输入f10,f5,f1,状态机产生控制信号,修改时间,日期使能timeload,dateload,修改密码使能,存储记录使能store,运营控制信号showXX,阅读记录信号readXX,找零信号等。

数据处理模块产生时间time,日期date,密码code,里程kilo,收费charge,存储器记录输出record等。

输出模块输入包括显示状态控制信号ss,各数据处理单元的显示输出内容,输出为6个8段数码管的信号,和一个闹钟到信号alarmsignal。

6、状态流程图:

⏹系统工作状态流程

由于系统比较庞大,操作过程比较多,所以涉及的状态控制也比较多,为了更加清楚地表示各状态间的控制转移,以及不同状态对应的控制输出信号,现采用多状态机的描述方法。

包括主流程图,各子流程图,其中一些具有类似功能的流程就省略了,比如校准日期,设置闹钟,设置参数的流程就和校准时间的流程类似。

1.总流程图:

2.出租车运营流程图

3.校准时间流程图:

4.管理员登录流程:

5.管理员修改密码流程

6.管理员阅读运营记录流程图:

7、程序清单

由于本系统的复杂性,所以程序比较多,这里仅列出主要的程序,同一个程序中类似的代码则省略,具有类似功能的代码仅举其一。

--键盘译码,按键动作标志生成模块--

libraryieee;

useieee.std_logic_1164.all;

entitykey_decoderis

port(col3,col2,col1,col0:

instd_logic;

row3,row2,row1,row0:

instd_logic;

clk,scan_clk:

instd_logic;

keyvalue:

outstd_logic_vector(3downto0);

pressed,stop:

outstd_logic);

endkey_decoder;

architecturertlofkey_decoderis

signaltemp:

std_logic_vector(7downto0);

signaltemp_pressed:

std_logic;

signalq1,q2,q3,q4,q5,q6:

std_logic;

signalkeypressed_asy:

std_logic;

begin

temp<=row3&row2&row1&row0&col3&col2&col1&col0;

process(temp)--键盘译码

begin

casetempis

when"11101110"=>keyvalue<="0000";

temp_pressed<='1';

when"11101101"=>keyvalue<="0001";

temp_pressed<='1';

省略部分

when"01111101"=>keyvalue<="1101";

temp_pressed<='1';

when"01111011"=>keyvalue<="1110";

temp_pressed<='1';

when"01110111"=>keyvalue<="1111";

temp_pressed<='1';

whenothers=>temp_pressed<='0';

endcase;

endprocess;

process(scan_clk)--按键动作标志消抖

begin

if(scan_clk'eventandscan_clk='1')then

q1<=temp_pressed;

q2<=q1;

q3<=q2;

q4<=q3;

endif;

keypressed_asy<=q1orq2orq3orq4;

endprocess;

process(clk)--按键动作标志与全局时钟同步化

begin

if(clk'eventandclk='1')then

q5<=keypressed_asy;

q6<=q5;

endif;

pressed<=q5andnot(q6);

endprocess;

stop<=col3andcol2andcol1andcol0;

endrtl;

--里程计数模块--

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

entitykilocounteris

port(start,mile,pause:

instd_logic;--开始计数,里程脉冲输入,暂停使能输入端

kilo:

outstd_logic_vector(11downto0);--公里数输出端

high_3,high_15:

outstd_logic);--大于三公里,大于15公里的使能输出端

endkilocounter;

architecturertlofkilocounteris

signalk1,k0,k00:

std_logic_vector(3downto0);

begin

process(start,pause,mile)

begin

ifstart='0'then--未进入里程计数时里程数始终保持为零

k1<="0000";k0<="0000";k00<="0000";

high_3<='0';high_15<='0';

else

ifpause='1'then--等待状态下保持里程数

k1<=k1;k0<=k0;k00<=k00;

elsifrising_edge(mile)then--在里程脉冲下正常计数

ifk00="1001"then

k00<="0000";

ifk0="1001"then

k0<="0000";

ifk1="1001"then

k1<="0000";

else

k1<=k1+1;

endif;

else

k0<=k0+1;

endif;

else

k00<=k00+1;

endif;

endif;

endif;

ifk0>="0011"then--达到里程要求时标志信号有效

high_3<='1';

endif;

ifk1>="0010"or(k1="0001"andk0>="0101")then

high_15<='1';

endif;

endprocess;

kilo(11downto8)<=k1;kilo(7downto4)<=k0;kilo(3downto0)<=k00;

endrtl;

--计时模块--

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entitytime_counteris

port(clk,reset,timeload:

instd_logic;--全局时钟输入,开机复位端,修改时间置数端

buffertime:

instd_logic_vector(23downto0);--时间并行输入端

time:

outstd_logic_vector(23downto0);--时间输出端

ci:

outstd_logic);--时间进位进日月模块

endtime_counter;

architecturertloftime_counteris

signalclk1s:

std_logic;

signaltemp_time5,temp_time4,temp_time3,temp_time2,temp_time1,temp_time0:

std_logic_vector(3downto0);

componentdivider_1s--500分频器说明

port(clk:

instd_logic;

clk1s:

outstd_logic);

endcomponent;

begin

divider1s:

divider_1s--500分频器实例化

portmap(clk=>clk,

clk1s=>clk1s);

process(clk1s,clk,reset,timeload)

begin

ifreset='0'then--复位清零

temp_time5<="0000";temp_time4<="0000";temp_time3<="0000";temp_time2<="0000";temp_time1<="0000";temp_time0<="0000";

elsifrising_edge(clk)then

iftimeload='1'then--修改时间时置数

temp_time5<=buffertime(23downto20);

temp_time4<=buffertime(19downto16);

temp_time3<=buffertime(15downto12);

temp_time2<=buffertime(11downto8);

temp_time1<=buffertime(7downto4);

temp_time0<=buffertime(3downto0);

else--正常计时

ifclk1s='1'then

iftemp_time0="1001"then

temp_time0<="0000";

iftemp_time1="0101"then

temp_time1<="0000";

iftemp_time2="1001"then

temp_time2<="0000";

iftemp_time3="0101"then

temp_time3<="0000";

iftemp_time4="1001"andtemp_time5="0000"then

temp_time4<="0000";temp_time5<="0001";

elsiftemp_time4="1001"andtemp_time5="0001"then

temp_time4<="0000";temp_time5<="0010";

elsiftemp_time4="0011"andtemp_time5="0010"then

temp_time4<="0000";temp_time5<="0000";

else

temp_time4<=temp_time4+1;

endif;

else

temp_time3<=temp_time3+1;

endif;

else

temp_time2<=temp_time2+1;

endif;

else

temp_time1<=temp_time1+1;

endif;

else

temp_time0<=temp_time0+1;

endif;

endif;

endif;

endif;

--当计到23:

59:

59出现进位信号至日月模块--

iftemp_time5&temp_time4&temp_time3&temp_time2&temp_time1&temp_time0="001000110101100101011001"then

ci<='1';

else

ci<='0';

endif;

endprocess;

time(23downto20)<=temp_time5;time(19downto16)<=temp_time4;time(15downto12)<=temp_time3;time(11downto8)<=temp_time2;time(7downto4)<=temp_time1;time(3downto0)<=temp_time0;

endrtl;

--计费模块--

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entitytotal_chargeis

port(start,pause,mile,f_wait:

instd_logic;--未运营状态,等待暂停状态,里程脉冲,等待时间脉冲

high_3,high_15:

instd_logic;--里程标志输入

time:

instd_logic_vector(23downto0);--时间输入

charge:

outstd_logic_vector(19downto0));--计费总价输出,分别为百,十,个,十分,百分位

endtotal_charge;

architecturertloftotal_chargeis

signalc4,c3,c2,c1,c0:

std_logic_vector(3downto0);

begin

process(time,pause,start,mile,f_wait,high_3,high_15)

variablehour_h,hour_l:

std_logic_vector(3downto0);

begin

hour_h:

=time(23downto20);

hour_l:

=time(19downto16);

ifstart='0'then--未运营时价格总为零

c4<="0000";c3<="0000";c2<="0000";c1<="0000";c0<="0000";

else

if(hour_h="0000"andhour_l>="0110")orhour_h="0001"or(hour_h="0010"andhour_l<="0010")then--白天运营

ifpause='1'then--等待下的计费

ifrising_edge(f_wait)then--即pause='1'进入等待状态

ifc2="1001"orc2="1000"then

ifc2="1001"then

c2<="0001";

else

c2<="0000";

endif;

ifc3="1001"then

c3<="0000";

ifc4="1001"then

c4<="0000";

else

c4<=c4+1;

endif;

else

c3<=c3+1;

endif;

else

c2<=c2+2;

endif;

endif;

else

ifrising_edge(mile)then--正常运营

ifhigh_3='0'then

c4<="0000";c3<="0000";c2<="1001";c1<="0000";c0<="0000";

elsifhigh_15='0'then

ifc1="1001"then

c1<="0000";

ifc2="1001"then

c2<="0000";

ifc3="1001"then

c3<="0000";

ifc4="1001"then

c4<="0000";

elsec4<=c4+1;

endif;

elsec3<=c3+1;

endif;

elsec2<=c2+1;

endif;

elsec1<=c1+1;

endif;

elsifhigh_3='1'andhigh_15='1'then

if(c0="0101"andc1="1000")orc1="1001"then

ifc1="1001"andc0="0101"then

c0<="0000";c1<="0001";

elsifc1="1001"andc0="0000"then

c0<="0101";c1<="0000";

elsifc1="1000"andc0="0101"then

c0<="0000";c1<="0000";

endif;

ifc2="1001"then

c2<="0000";

ifc3="1001"then

c3<="0000";

ifc4="1001"then

c4<="0000";

elsec4<=c4+1;

endif;

elsec3<=c3+1;

endif;

elsec2<=c2+1;

endif;

elsifc0="0000"then

c0<="0101";c1<=c1+1;

else

c0<="0000";c1<=c1+"0010";

endif;

endif;

endif;

endif;

else--夜间运营模式

ifpause='1'then

ifrising_edge(f_wait)then

省略部分

endprocess;

charge(19downto16)<=c4;charge(15downto12)<=c3;charge(11downto8)<=c2;charge(7downto4)<=c1;charge(3downto0)<=c0;

endrtl;

--铃声产生模块--

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entitybell_prois

port(alarm_on,clk,alarm_load,pressed:

instd_logic;--闹钟开关,时钟,修改置数,键盘响应

buffertime:

instd_logic_vector(15downto0);--修改时间并行输入端

time:

instd_logic_vector(23downto0);--当前时间并行输入

keyvalue:

instd_logic_vector(3downto0);--键盘值输入端

alarm_signal:

outstd_logic);--闹铃信号输出端

endbell_pro;

architecturertlofbell_prois

signalalarm:

std_logic;

typestateis(s0,s1,s2,s3);

signalpre_state:

state:

=s0;

signalnext_state:

state:

=s0;

signaliner_ala_time:

std_logic_vector(15downto0);

begin

process(clk)--修改置数进程

begin

ifrising_edge(clk)then

ifalarm_load='1'then

iner_ala_time<=buffertime;

endif;

endif;

endprocess;

process(clk,alarm_on)--状态转移进程

begin

ifalarm_on='0'then

pre_state<=s0;

elsifrising_edge(clk)then

pre_state<=next_state;

endif;

endprocess;

process(pre_state,time,iner_ala_time,pr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1