


以上是實驗箱、實驗要求以及我的設計電路。
運行了很多遍,好像是卡在了某一個回圈,輸出不來東西。
這是我的設計思路:
1.8253輸出周期為兩秒的固定頻率脈沖(方式二)
2.CL存放每一層的樓層回應狀態,例如一層回應為00000001B,一層、五層、七層回應為01010001B,CH存放當前層,默認為4層,及00001000B
3.鍵盤每次按下就更新CL,并重新初始化8253,重新計數,否則等待2秒時間到,判斷CL是否為00H,若是,就繼續在鍵盤這里回圈,等待按鍵,否則跳轉去讓電機、LCD變化
4.在電梯運動時,首先判斷當前樓層以上是否為0,若為0,則跳轉至下降運動,否則就開始上升運動,下降則判斷當前樓層以下是否為0,若為0則說明CL已經是00H,回到上述鍵盤處回圈(所以我設計的這個電梯的弊端在不能按照就近原則載人,若當前為4樓,3樓和7樓都有人按鍵,電梯只能先去7樓)
5.在電梯運動時可以按除了開關門以外的鍵,更新CL的值,此時按鍵不會重新計數。
uj5u.com熱心網友回復:
這是我的代碼:IO8255A EQU 280H
IO8255B EQU 281H
IO8255C EQU 282H
IO8255KZ EQU 283H
IO0832 EQU 288H
IO82530 EQU 290H
IO82531 EQU 291H
IO8253KZ EQU 293H
DATA SEGMENT
HZ_TAB DW 0A1A0H,0A1A0H,0A1A0H,0A1A0H,0A1A0H,0A1A0H,0A1A0H,0A1A0H
HZ_ADR DB ? ;存放顯示行起始埠地址
TABLE DB 77H,7BH,7DH,7EH,0B7H,0BBH,0BDH,0BEH
DB 0D7H,0DBH,0DDH,0DEH,0E7H,0EBH,0EDH,0EEH
DATA ENDS
STACK SEGMENT STACK
DW 50 DUP(0)
TOP_STACK LABEL WORD
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,STACK
MOV SS,AX
LEA SP,TOP_STACK
MOV AX,DATA
MOV DS,AX
MOV DX, IO8255KZ
MOV AL,80H
CALL CLEAR
LEA BX, HZ_TAB
MOV BYTE PTR HZ_ADR, 88H
CALL LCD_DISP ;LCD_DISP的作用是將某一行的顯示用HZ_TAB的內容表示,這里是將88H及第三行用“?”表示,達到清屏效果
LEA BX, HZ_TAB
MOV BYTE PTR HZ_ADR, 90H ;這是第二行
CALL LCD_DISP ;以上是初始化,將LCD第二、三行清空
MOV BYTE PTR HZ_ADR, 8BH
MOV AX,0A3B4H ;LCD 8BH位置顯示樓層數 這里顯示初始樓層4層
CALL LCD_PLAY ;LCD_PLAY的作用是向LCD某一個埠輸送數值,這里是向8BH輸送0A3B4H,效果是顯示4在第三行中間位置
MOV CL,00H ;CL存放1-8層樓是否回應的狀態0/1
MOV CH,08H ;CH存放當前的樓層數
DEL: ;8253輸出兩秒周期的固定頻率脈沖(方式二)
MOV DX,IO8253KZ
MOV AL,00110111B
OUT DX,AL
MOV DX,IO82530
MOV AL,00H
OUT DX,AL
MOV AL,80H
OUT DX,AL
MOV DX,IO8253KZ
MOV AL,01110101B
OUT DX,AL
MOV DX,IO82531
MOV AL,00H
OUT DX,AL
MOV AL,05H
OUT DX,AL
DEL_0: ;若8253輸出為1,則跳轉T2,否則跳轉T0
MOV DX,IO8255KZ
MOV AL,81H
OUT DX,AL
MOV DX,IO8255C
IN AL,DX
AND AL,08H
CMP AL,08H
JZ T2
JNZ T0
T0: CMP CL,00H ;在8253輸出為0時,及兩秒時間到,判斷此時CL中各樓層回應狀態是否更新,
;有則跳轉DIANJI_UP電機、LCD開始變化,否則回DEL_0繼續進行判斷
JZ DEL_0
JNZ DIANJI_UP
T1: MOV BYTE PTR HZ_ADR, 93H ;LCD 93H位置顯示電梯的上升下降標志,這里先清空,因為還沒開始運動
MOV AX,0A1A0H
CALL LCD_PLAY
T2: MOV DX,IO8255KZ ;這里開始是鍵盤的匯編代碼
MOV AL,10000011B
OUT DX,AL
MOV DX,IO8255C
MOV AL,00H
OUT DX,AL
MOV DX,IO8255B
WAIT_OPEN: IN AL,DX ;確認所有鍵是否松開,否,則進入回圈
AND AL,0FH
CMP AL,0FH
JNE WAIT_OPEN
WAIT_PRES: ;判斷是否有鍵壓下
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE DEL_0 ;若無,則進入DEL_0讀秒,若兩秒內無鍵壓下,且CL不為00H,就進行電機、LCD的變化
MOV BX,16EAH
DELAY_0: DEC BX ;消除鍵盤抖動,20ms
JNZ DELAY_0
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES
MOV AL,0EFH
MOV AH,AL
NEXT_ROW: MOV DX,IO8255C
OUT DX,AL
MOV DX,IO8255B
IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE ENCODE
ROL AH,01
MOV AL,AH
JMP NEXT_ROW
ENCODE:
MOV BX,000FH
IN AL,DX
NEXT_TRY: CMP AL,TABLE[BX]
JE DONE
DEC BX
JNS NEXT_TRY
DONE: ;最終,鍵盤所按下的值存放在BL中
CMP BL,09H
JC PD1
CMP BL,0CH
JNC PD2
PD1: CALL PAND1 ;PAND1是將BL所存的樓層數轉換為該樓層的回應狀態存放到CL里,1樓按下就OR CL,01H,4樓按下就是OR CL,08H
JMP DEL
PD2: CALL PAND2 ;PAND2處理C、D、E、F,C和D表示一樓的狀態(OR CL,01H)
;同理E和F為五樓的(其實C和D,E和F功能一樣,設定上下是為了還原)
JMP DEL ;更新完CL,因為有鍵按下,回到8253的初始化,重新初始化,這是為了重新開始兩秒的計數,還原電梯每次按下鍵之后會再等幾秒
DIANJI_UP:
CMP CL,00H
JZ T1 ;確保CL不為0
MOV AH,CH
MOV AL,CH
U1: ROL AH,01H
CMP AH,01H
JNZ U2
JZ U3
U2: OR AL,AH
JMP U1
U3: MOV AH,CL
AND AH,AL
CMP AH,00H
JZ D0 ;從JZ T1到這里的代碼的作用是判斷從當前樓層向上的狀態是否為0
;為0則說明不需要往上運動了,跳轉至電梯下降代碼,下降代碼也同理
MOV BYTE PTR HZ_ADR, 93H
MOV AX,0A1C4H
CALL LCD_PLAY ;在LCD 93H及數字的上方顯示上升下降按鈕,下降代碼也同理
U4: MOV AH,CH
NOT AH
MOV AL,CL
AND AL,CH
CMP AL,00H ;判斷狀態CL中,當前樓層狀態是否為1,以確定是否在這一樓層停留
JZ U6
JNZ U5
D0: JMP DIANJI_DOWN
U5: AND CL,AH ;若為1,現將當前樓層狀態歸0,然后跳轉U8停止電機運動,并回到T1重新進行電梯是否開始運動的判斷
JMP U8
U6: MOV AL,081H ;否則電機開始運動
MOV DX,IO0832
OUT DX,AL
MOV BYTE PTR HZ_ADR, 8BH
MOV AL,CH
MOV AH,00H
U7: ROR AL,01H
INC AH
CMP AL,80H
JNZ U7
MOV BX,0A3B0H
ADD BL,AH
MOV AX,BX
CALL LCD_PLAY ;以上代碼是將當前樓層CH狀態轉換為樓層數字,然后在LCD中顯示出來
ROL CH,01H ;再更新CH的樓層號為下一樓層
DEL_1: ;以下是鍵盤代碼,與前面的鍵盤代碼的不同之處在于,這里不重新初始化8253,及電梯在運動程序中可以按除了開關門外的鍵
;及更新CL的值,但是不會重新讀秒,只有在電梯停止時,每次按鍵才會重新開始2秒的計數
MOV DX,IO8255KZ
MOV AL,81H
OUT DX,AL
MOV DX,IO8255C
IN AL,DX
AND AL,08H
CMP AL,08H
JZ X2
JNZ DIANJI_UP
X2: MOV DX,IO8255KZ
MOV AL,10000011B
OUT DX,AL
MOV DX,IO8255C
MOV AL,00H
OUT DX,AL
MOV DX,IO8255B
WAIT_OPEN1: IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE WAIT_OPEN1
WAIT_PRES1:
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE DEL_1
MOV BX,16EAH
DELAY_01: DEC BX
JNZ DELAY_01
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES1
MOV AL,0EFH
MOV AH,AL
NEXT_ROW1: MOV DX,IO8255C
OUT DX,AL
MOV DX,IO8255B
IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE ENCODE1
ROL AH,01
MOV AL,AH
JMP NEXT_ROW1
ENCODE1:
MOV BX,000FH
IN AL,DX
NEXT_TRY1: CMP AL,TABLE[BX]
JE DONE1
DEC BX
JNS NEXT_TRY1
DONE1:
CMP BL,09H
JC JP1
CMP BL,0CH
JNC JP2
JP1: CALL PAND1
JMP DEL_1
JP2: CALL PAND2
JMP DEL_1 ;因此此處只用跳轉到DEL_1判斷即可
U8: MOV DX,IO0832
MOV AL,00H
OUT DX,AL
MOV BYTE PTR HZ_ADR, 8BH
MOV AL,CH
MOV AH,00H
U9: ROR AL,01H
INC AH
CMP AL,80H
JNZ U9
MOV BX,0A3B0H
ADD BL,AH
MOV AX,BX
CALL LCD_PLAY ;以上是電梯停止之后顯示當前樓層數的代碼
JMP T1
DIANJI_DOWN: ;還沒寫好,開關門代碼也沒寫好
LCD_DISP PROC
PUSH CX
MOV CL,8
CONTINUE:
MOV AL,HZ_ADR
MOV DX, IO8255A
OUT DX, AL
CALL CMD_SETUP
MOV AX,HZ_TAB[BX]
PUSH AX
MOV AL,AH
MOV DX, IO8255A
OUT DX,AL
CALL DATA_SETUP
CALL DELAY
POP AX
MOV DX, IO8255A
OUT DX, AL
CALL DATA_SETUP
CALL DELAY
INC BX
INC BX
INC BYTE PTR HZ_ADR
DEC CL
JNZ CONTINUE
POP CX
RET
LCD_DISP ENDP
LCD_PLAY PROC
PUSH AX
MOV DX,IO8255KZ
MOV AL,80H
OUT DX,AL
MOV AL,HZ_ADR
MOV DX, IO8255A
OUT DX, AL
CALL CMD_SETUP
POP AX
PUSH AX
MOV AL,AH
MOV DX, IO8255A
OUT DX,AL
CALL DATA_SETUP
CALL DELAY
POP AX
MOV DX, IO8255A
OUT DX, AL
CALL DATA_SETUP
CALL DELAY
LCD_PLAY ENDP
uj5u.com熱心網友回復:
PAND1 PROCMOV AL,10000000B
PUSH CX
MOV CL,BL
ROL AL,CL
POP CX
MOV AH,CL
AND AH,AL
CMP AH,00H
JZ PDS1
JNZ PDS2
PDS1: OR CL,AL
JMP PDS3
PDS2: NOT AL
AND CL,AL
JMP PDS3
PDS3: NOP
PAND1 ENDP
PAND2 PROC
CMP BL,0CH
JZ PDT1
CMP BL,0DH
JZ PDT2
CMP BL,0EH
JZ PDT3
CMP BL,0FH
JZ PDT4
PDT1:
MOV AL,01H
OR CL,AL
JMP PDTE
PDT2:
MOV AL,01H
OR CL,AL
JMP PDTE
PDT3:
MOV AL,10H
OR CL,AL
JMP PDTE
PDT4:
MOV AL,10H
OR CL,AL
JMP PDTE
PDTE: NOP
PAND2 ENDP
DELAY PROC
PUSH CX
PUSH DX
MOV CX, 0FFFFH
X3: LOOP X3
POP DX
POP CX
RET
DELAY ENDP
CLEAR PROC
MOV AL,0CH
MOV DX, IO8255A
OUT DX,AL
CALL CMD_SETUP
RET
CLEAR ENDP
CMD_SETUP PROC
PUSH AX
MOV DX, IO8255C ;指向8255埠控制埠
NOP
MOV AL,00000000B ;PC1置0,pc0置0 (LCD I端=0,W端=0)
OUT DX, AL
CALL DELAY
NOP
MOV AL,00000100B ;PC2置1 (LCD E端=1)
OUT DX, AL
NOP
CALL DELAY
MOV AL, 00000000B ;PC2置0,(LCD E端置0)
OUT DX, AL
CALL DELAY
POP AX
RET
CMD_SETUP ENDP
DATA_SETUP PROC
PUSH AX
MOV DX, IO8255C ;指向8255控制埠
MOV AL,00000001B ;PC1置0,PC0=1 (LCD I端=1)
OUT DX, AL
NOP
CALL DELAY
MOV AL,00000101B ;PC2置1 (LCD E端=1)
OUT DX, AL
NOP
CALL DELAY
MOV AL, 00000001B ;PC2置0,(LCD E端=0)
OUT DX, AL
NOP
CALL DELAY
POP AX
RET
DATA_SETUP ENDP
CODE ENDS
END
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/238191.html
標籤:匯編語言
上一篇:abap 選擇畫面上的checkbox怎么控制alv結果畫面欄位出力
下一篇:回文聯:
