EMU8086编码:多级水位传感器和雨量传感器

问题描述 投票:0回答:1
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

assembly x86-16 emu8086
1个回答
0
投票

也许水位杆无法正确读取...例如当我输入80时,它只是将其读取为0

观察力好!

IMUL BX, 10           ; Multiply current value by 10
ADD  BX, AX           ; Add new digit

emu8086 是 处理器的模拟器,该特定 CPU 不知道

imul bx, 10
。因为 emu8086 也因其许多错误而闻名,所以它很可能接受您的
IMUL BX, 10
并将其编码为简单的 AX * BX。
此外,新数字的添加是添加 AH 寄存器中的任何内容。你应该事先确保AH已清空。

接下来是替换代码:

    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
放入 CH 寄存器中。

© www.soinside.com 2019 - 2024. All rights reserved.