标题: 51单片机“出租车计费器”proteus仿真 附原理图和汇编语言代码 [打印本页]
作者: yunshuayun 时间: 2020-5-25 08:36
标题: 51单片机“出租车计费器”proteus仿真 附原理图和汇编语言代码
这是我大二辅修计算机学院单片机的最终任务
上大学以来第一次独立完成这样的任务(大二下学期完成了这个任务)特别感谢我的伙伴Mr.关 @黑河豚 备注:代码共300多行,难以忘记那时候和黑河豚天天打代码,不过最终漂亮地完成后那种喜悦非常强烈。
运行视频在此:https://www.bilibili.com/video/BV1gE411L7w2
一. 设计要求
1、用Proteus设计原理图,要求显示出里程,速度,总价
2、用信号发生器来产生出租车的模拟信号,每个脉冲相当于轮胎转了一圈。
3、出租车轮胎周长按1.83米计算。2公里以内按8元计算,超过2公里每公里按2.6元计算。不考虑其他费用。
4、速度的单位为公里/小时,里程的单位为公里(有两位小数)。当信号发生器的输出为10HZ时,速度应该为65.8公里/小时。
二. 设计思路
里程:利用INT0号中断在中断进程中使得寄存器R3每中断一次加一,加满后向R4进位,然后乘以表示轮胎周长的常量Circumference,经过换算后就可以得到十进制的里程数,再将其转移到相应的显示内存中。
速度:同样利用INT0中断每中断一次使得R5加一,再利用计时器记10ms,在记满一秒时将R5中内容转移到R6中,R6中内容是每秒钟轮胎旋转的圈数,可以表示出租车行驶的速度,换算单位和进制后存储在相应的显示内存中,就可以显示速度。
费用:先判断里程是否大于2km,若不大于,则显示为2元,若大于2km,则跳入计费程序,先把里程减去2km,然后剩余的里程与2.6元做乘法,换算进制后储存到相应的显示内存即可。
按钮暂停计费/重新计费:若按钮从未按下到按下,则使循环包括更新显示内容和显示,若按钮松开,则只显示而不更新,若再次按下,则先使得R3;R4;R5;R6内容清零再更新与显示
三. 模块划分
Display:播放程序
Delay:延时程序
Bin:三位16进制数转四位十进制数程序
Calculatemilage:通过R3计算出里程数的程序
nextMilage:将里程数搬入显示内存的程序
CalculateSPEED:通过R6计算速度的程序
nextSPEED:将速度搬入显示内存的程序
CalculatePRICE:通过里程数判断并计算费用的程序
PlayPRICE:将费用搬入显示内存的程序
MAIN:中断设定
WAIT:主循环
Milage:里程,速度中断计数程序
Speed:速度定时读取程序
代码如下:
;作者:云树阿云
;协助者:黑河豚
;指导老师:知足常乐(朱老师)
$NOMOD51
$INCLUDE (8051.MCU)
cDisplayBuffer EQU 30H
cDisplayBit EQU 3CH
Circumference EQU 0B7H
StartpriceH EQU 03H
StartpriceL EQU 20H
PriceL EQU 1AH
ORG 0000H
JMP MAIN
ORG 0003H
JMP Milage
ORG 000BH
JMP Speed
DispTable:
DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH ,0BFH, 86H, 0DBH, 0CFH, 0E6H, 0EDH, 0FDH, 87H, 0FFH, 0EFH
Display:
MOV A, cDisplayBit
MOV P2, A
MOV DPTR, #DispTable
MOV A, #cDisplayBuffer
ADD A, cDisplayBit
MOV R0, A
MOV A, @R0
MOVC A, @A+DPTR
MOV P1, A
INC cDisplayBit
ANL cDisplayBit, #15
RET
Delay:
MOV R0, #10
MOV R1, #10
DJNZ R1, $
DJNZ R0, $-4
RET
Bin:
MOV R0, #42H ;42H为高位字节,43H为低位字节
MOV R1, #45H
CLR A
MOV @R1,A
INC R1
MOV @R1,A
INC R1
MOV @R1,A
INC R1
MOV @R1,A
PUSH 7
MOV R7,#24
BD1:
CLR C
INC R0
INC R0
MOV A,@R0
RLC A
MOV @R0,A
DEC R0
MOV A,@R0
RLC A
MOV @R0,A
DEC R0
MOV A,@R0
RLC A
MOV @R0,A
PUSH 1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
DEC R1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
DEC R1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
DEC R1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
POP 1
DJNZ R7,BD1
POP 7
RET
Calculatemilage:
MOV A,R3
MOV B,#Circumference
MUL AB
MOV 43H,B
MOV 44H,A
MOV A,R4
MOV B,#Circumference
MUL AB
ADD A,43H
MOV 43H,A
MOV A,B
ADDC A,#0
MOV 42H,A
RET
nextMilage:
MOV A,47H
MOV B,#10H
DIV AB
MOV 37H,A
MOV A,46H
MOV B,#10H
DIV AB
MOV 36H,B
ADD A,#10
MOV 35H,A
MOV A,45H
MOV B,#10H
DIV AB
MOV 34H,B
RET
CalculateSPEED:
MOV A,R6
MOV B,#Circumference
MUL AB
MOV 42H,B
MOV B,#24H
MUL AB
MOV 44H,A
MOV 43H,B
MOV A,42H
MOV B,#24H
MUL AB
ADD A,43H
MOV 43H,A
MOV A,B
ADDC A,#0
MOV 42H,A
RET
nextSPEED:
MOV A,47H
MOV B,#10H
DIV AB
MOV 3BH,B
ADD A,#10
MOV 3AH,A
MOV A,46H
MOV B,#10H
DIV AB
MOV 39H,B
MOV 38H,A
RET
CalculatePRICE:
MOV A,34H
CLR C
SUBB A,#1
JNC nextPRICE
CLR C
MOV A,35H
SUBB A,#12
JNC nextPRICE
MOV 42H,#00H
MOV 44H,#StartpriceL
MOV 43H,#StartpriceH
RET
nextPRICE:
CLR C
MOV A,36H
SUBB A,#0
MOV 44H,A
MOV A,35H
SUBB A,#12
MOV 43H,A
MOV A,34H
SUBB A,#0
MOV 42H,A
MOV 46H,#00H
MOV A,44H
MOV B,#1
MUL AB
MOV 45H,A
MOV A,43H
MOV B,#10
MUL AB
ADD A,45H
MOV 45H,A
MOV A,#00
ADDC A,#00
MOV 46H,A
MOV A,42H
MOV B,#100
MUL AB
ADD A,45H
MOV 45H,A
MOV A,46H
ADDC A,#00
ADD A,B
MOV 46H,A
MOV A,45H
MOV B,#priceL
MUL AB
MOV 53H,A
MOV 52H,B
MOV A,46H
MOV B,#priceL
MUL AB
ADD A,52H
MOV 52H,A
MOV A,B
ADDC A,#0
MOV 51H,A
MOV A,53H
ADD A,#StartpriceL
MOV 53H,A
MOV A,52H
ADDC A,#00
ADD A,#StartpriceH
MOV 52H,A
MOV A,51H
ADDC A,#00
MOV 51H,A
MOV 44H,53H
MOV 43H,52H
MOV 42H,51H
RET
PlayPRICE:
MOV A,48H
MOV B,#10H
DIV AB
MOV 33H,B
MOV 32H,A
MOV A,47H
MOV B,#10H
DIV AB
MOV 30H,A
MOV A,B
ADD A,#10
MOV 31H,A
RET
MAIN:
MOV R2,#100
MOV SP,#60H
MOV TMOD,#01H
MOV TL1,#00H
MOV TH1,#0B8H
SETB TR0
SETB ET0
SETB IT0
SETB EX0
SETB EA
DECIDE:
JNB P3.7,WAIT
SJMP DECIDE
WAIT:
LCALL Calculatemilage
LCALL Bin
LCALL nextMilage
LCALL CalculatePRICE
LCALL Bin
LCALL PlayPRICE
LCALL CalculateSPEED
LCALL Bin
LCALL nextSPEED
LCALL Display
LCALL Delay
JNB P3.7,WAIT
STOP:
LCALL Display
LCALL Delay
JNB P3.7,RESTART
SJMP STOP
RESTART:
MOV R3,#00H
MOV R4,#00H
MOV R5,#00H
MOV R6,#00H
SJMP MAIN
Milage:
;MOV 23H,R3
;MOV 24H,R4
;MOV 25H,R5
;PUSH 3
;PUSH 4
;PUSH 5
PUSH PSW
INC R3
INC R5
CJNE R3,#0FFH,OUT
MOV R3,#0
INC R4
OUT:
POP PSW
;POP 25H
;POP 24H
;POP 23H
RETI
Speed:
;MOV 26H,R6
MOV 27H,A
;PUSH 5
;PUSH 6
PUSH 27H
PUSH PSW
MOV TL0,#00H
MOV TH0,#0B8H
DJNZ R2,OUT2
MOV A,R5
MOV R6,A
MOV R2,#100
MOV R5,#00H
OUT2:
POP PSW
POP 27H
;POP 26H
; POP 25H
MOV A,27H
RETI
END
-
_E8ZBV]XVRI[%EQ~E3C%FN4.png
(75.57 KB, 下载次数: 228)
原理图
-
-
云树阿云的出租车计费系统.rar
28.5 KB, 下载次数: 190, 下载积分: 黑币 -5
proteus工程
作者: songxia8013 时间: 2020-5-25 15:32
这速度太快了,能跑到六七百公里每小时,这出租车是飞起来了吗?
作者: yunshuayun 时间: 2020-5-25 18:19
哈哈,这只是用波形测试这个系统正不正常,显示的速度只是来源于频率,不是实际出租车的速度
作者: songxia8013 时间: 2020-5-25 19:23
嗯 知道的 哈哈
作者: rofgmd 时间: 2020-5-29 15:31
你好,可以请想问一下存到内存那段程序的思路嘛,例如以下这段程序
nextMilage:
MOV A,47H
MOV B,#10H
DIV AB
MOV 37H,A
MOV A,46H
MOV B,#10H
DIV AB
MOV 36H,B
ADD A,#10
MOV 35H,A
MOV A,45H
MOV B,#10H
DIV AB
MOV 34H,B
RET
作者: yunshuayun 时间: 2020-5-30 17:34
里程思路:利用INT0号中断在中断进程中使得寄存器R3每中断一次加一,加满后向R4进位,然后乘以表示轮胎周长的常量Circumference,经过换算后就可以得到十进制的里程数,再将其转移到相应的显示内存中。
这段程序是将换算为10进制BCD码的里程(45H,46H,47H)通过除以#10来取十位,个位,并且存入相应的显示单元(34H,35H,36H,37H)
作者: Stranger-- 时间: 2020-6-12 12:36
你好,请问一下为什么Bin那里的R7设置为24吗
作者: Hibari 时间: 2020-6-15 19:32
那个波形器怎么找啊
作者: yunshuayun 时间: 2020-6-20 15:58
不好意思,这一段十六进制变为BCD码的代码是我师傅统一提供的,说来惭愧,具体原理我还不清楚
这是师傅的原始代码
;如果有需要,认真仿真此程序
cDisplayBuffer EQU 30H ;在显示的内容在30H-37H
cDisplayBit EQU 38H ;当前显示的位
cCount EQU 40H
ORG 0000H
LJMP Main
Main:
MOV 42H,#5BH ;把此两内存改为其它值,分析44H,45H,46H的内容
MOV 43H,#4AH
MOV R0,#42H ;42H为高位字节,43H为低位字节
MOV R1,#44H
LCALL BinDec ;结果为6位BCD码,仔细分析 44H,45H,46H的内容
SJMP $
;---------------BinDec---------------------------
; 把双字节的十六进制数转换为BCD码
; 输入: R0 - 十六进制数的高字节地址
; R1 - 转换后BCD码的高位地址
BinDec:
CLR A
MOV @R1,A
INC R1
MOV @R1,A
INC R1
MOV @R1,A
PUSH 7
MOV R7,#16
BD1:
CLR C
INC R0
MOV A,@R0
RLC A
MOV @R0,A
DEC R0
MOV A,@R0
RLC A
MOV @R0,A
PUSH 1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
DEC R1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
DEC R1
MOV A,@R1
ADDC A,@R1
DA A
MOV @R1,A
POP 1
DJNZ R7,BD1
POP 7
RET
;---------------BinDec---------------------------
END
作者: yunshuayun 时间: 2020-6-20 16:07
运行过程中:
调试-VSM signal generator
即可
作者: 1142892859 时间: 2020-6-26 15:01
里程超过10的时候费用溢出了吧
作者: Jeff_BlindCat 时间: 2020-6-27 12:13
汇编菜鸟的菜鸟悄悄的来膜拜下,还是继续先把俺滴C鼓捣明白吧。
作者: yunshuayun 时间: 2020-6-28 14:46
啊!跑了一下发现确实有这个bug,交项目的时候没发现,谢谢你提醒我这个bug!
作者: yunshuayun 时间: 2020-6-29 08:14
加油!
作者: 唐吉坷德 时间: 2020-7-1 12:08
$NOMOD51
$INCLUDE (8051.MCU)
具体指什么
初学小白 望大神指导一下
作者: Rainnny 时间: 2020-7-1 23:20
你好,在一开始定义常数的时候轮胎周长1.83是0B7H,计费的起步价8是0320H,超出的费用2.6是1AH,它们变换的程度不同,在十六进制——BCD码——十进制的过程,小数点的位置是怎么控制到正确显示结果的呢?小白实在不懂
,不知道有没有把问题问清楚,期待大神解答
作者: yunshuayun 时间: 2020-7-2 10:00
这是创建proteus AT89C51工程自带的代码
8051.MCU定义了一些寄存器的名称,更方便使用
; 8051 processor definition file
; ==============================
P0 DATA 080H
SP DATA 081H
DPL DATA 082H
DPH DATA 083H
PCON DATA 087H
TCON DATA 088H
TMOD DATA 089H
TL0 DATA 08AH
TL1 DATA 08BH
TH0 DATA 08CH
TH1 DATA 08DH
P1 DATA 090H
SCON DATA 098H
SBUF DATA 099H
P2 DATA 0A0H
IE DATA 0A8H
P3 DATA 0B0H
IP DATA 0B8H
PSW DATA 0D0H
ACC DATA 0E0H
B DATA 0F0H
IT0 BIT 088H
IE0 BIT 089H
IT1 BIT 08AH
IE1 BIT 08BH
TR0 BIT 08CH
TF0 BIT 08DH
TR1 BIT 08EH
TF1 BIT 08FH
RI BIT 098H
TI BIT 099H
RB8 BIT 09AH
TB8 BIT 09BH
REN BIT 09CH
SM2 BIT 09DH
SM1 BIT 09EH
SM0 BIT 09FH
EX0 BIT 0A8H
ET0 BIT 0A9H
EX1 BIT 0AAH
ET1 BIT 0ABH
ES BIT 0ACH
EA BIT 0AFH
RXD BIT 0B0H
TXD BIT 0B1H
INT0 BIT 0B2H
INT1 BIT 0B3H
T0 BIT 0B4H
T1 BIT 0B5H
WR BIT 0B6H
RD BIT 0B7H
PX0 BIT 0B8H
PT0 BIT 0B9H
PX1 BIT 0BAH
PT1 BIT 0BBH
PS BIT 0BCH
P BIT 0D0H
OV BIT 0D2H
RS0 BIT 0D3H
RS1 BIT 0D4H
F0 BIT 0D5H
AC BIT 0D6H
CY BIT 0D7H
RESET CODE 000H
EXTI0 CODE 003H
TIMER0 CODE 00BH
EXTI1 CODE 013H
TIMER1 CODE 01BH
SINT CODE 023H
作者: 唐吉坷德 时间: 2020-7-16 17:42
为什么有那个DispTable:
DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH ,0BFH, 86H, 0DBH, 0CFH, 0E6H, 0EDH, 0FDH, 87H, 0FFH, 0EFH
作者: yunshuayun 时间: 2020-7-17 10:24
唐吉坷德 发表于 2020-7-16 17:42
为什么有那个DispTable:
DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH ,0BFH, 8 ...
这是用于显示数字和带小数点的数字的表格,每一个数都代表着一个可以用于数码管显示的字符,如:“1,2,3,4等等”
可以了解一下数码管显示的原理
作者: cat_love 时间: 2020-10-27 10:20
请问一下,你的代码是在哪个软件运行的呢
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |