Assembly Language for MCU 8051 IDE with AT89S52 microcontroller

105 views Asked by At

I have a question about assembly language for MCU 8051 IDE using AT89S52 microcontroller. Write a program that replicate a pedestrian crossing light with one button input. The system will be in STOP state until a button is pressed. After a delay, the state will transit to GO state and will stay in this state for a longer delay. Then the system will transit back to STOP state. Anyone have idea to solve it? Appreciate it a lot.

Here is my code. It was not working as my expectation. As I mentioned before, I am using MCU 8051 IDE with AT89S52 microcontroller. When I run the program, the LEDs I connected to P1.0 and P1.1 is lighting on. When I pressed the push button, after some time, the LEDs for P1.0 light off. And didn't light up anymore. LEDs for P1.1 still continue lighting on. Where is my error in this case?

    ORG 00H ; Start of code memory
    
    MOV A,#00H
    MOV P1,A    ; SET PORT 1 AS OUTPUT PORT
    MOV A,#0FFH
    MOV P2,A    ; SET PORT 2 AS INPUT PORT
    
WAIT_FOR_BUTTON_PRESS:
    MOV R2, #03H  ; Initialize a counter for stable button state

CHECK_BUTTON_STATE:
    JNB P2.0, BUTTON_RELEASED  ; If the button is released, proceed
    CALL DELAY_MS  ; Introduce a small delay
    JB P2.0, CHECK_BUTTON_STATE  ; If the button is still pressed, continue checking
    DEC R2  ; Decrement the counter
    JZ BUTTON_PRESSED  ; If the button state is stable, consider it pressed

BUTTON_RELEASED:
    MOV R2, #03H  ; Reset the counter if the button is released
    SJMP WAIT_FOR_BUTTON_PRESS  ; Continue waiting for a button press

BUTTON_PRESSED:
    MOV P1, #01H  ; Set initial state to STOP
    CALL DELAY_SEC  ; Wait for a delay

TRAFFIC_LIGHT_LOOP:
    MOV P1, #02H    ; Set state to GO
    CALL DELAY_SEC  ; Wait for a longer delay

    MOV P1, #01H    ; Set state to STOP
    CALL DELAY_SEC  ; Wait for a delay

    SJMP TRAFFIC_LIGHT_LOOP ; Repeat the traffic light sequence

DELAY_MS:
    MOV R1, #5
    
DELAY_MS_LOOP:
    MOV R0, #50
    
DELAY_LOOP:
    DJNZ R0, DELAY_LOOP
    DJNZ R1, DELAY_MS_LOOP
    RET

DELAY_SEC:
        MOV R1, #5
DELAY_SEC_LOOP:
    CALL DELAY_MS   ; Call the millisecond delay routine
    DJNZ R1, DELAY_SEC_LOOP
    RET

    END

Anyone found out my error in the code above? Thank you.

1

There are 1 answers

0
Erik Eidt On

There's no exit condition test in the loop TRAFFIC_LIGHT_LOOP:, so why are you expecting that to do other than what that loop body does, forever?

(Only by using interrupts can you exit that loop as it stands, but you have said and shown nothing about setting up a timer or other interrupt.)