摘 要
本设计的是一个基于单片机AT89S52的出租车自动计费设计,附有复位电路,时钟电路,键盘电路等。复位电路是单片机的初始化操作,除了正常的初始化外,为摆脱困境,通过复位电路可以重新开始。时钟电路采用12MHz的晶振,作为系统的时钟源,具有较高的准确性。
在上电时字符型液晶1602显示最初的起步价,里程收费,等待时间收费三种收费,通过按键可以调整起步价,里程收费,等待时间收费。通过按键模拟出租车的运行,暂停,停止。在1602液晶上可以显示运行的时间,运行时暂停的时间,通过计算可以得出总共的费用和总的路程。在这里主要是以AT89S52单片机为核心控制器,P0口接1602液晶显示模块,P1口接按键的,通过按键输入。
关键字 AT89S52;1602液晶;出租车计费器
ABSTRACT
The design is based on a monolithic integrated circuit AT89S52 taxi billing design, with reset circuit, clocking circuit, keyboard circuit. Reset circuit is initialized, besides the normal operation of the initial dilemma, as a foreigner, through the reset circuit can start again. 12MHz adopts the clock circuit, as a system of crystal oscillator, higher clock source.
The characters in the crystal that the initial 1602, charges, fees mileage waiting time, three buttons can be adjusted by charging fees, just waiting time, mileage. Through the simulation of the taxi, buttons, stop. Suspension In the liquid crystal display can run 1602, operation time, when suspension can be obtained by the computation of the total cost.here is mainly for the core controller, AT89S52 SCM P0 mouth after 1602 LCD module, P1 mouth after the keys, through the keystroke.
Keyword: AT89S52;1602 LCD;Taxi devices
目 录
1 课程设计书·······················································································3 1.1 课程设计任务············································································3 1.2 功能要求···················································································3 1.3 课程设计方案············································································3 2 硬件电路设计····················································································5 2.1 振荡电路设计············································································4 2.2 复位电路设计·············································································4 2.3 键盘接口电路·············································································6 2.4 显示电路···················································································6 2.5 直流电机电路·············································································7 2.6 单片机各引脚功能说明································································7 2.7 L298和1602液晶的简介·····························································9 3 软件设计·························································································13 3.1 单片机资源··············································································13 3.2 单片机模块··············································································13 3.3 系统程序流程框图····································································16 4 proteus调试····················································································17 4.1 proteus介绍··············································································17 4.2 proteus界面介绍·······································································17 4.3 proteus的简单使用····································································18 4.4 仿真结果···················································································20 心得体会······························································································21 参考文献······························································································22 致谢····································································································23 附录1 元件清单···················································································24 附录2 程序清单···················································································25 附录3 原理图······················································································33
1
1 课程设计任务书
1.1 课程设计任务
设计一个出租车自动计费器,计费包括起步价、行车里程计费、等待时间计费三部分,用1602液晶 显示总金额,运行时间,暂停时间,最大值为99.9元,起步价为5.0元,3Km之内起步价计费,超过3Km,设速度为100m/s,10s增加1.3元(即1KM增加1.3元),等待时间单价为每分钟1.5元,用液晶显示总里程,同时用液晶显示等待时间和运行花费时间。 设计要求: 一、计费功能
费用的计算是按行驶里程收费。设起步价为5.00元。 1、当里程<3km时,按起价计算费用 2、当里程>3km时,每公里按1.3元计费 3、等待累计时间>2min时,按1.5元/min计费 二、显示功能
1、显示行驶里程:用四位数字显示,显示方式为“XXXX”,单位为km。计程范围0-99km,精确到1km。
2、显示等候时间:用两位数字显示,显示方式为“XX”,单位为min。计时范围0-59min,精确到1min。
3、显示总费用:用四位数字显示,显示方式为“XXX.X”,单位为元。计价范围0-999.9元,精确到0.1元。
1.2 功能要求
本出租车自动计费,上电后显示最初的起步价,里程计费单价,等待时间计费单价,通过按键可以调节起步价,里程计费单价,等待时间计费单价。同时具有运行,暂停,停止等状态,可以显示运行的时间,同时可以显示暂停的时间,具有累加功能,暂停和运行时间在暂停和运行前一次的状态上计时。出租车停止后能够显示行驶的总费用。
1.3 课程设计方案
方案一:采用数字电子技术,利用555定时芯片构成多谐振荡器,或采用外围的晶振电路作为时钟脉冲信号,采用计数芯片对脉冲尽心脉冲的计数和分频,最后通过译码电路对数据进行译码,将译码所得的数据送给数码管显示,一下是该方案的流程框图,方案一如图1.1所示:
2
等待信号计时,计费,译时钟脉冲公里脉冲数码管显示计费脉冲码图1.1方案一 案二:采用EDA技术,根据层次化设计理论,该设计问题自顶向下可分为分频模块,控制模块 计量模块、译码和动态扫描显示模块,其系统框图如图1.2所示:
图1.2方案二
方案三:采用MCU技术,通过单片机作为主控器,利用1602字符液晶作为显示电路,采用外部晶振作为时钟脉冲,通过按键可以方便调节,一下是方案三的系统流程图,本方案主要是必须对于数字电路比较熟悉,成本又高。方案图如图1.3所示:
电源电路1602AT89S52按键电路直流电机液晶LED灯图1.3方案三 方案总结:通过各个方案的比较本次采用方案三,不但控制简单,而且成本低廉,设计电路简单。
2硬件电路设计
3
2.1 振荡电路
单片机内部有一个高增益、反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。通过这两个引脚在芯片外并接石英晶体振荡器和两只电容(电容和一般取
33pF)。这样就构成一个稳定的自激振荡器。
振荡电路脉冲经过二分频后作为系统的时钟信号,再在二分频的基础上三分频产生ALE信号,此时得到的信号时机器周期信号。振荡电路如图2.1所示:
图2.1振荡电路
2.2 复位电路设计
复位操作有两种基本形式:一种是上电复位,另一种是按键复位。按键复位具有上电复位功能外,若要复位,只要按图中的RESET键,电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。上电复位电路要求接通电源后,通过外部电容充电来实现单片机自动复位操作。上电瞬间RESET引脚获得高电平,随着电容的充电,RERST引脚的高电平将逐渐下降。RERST引脚的高电平只要能保持足够的时间(2个机器周期),单片机就可以进行复位操作。按键复位电路图如图2.2所示。
图2.2复位电路
2.3 键盘接口电路
(1)独立式键盘:独立式键盘中,每个按键占用一根I/O口线,每个按键电路相对独立。I/O口通过按键与地相连,I/O口有上拉电阻,无键按下时,引脚端为高电平,有键
4
按下时,引脚电平被拉低。I/O口内部有上拉电阻时,外部可不接上拉电阻。键盘接口电路如图2.3所示:
图2.3键盘接口电路
2.4 显示电路
对于现实电路我们可以采用数码管,也可以采用液晶显示,液晶又分字符型和点阵型,我们使用的液晶是字符型液晶,并且带字符库的,不需要查找代码。英文字符就可。液晶电路使用时,如果发现液晶不亮可以调节连接液晶的点位器,改变液晶的亮度。显示电路如图2.4所示:
图2.4显示电路
2.5 直流电机电路
该直流电机主要是通过驱动芯片L298来驱动,这款芯片可以同时驱动2个直流电机,可以用直流电或PWM脉冲波驱动第5,7脚为控制电机的正反转,一个接负电压,一个接正电压,第6脚ENA控制电机的转速,通过PWM可以控制转速,这里我们给
5
它一个高电平就可以了。直流电机电路如图2.5所示:
图2.5直流电机电路
2.6 单片机各引脚功能说明
AT89S52电路图如图2.6所示:
VCC:供电电压。GND:接地。P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行
校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向
I/O口,P1口缓冲器能接收输出4TTL门电流。 图2.6AT89S52
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是
由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电
6
流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3口也可作为AT89S52的一些特殊功能口,如表2.1所示。
表2.1 AT89S52的一些特殊功能口 管脚 P3.0 RXD P3.1 TXD P3.2 /INT0 P3.3 /INT1 P3.4 T0 P3.5 T1 P3.6 /WR P3.7 /RD 备选功能 (串行输入口) (串行输出口) (外部中断0) (外部中断1) (记时器0外部输入) (记时器1外部输入) (外部数据存储器写选通) (外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。 ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。
2.7 L298和1602液晶的简介
2.7.1 字符液晶1602的介绍
7
字符型液晶1602主要技术参数如表2.2所示:
表2.2 字符型液晶1602主要技术参数
显示容量: 芯片工作电压: 工作电流: 模块最佳工作电压: 字符尺寸:
16*2个字符 4.5—5.5V 2.0mA(5.0V) 5.0V 2.95*4.35(W*H)mm 接口信号说明如表2.3所示:
表2.3 1602接口信号说明
编号 1 2 3 4 5 6 7 8 符号 Vss VDD VL Rs R/W E D0 D1 引脚说明 电源地 电源正极 液晶显示偏压信号 数据/命令选择端(H/L) 读/写选择端(H/L) 使能信号 DataI/O DataI/O 编号 9 10 11 12 13 14 15 16 符号 D2 D3 D4 D5 D6 D7 BLA BLK 引脚说明 DataI/O DataI/O DataI/O DataI/O DataI/O DataI/O 背光源正极 背光源负极 控制器接口说明(HD44780及兼容芯片) 1、 基本操作时序
a 读状态:输入:Rs=L, Rw=H, E=H 输出:D0—D7=状态字 b 写指令:输入:Rs=L, Rw=L, D0—D7=指令码 输出:无 E=高脉冲
C 读数据:输入:Rs=H, Rw=L, E=H 输出:D0—D7=数据 d 写数据:输入:Rs=H, Rw=L, D0—D7=数据 输出:无 E=高脉冲
状态字说明如表2.4所示:
表2.4状态字说明(a)
STA7 D7
表2.5 状态字说明(b)
STA0--6 STA7 当前数据地址指针的数值 读写操作使能 1:禁止 0:允许 STA6 D6 STA5 D5 STA4 D4 STA3 D3 STA2 D2 STA1 D1 STA0 D0 注:对控制器进行读写操作之前,都必须进行读写检测,确保STA7为0 RAM地址映射图
8
控制器内部带有80*8位(80字节)的RAM缓冲区,对应关系如下图2.6所示:
表2.6 RAM地址映射图LCD16字*2行
00 01 02 03 04 05 06 07 08 09 0A 40 41 42 43 44 45 46 47 48 49 4A 0B 4B 0C 4C 0D 4D 0E 4E 0F 4F 50 … 67 10 … 27 指令说明 初始化设置
显示模式设置如表2.7所示:
表2.7 显示模式设置
指令码 0
0 1 1 1 0 0 功能 0 设置16*2显示,5*7点阵,8位数据接口 显示开关及光标设置如表2.8所示:
表2.8 显示开关及光标设置
指令码 0 0 0 0 1 D C B 功能 D=1 开显示; D=0 关显示 C=1 显示光标; C=0 不显示光标 B=1 光标闪烁; B=0 光标不显示 0 0 0 0 0 1 N S N=1 当读或写一个字符后地址指针加一,且光标加一 N=0 当读或写一个字后地址指针减一,且光标减一 S=1 当写一个字符后,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果 S=0 当写一个字符,整屏显示不移动 数据控制
控制器内部没有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM。
数据指针设置如表2.9所示
表2.9 数据指针设置(a)
指令码 80H+地址码(0—27H, 40—67H)
功能 设置数据地址指针 读数据:见c 写数据:见d
其它设置如表2.10所示
表2.10 数据指针设置(b)
9
指令码 01H 02H
功能 显示清屏:1.数据指针清零 2.所有显示清零 显示回车:1.数据指针清零 供电电路如图2.7所示:
单电源 (字符型模块)
双电源 (字符和图形型模块)
图2.7 供电电路
2.7.2 L298驱动芯片简介
以下是L298驱动芯片的管脚图,如图2.8所示:
3 软件设计
图2.8 L298芯片图
1脚:电流监测端A 3脚:输出端 5脚:输入端
10
2脚:输出端
4脚:功率电源电压(+12V) 6脚:时能端(通过电阻接地)
7脚:输入端 9脚:逻辑电源电压端(+5V) 11脚:使能端 13脚:输出端
15脚:电流监测端B
3.1 单片机资源使用
8脚:GND接地
10脚:输入端 12脚:输入脚
14脚:输出端
3软件设计
11
在本次设计中像电路键盘用到了P1口,其中P1.0到P1.4口作为键盘的输 入,直流电机电路的控制线用了P2口线,P3.0、P3.1、P3.2分别为led信号控制脚。显示电路用到了P0和P2口,P0口为液晶的数据口。
3.2 单片机软件模块设计 3.2.1 中断子函数
对于中断程序,只要定时器计数满就会产生中断50ms中断一次,共计20次,秒钟加1,秒钟计满再分钟加,当分钟加到99时全部清零。以下是中断子函数的流程图如图3.1所示:
3.2.2 判键子函数 开始否是否产生中断?是Count++否Count=20?是Second++count=0否Second=60?是Minite++second=0否图3.1中断子程序流程图 是Minite=0Minite=99? 对于独立式键盘判键,首先看有键按下不,如果有键按下则延时一会儿,在判断结束是否真的有键按下,如果确实有键按下,在判键释放,最后执行键功能程序。判键子函数的流程框图如图3.2所示:
12
开始LCD初始化LCD写命令LCD判忙否P0.7=0?否是写完成了?是 设置字符位置图3.2判键子程序流程图
写数据 3.2.3 显示子程序 判忙 1602液晶是字符型液晶,它的内部自带字符库,它可以写两行的字符,同时每行否可以写40个字符,在写显示程序的时候,我们先写命令,再设定字符显示,最后写数P0.7=0?据,在每写一次命令或数据都需要判断液晶是否忙。液晶显示程序流程图如图3.3所示: 是
13
否写完成了?是结束
否否Jump_in=1?开始定时器初始化液晶初始化否判断按键函数1是V=?V=1V=2V=3Value1+10Value2+5Value3+5数据处理显示函数是液晶清屏V1=13.3 总程序流程框图 运行3.3显示子程序流程图 是 V1=?V1=2V1=3暂停判断按键函数整体程序的流程框图如图3.4所示:
否Jump_out=1?停止数据处理显示函数清零函数是液晶清屏结束 14
图3.4整体程序的流程框图
4 protues的简介
4.1 Protues介绍
Proteus软件[10]是来自英国Labcenter electronics公司的EDA工具软件,它组合了高
15
级原理布图、混合模式SPICE仿真,PCB设计以及自动布线来实现一个完整的电子设计系统。此系统受益于15年来的持续开发,被《电子世界》在其对PCB设计系统的比较文章中评为最好产品—“The Route to PCB CAD”。Proteus 产品系列也包含了我们革命性的VSM技术,用户可以对基于微控制器的设计连同所有的周围电子器件一起仿真。用户甚至可以实时采用诸如LED/LCD、键盘、RS232终端等动态外设模型来对设计进行交互仿真。
其功能模块:—个易用而又功能强大的ISIS原理布图工具;PROSPICE混合模型SPICE仿真;ARES PCB设计。PROSPICE 仿真器的一个扩展PROTEUS VSM:便于包括所有相关的器件的基于微处理器设计的协同仿真。此外,还可以结合微控制器软件使用动态的键盘,开关,按钮,LEDs甚至LCD显示CPU模型。支持许多通用的微控制器,如PIC,AVR,HC11以及8051。最新支持ARM。交互的装置模型包括:LED和LCD显示,RS232终端,通用键盘,I2C,SPI器件。强大的调试工具,包括寄存器和存储器,断点和单步模式。IAR C-SPY 和Keil uVision2等开发工具的源层调试。应用特殊模型的DLL界面-提供有关元件库的全部文件。
4.2 proteus界面介绍
Proteus ISIS [11]的工作界面是一种标准的Windows界面,如图4.1所示。包括:标题栏、主菜单、标准工具栏、绘图工具栏、状态栏、对象选择按钮、预览对象方位控制按钮、仿真进程控制按钮、预览窗口、对象选择器窗口、图形编辑窗口。
16
图4.1 Proteus 窗口界面图
4.3 Protues的简单使用
(1)新建原理图
启动protues软件,单击file菜单下的new,弹出下图所示窗口,选择纸张大小。示意图如图4.2所示:
17
图4.2新建原理图示意图
(2)寻找元件
启动Proteus软件,单击挑选元件按钮P,在元件库中选出所需元器件,出现如图
4.3所示窗口,输入器件关键词选取元件,再连好线。
18
图4.3 选取元件库中元件示意图
(2)系统调试
双击单片机出现下图所示画面4.4,在Program File一栏中选取仿真项目的源程序代码,点击OK。
图4.4 加载程序图
.
单击Play按钮,进入仿真状态仿真按钮如4.4所示其中按钮1为开始运行,按钮2为step,按钮3为暂停,按钮4为停止。
图4.5 仿真按钮示意图
4.4 Protues仿真结果
通过仿真,上电时液晶显示起步价,里程单价,等待单价(以每分钟为单位),按键1可以选择调整起步价,里程价,等待单价,再按键3进入待运行状态,按键4可以运行,暂停,停止同时显示运行的时间,等待的时间和总的金额数,最后按键5可以退出,重新计费。在30s钟内液晶显示起步价,30s后开始计价,等待价每1分钟,才收费一次。
19
心得体会
出租车计费器系统的设计已经全部完成,能按预期的效果进行模拟汽车启动,停止,暂停等功能,并能够通过LCD显示车费数目。本款出租车计价器包括单价输出、单价调整、显示当前的系统时间等功能。另外,多功能出租车计价器还具有性能可靠、电路简单、成本低、实用性强等特点,加上经过优化的程序,使其有很高的智能化水平。
几个月来,经过自己努力,基本上完成了设计要求的内容,在系统可行性分析、原理图设计等方面都作了许多实际工作,取得了一些成绩,同时也遇到了一些问题,存在一些不足。经过这几个月的学习和工作,我觉得自己不论是在理论知识方面还是在动手能力方面都有了不小的进步,自己从中受益匪浅。这次设计很好的把以前学到的理论知识应用于实践,使我认识到理论知识与实践之间有一定的差距,只有通过不断的努力学习和实践才能很好的把理论知识应用到实践当中,也只有通过不断的实践才能对理论知识的理解。
通过这次设计不仅学会了如何去查找相关资料,更重要的是通过查找资料和翻阅书籍学到了不少知识,扩大了知识面,提高了知识水平。经过单元设计和系统设计巩固了以前所学的专业知识,自己真正认识到理论联系实际的重要性,为以后的学习和工作提供了很多有价值的经验。通过这次设计不仅增强了自己的动脑能力和动手能力,也提高了我思考问题、分析问题、解决问题的能力,更重要的是学会用工程化的思想来解决问题。这在以前的学习过程中是不曾学到的。在短短的三个月时间内完成设计内容,在很大程度上得益于老师的帮助。
这次设计是我认真认识到完整、严谨、科学分析问题、解决问题的思想是多么的重要,只有拥有了科学的态度才能设计出有用的产品。另外通过本次设计,是我认识到自己理论知识的应用能力有很大的欠缺,需要在以后的学习中进一步提高。
参考文献
20
[1] 李广弟,朱月秀,冷祖祁.单片机基础[M].第3版.北京航空航天大学出版社,2007年1月
[2]李华.MCS-51系列单片机实用接口技术[M].北京航空航天大学出版社,1996
[3] 马忠梅,张凯,马岩,单片机的C语言应用程序设计,[M],北京:北京航空航天大学出版社,2003.11;
[4] 胡辉,单片机原理及应用设计—21世纪高等院校规划教材[M],水利水电出版社,2005.7;
[5] 刘守义,单片机应用技术[M],西安:西安电子科技大学出版社,1996.8;
致谢
21
本论文是在何淑珍老师的悉心指导下完成的,何老师的渊博学识和丰富经验给我留下了深刻的印象。从何老师那里我学到的不仅是专业知识与实际问题科学解决的方法,更为重要的是勤奋和严谨治学的精神以及对学生的认真负责,老师的谆谆教诲使我受益匪浅,在此向何老师表示衷心的感谢并致以崇高的敬意!感谢家人给予我学业上和生活上的支持与照顾。同时感谢给予我帮助的各位老师、同学以及朋友们!
附录1 元件件清单 表5.1元器件清单
22
名称 规格 200 1K 10K 100 数量 1个 1个 5个 2个 2个 2个 3个 6个 1个 1个 1排 1块 1块 1块 备注 极性电容 内带字符库 电阻 电容 发光二极管 按键 直流电机 晶振 排阻 芯片 1602液晶
33pF 22μF 12MHz 102 AT89S52 L298
附录2 程序清单
//*******************************************
23
//日期:2010.5.9 //姓名:肖银伟
//名称:出租车自动计费器 //公司;湖南工学院
//******************************************* #include sbit rw=P2^1;//读或写 sbit rs=P2^0;// sbit en=P2^2;//读写时能控制端 sbit b=P0^7;//液晶判断忙标志位 void lcd_init();// void wr_com(uchar command);//液晶写命令 void wr_data(uchar data0);//写数据 void lcd_clear();//液晶清屏 void lcd_set();//设置液晶的起始位置 void busy();//液晶判忙函数 void display();//显示 void printstring(uchar *s);//直接写字符 void display1(); void key1(); sbit K=P1^0; sbit K1=P1^1; sbit K2=P1^2; sbit K3=P1^3; sbit K4=P1^4; sbit g=P2^7; sbit aa=P2^3; sbit bb=P2^4; sbit cc=P2^5; sbit led_run=P3^0; 24 sbit led_await=P3^1; sbit led_stop=P3^2; bit f_start;//开始标志位 bit jump_in;//跳入开始标志位 bit jump_out;//跳出标志位 void key(); uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x70};//字符1,2,3,,,,,0 uchar dispbuf[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uchar dispbuf1[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uchar v,v1;//按键次数累加变量 uchar i; void init();// void chuli();// void chuli1();// void delay(uchar t);// void clear();// void set(uchar x);// void set1(uchar y);// uchar command;// uchar count,count1;// uchar second,minite,second1,minite1;// unsigned int tt,tt1;// unsigned char value1=50,value2=25,value3=15;//起始价,运行价,等待价 unsigned int money;//金额变量 //******************************************* void main() { init(); 25 lcd_init(); while(1) { key1(); chuli(); display(); if(jump_in==1) { jump_in=0; lcd_init(); while(1) { key(); chuli1(); display1(); if(jump_out==1) { lcd_init(); jump_out=0; clear(); break; } } } } } //******************************************* void clear()//跳出下一次 { TR0=0; TR1=0; money=0; second=0; second1=0; 26 minite=0; minite1=0; value1=50; value2=25; value3=15; led_run=1; led_await=1; led_stop=1; v=0; v1=0; for(i=0;i<15;i++) { dispbuf[i]=0; dispbuf1[i]=0; } } //******************************************* void init()//定时器初始化 { TMOD=0x11; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=(65536-50000)/256; TL1=(65536-50000)%256; ET0=1; ET1=1; EA=1; TR0=0; TR1=0; } //******************************************* void t0_(void) interrupt 1 using 0//定时器0中断 { count++; 27 if(count==20) { count=0; second++; if(second==60) { second=0; minite++; if(minite==99) { minite=0; } } } TH0=(65536-50000)/256; TL0=(65536-50000)%256; dispbuf1[0]=minite/10; dispbuf1[1]=minite%10; dispbuf1[2]=second/10; dispbuf1[3]=second%10; } //******************************************* void t1_(void) interrupt 3 using 3//定时器1中断 { count1++; if(count1==20) { count1=0; second1++; if(second1==60) { second1=0; minite1++; if(minite1==99) 28 { minite1=0; } } } TH1=(65536-50000)/256; TL1=(65536-50000)%256; dispbuf1[4]=minite1/10; dispbuf1[5]=minite1%10; dispbuf1[6]=second1/10; dispbuf1[7]=second1%10; } //******************************************* void lcd_init()//液晶初始化 { wr_com(0x3c); wr_com(0x06); wr_com(0x0c); wr_com(0x01); } //******************************************* void wr_com(uchar command)//液晶写命令 { busy(); rs=0; rw=0; P0=command; en=1; en=0; } //******************************************* void wr_data(uchar data0)//液晶写数据 { busy(); 29 rs=1; rw=0; P0=data0; en=1; en=0; } //******************************************* void busy()//液晶判忙 { while(1) { en=0; rs=0; rw=1; P0=0xff; en=1; if(b!=1)break; } en=0; } //******************************************* void chuli()//数值处理 { dispbuf[0]=value1/100%10; dispbuf[1]=value1/10%10; dispbuf[2]=value1%10; dispbuf[3]=value2/100%10; dispbuf[4]=value2/10%10; dispbuf[5]=value2%10; dispbuf[6]=value3/100%10; dispbuf[7]=value3/10%10; dispbuf[8]=value3%10; } //******************************************* 30 void display() { set(0); printstring(\"step :\"); wr_data(table[dispbuf[0]]); wr_data(table[dispbuf[1]]); printstring(\".\"); wr_data(table[dispbuf[2]]); set(16); printstring(\"mileage :\"); wr_data(table[dispbuf[3]]); wr_data(table[dispbuf[4]]); printstring(\".\"); wr_data(table[dispbuf[5]]); set1(0); printstring(\"await :\"); wr_data(table[dispbuf[6]]); wr_data(table[dispbuf[7]]); printstring(\".\"); wr_data(table[dispbuf[8]]); /* set1(16); printstring(\"run : \"); wr_data(table[dispbuf1[0]]); wr_data(table[dispbuf1[1]]); printstring(\":\"); wr_data(table[dispbuf1[2]]); wr_data(table[dispbuf1[3]]); */ } //******************************************* 31 void chuli1() { if(f_start==1) { tt=minite*60+second;//总时间 tt1=minite1;//等待时间 money=value1+value2*0.1*tt+value3*tt1;//起始价+每公里价*时间*速度+等待价*等待时间 } else if(f_start==0) { money=0; } dispbuf1[8]=money/100%10;// dispbuf1[9]=money/10%10;// dispbuf1[10]=money%10;// } //******************************************* void display1() { set(0); printstring(\"run: \"); wr_data(table[dispbuf1[0]]); wr_data(table[dispbuf1[1]]); printstring(\":\"); wr_data(table[dispbuf1[2]]); wr_data(table[dispbuf1[3]]); set(14); printstring(\"await:\"); wr_data(table[dispbuf1[4]]); wr_data(table[dispbuf1[5]]); printstring(\":\"); wr_data(table[dispbuf1[6]]); 32 wr_data(table[dispbuf1[7]]); set1(0); printstring(\"sum is: \"); wr_data(table[dispbuf1[8]]); wr_data(table[dispbuf1[9]]); printstring(\".\"); wr_data(table[dispbuf1[10]]); } //******************************************* void printstring(uchar *s)//行字符函数 { while(*s) wr_data(*s++); } //******************************************* void key() { if(K3==0) { delay(50); if(K3==0) { while(K3==0); } switch(v1) { case 1:f_start=1;TR0=1;TR1=0;led_run=0;led_await=1;led_stop=1;aa=1;bb=0;cc=1;break; v1++; if(v1==4) v1=0; } 33 } case 2:TR0=0;TR1=1;led_run=1;led_await=0;led_stop=1;aa=0;cc=0;break; case 3:TR0=0;TR1=0;led_run=1;led_await=1;led_stop=0;break; if(K4==0) { delay(50); } } //******************************************* void delay(uchar t) { while(--t); } //******************************************* void set(uchar x) { command=0x80+x; wr_com(command); } //******************************************* void set1(uchar y) { command=0xc0+y; wr_com(command); } //******************************************* void key1() { if(K==0) if(K4==0) { while(K4==0); jump_out=1; } 34 { delay(100); if(K==0) { while(K==0); v++; if(v==4) v=0; } } switch(v) { case 0:break; case 1:if(K1==0){while(K1==0);value1=value1+10;}break;//起步价加10 case 2:if(K1==0){while(K1==0);value2=value2+5;}break;//单价加5 case 3:if(K1==0){while(K1==0);value3=value3+5;}break;//停止加5 } if(K2==0) { delay(50); if(K2==0) { while(K2==0); jump_in=1;// } } } 35 因篇幅问题不能全部显示,请点此查看更多更全内容