標題: 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)
下載附件
2020-5-25 08:26 上傳
原理圖
-
-
云樹阿云的出租車計費系統.rar
2020-5-25 08:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
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.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |