code !
$mod51
;***************************************
;* LED PWM 2 *
;* Amateur World *
;***************************************
; R7 is used to hold a value between 0 and 255 which will correspond to a
brightness
; level for the LED. Timer 0 will be used to create the Pulse Width Modulated
output.
; Timers are generally used to repeatedly measure the same fixed interval of
time.
; In this case we want to measure 2 periods of time. The high output period and
the
; low output period.
;***************************************
; RESET ;reset routine
ORG 0H ;locate routine at 00H
AJMP START ;jump to START
;***************************************
; INTERRUPTS (not used) ;place interrupt routines at appropriate
;memory locations
ORG 03H ;external interrupt 0
RETI
ORG 0BH ;timer 0 interrupt
AJMP TIMER_0_INTERRUPT ; go to interrupt routine (can be anywhere we want)
; since a jump does not return to this point we do not
; need a Return command
ORG 13H ;external interrupt 1
RETI
ORG 1BH ;timer 1 interrupt
RETI
ORG 23H ;serial port interrupt
RETI
ORG 25H ;locate beginning of rest of program
;***************************************
INITIALIZE: ; set up control registers
MOV TMOD,#00H ; set timer 0 to Mode 0 (8 bit Timer with 5 bit prescalar)
SETB TR0 ; turn on timer 0
MOV PSW,#00H
SETB EA ; Enable Interrupts (each individual interrupt must also be enabled)
SETB ET0 ; Enable Timer 0 Interrupt
RET
;***************************************
; Real code starts below.
;***************************************
; The LED is off during the high section and on during the low section of each
cycle
; The Flag F0 is used to remember whether we are timing tlow or thigh.
TIMER_0_INTERRUPT:
JB F0, HIGH_DONE ; If F0 is set then we just finished the high section of the
LOW_DONE: ; cycle so Jump to HIGH_DONE
SETB F0 ; Make F0=1 to indicate start of high section
SETB P1.0 ; Turn off LED
MOV TH0, R7 ; Load high byte of timer with R7 (our pulse width control value)
CLR TF0 ; Clear the Timer 0 interrupt flag
RETI ; Return from Interrupt to where the program came from
HIGH_DONE:
CLR F0 ; Make F0=0 to indicate start of low section
CLR P1.0 ; Turn on LED
MOV A, #0FFH ; Move FFH (255) to A
CLR C ; Clear C (the carry bit) so it does not affect the subtraction
SUBB A, R7 ; Subtract R7 from A. A = 255 - R7.
MOV TH0, A ; so the value loaded into TH0 + R7 = 255
CLR TF0 ; Clear the Timer 0 interrupt flag
RETI ; Return from Interrupt to where the program came from
;***************************************
START: ;main program (on power up, program starts at this point)
ACALL INITIALIZE ;set up control registers
MOV R7, #00H ; set pulse width control to dim
TEST: LCALL TIMER
INC R7 ;FROM HERE TO TEST IS THE TRICK TO VARY R7 AS WELL AS
;THE INTENSITY OF LED
CJNE R7,#0FFH,TEST
TEST1
TEST1: LCALL TIMER
DEC R7
CJNE R7,#00H,TEST1
LCALL TEST
;go to LOOP(always jump back to point labeled LOOP)
TIMER: push 00h
push 01h
push 02h ;store the internal location 00h,01h,02h contents
mov 02h,#03h
USER_L2:
mov 01h,#0ffh
USER_L1:
mov 00h,#0ffh
DJNZ 00h,$;decreament the internal location 00h
;content repeat until it becomes 0
DJNZ 01h,USER_L1 ;""""""
DJNZ 02h,USER_L2 ;""""""
pop 02h
pop 01h
pop 00h
RET
END ;end program
You might be also interested in:
:: Traffic light control system using 8086
:: Assembly Language Program to serve NMI
:: Interfacing Stepper Motor to 8086 using 8255
No comments:
Post a Comment