出租车计价器
摘 要:出租车计价器是乘客和司机的交易准则,它是出租车行业发展的重要标志,是出租车中最重要的工具。它关系着交易双方的利益。具有良好性能的计价器无论是对广大出租车司机朋友还是乘客来说都是很必要的。因此,汽车计价器的研究也是十分有一个应用价值的。该系统由AT89S51单片机控制,满足计程、计时、计费、存储等多种计量功能为一体的出租车计价器的实用要求。相比于普通的模拟电路控制,采用单片机进行的设计相对来说功能强大,用较少的硬件和适当的软件相互配合可以很容易的实现设计要求,且灵活性强,可以通过软件编程来完成更多的附加功能。针对计费模式的切换,通过软件编程就可以轻易而举的实现。避免了机械开关带来的不稳定因素。
关键词:出租车计价器 单片机 控制
目 录
第一章 前 言 ................................................................................................................... 1
第二章 设计要求 ............................................................................................................................... 1
2.1 基本功能 ................................................................................................................ 1
2.3 扩展功能 ................................................................................................................ 2
第三章 系统的组成及工作原理 ................................................................................................... 2
3.1 系统的硬件构成及功能 ...................................................................................... 2
3.2 AT89S51单片机及其引脚说明 ........................................................................... 3
第四章 硬件电路方案设计............................................................................................................. 6
4.1 方案比较与确定 .................................................................................................. 6
4.2 里程计算、计价单元的设计 .............................................................................. 6
4.3 显示单元电路设计 ................................................................................................ 8
4.4 键盘显示模块设计 ................................................................................................ 9
第5章 系统的软件设计 ............................................................................................................... 11
5.1 系统主程序设计 ................................................................................................ 11
5.2 定时中断服务程序 ............................................................................................ 13
5.3 显示服务程序 .................................................................................................... 13
5.4 键盘服务程序 .................................................................................................... 14
第6章 系统调试与测试结果分析 ................................................................................. 16
6.1 使用的仪器仪表和工具 .................................................................................... 16
6.2 调试的方法 ........................................................................................................ 16
第7章 结论 ..................................................................................................................... 17
参考文献 ............................................................................................................................. 18
附录 ..................................................................................................................................... 19
附录1 总体设计电路图 ............................................................................................. 19
附录2 元件清单 ......................................................................................................... 19
附录3 全部源程序 ..................................................................................................... 20
第一章 前 言
随着我国国民经济的告诉发展,出租车已成为城市公共交通的重要组成部分。出租车计价器这一专用计算器具必须经当地技监局所属的管理部门坚定认可,且出租车安装计价器整车鉴定合格后才能运营。针对电子式出租车计价器,建设部于1997年12月1日开始贯彻新的行业标准“CJ5024-1997”,要求“本标准实施之日起,电子式出租车计价器的设计,制造,和检验必须符合本标准的规定”。根据新标准选择性能价格比高的计价器,并与有关出租车管理部门一起确定选用哪个品牌则是计量部门的职责。如何选用计价器,主要应考虑两个方面:第一是性能和质量是否符合新标准CJ5024-1997,性能还包括本地区行政管理部门随时间,区域和车型在运价上的调整,如里程费,等候费,空贴费,夜间补偿费等作变更时,改变计价器运行程序的繁简程度。同时要考虑计价器自身防作弊的性能。第二要关注该品牌计价器是否具备升级换代或者是扩展功能。虽然现在个别大城市有全部更新出租车计价器一步到位的能力,但绝大部分城市还不具备这种条件,须按步骤先安装计价器,再装语音提示器,然后才考虑票据打印或者IC卡管理及收费等问题,这样在选用计价器时就要想到它在未来发展中的配套能力,否则将延误出租车科学化管理的进程。
本次课程设计利用单片机技术来实现一台多功能出租车计价器,具有性能可靠、电路简单、成本低等特点。
第二章 设计要求
2.1 基本功能
(1)显示:可以显示里程、金额、等待时间、速度。
(2)计费功能:起步公里数为2公里,价格为6元;若实际运行大于2公里,按单程价格为1.6元/公里,往返则价格为1.6元/公里。
(3)按键功能:单程/往返分别由“单程” 按键和“往返” 按键设定;按“暂停” 键,计价器可暂停计价;按“清除” 键,计价器能将记录数据(里程、等待时间与金额等)自动清0;按“查询”键,能自动显示总等待时间;按“返回”
键,仍然显示里程和金额。
2.2 性能:公里数检测误差不超过±10%。
2.3 扩展功能
停车计费功能:用单片机控制电机转动,并用光电传感器检测转盘转动模拟车速,车速与转盘转速成正比。车速<5公里/小时的时间累积为总等待时间,每5分钟等待时间相当于里程数增加1公里。
第三章 系统的组成及工作原理
本系统的硬件设计主要包括单片机AT89S51、数据显示部件、模拟行驶路程单元、及计价单元的设计。在硬件设计过程中,充分利用各部件的功能,实现多功能的出租车计价器设计。
3.1 系统的硬件构成及功能
计价器的单片机控制方案图如图1 单片机控制方案图所示。
利用单片机丰富的IO端口,及其控制的灵活性,实现基本的里程计价功能和价格选择、时间显示控制等功能。不但能实现所要求的功能而且能在很大的程度上扩展功能,而且还可以方便的对系统进行升级。具体电路参见附录中“多功能出租车计价器总体电路图”如图3.1 单片机控制方案图。
图3.1 单片机控制方案图
3.2 AT89S51单片机及其引脚说明
AT89S51是美国ATMEL公司生产的低功耗,高性能CMOS 8位单片机,片内含4KB的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器既可在线编程(ISP)也可用传统方法进行编程及通用 8位微处理器于单片芯片中,具有高性价比。
AT89S51是一个有40个引脚的芯片,引脚配置如图3.2 AT89S51引脚配置所示。
图3.2 AT89S51引脚配置
AT89S51芯片的40个引脚功能为:
VCC 电源电压。
GND 接地。
RST 复位输入。
当RST变为高电平并保持2个机器周期时,将使单片机复位。WDT溢出将使该引脚输出高电平,设置SFR AUXR的DISRTO位(地址8EH)可打开或关闭该功能。DISKRTO位缺省为RESET输出高电平打开状态。
XTAL1 反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2 来自反向振荡放大器的输出。
P0口 一组8位漏极开路型双向I/O口。也即地址/数据总线复用口。作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
P1口 一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个
引脚被外部信号拉低时会输出一个电流(IIL)。Flash编程和程序校验期间,P1接收低8位地址。P1口部分端口引脚及功能如表3-1 P1口特殊功能所示。
表3-1 P1口特殊功能
P2口 一个带内部上拉电阻的8位双向I/O口。P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16位地址的外部数据存储器时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器时,P2口线上的内容在整个访问期间不改变。Flash编程和程序校验期间,P2亦接收低8位地址。
P3口 一个带内部上拉电阻的8位双向I/O口。P3的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写“1”时,它们被内部的上拉电阻把拉到高电并可作输入端口。作输入端口使用时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能,如表3-2 P3口特殊功能所示。P3口还接收一些用于Flash闪速存储器编程和程序校验期间的控制信号。
表3-2 P3口特殊功能
PSEN/ 程序储存允许输出是外部程序存储器的读先通信号,当AT89S51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN/有效,即输出两个脉
冲。当访问外部数据存储器,没有两次有效的PSEN/信号。
EA/VPP 外部访问允许。欲使CPU仅访问外部程序存储器,EA端必须保持低电平,需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。Flash存储器编程时,该引脚加上+12V的编程电压VPP。
第四章 硬件电路方案设计
4.1 方案比较与确定
出租车计价系统在模拟车轮转动方面上可以采用两种方案:一种是用555芯片产生固定频率的脉冲模拟。这种方案产生脉冲频率很高,但是调节比较麻烦。第二种是采用槽型光耦的通与断来模拟转动,使用电机转盘对光耦的切割来产生脉冲。这种方案产生脉冲频率不高,但是转速可以轻松调节。经过仔细考虑和权衡,由于两种方案均有其优点,决定同时使用两种方案,两个模拟源可以根据需要任意使用。
在显示问题上,可以使用7279芯片控制显示,也可以通过动态扫描实现显示功能。考虑到动态扫描使用的硬件较少,本着简捷易行的原则,采用了动态扫描的方案。
4.2 里程计算、计价单元的设计
里程计算是通过安装在车轮上的霍尔传感器A44E检测到的信号,在该系统中用两种脉冲发生器进行模拟,送到单片机,经处理计算,送给显示单元的。其原理如图4.1 所示。
图4.1 模拟测距示意图
555电路来产生一个脉冲来模拟霍尔传感器输出的里程脉冲,选择P1.0口作为信号的输入端,内部采用外部中断0,555脉冲产生电路输出一个脉冲信号直接加到IO口P1.0上(产生的频率F=1/T=1.414/[(R1+2R2)C1]),由单片机的内部算法对脉冲计数,通过计算将脉冲增加体现在金额和里程上。具体电路如图4.2所示。
图4.2 555脉冲产生电路图
光偶电路是以光为媒介传输电信号的一种光一电转换器件,是另一种模拟将出
租车行驶时车轮所转的圈数转换成脉冲信号送入数据处理电路。H92B4是光偶电路的基本元件,它由发光源和受光器两部分组成,发光源为发光二极管,受光器为光敏三极管。当发光源与受光器之间存在光线阻挡时,输出端由高电平变为低电平,恢复光通路又变为高电平,就这样形成一个个的高低电平脉冲。选择P3.4.口作为信号的输入端,内部采用外部中断0,光偶电路输出一个脉冲信号直接加到外部中断0上,引起单片机的中断,对脉冲计数,通过计算将脉冲增加体现在金额和里程上。具体电路如图4.3所示。
图4.3 H92B4光偶电路
4.3 显示单元电路设计
由于设计要求有里程、金额、等待时间、速度显示输出,所以采用8位LED数码管的分屏显示。
显示电路由8数据锁存器74HC573、译码器74LS138、8位LED数码管组成。电路如图6所示,74HC573用于连接51单片机和LED数码管,51单片机的P0.0~P0.7分别顺序对应数码管的A~G和dp,当位P0.0为1时,对应A段点亮,以次类推。而51单片机的P2.0~P2.2接74LS138的ABC输入口,其8个输出口分别接到8个数码管,这样就可以进行3-8译码控制8个数码管的显示。
显示模块电路图见图4.4
各个数码管显示内容示意图见图4.5
图4.4显示单元电路
图4.5 数码管显示内容示意图(上下复用)
4.4 键盘显示模块设计
键盘采用4*4矩阵按键,接在AT89S51的P3口,当有键按下时,相对应的接口被置0。矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上,设置一个按键。如图4.6所示,行线接P3.0~P3.3,列线接P3.4~P3.7。
图4.6 矩阵键盘电路
按键S1:单程按键。按下该键,里程随脉冲数成正比累加,在里程大于3公里后,金额数按单程价格为2元/公里进行累加。
按键S2:往返按键。按下该键,里程随脉冲数成正比累加,在里程大于3公里后,金额数按单程价格为1.5元/公里进行累加。
按键S3:暂停按键。到达目的地后,按“暂停” 键,计价器可暂停计价。
按键S4:清除按键。按“清除” 键,计价器能将记录数据(里程、等待时间与价格等)自动清0。
按键S5:查询按键。按“查询”键,能自动显示总等待时间。
按键S6:返回按键。按下该键,回到显示里程数、金额状态。
第5章 系统的软件设计
本系统的软件设计主要可分为主程序模块、定时计数中断程序、里程计数中断服务程序、中途等待中断服务程序、显示子程序服务程序、键盘服务程序六大模块。下面对各部分模块作介绍。
5.1 系统主程序设计
在主程序模块中,需要完成对各接口芯片的初始化、出租车起价和单价的初始化、中断向量的设计以及开中断、循环等待等工作。另外,在主程序模块中还需要设置启动/清除标志寄存器、里程寄存器和价格寄存器,并对它们进行初始化。然后,主程序将根据各标志寄存器的内容,分别完成启动、清除、计程和计价等不同的操作。主程序流程图如图5.1 所示。当按下S1时,就启动计价,将根据里程寄存器中的内容计算和判断出行驶里程是否已超过起价公里数。若已超过,则根据里程值、每公里的单价数和起价数来计算出当前的累计价格,并将结果存于价格寄存器中,然后将时间和当前累计价格送显示电路显示出来。当到达目的地的时候,由于霍尔开关没有送来脉冲信号,就停止计价,显示当前所应该付的金额和对应的单价,到下次启动计价时,系统自动对显示清零,并重新进行初始化过程。
图5.1 程序流程图
5.2 定时中断服务程序
在定时中断服务程序中,每1/40s 产生一次中断,当产生40 次中断的时候,也就到了一秒,送数据到相应的显示缓冲单元,并调用显示子程序实时显示。其程序流程如图5.2 所示。
图5.2 定时中断服务程序
5.3 显示服务程序
数码管在一般情况下显示里程数,价格两项数据,当按下键5时则跳转显示等待时间和车速两项数据。当按下键6时则返回显示里程数,价格两项数据。程序流程图如图5.3:
图5.3 显示服务程序
5.4 键盘服务程序
键盘采用查询的方式,放在主程序中,当没有按键按下的时候,单片机循环主程序,一旦有按键按下,便转向相应的子程序处理,处理结束再返回。
参见图9,六个按键分别对应六个简单的子程序。
如果按键S1被按下,则调用第一个子程序:begin_signal标志置1,将s_or_d标志置0;表示单程开始。
如果按键S2被按下,则调用第一个子程序:begin_signal标志置1,将s_or_d标志置1; 表示往返开始。
如果按键S3被按下,则调用第一个子程序:begin_signal标志置0; 表示暂停。
如果按键S4被按下,则调用第一个子程序:pulse_counter标志置0,将t置0; 表示将显示数据清空。
如果按键S5被按下,则调用第一个子程序:dispflag标志置1; 表示进入查询界面。
如果按键S6被按下,则调用第一个子程序:dispflag标志置0; 表示退出查询界面。
第6章 系统调试与测试结果分析
根据系统设计方案,本系统的调试共分为三大部分:硬件调试,软件调试和软硬件联调。测试包括里程计价测试、掉电存储测试测试。
6.1 使用的仪器仪表和工具
数字万用表 DT9203
单片机仿真器 STC_ISP
双踪稳压稳流电源 DH1718E-5
数字示波器 TDS1002
电烙铁
单片机实验板
6.2 调试的方法
根据系统设计方案,本系统的调试共分为三大部分:硬件调试,软件调试和软硬件联调。由于在系统设计中采用模块设计法,所以方便对各电路模块功能进行逐级测试。
确定方案后的焊接过程很顺利,3天后就完成了大部分电路的焊接工作,进行简单的程序测试后发现一个问题:由于要用到555芯片产生脉冲,预先设计的电路中没有提供5V电源给555供电。我们想到外接一个5V的直流电源,发现这样会使整个系统显示累赘而难以操作。后来我们想到与单片机最小系统的Vcc和555芯片共用5V电源。于是将555的电源和地接到了最小系统的Vcc和地。这样,只要单片机一上电,555便可以正常工作,操作起来非常方便和快捷。
在软件设计过程中遇到一个严重的问题就是系统的时序设计。我们发现程序的键盘扫描程序和中断程序发生冲突。导致按键功能和显示功能不能同时出现。后来经过排查发现,中断子程序设计的不合理,导致发生了中断嵌套。将中断子程序的部分内容调整到主程序中调用子程序则这解决了这一问题。
第7章 结论
经过这些天有关于出租车计价器的课程设计,使我对单片机的应用有了更深的了解。在课程设计的过程中,还是碰到了许多的问题。比如,对于数码管动态扫描显示和键盘的延时防抖的综合编程不能较好地解决;对于代码的前后顺序及调用掌握得还不够好;对于一些相关的应用软件没能熟练掌握。通过这几天晚上的苦想和反复调试,以及参考网上的程序,最终还是把问题解决了。
通过这次课程设计,我最大的收获就是自己的动手能力和独立解决问题的能力得到了很大的提高,也充分体会到了自己设计东西的乐趣、学会查阅资料和对别人的东西融会变通的重要性,也明白了很多知识光靠趴在书本上学是学不到其中的精髓的,必须亲自去试着实践,亲自去经历才能对它们真正的掌握,凡事都要自己去动下手,去实践一下,遇到困难,永远不要沮丧气馁。在动手的过程中,不仅能增强实践能力,而且在理论上可以有更深的认识;这次设计给了我极大的鼓舞和信心,相信在以后的学习中可以通过不断的摸索和实践来提高其他方面的知识。通过本次课程设计,又使我学到了许多书本上无法学到的知识,也使也深该体会到单片机技术应用领域的广泛,不仅使我对学过的单片机知识有了很多的巩固,同时也对单片机这一门课程产生了更大的兴趣。
在本次课程设计过程中,我学会了在网络上查找有关本设计的各硬件的资源,其中包括:AT89S51单片机及其引脚说明、555引脚图及其引脚功能等,为本次课程设计提供了一定的资料。也为以后的进一步学习打下了坚实的基础。
参考文献
[1] 张友德 赵志英 涂时亮 编 单片微型机原理、应用与实验 上海:复旦
大学出版社2005.12 全书
[2] 徐光翔 单片机原理接口及应用 南京大学出版社
[3] 张淑清等. 单片微型计算机接口技术及其应用 北京:国防工业出版社,
[4] 王晓君等. MCS-51及兼容单片机原理与选型 北京:电子工业出版社
[5]张鑫、华臻、陈书谦.《单片机原理及应用》[M].电子工业出版社,2005.P110~136.
[6]丁元杰、吴大伟.《单片微机实题集与实验指导书》[M].机械工业出版社, 2004.P124~125.
[7] AT89C52概述[EB/OL]:http://baike.baidu.com/view/2251929.html
附录
附录1 总体设计电路图
附录2 元件清单
附录3 全部源程序
该出租车计价器的系统软件设计源程序如下: #include #define uint unsigned int #define uchar unsigned char
#define rate 15//脉冲数与里程数的比例 sbit P20=P2^0; sbit P21=P2^1;
sbit P22=P2^2; //接 74 LS 138 控制 数码管 sbit pulse_in=P1^0; bit pulse=1; bit dispflag; uchar num,temp;
bit begin_signal;// 开始标志 bit s_or_d;//单程 还是往返 标志 uint times; // 定时次数 uint pulse_counter; uint record; uint s_temple;
uint s,m; //里程数 s 和 金额 m uint t; //等待时间
char baiwei,shiwei,gewei,xiaoshu; char keynum; //键盘 的键值 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40}; //0~f and '-'的字型码(共阴) //声明 区
void delay(uint x); void init();
void divide(uint counter); void select(bit a,bit b,bit c); void debouncer(void); uchar keyscan(void);
void delay(uint x)//延时 x ms . { }
void init() // 定时器初始化 { }
void divide(uint counter) { {
if(dispflag==0)
P0=0x00;
counter=counter*10/rate; xiaoshu=counter%10; gewei=(counter/10)%10; shiwei=(counter/100)%10; baiwei=(counter/1000)%10; if(counter
uint i,j; for(i=0;i
for(j=0;j
TMOD=0x01;
TH0=(65536-25000)/256;// timer=1/40s TL0=(65536-25000)%256; EA=1; ET0=1; TR0=1;
} else {
if(s_or_d==0) m=80+2*(counter-30)+t/300; else
m=80+1.5*(counter-30)+t/300;
select(1,1,0); //显示里程数目 P0=table[xiaoshu]; delay(2); select(0,1,0); P0=table[gewei]|0x80; delay(2); select(1,0,0); P0=table[shiwei]; delay(2); select(0,0,0); P0=table[baiwei]; delay(2); xiaoshu=m%10; gewei=(m/10)%10; shiwei=(m/100)%10; baiwei=(m/1000)%10;
select(1,1,1); //显示 金额数目 P0=table[xiaoshu]; delay(2); select(0,1,1); P0=table[gewei]|0x80; delay(2); select(1,0,1); P0=table[shiwei]; delay(2); select(0,0,1); P0=table[baiwei]; delay(2);
P0=0x00;
} }
xiaoshu=t%10; gewei=(t/10)%10; shiwei=(t/100)%10; baiwei=(t/1000)%10;
select(1,1,0); //显示 等待时间 P0=table[xiaoshu]; delay(2); select(0,1,0); P0=table[gewei]; delay(2); select(1,0,0); P0=table[shiwei]; delay(2); select(0,0,0); P0=table[baiwei]; delay(2);
void timer0() interrupt 1 {
TH0=(65536-25000)/256; TL0=(65536-25000)%256; if(begin_signal==1) {
if(pulse_in!=pulse) {
{ }
delay(10);
if(pulse_in!=pulse) { }
pulse=~pulse; pulse_counter++;
if (times==39)//1 s timer completed
times=0;
if((pulse_counter-record)
t++;
小于 5 , 则等待时间 增加
record=pulse_counter;
}
times++;
}
// s_temple=pulse_counter/2; // divide(s_temple);
}
void select(bit a,bit b,bit c) { P20=a; P21=b; P22=c;
}
void debouncer(void)// 防抖动 { uint i;
for(i=0;i
}
uchar keyscan() {
P3=0x7f; temp=P3; temp=temp&0x0f; while(temp!=0x0f) { delay(10); temp=P3;
temp=temp&0x0f;
程序
while(temp!=0x0f)
{ temp=P3;
switch(temp) { }
case 0x7e:num=1; }
break; break; break; break; } { }
temp=P3; temp=temp&0x0f;
case 0x7d:num=2; case 0x7b:num=3; case 0x77:num=4;
while(temp!=0x0f)
P3=0xbf; temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
delay(10); temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
temp=P3; {
switch(temp)
} }
case 0xbe:num=5;
break; break; break; break;
case 0xbd:num=6; case 0xbb:num=7; case 0xb7:num=8;
while(temp!=0x0f) }
{ }
temp=P3; temp=temp&0x0f;
P3=0xdf; temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
delay(10); temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
temp=P3; {
switch(temp)
case 0xde:num=9;
break; break;
case 0xdd:num=10; case 0xdb:num=11;
} }
break; break;
case 0xd7:num=12;
while(temp!=0x0f) }
{ }
temp=P3; temp=temp&0x0f;
P3=0xef; temp=P3; temp=temp&0x0f;
while(temp!=0x0f)
{
delay(10); temp=P3; temp=temp&0x0f; while(temp!=0x0f) {
temp=P3; { }
switch(temp)
case 0xee:num=13; break;
case 0xe7:num=16;
break; break; break;
case 0xed:num=14; case 0xeb:num=15;
while(temp!=0x0f)
}
}
}
{ }
temp=P3; temp=temp&0x0f;
return num;
void singleway(void)// 单程 开始 函数 { }
void doubleway(void)//往返 开始 函数 { }
void pause(void)//暂停 函数 { }
void clear(void)// 清除 函数 { }
void check(void)// 查询 函数 { }
void check2(void)// 查询 函数 {
dispflag=0;
begin_signal=1; s_or_d=0;
begin_signal=1; s_or_d=1;
begin_signal=0;
pulse_counter=0; t=0;
dispflag=1;
}
void sentence(void)// 判定键盘值 {
}
main()
{
}
init(); while (1) { } divide(pulse_counter); keynum=keyscan(); sentence(); if(keynum!=0) { } switch(keynum) { } case 1: case 2: case 3: case 4: case 5: case 6: singleway();break; doubleway();break; pause();break; clear();break; check();break; check2();break;
29
出租车计价器
摘 要:出租车计价器是乘客和司机的交易准则,它是出租车行业发展的重要标志,是出租车中最重要的工具。它关系着交易双方的利益。具有良好性能的计价器无论是对广大出租车司机朋友还是乘客来说都是很必要的。因此,汽车计价器的研究也是十分有一个应用价值的。该系统由AT89S51单片机控制,满足计程、计时、计费、存储等多种计量功能为一体的出租车计价器的实用要求。相比于普通的模拟电路控制,采用单片机进行的设计相对来说功能强大,用较少的硬件和适当的软件相互配合可以很容易的实现设计要求,且灵活性强,可以通过软件编程来完成更多的附加功能。针对计费模式的切换,通过软件编程就可以轻易而举的实现。避免了机械开关带来的不稳定因素。
关键词:出租车计价器 单片机 控制
目 录
第一章 前 言 ................................................................................................................... 1
第二章 设计要求 ............................................................................................................................... 1
2.1 基本功能 ................................................................................................................ 1
2.3 扩展功能 ................................................................................................................ 2
第三章 系统的组成及工作原理 ................................................................................................... 2
3.1 系统的硬件构成及功能 ...................................................................................... 2
3.2 AT89S51单片机及其引脚说明 ........................................................................... 3
第四章 硬件电路方案设计............................................................................................................. 6
4.1 方案比较与确定 .................................................................................................. 6
4.2 里程计算、计价单元的设计 .............................................................................. 6
4.3 显示单元电路设计 ................................................................................................ 8
4.4 键盘显示模块设计 ................................................................................................ 9
第5章 系统的软件设计 ............................................................................................................... 11
5.1 系统主程序设计 ................................................................................................ 11
5.2 定时中断服务程序 ............................................................................................ 13
5.3 显示服务程序 .................................................................................................... 13
5.4 键盘服务程序 .................................................................................................... 14
第6章 系统调试与测试结果分析 ................................................................................. 16
6.1 使用的仪器仪表和工具 .................................................................................... 16
6.2 调试的方法 ........................................................................................................ 16
第7章 结论 ..................................................................................................................... 17
参考文献 ............................................................................................................................. 18
附录 ..................................................................................................................................... 19
附录1 总体设计电路图 ............................................................................................. 19
附录2 元件清单 ......................................................................................................... 19
附录3 全部源程序 ..................................................................................................... 20
第一章 前 言
随着我国国民经济的告诉发展,出租车已成为城市公共交通的重要组成部分。出租车计价器这一专用计算器具必须经当地技监局所属的管理部门坚定认可,且出租车安装计价器整车鉴定合格后才能运营。针对电子式出租车计价器,建设部于1997年12月1日开始贯彻新的行业标准“CJ5024-1997”,要求“本标准实施之日起,电子式出租车计价器的设计,制造,和检验必须符合本标准的规定”。根据新标准选择性能价格比高的计价器,并与有关出租车管理部门一起确定选用哪个品牌则是计量部门的职责。如何选用计价器,主要应考虑两个方面:第一是性能和质量是否符合新标准CJ5024-1997,性能还包括本地区行政管理部门随时间,区域和车型在运价上的调整,如里程费,等候费,空贴费,夜间补偿费等作变更时,改变计价器运行程序的繁简程度。同时要考虑计价器自身防作弊的性能。第二要关注该品牌计价器是否具备升级换代或者是扩展功能。虽然现在个别大城市有全部更新出租车计价器一步到位的能力,但绝大部分城市还不具备这种条件,须按步骤先安装计价器,再装语音提示器,然后才考虑票据打印或者IC卡管理及收费等问题,这样在选用计价器时就要想到它在未来发展中的配套能力,否则将延误出租车科学化管理的进程。
本次课程设计利用单片机技术来实现一台多功能出租车计价器,具有性能可靠、电路简单、成本低等特点。
第二章 设计要求
2.1 基本功能
(1)显示:可以显示里程、金额、等待时间、速度。
(2)计费功能:起步公里数为2公里,价格为6元;若实际运行大于2公里,按单程价格为1.6元/公里,往返则价格为1.6元/公里。
(3)按键功能:单程/往返分别由“单程” 按键和“往返” 按键设定;按“暂停” 键,计价器可暂停计价;按“清除” 键,计价器能将记录数据(里程、等待时间与金额等)自动清0;按“查询”键,能自动显示总等待时间;按“返回”
键,仍然显示里程和金额。
2.2 性能:公里数检测误差不超过±10%。
2.3 扩展功能
停车计费功能:用单片机控制电机转动,并用光电传感器检测转盘转动模拟车速,车速与转盘转速成正比。车速<5公里/小时的时间累积为总等待时间,每5分钟等待时间相当于里程数增加1公里。
第三章 系统的组成及工作原理
本系统的硬件设计主要包括单片机AT89S51、数据显示部件、模拟行驶路程单元、及计价单元的设计。在硬件设计过程中,充分利用各部件的功能,实现多功能的出租车计价器设计。
3.1 系统的硬件构成及功能
计价器的单片机控制方案图如图1 单片机控制方案图所示。
利用单片机丰富的IO端口,及其控制的灵活性,实现基本的里程计价功能和价格选择、时间显示控制等功能。不但能实现所要求的功能而且能在很大的程度上扩展功能,而且还可以方便的对系统进行升级。具体电路参见附录中“多功能出租车计价器总体电路图”如图3.1 单片机控制方案图。
图3.1 单片机控制方案图
3.2 AT89S51单片机及其引脚说明
AT89S51是美国ATMEL公司生产的低功耗,高性能CMOS 8位单片机,片内含4KB的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器既可在线编程(ISP)也可用传统方法进行编程及通用 8位微处理器于单片芯片中,具有高性价比。
AT89S51是一个有40个引脚的芯片,引脚配置如图3.2 AT89S51引脚配置所示。
图3.2 AT89S51引脚配置
AT89S51芯片的40个引脚功能为:
VCC 电源电压。
GND 接地。
RST 复位输入。
当RST变为高电平并保持2个机器周期时,将使单片机复位。WDT溢出将使该引脚输出高电平,设置SFR AUXR的DISRTO位(地址8EH)可打开或关闭该功能。DISKRTO位缺省为RESET输出高电平打开状态。
XTAL1 反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2 来自反向振荡放大器的输出。
P0口 一组8位漏极开路型双向I/O口。也即地址/数据总线复用口。作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
P1口 一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个
引脚被外部信号拉低时会输出一个电流(IIL)。Flash编程和程序校验期间,P1接收低8位地址。P1口部分端口引脚及功能如表3-1 P1口特殊功能所示。
表3-1 P1口特殊功能
P2口 一个带内部上拉电阻的8位双向I/O口。P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16位地址的外部数据存储器时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器时,P2口线上的内容在整个访问期间不改变。Flash编程和程序校验期间,P2亦接收低8位地址。
P3口 一个带内部上拉电阻的8位双向I/O口。P3的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写“1”时,它们被内部的上拉电阻把拉到高电并可作输入端口。作输入端口使用时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能,如表3-2 P3口特殊功能所示。P3口还接收一些用于Flash闪速存储器编程和程序校验期间的控制信号。
表3-2 P3口特殊功能
PSEN/ 程序储存允许输出是外部程序存储器的读先通信号,当AT89S51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN/有效,即输出两个脉
冲。当访问外部数据存储器,没有两次有效的PSEN/信号。
EA/VPP 外部访问允许。欲使CPU仅访问外部程序存储器,EA端必须保持低电平,需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。Flash存储器编程时,该引脚加上+12V的编程电压VPP。
第四章 硬件电路方案设计
4.1 方案比较与确定
出租车计价系统在模拟车轮转动方面上可以采用两种方案:一种是用555芯片产生固定频率的脉冲模拟。这种方案产生脉冲频率很高,但是调节比较麻烦。第二种是采用槽型光耦的通与断来模拟转动,使用电机转盘对光耦的切割来产生脉冲。这种方案产生脉冲频率不高,但是转速可以轻松调节。经过仔细考虑和权衡,由于两种方案均有其优点,决定同时使用两种方案,两个模拟源可以根据需要任意使用。
在显示问题上,可以使用7279芯片控制显示,也可以通过动态扫描实现显示功能。考虑到动态扫描使用的硬件较少,本着简捷易行的原则,采用了动态扫描的方案。
4.2 里程计算、计价单元的设计
里程计算是通过安装在车轮上的霍尔传感器A44E检测到的信号,在该系统中用两种脉冲发生器进行模拟,送到单片机,经处理计算,送给显示单元的。其原理如图4.1 所示。
图4.1 模拟测距示意图
555电路来产生一个脉冲来模拟霍尔传感器输出的里程脉冲,选择P1.0口作为信号的输入端,内部采用外部中断0,555脉冲产生电路输出一个脉冲信号直接加到IO口P1.0上(产生的频率F=1/T=1.414/[(R1+2R2)C1]),由单片机的内部算法对脉冲计数,通过计算将脉冲增加体现在金额和里程上。具体电路如图4.2所示。
图4.2 555脉冲产生电路图
光偶电路是以光为媒介传输电信号的一种光一电转换器件,是另一种模拟将出
租车行驶时车轮所转的圈数转换成脉冲信号送入数据处理电路。H92B4是光偶电路的基本元件,它由发光源和受光器两部分组成,发光源为发光二极管,受光器为光敏三极管。当发光源与受光器之间存在光线阻挡时,输出端由高电平变为低电平,恢复光通路又变为高电平,就这样形成一个个的高低电平脉冲。选择P3.4.口作为信号的输入端,内部采用外部中断0,光偶电路输出一个脉冲信号直接加到外部中断0上,引起单片机的中断,对脉冲计数,通过计算将脉冲增加体现在金额和里程上。具体电路如图4.3所示。
图4.3 H92B4光偶电路
4.3 显示单元电路设计
由于设计要求有里程、金额、等待时间、速度显示输出,所以采用8位LED数码管的分屏显示。
显示电路由8数据锁存器74HC573、译码器74LS138、8位LED数码管组成。电路如图6所示,74HC573用于连接51单片机和LED数码管,51单片机的P0.0~P0.7分别顺序对应数码管的A~G和dp,当位P0.0为1时,对应A段点亮,以次类推。而51单片机的P2.0~P2.2接74LS138的ABC输入口,其8个输出口分别接到8个数码管,这样就可以进行3-8译码控制8个数码管的显示。
显示模块电路图见图4.4
各个数码管显示内容示意图见图4.5
图4.4显示单元电路
图4.5 数码管显示内容示意图(上下复用)
4.4 键盘显示模块设计
键盘采用4*4矩阵按键,接在AT89S51的P3口,当有键按下时,相对应的接口被置0。矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上,设置一个按键。如图4.6所示,行线接P3.0~P3.3,列线接P3.4~P3.7。
图4.6 矩阵键盘电路
按键S1:单程按键。按下该键,里程随脉冲数成正比累加,在里程大于3公里后,金额数按单程价格为2元/公里进行累加。
按键S2:往返按键。按下该键,里程随脉冲数成正比累加,在里程大于3公里后,金额数按单程价格为1.5元/公里进行累加。
按键S3:暂停按键。到达目的地后,按“暂停” 键,计价器可暂停计价。
按键S4:清除按键。按“清除” 键,计价器能将记录数据(里程、等待时间与价格等)自动清0。
按键S5:查询按键。按“查询”键,能自动显示总等待时间。
按键S6:返回按键。按下该键,回到显示里程数、金额状态。
第5章 系统的软件设计
本系统的软件设计主要可分为主程序模块、定时计数中断程序、里程计数中断服务程序、中途等待中断服务程序、显示子程序服务程序、键盘服务程序六大模块。下面对各部分模块作介绍。
5.1 系统主程序设计
在主程序模块中,需要完成对各接口芯片的初始化、出租车起价和单价的初始化、中断向量的设计以及开中断、循环等待等工作。另外,在主程序模块中还需要设置启动/清除标志寄存器、里程寄存器和价格寄存器,并对它们进行初始化。然后,主程序将根据各标志寄存器的内容,分别完成启动、清除、计程和计价等不同的操作。主程序流程图如图5.1 所示。当按下S1时,就启动计价,将根据里程寄存器中的内容计算和判断出行驶里程是否已超过起价公里数。若已超过,则根据里程值、每公里的单价数和起价数来计算出当前的累计价格,并将结果存于价格寄存器中,然后将时间和当前累计价格送显示电路显示出来。当到达目的地的时候,由于霍尔开关没有送来脉冲信号,就停止计价,显示当前所应该付的金额和对应的单价,到下次启动计价时,系统自动对显示清零,并重新进行初始化过程。
图5.1 程序流程图
5.2 定时中断服务程序
在定时中断服务程序中,每1/40s 产生一次中断,当产生40 次中断的时候,也就到了一秒,送数据到相应的显示缓冲单元,并调用显示子程序实时显示。其程序流程如图5.2 所示。
图5.2 定时中断服务程序
5.3 显示服务程序
数码管在一般情况下显示里程数,价格两项数据,当按下键5时则跳转显示等待时间和车速两项数据。当按下键6时则返回显示里程数,价格两项数据。程序流程图如图5.3:
图5.3 显示服务程序
5.4 键盘服务程序
键盘采用查询的方式,放在主程序中,当没有按键按下的时候,单片机循环主程序,一旦有按键按下,便转向相应的子程序处理,处理结束再返回。
参见图9,六个按键分别对应六个简单的子程序。
如果按键S1被按下,则调用第一个子程序:begin_signal标志置1,将s_or_d标志置0;表示单程开始。
如果按键S2被按下,则调用第一个子程序:begin_signal标志置1,将s_or_d标志置1; 表示往返开始。
如果按键S3被按下,则调用第一个子程序:begin_signal标志置0; 表示暂停。
如果按键S4被按下,则调用第一个子程序:pulse_counter标志置0,将t置0; 表示将显示数据清空。
如果按键S5被按下,则调用第一个子程序:dispflag标志置1; 表示进入查询界面。
如果按键S6被按下,则调用第一个子程序:dispflag标志置0; 表示退出查询界面。
第6章 系统调试与测试结果分析
根据系统设计方案,本系统的调试共分为三大部分:硬件调试,软件调试和软硬件联调。测试包括里程计价测试、掉电存储测试测试。
6.1 使用的仪器仪表和工具
数字万用表 DT9203
单片机仿真器 STC_ISP
双踪稳压稳流电源 DH1718E-5
数字示波器 TDS1002
电烙铁
单片机实验板
6.2 调试的方法
根据系统设计方案,本系统的调试共分为三大部分:硬件调试,软件调试和软硬件联调。由于在系统设计中采用模块设计法,所以方便对各电路模块功能进行逐级测试。
确定方案后的焊接过程很顺利,3天后就完成了大部分电路的焊接工作,进行简单的程序测试后发现一个问题:由于要用到555芯片产生脉冲,预先设计的电路中没有提供5V电源给555供电。我们想到外接一个5V的直流电源,发现这样会使整个系统显示累赘而难以操作。后来我们想到与单片机最小系统的Vcc和555芯片共用5V电源。于是将555的电源和地接到了最小系统的Vcc和地。这样,只要单片机一上电,555便可以正常工作,操作起来非常方便和快捷。
在软件设计过程中遇到一个严重的问题就是系统的时序设计。我们发现程序的键盘扫描程序和中断程序发生冲突。导致按键功能和显示功能不能同时出现。后来经过排查发现,中断子程序设计的不合理,导致发生了中断嵌套。将中断子程序的部分内容调整到主程序中调用子程序则这解决了这一问题。
第7章 结论
经过这些天有关于出租车计价器的课程设计,使我对单片机的应用有了更深的了解。在课程设计的过程中,还是碰到了许多的问题。比如,对于数码管动态扫描显示和键盘的延时防抖的综合编程不能较好地解决;对于代码的前后顺序及调用掌握得还不够好;对于一些相关的应用软件没能熟练掌握。通过这几天晚上的苦想和反复调试,以及参考网上的程序,最终还是把问题解决了。
通过这次课程设计,我最大的收获就是自己的动手能力和独立解决问题的能力得到了很大的提高,也充分体会到了自己设计东西的乐趣、学会查阅资料和对别人的东西融会变通的重要性,也明白了很多知识光靠趴在书本上学是学不到其中的精髓的,必须亲自去试着实践,亲自去经历才能对它们真正的掌握,凡事都要自己去动下手,去实践一下,遇到困难,永远不要沮丧气馁。在动手的过程中,不仅能增强实践能力,而且在理论上可以有更深的认识;这次设计给了我极大的鼓舞和信心,相信在以后的学习中可以通过不断的摸索和实践来提高其他方面的知识。通过本次课程设计,又使我学到了许多书本上无法学到的知识,也使也深该体会到单片机技术应用领域的广泛,不仅使我对学过的单片机知识有了很多的巩固,同时也对单片机这一门课程产生了更大的兴趣。
在本次课程设计过程中,我学会了在网络上查找有关本设计的各硬件的资源,其中包括:AT89S51单片机及其引脚说明、555引脚图及其引脚功能等,为本次课程设计提供了一定的资料。也为以后的进一步学习打下了坚实的基础。
参考文献
[1] 张友德 赵志英 涂时亮 编 单片微型机原理、应用与实验 上海:复旦
大学出版社2005.12 全书
[2] 徐光翔 单片机原理接口及应用 南京大学出版社
[3] 张淑清等. 单片微型计算机接口技术及其应用 北京:国防工业出版社,
[4] 王晓君等. MCS-51及兼容单片机原理与选型 北京:电子工业出版社
[5]张鑫、华臻、陈书谦.《单片机原理及应用》[M].电子工业出版社,2005.P110~136.
[6]丁元杰、吴大伟.《单片微机实题集与实验指导书》[M].机械工业出版社, 2004.P124~125.
[7] AT89C52概述[EB/OL]:http://baike.baidu.com/view/2251929.html
附录
附录1 总体设计电路图
附录2 元件清单
附录3 全部源程序
该出租车计价器的系统软件设计源程序如下: #include #define uint unsigned int #define uchar unsigned char
#define rate 15//脉冲数与里程数的比例 sbit P20=P2^0; sbit P21=P2^1;
sbit P22=P2^2; //接 74 LS 138 控制 数码管 sbit pulse_in=P1^0; bit pulse=1; bit dispflag; uchar num,temp;
bit begin_signal;// 开始标志 bit s_or_d;//单程 还是往返 标志 uint times; // 定时次数 uint pulse_counter; uint record; uint s_temple;
uint s,m; //里程数 s 和 金额 m uint t; //等待时间
char baiwei,shiwei,gewei,xiaoshu; char keynum; //键盘 的键值 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40}; //0~f and '-'的字型码(共阴) //声明 区
void delay(uint x); void init();
void divide(uint counter); void select(bit a,bit b,bit c); void debouncer(void); uchar keyscan(void);
void delay(uint x)//延时 x ms . { }
void init() // 定时器初始化 { }
void divide(uint counter) { {
if(dispflag==0)
P0=0x00;
counter=counter*10/rate; xiaoshu=counter%10; gewei=(counter/10)%10; shiwei=(counter/100)%10; baiwei=(counter/1000)%10; if(counter
uint i,j; for(i=0;i
for(j=0;j
TMOD=0x01;
TH0=(65536-25000)/256;// timer=1/40s TL0=(65536-25000)%256; EA=1; ET0=1; TR0=1;
} else {
if(s_or_d==0) m=80+2*(counter-30)+t/300; else
m=80+1.5*(counter-30)+t/300;
select(1,1,0); //显示里程数目 P0=table[xiaoshu]; delay(2); select(0,1,0); P0=table[gewei]|0x80; delay(2); select(1,0,0); P0=table[shiwei]; delay(2); select(0,0,0); P0=table[baiwei]; delay(2); xiaoshu=m%10; gewei=(m/10)%10; shiwei=(m/100)%10; baiwei=(m/1000)%10;
select(1,1,1); //显示 金额数目 P0=table[xiaoshu]; delay(2); select(0,1,1); P0=table[gewei]|0x80; delay(2); select(1,0,1); P0=table[shiwei]; delay(2); select(0,0,1); P0=table[baiwei]; delay(2);
P0=0x00;
} }
xiaoshu=t%10; gewei=(t/10)%10; shiwei=(t/100)%10; baiwei=(t/1000)%10;
select(1,1,0); //显示 等待时间 P0=table[xiaoshu]; delay(2); select(0,1,0); P0=table[gewei]; delay(2); select(1,0,0); P0=table[shiwei]; delay(2); select(0,0,0); P0=table[baiwei]; delay(2);
void timer0() interrupt 1 {
TH0=(65536-25000)/256; TL0=(65536-25000)%256; if(begin_signal==1) {
if(pulse_in!=pulse) {
{ }
delay(10);
if(pulse_in!=pulse) { }
pulse=~pulse; pulse_counter++;
if (times==39)//1 s timer completed
times=0;
if((pulse_counter-record)
t++;
小于 5 , 则等待时间 增加
record=pulse_counter;
}
times++;
}
// s_temple=pulse_counter/2; // divide(s_temple);
}
void select(bit a,bit b,bit c) { P20=a; P21=b; P22=c;
}
void debouncer(void)// 防抖动 { uint i;
for(i=0;i
}
uchar keyscan() {
P3=0x7f; temp=P3; temp=temp&0x0f; while(temp!=0x0f) { delay(10); temp=P3;
temp=temp&0x0f;
程序
while(temp!=0x0f)
{ temp=P3;
switch(temp) { }
case 0x7e:num=1; }
break; break; break; break; } { }
temp=P3; temp=temp&0x0f;
case 0x7d:num=2; case 0x7b:num=3; case 0x77:num=4;
while(temp!=0x0f)
P3=0xbf; temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
delay(10); temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
temp=P3; {
switch(temp)
} }
case 0xbe:num=5;
break; break; break; break;
case 0xbd:num=6; case 0xbb:num=7; case 0xb7:num=8;
while(temp!=0x0f) }
{ }
temp=P3; temp=temp&0x0f;
P3=0xdf; temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
delay(10); temp=P3; temp=temp&0x0f;
while(temp!=0x0f) {
temp=P3; {
switch(temp)
case 0xde:num=9;
break; break;
case 0xdd:num=10; case 0xdb:num=11;
} }
break; break;
case 0xd7:num=12;
while(temp!=0x0f) }
{ }
temp=P3; temp=temp&0x0f;
P3=0xef; temp=P3; temp=temp&0x0f;
while(temp!=0x0f)
{
delay(10); temp=P3; temp=temp&0x0f; while(temp!=0x0f) {
temp=P3; { }
switch(temp)
case 0xee:num=13; break;
case 0xe7:num=16;
break; break; break;
case 0xed:num=14; case 0xeb:num=15;
while(temp!=0x0f)
}
}
}
{ }
temp=P3; temp=temp&0x0f;
return num;
void singleway(void)// 单程 开始 函数 { }
void doubleway(void)//往返 开始 函数 { }
void pause(void)//暂停 函数 { }
void clear(void)// 清除 函数 { }
void check(void)// 查询 函数 { }
void check2(void)// 查询 函数 {
dispflag=0;
begin_signal=1; s_or_d=0;
begin_signal=1; s_or_d=1;
begin_signal=0;
pulse_counter=0; t=0;
dispflag=1;
}
void sentence(void)// 判定键盘值 {
}
main()
{
}
init(); while (1) { } divide(pulse_counter); keynum=keyscan(); sentence(); if(keynum!=0) { } switch(keynum) { } case 1: case 2: case 3: case 4: case 5: case 6: singleway();break; doubleway();break; pause();break; clear();break; check();break; check2();break;
29