Untitled
unknown
assembly_x86
2 years ago
2.1 kB
8
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, #00010000B ; 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)
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
RETI ; Return from Interrupt
PWM_STOP:
CLR TR0 ; Stop timer to stop PWM
RET
ENDEditor is loading...
Leave a Comment