Program UTS Wisnu

 avatar
unknown
assembly_x86
3 days ago
5.2 kB
4
Indexable
.INCLUDE "m328def.inc"

.DEF temp       = r16
.DEF result     = r17
.DEF disp_val   = r18
.DEF digit1_pat = r19
.DEF digit2_pat = r20
.DEF digit3_pat = r21
.DEF d_tens     = r22
.DEF d_units    = r23
.DEF temp2      = r24
.DEF dly_cnt_1  = r25
.DEF dly_cnt_2  = r26

.EQU SEG_A = 6
.EQU SEG_B = 5
.EQU SEG_C = 4
.EQU SEG_D = 3
.EQU SEG_E = 2
.EQU SEG_F = 1
.EQU SEG_G = 0
.EQU SS1_PIN = PB3
.EQU SS2_PIN = PB2
.EQU SS3_PIN = PB1
.EQU BTN1_PIN = PD2
.EQU BTN2_PIN = PD3
.EQU SEG_MINUS = (1<<SEG_G)
.EQU SEG_BLANK = 0x00
.EQU ALL_DIGITS_OFF = (1<<SS1_PIN)|(1<<SS2_PIN)|(1<<SS3_PIN)

.DSEG
current_digit: .BYTE 1

.CSEG

.ORG 0x0000
    RJMP RESET
.ORG INT0addr
    RJMP INT0_ISR
.ORG INT1addr
    RJMP INT1_ISR
.ORG OVF0addr
    RJMP TIMER0_OVF_ISR

RESET:
    LDI temp, HIGH(RAMEND)
    OUT SPH, temp
    LDI temp, LOW(RAMEND)
    OUT SPL, temp

    LDI temp, 0xFF
    OUT DDRC, temp
    LDI temp, SEG_BLANK
    OUT PORTC, temp

    LDI temp, (1<<SS1_PIN)|(1<<SS2_PIN)|(1<<SS3_PIN)
    OUT DDRB, temp
    IN temp, PORTB
    ORI temp, ALL_DIGITS_OFF
    OUT PORTB, temp

    CLR temp
    OUT DDRD, temp

    CLR result
    LDI digit1_pat, SEG_BLANK
    LDI digit2_pat, SEG_BLANK
    LDI digit3_pat, SEG_BLANK

    LDI temp, (0<<ISC11)|(1<<ISC10) | (0<<ISC01)|(1<<ISC00)
    STS EICRA, temp

    LDI temp, (1<<INT1)|(1<<INT0)
    OUT EIMSK, temp

    LDI temp, (1<<CS01)
    OUT TCCR0B, temp
    CLR temp
    STS TIMSK0, temp

    SEI

MAIN_LOOP:
    NOP
    RJMP MAIN_LOOP

INT0_ISR:
    PUSH temp
    IN temp, SREG
    PUSH temp

    SBIS PIND, BTN1_PIN
    RJMP INT0_Pressed

INT0_Released:
    RCALL Disable_Display
    RJMP INT0_Exit

INT0_Pressed:
    LDI result, 20
    RCALL Update_Display_Data
    RCALL Enable_Display

INT0_Exit:
    POP temp
    OUT SREG, temp
    POP temp
    RETI

INT1_ISR:
    PUSH temp
    IN temp, SREG
    PUSH temp

    SBIS PIND, BTN2_PIN
    RJMP INT1_Pressed

INT1_Released:
    RCALL Disable_Display
    RJMP INT1_Exit

INT1_Pressed:
    LDI result, -20
    RCALL Update_Display_Data
    RCALL Enable_Display

INT1_Exit:
    POP temp
    OUT SREG, temp
    POP temp
    RETI

TIMER0_OVF_ISR:
    PUSH temp
    IN temp, SREG
    PUSH temp
    PUSH temp2
    PUSH digit1_pat
    PUSH digit2_pat
    PUSH digit3_pat

    IN temp, PORTB
    ORI temp, ALL_DIGITS_OFF
    OUT PORTB, temp

    LDS temp2, current_digit

    CPI temp2, 1
    BREQ DispDigit1_ISR
    CPI temp2, 2
    BREQ DispDigit2_ISR

