资源描述
单片机与嵌入式系统应用课程作业
出租车计价器设计
伍龙军 05075 机械设计及理论
2010年7月4日
摘要:本文介绍了利用单片机AT89C52进行出租车计价器的设计的过程,简要介绍了DS1302涓流充电时钟保持芯片的原理与应用,并用Proteus软件仿真。
关键词:出租车计价器,单片机,DS1302
1 引言
随着生活水平的不断提高,越来越多的人在短距离出行时选择乘坐出租车,因此设计一个性能稳定、计费准确、功能强大、使用方便的计价器就成为了人们关心的问题。本文对出租车计价器进行了初步的设计,现有功能基本能满足当前的需求。
2 基本要求
(1)计价功能,在白天与夜间收费标准不同;
(2)时间显示及修改功能。
假设:轮胎每转一圈为0.5m,价格为:白天起价1公里5元,单价每公里1.4元;夜间起价1公里6元,单价每公里1.8元。夜间为22:00~次日06:00前。
3 硬件电路设计
3.1计价器总体硬件结构
计价器总体组成框图如图1所示。
3.2基本外围电路
基本外围电路包括晶振电路和复位电路。晶振采用12MHz,方便计时。由于在Proteus中找不到专用复位芯片,所以采用基本的上电与按钮复位电路。如附录1中所示。
3.3各部分电路
下面介绍各部分电路的设计。
3.3.1计费电路
在实际应用中,常常使用霍尔传感器测距,轮胎每转一圈即发送一个方波。为方便模拟,这里加入一个信号发生器代替霍尔传感器,用来产生汽车行驶产生的方波。而且信号发生器产生的方波信号可以改变频率,就相当于改变了汽车的行驶速度。再加入示波器后,非常便于观察。
采用单片机的T0计数器计数。并将其设置为门控方式,当外部中断0的值为1时打开中断。如电路图中所示,当计价开关闭合后,相当于将“空车”牌按下,从而打开T0计数器中断,从而当方波进入T0后即计数,使金额和里程增加。当计价开关打开后,外部中断0接口的值变为0,又会引发外部中断0,此时调用清零程序,可将金额、里程等值复位。
3.3.2时钟及金额、里程显示电路
该设计采用两片6位8段LED显示器。一片显示当前时间,格式为HH:MM:SS。一片显示金额和里程,分别显示三位:金额显示十元、元和角,里程显示十公里、公里、十分之一公里。当未计费时不显示金额和里程。考虑到实际情况,金额和里程均不会达到100,因此采用6位LED显示已足够。
整个显示过程采用轮流显示每一位的方式,由T1计时器计时,每4ms显示一位。显示内容由P0口输出。用2片2-4译码器74LS139,可将P2口低4位送出的内容译码为16个地址,这里采用其中的12个,代表12位LED的显示地址。
3.3.3按键电路
这里使用了3个按键,分别为:设置按键、+键、-键。当未计费时即可使用这三个键设置时间。按一下设置按键为设置小时,两下设置分钟,三下设置秒钟,第四下保存设置。设置过程中设置指示灯点亮。若在设置过程中开始计费,则设置不会被保存,且指示灯熄灭。
按键分别接入P2口的高3位,由外部中断1响应。当按下按键后即触发外部中断1。由于按键时间相对于单片机响应时间来说非常长,所以此时可根据P2口的高3位判断是哪个按键按下,再在中断程序中做出相应操作。
3.3.4 DS1302芯片接口电路
DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、日期、月、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM 指示决定采用24或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:(1)RES复位,(2)I/O(数据线),(3)SCLK(串行时钟)。时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW。
DS1302是由DS1202改进而来,增加了以下的特性:双电源管脚用于主电源和备份电源供应,Vcc1为可编程涓流充电电源,附加七个字节存储器。它广泛应用于电话、传真、便携式仪器以及电池供电的仪器仪表等产品领域。下面将主要的性能指标作一综合:
实时时钟具有能计算2100 年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力
u 31×8位暂存数据存储RAM
u 串行I/O 口方式使得管脚数量最少
u 宽范围工作电压:2.0~5.5V
u 工作电流:2.0V时,小于300nA
u 读/写时钟或RAM数据时,有两种传送方式:单字节传送和多字节传送(字符组方式)
u 8脚DIP封装或可选的8脚SOIC封装(根据表面装配)
u 简单3 线接口
u 与TTL 兼容(Vcc=5V)
u 可选工业级温度范围-40 度~+85度
u 与DS1202 兼容
u 在DS1202 基础上增加的特性:
− 对Vcc1有可选的涓流充电能力
− 双电源管用于主电源和备份电源供应
− 备份电源管脚可由电池或大容量电容输入
− 附加的7 字节暂存存储器
DS1302 的管脚排列及描述如下图及表所示
管脚描述:
X1,X2 --32.768KHz 晶振管脚
GND --地
RST --复位脚
I/O --数据输入/输出引脚
SCLK --串行时钟
Vcc1,Vcc2 --电源供电管脚
该电路通过从DS1302芯片接收数据获取时间。若时间为夜间(22:00~次日06:00前),则点亮夜间指示灯,并改变价格。
4 程序设计
4.1总体程序框图
如图所示为总体程序框图
4.2子程序设计
子程序主要包括:初始化程序INIT、读取时间程序RDTIME、写入时间程序WTTIME。两个时间程序还需调用:从DS1302读取数据的子程序RECEIVE、从DS1302发送数据的子程序SEND。
初始化程序INIT主要功能是将各项数据赋初值、开中断。
读取时间程序RDTIME则给控制字赋值,然后调用RECEIVE程序,再将返回的值分别保存到小时、分钟、秒钟。最后根据小时对单价作出调整。
写入时间程序WTTIME则给控制字赋值,然后调用SEND程序分别将小时、分钟、秒钟保存到DS1302芯片中。
4.3中断程序设计
中断程序在整个程序中占有最重要到地位。下面分别作介绍。
4.3.1 计数器T0的中断程序
计数器T0的中断程序START框图如下。
在该程序中,接收到第一个脉冲后开始计算里程,将金额设置为起价5元。之后每100个脉冲(50米)对里程做一次加法运算。当脉冲数达到2000个(1公里)后开始对金额递增。
4.3.2外部中断0的中断程序
当计时开关断开后会触发外部中断0,从而调用中断程序CLEAR。该程序将各项数据复位。
4.3.3外部中断1的中断程序
当没有计费且按下按键时触发外部中断1。首先判断按下哪个键。
若按下设置键则改变设置类型。按一次设置键,则设置小时;按两次则设置分钟;按三次设置秒钟;按四次则调用WTTIME程序将设置好的值写入DS1302芯片中。
若按下+键,则判断设置类型,根据设置类型分别对小时、分钟、秒钟加一。
若按下-键,则根据设置类型分别对小时、分钟、秒钟减一。
4.3.4定时器T1的中断程序
定时器T1的中断程序即为显示程序。该程序每4ms显示一位。若没有处于设置时间状态,则每秒钟读取一次时间;否则不读取时间,只显示当前值,以便于对时间进行设置。
显示程序轮流对12位LED进行显示,并在适当地方加上小数点。若没有计费,则不显示金额和里程。流程图见下页。
5总结
该设计实现了计价器的基本功能。若要进行扩展,可在以下方面进行考虑:语音功能、打印功能、防作弊功能、IC卡的使用以及其它对系统的保护功能等。
通过这次设计,我对8051系列单片机的内部结构、存储空间有了更深入细致的了解,对汇编程序的编写及中断的应用更加熟练;通过对DS1302芯片、LED显示器和按键的使用,对接口技术对应用有了初步的认识。希望今后通过努力,使自己对该课程知识及应用能达到熟练掌握直至精通的程度。
附录1:电路图
附录2:计价效果图(晚上时间21:09:10,公里数为8.4,价格为15.3)
附录3:时间设置效果图(当前时间:21:24:20,设置时间:23:37:56)
附录4:源代码
;*************************************
;出租车计价器程序
;05075,伍龙军
;2006.7.9-7.13
;************************************
;各项常量
;**********************************
PRICE EQU 1FH ;保存单价地址
PULSE EQU 1EH ;保存脉冲数的地址
TURN EQU 1DH ;显示轮换记录器,为12时显示小时十位,为11时显示小时个位,依次类推
RDTM EQU 1CH ;读取时间计数器,0.5秒钟读一次
SUMYUAN EQU 1BH ;保存金额元(BCD码)地址
SUMJF EQU 1AH ;保存金额角和分(BCD码)地址
DISM EQU 19H ;保存路程公里数地址
DISF EQU 18H ;保存路程小数地址
TIMEH EQU 17H ;保存时间小时地址
TIMEM EQU 16H ;保存时间分钟地址
TIMES EQU 15H ;保存时间秒钟地址
BITCNT EQU 14H ;保存传输位的地址
CMD EQU 13H ;保存命令字的地址
RCV EQU 12H ;接收数据缓冲区的地址
SND EQU 11H ;发送数据缓冲区的地址
SETTM EQU 10H ;设置时间
SPRICE EQU 09H ;保存起价地址
HOUR1 EQU 0FH ;小时十位显示地址
HOUR0 EQU 0EH ;小时个位显示地址
MIN1 EQU 0DH ;分钟十位显示地址
MIN0 EQU 0CH ;分钟个位显示地址
SEC1 EQU 0BH ;秒钟十位显示地址
SEC0 EQU 0AH ;秒钟个位显示地址
TENY EQU 09H ;金额十元显示地址
ONEY EQU 08H ;金额元显示地址
TENTHY EQU 07H ;金额角显示地址
TENM EQU 06H ;路程十公里显示地址
ONEM EQU 05H ;路程公里显示地址
TENTHM EQU 04H ;路程十分之一公里显示地址
DSIO BIT P1.0 ;DS1302的数据传送总线地址
DSCLK BIT P1.1 ;DS1302的时钟控制总线地址
DSRST BIT P1.2 ;DS1302的复位总线地址
LEDNT BIT P1.7 ;夜晚指示灯
LEDSET BIT P1.6 ;设置时间指示灯
STTM BIT P2.5 ;设置按键口
STADD BIT P2.6 ;时间增加按键口
STDEC BIT P2.7 ;时间减少按键口
;*********************************
;程序开始
;********************************
ORG 0000H
AJMP MAIN
ORG 0003H ;外部中断0程序,清零
AJMP CLEAR
ORG 000BH ;T0中断程序,计价,计里程
AJMP START
ORG 0013H
AJMP BUTTON ;外部中断1程序,响应按键
ORG 001BH ;T1中断程序,显示
AJMP DISP
MAIN: ACALL INIT
AJMP $
;**************************************************************************
;子程序
;******************************
;初始化程序
;设置初值,开中断
;******************************
INIT: MOV SP,#30H ;设置堆栈到用户RAM区
MOV DPTR,#TAB
MOV PRICE,#07H
MOV SPRICE,#05H
CLR LEDNT
CLR LEDSET
MOV SETTM,#4
MOV TURN,#12
MOV SUMYUAN,#0ABH ;金额为0
MOV SUMJF,#0AAH
MOV DISM,#0ABH ;路程为0
MOV DISF,#0AAH
MOV PULSE,#22
ACALL RDTIME ;读取时间
MOV RDTM,#250 ;读取时间计数器初值
MOV TMOD,#00011101B ;T1以方式1计时,非门控方式
;T0以方式1计数,门控方式
SETB TR0 ;T0采用门控方式
SETB IT0 ;外部中断0为边沿触发方式
SETB IT1 ;外部中断1为边沿触发方式
CLR P3.2
MOV TH1,#0F0H ;4ms产生一次中断
MOV TL1,#060H
MOV TH0,#0FFH ;第一个脉冲发生中断赋初值
MOV TL0,#0FFH
SETB EA ;开CPU中断
SETB EX0 ;开外部中断0
SETB EX1 ;开外部中断1
SETB ET0 ;开T0中断
SETB ET1 ;开T1中断
SETB TR1 ;T1计时开始
RET
;******************************
;RDTIME读取时间程序
;从DS1302读取时间
;******************************
RDTIME: MOV CMD,#85H ;接收小时控制字#85H
ACALL RECEIVE
MOV TIMEH,RCV
MOV CMD,#83H ;接收分钟控制字#83H
ACALL RECEIVE
MOV TIMEM,RCV
MOV CMD,#81H ;接收秒钟控制字#81H
ACALL RECEIVE
MOV TIMES,RCV
MOV A,TIMEH ;判断时间,
;若在6点之前或22点之后,价格改变
CJNE A,#06H,$+3
JNC SKIP6
MOV PRICE,#09H ;6点之前
MOV SPRICE,#06H
SETB LEDNT
AJMP NIGHT
SKIP6: CJNE A,#22H,$+3
JC DAY
MOV PRICE,#09H ;22点之后
MOV SPRICE,#06H
SETB LEDNT
AJMP NIGHT
DAY: MOV PRICE,#07H ;白天
MOV SPRICE,#05H
CLR LEDNT
NIGHT: RET
;********************************
;WTTIME写入时间程序
;将调整的时间输入DS1302
;*******************************
WTTIME: MOV CMD,#84H ;发送小时控制字#84H
MOV SND,TIMEH
ACALL SEND
MOV CMD,#82H ;发送分钟控制字#82H
MOV SND,TIMEM
ACALL SEND
MOV CMD,#80H ;发送秒钟控制字#80H
MOV SND,TIMES
ACALL SEND
RET
;********************************
;从DS1302读出数据的程序
;*******************************
RECEIVE:
CLR DSRST ;复位引脚为低电平,所有数据传送终止
NOP
CLR DSCLK ;清时钟总线
NOP
SETB DSRST ;复位引脚为高电平,逻辑控制有效
NOP
MOV A,CMD ;准备发送命令字节
MOV BITCNT,#8 ;命令字节为8位
RB0: RRC A ;将最低位传送给进位位C
MOV DSIO,C ;位传送至数据总线
NOP
SETB DSCLK ;时钟上升沿,发送数据有效
NOP
CLR DSCLK ;清时钟总线
DJNZ BITCNT,RB0 ;位传送未完毕则继续
NOP ;准备接收数据
CLR A ;清累加器
CLR C ;清进位位C
MOV BITCNT,#8 ;接收位数为8位
RB1: NOP
MOV C,DSIO ;数据总线上的数据传送给C
RRC A ;从最低位接收数据
SETB DSCLK ;时钟总线置高
NOP
CLR DSCLK ;时钟下降沿接收数据有效
DJNZ BITCNT,RB1 ;接收未完成则继续
NOP
CLR DSRST ;逻辑操作完毕,清RST
MOV RCV,A ;接收到的完整数据字节
;放入接收数据缓冲区
RET
;*******************************
;向DS1302写入数据的程序
;******************************
SEND: CLR DSRST ;复位引脚为低电平,所有数据传送终止
NOP
CLR DSCLK ;清时钟总线
NOP
SETB DSRST ;复位引脚为高电平,逻辑控制有效
NOP
MOV A,CMD ;准备发送命令字节
MOV BITCNT,#8
SB0: RRC A
MOV DSIO,C
NOP
SETB DSCLK
NOP
CLR DSCLK
DJNZ BITCNT,SB0
NOP
MOV A,SND ;准备发送数据,过程与上面相同
MOV BITCNT,#8
SB1: RRC A
MOV DSIO,C
NOP
SETB DSCLK
NOP
CLR DSCLK
DJNZ BITCNT,SB1
NOP
CLR DSRST
RET
;************************************************************************
;以下为中断程序
;********************************
;T0的中断程序
;来一个脉冲记一次数
;*******************************
START: MOV TH0,#0FFH ;每100个脉冲(50米)计一次
MOV TL0,#09CH
MOV SETTM,#4
CLR LEDSET
MOV A,PULSE
CJNE A,#22,NEXT ;价格初始化
MOV SUMYUAN,SPRICE ;起价
MOV SUMJF,#00H
MOV DISM,#00H ;路程为0
MOV DISF,#00H
MOV PULSE,#21
AJMP SKIPCT
NEXT: MOV A,DISF ;每100个脉冲增加50米
ADD A,#5
DA A
MOV DISF,A
MOV A,DISM
ADDC A,#0
DA A
MOV DISM,A
DJNZ PULSE,SKIPCT ;未到1公里(20*100个脉冲)不计费
MOV A,SUMJF ;计算角和分
ADD A,PRICE ;加7分钱,夜间加9分
DA A ;调整为BCD码
MOV SUMJF,A ;保存
MOV A,SUMYUAN ;计算元
ADDC A,#0 ;加进位
DA A ;调整
MOV SUMYUAN,A ;保存
MOV PULSE,#1
SKIPCT: RETI
;********************************
;外部中断0中断程序
;将金额和路程清零
;********************************
CLEAR: MOV SETTM,#4
MOV SUMYUAN,#0ABH
MOV SUMJF,#0AAH
MOV DISM,#0ABH
MOV DISF,#0AAH
MOV PULSE,#22
MOV TH0,#0FFH ;第一个脉冲发生中断赋初值
MOV TL0,#0FFH
RETI
;*********************************
;外部中断1程序BUTTON
;按键程序,判断是哪一个按键按下,并作出相应设置
;********************************
BUTTON: MOV A,P2
ANL A,#0E0H ;取P2的最高三位
CJNE A,#0C0H,SETAD ;第5位为0时为设置键
DJNZ SETTM,ST ;若按到第4为设置时间成功
CLR LEDSET ;设置灯熄灭
ACALL WTTIME ;设置时间
MOV SETTM,#4
AJMP SKIPST
ST: SETB LEDSET ;按1次为小时设置,2次为分钟设置,
;3次为秒钟设置
AJMP SKIPST
SETAD: CJNE A,#0A0H,SETDE ;第6位为0时为增加键
MOV A,SETTM
CJNE A,#3,ADDM ;为3时设置小时
MOV A,TIMEH
INC A
DA A
CJNE A,#24H,HLT24
MOV A,#0
HLT24: MOV TIMEH,A
AJMP SKIPST
ADDM: CJNE A,#2,ADDS ;为2时设置分钟
MOV A,TIMEM
INC A
DA A
CJNE A,#60H,MLT60
MOV A,#0
MLT60: MOV TIMEM,A
AJMP SKIPST
ADDS: CJNE A,#1,SKIPST ;为1时设置秒钟
MOV A,TIMES
INC A
DA A
CJNE A,#60H,SLT60
MOV A,#0
SLT60: MOV TIMES,A
AJMP SKIPST
SETDE: MOV A,SETTM ;第7位为0时为减少键
CJNE A,#3,DECM
MOV A,#99H
ADD A,TIMEH
DA A
CJNE A,#99H,HGT0
MOV A,#23H
HGT0: MOV TIMEH,A
AJMP SKIPST
DECM: CJNE A,#2,DECS
MOV A,#99H
ADD A,TIMEM
DA A
CJNE A,#99H,MGT0
MOV A,#59H
MGT0: MOV TIMEM,A
AJMP SKIPST
DECS: CJNE A,#1,SKIPST
MOV A,#99H
ADD A,TIMES
DA A
CJNE A,#99H,SGT0
MOV A,#59H
SGT0: MOV TIMES,A
SKIPST: RETI
;********************************
;T1的中断程序
;轮流显示LED每一位
;*********************************
DISP: MOV TH1,#0F0H ;恢复初值
MOV TL1,#060H
MOV A,SETTM
CJNE A,#4,HR1
展开阅读全文