Untitled

 avatar
unknown
assembly_x86
a year ago
2.2 kB
4
Indexable
ORG 00H
    PWM_PIN EQU P1.0    ; PWM output pin
    PWM_FLAG EQU 0    ; Flag to indicate high/low signal
    COUNT_LIMIT EQU 5 ; Count limit for Timer 1

    JMP PWM_SETUP

ORG 0BH ; Vector Address for Timer 0 Interrupts
    JMP TIMER0_ISR

MAIN:
    AGAIN: 
        MOV A, #0
        MOV P2, A
        MOV TMOD, #00010001B ; TIMER 1 IS SET FOR MODE 1, TIMER OPERATION

    ; why this is almost equals 1 second ??
    ; cause 11.0592 MHz crystal is used    
    REPEAT: 
        MOV R5, #20D
    LOOP:     
        MOV TH1, #4CH ; TIMER 1 HIGH BYTE IS LOADED
        MOV TL1, #00H ; TIMER 1 LOW BYTE IS LOADED
        SETB TR1 ; START TIMER 1

    POLL:
        JNB TF1, POLL ; LOOP AROUND UNTIL TIMER 1 OVERFLOWS
        CLR TR1 ; STOP TIMER 1
        CLR TF1 ; CLEAR OVERFLOW FLAG

        DJNZ R5, LOOP
        INC A
        MOV P2, A
        CJNE A, #COUNT_LIMIT, REPEAT

        ; When the count reaches COUNT_LIMIT, activate PWM
        SETB PWM_FLAG
        JMP AGAIN

PWM_SETUP:
    MOV TMOD, #00H     ; Timer0 in Mode 0
    MOV R7, #128    ; Set pulse width control (0-255)
    SETB EA     ; Enable Global Interrupts
    SETB ET0     ; Enable Timer 0 Interrupt
    SETB TR0     ; Start Timer
    JMP $

TIMER0_ISR: ; Called when Timer 0 Overflows (TF0 = 1)
    JB PWM_FLAG, LOW_PERIOD ; If PWM_FLAG flag is set, then we just finished the high section of the cycle, so jump to LOW_PERIOD

HIGH_PERIOD:
    SETB PWM_FLAG ; Make PWM_FLAG=1 to indicate the start of the high section
    SETB PWM_PIN ; Make PWM output pin High
    MOV A, #0FFH ; Move FFH (255) to A
    CLR C ; Clear C.F (the carry flag) so it doesn't affect the subtraction SUBB
    SUBB A, R7 ; Subtract R7 from A.
                ; A = 255 - R7. (A = A - C.F - R7)
    MOV TH0, A ; The difference value loaded into TH0 (TH0 + R7 = 255)
    CLR TF0 ; Clear the Timer 0 interrupt flag
    RETI ; Return from Interrupt

LOW_PERIOD:
    CLR PWM_FLAG ; Make PWM_FLAG=0 to indicate the start of the low section
    CLR PWM_PIN ; Make PWM output pin low
    MOV TH0, R7 ; Load the high byte of the timer with R7
    CLR TF0 ; Clear the Timer 0 interrupt flag
    RETI ; Return from Interrupt

PWM_STOP:
    CLR TR0 ; Stop timer to stop PWM
    RET

END
Editor is loading...
Leave a Comment