单片机大作业:出租车计费器

一、设计要求

  1. 设计一个出租车计费器程序(含原理图),要求如下:
  2. 用Proteus设计原理图,要求显示出里程,速度,总价
  3. 使用一个按钮,按下按钮开始计费,松开按钮停止计费
  4. 用信号发生器来产生出租车的模拟信号
  5. 提交实验文档和工程文件,作业提交后要找老师答辩才能评定成绩
  6. 出租车轮胎周长按1.83米计算。2公里以内按8元计算,超过2公里每公里按2.6元计算。不考虑其他费用
  7. 要求用汇编语言编程,不能用C编程
  8. 实验文档要写清楚算法,所用到内存的含义

二、设计思路 

  1. 使用外部中断INT0PROC对轮胎转过圈数计数
    1. R3,R4分别表示轮胎转过总圈数的低字节和高字节。
    2. R5表示每秒轮胎转过的圈数,每次计算完速度后清零。
  2. 计算出租车行驶路程DISTANCE
    1. #circumstance内存储#183
    2. 双字节数R4R3乘#circumstance,得到三字节数3FH,3EH,3DH。
  3. 使用定时器计算出租车行驶速度SERVE,SPEED
    1. 使用模式1,晶振频率为22.1184MHZ,单次中断为5ms,200次中断后调用函数SPEED。
    2. v=R5*183*6*6/1000,
    3. 在程序中先进行一次单字节乘法,#circumstance乘#36,结果存储在41H,40H中。
    4. 再进行一次双字节乘乘单字节,41H,40H乘R5,结果存储在47H,46H,45H中。
  4. 计算总费用FEE
    1. 判断路程是否大于2km,如果不大于,就向48H,49H,4AH中分别传入#0CH,#35H,#00H。
    2. 如果路程大于2km,则每次调用FEE函数时计算增加的路程,增加的路程存储在4EH,4FH中。
    3. 增加的路程4FH,4EH乘#26,得出本次调用增加的费用,存储在4DH,4CH,4BH中。
    4. 由于显示程序是三字节转10进制数,而1.83m*0.001m/km*2.6元/km已经有6位小数,如果直接把结果加上原有费用,则费用最多能显示16.77元。所以需要调用DIV1函数对结果除以10。
    5. 得到本次调用增加的费用后,加到原有的费用上再显示数字。
  5. 除法函数DIV1
    1. DIV1是一个除法函数,用于三字节数除以#10,用循环相减法实现。
  6. 显示结果DISDISTANCE、DISSPEED、DISFEE
    1. 把结果的高位、中位、低位分别传给42H、43H、44H。
    2. 再调用把双字节的十六进制数转换为BCD码的函数BinDec。
    3. 调用BinDec后50H~53H共存放了八位数字,根据所得结果小数点的位数,取用八位中的四位数字显示。
    4. 其中,带小数点的数,需要加10显示小数点。
  7. 数码管显示函数Display
    1. DispTable: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH ,0BFH, 86H, 0DBH, 0CFH, 0E6H, 0EDH, 0FDH, 87H, 0FFH, 0EFH;分别对应0-19,其中10+i表示带有小数点的数字i。
  8. 延时函数DELAY
    1. 和Display同时调用用于显示暂停后的费用。
  9. MAIN函数
    1. 设置寄存器、定时器、外部中断和定时器中断
    2. M1循环调用Display; DISTANCE; DISDISTANCE; DISSPEED; FEE; DISFEE;
    3. M2用于暂停显示路费。

三、作品截图

四、代码与相关注释

cDisplayBuffer	EQU		30H		;在显示的内容在30H-37H
cDisplayBit	EQU		3CH		;当前显示的位
circumference   EQU		0B7H

       ORG   	0000H
       LJMP	Main
       ORG	0003H
       LJMP	INT0PROC
       ORG   	000BH
       LJMP	SERVE	

Main:
	  MOV	cDisplayBuffer,#0
	  MOV	cDisplayBuffer+1,#10
	  MOV	cDisplayBuffer+2,#0
	  MOV	cDisplayBuffer+3,#0

	  MOV	cDisplayBuffer+4,#0
	  MOV	cDisplayBuffer+5,#10
	  MOV	cDisplayBuffer+6,#0
	  MOV	cDisplayBuffer+7,#0
	  
	  MOV	cDisplayBuffer+8,#0
	  MOV	cDisplayBuffer+9,#0
	  MOV	cDisplayBuffer+10,#10
	  MOV	cDisplayBuffer+11,#0
