ORG 100h ; Start address for EMU8086
; Define Ports
PORT_B EQU 12h ; LEDs (Green, Yellow, Red)
BUZZER_PORT EQU 18h ; Buzzer Control Port
; Define LED States
GREEN_LED EQU 01h ; Bit 0
YELLOW_LED EQU 02h ; Bit 1
RED_LED EQU 04h ; Bit 2
; MAIN PROGRAM
START:
CALL INIT ; Initialize system
JMP MAIN_LOOP ; Jump to the main program loop
; Subroutine: Initialize system
INIT:
MOV AL, 0 ; Turn off all LEDs and buzzer
OUT PORT_B, AL ; Clear LED states
OUT BUZZER_PORT, AL ; Turn off buzzer
RET
; MAIN PROGRAM LOOP
MAIN_LOOP:
CALL GET_INPUTS ; Get water level and rain status from user
CALL UPDATE_STATUS ; Update LED and buzzer status
CALL DISPLAY_RESULTS ; Show which LED is active and buzzer state
JMP MAIN_LOOP ; Repeat the loop
; Subroutine: Get inputs from user
GET_INPUTS:
; Prompt user for water level
LEA DX, MSG_WATER_LEVEL_PROMPT
CALL PRINT_STRING
CALL PRINT_NEWLINE
MOV BX, 0 ; Clear BX for water level
READ_WATER_LEVEL:
CALL READ_CHAR
CMP AL, 0Dh ; Check for Enter key (end of input)
JE END_WATER_INPUT
SUB AL, '0' ; Convert ASCII to integer
IMUL BX, 10 ; Multiply current value by 10
ADD BX, AX ; Add new digit
JMP READ_WATER_LEVEL
END_WATER_INPUT:
; Prompt user for rain status
LEA DX, MSG_RAIN_PROMPT
CALL PRINT_STRING
CALL PRINT_NEWLINE
CALL READ_CHAR
SUB AL, '0' ; Convert ASCII to integer
MOV BH, AL ; Store rain status in BH
RET
; Subroutine: Update LED and buzzer status
UPDATE_STATUS:
; Check rain status first
CMP BH, 1 ; Is it raining?
JE RED_ALERT ; If yes, jump to red alert
; Check water level
CMP BX, 30 ; Water level < 30 cm
JL GREEN_LEVEL ; Safe level, turn on green LED
CMP BX, 150 ; Water level <= 150 cm
JLE YELLOW_LEVEL ; Moderate level, turn on yellow LED
; Otherwise, high water level
JMP RED_ALERT
GREEN_LEVEL:
MOV AL, GREEN_LED ; Turn on green LED
OUT PORT_B, AL
MOV AL, 0 ; Turn off buzzer
OUT BUZZER_PORT, AL
MOV DL, 'G' ; G = Green LED
JMP END_UPDATE
YELLOW_LEVEL:
MOV AL, YELLOW_LED ; Turn on yellow LED
OUT PORT_B, AL
MOV AL, 0 ; Turn off buzzer
OUT BUZZER_PORT, AL
MOV DL, 'Y' ; Y = Yellow LED
JMP END_UPDATE
RED_ALERT:
MOV AL, RED_LED ; Turn on red LED
OUT PORT_B, AL
MOV AL, 1 ; Turn on buzzer
OUT BUZZER_PORT, AL
MOV DL, 'R' ; R = Red LED
JMP END_UPDATE
END_UPDATE:
MOV CL, DL ; Store the active LED indicator (G, Y, R) in CL
RET
; Subroutine: Display results
DISPLAY_RESULTS:
; Print active LED
LEA DX, MSG_LED_STATUS
CALL PRINT_STRING
CALL PRINT_NEWLINE
MOV DL, CL ; LED status (G, Y, R)
CALL PRINT_CHAR
CALL PRINT_NEWLINE
; Print buzzer status
LEA DX, MSG_BUZZER_STATUS
CALL PRINT_STRING
CALL PRINT_NEWLINE
IN AL, BUZZER_PORT ; Read buzzer state
CMP AL, 1
JE BUZZER_ON
LEA DX, MSG_BUZZER_OFF
JMP PRINT_BUZZER_MSG
BUZZER_ON:
LEA DX, MSG_BUZZER_ON
PRINT_BUZZER_MSG:
CALL PRINT_STRING
CALL PRINT_NEWLINE
RET
; Subroutine: Print a string
PRINT_STRING:
MOV AH, 09h ; DOS function to display a string
INT 21h
RET
; Subroutine: Print a character
PRINT_CHAR:
MOV AH, 02h ; DOS function to display a single character
INT 21h
RET
; Subroutine: Print a newline
PRINT_NEWLINE:
MOV AH, 02h
MOV DL, 0Dh ; Carriage return
INT 21h
MOV DL, 0Ah ; Line feed
INT 21h
RET
; Subroutine: Read a character from user
READ_CHAR:
MOV AH, 01h ; DOS function to read a character
INT 21h
RET
; Messages
MSG_WATER_LEVEL_PROMPT DB 'Enter water level in cm: $'
MSG_RAIN_PROMPT DB 'Enter rain status (0 = No Rain, 1 = Rain): $'
MSG_LED_STATUS DB 'Active LED: $'
MSG_BUZZER_STATUS DB 'Buzzer is: $'
MSG_BUZZER_ON DB 'ON$', 0
MSG_BUZZER_OFF DB 'OFF$', 0
END START
问题是此代码缺少黄色 LED,例如当用户输入 80 时。它仅显示绿色或红色。最重要的是,蜂鸣器不应该依赖于降雨状况。如果只有红色,则蜂鸣器会响。如何解决这个问题?
我确实改变了电路,但它总是搞砸。我注意到水位可能无法正确读取。当我在模拟器屏幕上添加显示输入水位时,它显示的值与我输入的值不同。例如,当我输入 80 时,它只是将其读取为 0
也许水位杆无法正确读取...例如当我输入80时,它只是将其读取为0
观察力好!
IMUL BX, 10 ; Multiply current value by 10 ADD BX, AX ; Add new digit
emu8086 是 8086 处理器的模拟器,该特定 CPU 不知道
imul bx, 10
。因为 emu8086 也因其许多错误而闻名,所以它很可能接受您的 IMUL BX, 10
并将其编码为简单的 AX * BX。接下来是替换代码:
xor bx, bx ; Clear BX for water level
READ_WATER_LEVEL:
CALL READ_CHAR
CMP AL, 13 ; Check for Enter key (end of input)
JE END_WATER_INPUT
SUB AL, '0' ; Convert ASCII to integer
cbw ; -> AX is [0,9]
xchg ax, bx ; Swap new digit and current value
mov dx, 10
mul dx ; Multiply current value by 10
add bx, ax ; Add new digit
JMP READ_WATER_LEVEL
END_WATER_INPUT:
CMP BH, 1 ; Is it raining? JE RED_ALERT ; If yes, jump to red alert ; Check water level CMP BX, 30 ; Water level < 30 cm
将“下雨状态”置于 BH 中,您正在玩一场危险的游戏。好消息是,它会正常工作,因为您的检查 CMP BX, 30
和
CMP BX, 150
都是在您已经确定 BH 不为 1,因此 BH 为 0 的时刻进行的。但是,请注意,这会限制 water水平(BL)至仅 255 厘米。请勿输入 256 或以上的数字。 您可以轻松选择将 rain status