DispDigit3_ISR:
    MOV temp, digit3_pat
    OUT PORTC, temp
    IN temp, PORTB
    ANDI temp, ~(1<<SS3_PIN)
    OUT PORTB, temp
    LDI temp2, 1
    RJMP UpdateCurrentDigit_ISR

DispDigit1_ISR:
    MOV temp, digit1_pat
    OUT PORTC, temp
    IN temp, PORTB
    ANDI temp, ~(1<<SS1_PIN)
    OUT PORTB, temp
    LDI temp2, 2
    RJMP UpdateCurrentDigit_ISR

DispDigit2_ISR:
    MOV temp, digit2_pat
    OUT PORTC, temp
    IN temp, PORTB
    ANDI temp, ~(1<<SS2_PIN)
    OUT PORTB, temp
    LDI temp2, 3
    RJMP UpdateCurrentDigit_ISR

UpdateCurrentDigit_ISR:
    STS current_digit, temp2

TIMER0_OVF_Exit:
    POP digit3_pat
    POP digit2_pat
    POP digit1_pat
    POP temp2
    POP temp
    OUT SREG, temp
    POP temp
    RETI

Enable_Display:
    PUSH temp
    LDI temp, (1<<TOIE0)
    STS TIMSK0, temp
    POP temp
    RET

Disable_Display:
    PUSH temp
    CLR temp
    STS TIMSK0, temp
    LDI temp, SEG_BLANK
    OUT PORTC, temp
    IN temp, PORTB
    ORI temp, ALL_DIGITS_OFF
    OUT PORTB, temp
    POP temp
    RET

Update_Display_Data:
    PUSH ZL
    PUSH ZH
    PUSH temp
    PUSH temp2
    PUSH disp_val
    PUSH d_tens
    PUSH d_units

    MOV disp_val, result
    TST disp_val
    BRMI Result_Negative_Sub

Result_Positive_Or_Zero_Sub:
    LDI digit1_pat, SEG_BLANK
    RJMP Convert_Value_Sub

Result_Negative_Sub:
    LDI digit1_pat, SEG_MINUS
    NEG disp_val

Convert_Value_Sub:
    CLR d_tens
    CLR d_units

Convert_Loop:
    CPI disp_val, 10
    BRLO Convert_Done

    SUBI disp_val, 10
    INC d_tens
    RJMP Convert_Loop

Convert_Done:
    MOV d_units, disp_val

Get_Patterns_Sub:
    MOV temp, d_tens
    RCALL Get_Segment_Code
    MOV digit2_pat, temp
    MOV temp, d_units
    RCALL Get_Segment_Code
    MOV digit3_pat, temp

Update_Exit_Sub:
    POP d_units
    POP d_tens
    POP disp_val
    POP temp2
    POP temp
    POP ZH
    POP ZL
    RET

Get_Segment_Code:
    PUSH temp2
    PUSH r0
    LDI ZL, LOW(Segment_Table*2)
    LDI ZH, HIGH(Segment_Table*2)
    MOV temp2, temp
    CLR temp
    ADD ZL, temp2
    ADC ZH, temp
    LPM
    MOV temp, r0
    POP r0
    POP temp2
    RET

Delay_10ms:
    PUSH dly_cnt_1
    PUSH dly_cnt_2
    LDI dly_cnt_1, 40
Delay_Outer_Loop:
    LDI dly_cnt_2, 85
Delay_Inner_Loop:
    DEC dly_cnt_2
    BRNE Delay_Inner_Loop
    DEC dly_cnt_1
    BRNE Delay_Outer_Loop
    POP dly_cnt_2
    POP dly_cnt_1
    RET

.ALIGN 2
Segment_Table:
.DB     0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B
Editor is loading...
Leave a Comment