;寄存器设置		
	  MOV	R3,#0		;记录轮胎圈数低位
	  MOV	R4,#0		;记录轮胎圈数高位
	  MOV	R5,#0
	  MOV	R6,#0		;200*5MS
;定时器设置      
	  MOV	SP,#60H		;设置堆栈指针
	  MOV	TMOD,#01H	;设置T0工作模式1
	  MOV	TH0,#0DCH	;装计数值高八位
	  MOV	TL0,#000H	;装计数值低八位;5MS

;外部中断		
	  SETB	EX0		;外部0中断允许位
	  SETB	IT0		;
;定时器中断 
	  SETB	TR0      	;启动定时
	  SETB 	ET0      	;T0开中断   	
	  
	  SETB   EA        	;CPU开中断

M1:	
	  LCALL	Display	
	  LCALL	DISTANCE		;计算距离
	  LCALL	DISDISTANCE		;显示距离
	  LCALL	DISSPEED		;显示速度
	  LCALL	FEE			;计算费用
	  LCALL	DISFEE			;显示费用
	  JNB	P3.7,M1
M2:		
	  LCALL	Display
	  LCALL	DELAY
	  JNB	P3.7,Main
	  SJMP	M2
		
;外部中断程序		
INT0PROC:
      PUSH	PSW
      PUSH	ACC
      JB	P3.2,INT2
      LCALL	COUNT		;记录轮胎转过圈数
INT2:
      POP	ACC
      POP	PSW
      RETI
	  
;定时器中断程序
SERVE:  
      PUSH	PSW
      PUSH	ACC
      MOV	TH0,#0DCH
      MOV	TL0,#000H
      CPL	P3.0
      INC	R6
      MOV	A,R6
      CJNE	A,#200,EXIT0
      LCALL	SPEED
      MOV	R6,#0
EXIT0:
      POP	ACC
      POP	PSW
      RETI         
      
;记录轮胎转过圈数
COUNT:
      PUSH	PSW
      PUSH	ACC
      INC	R5
      INC	R3
      MOV	A,R3
      JNZ	COUNT1
      INC	R4
COUNT1:
      POP	ACC
      POP	PSW
	  RET
	
;计算距离		
DISTANCE:

      MOV  	A,R3
      MOV  	B,#circumference
      MUL  	AB
      MOV  	3DH,A
      MOV  	3EH,B
      MOV  	A,R4
      MOV  	B,#circumference
      MUL  	AB
      ADD  	A,3EH
      MOV  	3EH,A
      MOV  	A,B
      ADDC 	A,#0
      MOV  	3FH,A

      RET
      
;计算速度      
SPEED:
      PUSH	ACC
      MOV  	A,#36
      MOV  	B,#circumference
      MUL  	AB      
      MOV  	40H,A
      MOV  	41H,B
      
      MOV  	A,40H
      MOV  	B,R5
      MUL  	AB
      MOV  	45H,A
      MOV  	46H,B
      MOV  	A,41H
      MOV  	B,R5
      MUL  	AB
      ADD  	A,46H
      MOV  	46H,A
      MOV  	A,B
      ADDC 	A,#0
      MOV  	47H,A
      
      MOV  	R5,#0
      POP	ACC
      RET
      
;计算费用
FEE:
      ;R4R3=#1093=#445H
      CLR	C
      MOV	A,R3
      SUBB	A,#45H
      MOV	A,R4
      SUBB	A,#04H
      JNC	MULFEE
      MOV	48H,#00H
      MOV	49H,#35H
      MOV	4AH,#0CH
      MOV	4EH,3DH
      MOV	4FH,3EH
      JMP	EXIT2
MULFEE: 

      CLR	C
      MOV	A,3DH
      SUBB	A,4EH
      MOV	4EH,A
      
      MOV	A,3EH
      SUBB	A,4FH
      MOV	4FH,A
      
      CLR	C
      MOV  	A,4EH
      MOV  	B,#26
      MUL  	AB
      MOV  	4BH,A
      MOV  	4CH,B
      MOV  	A,4FH
      MOV  	B,#26
      MUL 	AB
      ADD  	A,4CH
      MOV  	4CH,A
      MOV  	A,B
      ADDC 	A,#0
      MOV  	4DH,A
            
      LCALL	DIV1	
           
      ;+8
      MOV	4EH,3DH
      MOV	4FH,3EH
      
      CLR	C
      MOV	A,4BH
      ADDC	A,48H
      MOV	48H,A 
      
      MOV	A,4CH
      ADDC	A,49H
      MOV	49H,A    
      
      MOV	A,4DH
      ADDC	A,4AH
      MOV	4AH,A
EXIT2:
      RET
 
DIV1:
      PUSH	0
      PUSH	1
      PUSH	2
      MOV	R0,4BH
      MOV	R1,4CH
      MOV	R2,4DH
      MOV	4BH,#0
      MOV	4CH,#0
      MOV	4DH,#0
LOOP:
      CLR	C
      MOV	A,R0
      SUBB	A,#10
      MOV	R0,A
      MOV	A,R1
      SUBB	A,#0
      MOV	R1,A
      MOV	A,R2
      SUBB	A,#0
      MOV	R2,A
      JC	EXIT3		;C=1跳转

      CLR	C
      MOV	A,4BH
      ADDC	A,#1
      MOV	4BH,A
      MOV	A,4CH
      ADDC	A,#0
      MOV	4CH,A
      MOV	A,4DH
      ADDC	A,#0
      MOV	4DH,A
      SJMP	LOOP
EXIT3:
      POP	2
      POP	1
      POP	0
      RET

;延时程序		
DELAY:
      MOV	R0,#100
      MOV	R1,#10
      DJNZ	R1,$
      DJNZ	R0,$-4
      RET
 
;显示费用				
DISFEE:
		MOV		42H,4AH     ;高位字节
		MOV		43H,49H		;中位
		MOV		44H,48H		;低位
		MOV		R0,#42H
		MOV		R1,#50H
		LCALL	BinDec		
		MOV		A,52H		;
		SWAP	A		
		ANL		A,#0FH
		MOV		33H,A	;千位	
		
		MOV		A,51H		;
		ANL		A,#0FH
		MOV		32H,A	;万位		
		MOV		A,51H
		SWAP	A
		ANL		A,#0FH
	        ADD		A,#10		
		MOV		31H,A	;十万位
		
		MOV		A,50H		;
		ANL		A,#0FH
		MOV		30H,A	;百万位
		RET
DISSPEED:
		MOV		42H,47H     ;高位字节
		MOV		43H,46H		
		MOV		44H,45H		;低位字节
		MOV		R0,#42H
		MOV		R1,#50H
		LCALL	BinDec		
		MOV		A,52H		;
		ANL		A,#0FH
		MOV		3BH,A	;百位
		MOV		A,52H		;
		SWAP	A		
		ANL		A,#0FH
	        ADD		A,#10		
		MOV		3AH,A	;千位	
		
		MOV		A,51H		;
		ANL		A,#0FH
		MOV		39H,A	;万位
		MOV		A,51H
		SWAP	A
		ANL		A,#0FH
		MOV		38H,A	;十万位		
		RET
	 	
DISDISTANCE:
		MOV		42H,3FH     ;高位字节
		MOV		43H,3EH		
		MOV		44H,3DH		;低位字节
		MOV		R0,#42H
		MOV		R1,#50H
		LCALL	BinDec		
		MOV		A,52H		;
		SWAP	A		
		ANL		A,#0FH
		MOV		37H,A	;千位	
		
		MOV		A,51H		;
		ANL		A,#0FH
		MOV		36H,A	;万位
		MOV		A,51H
		SWAP	A
		ANL		A,#0FH
	        ADD		A,#10		
		MOV		35H,A	;十万位
		
		MOV		A,50H		;
		ANL		A,#0FH
		MOV		34H,A	;百万位
		MOV		A,50H		;
		RET


			

;---------------BinDec---------------------------
; 把双字节的十六进制数转换为BCD码
; 输入:   R0 - 十六进制数的高字节地址
;        R1 - 转换后BCD码的高位地址
BinDec:
		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
		
;---------------BinDec---------------------------		
		
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	;12个数
        RET
		END

作者: 公子小白

SOS团团员,非外星人、未来人、超能力者。。。

《单片机大作业:出租车计费器》有3个想法

  1. 请问设计思路中,“判断路程是否大于 2km,如果不大于,就向 48H,49H,4AH 中分别传入 #0CH,#35H,#00H。”是什么意思呢,为什么要放这三个立即数。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注