You are on page 1of 2

Pulse Width Modulation (PWM) 8051 Code example Idea Behind Implementation The basic idea behind PWM

implementation on 8051 is using timers and switching p ort pin highlow at defined intervals. As we have discussed in the introduction o f PWM that by changing the Ton time, we can vary the width of square wave keepin g same time period of the square wave. We will be using 8051 Timer0 in Mode 0. Values for high and low level will be lo aded in such a way that total delay remains same. If for high level we load a va lue X in TH0 then for low level TH0 will be loaded with 255-X so that total rema ins as 255. Assembly Code Example Timer setup for PWM CODE PWMPIN EQU P1.0 ; PWM output pin PWM_SETUP MOV TMOD,#00H ; Timer0 in Mode 0 MOV R7, #160 ; Set pulse width control ; The value loaded in R7 is value X as ; discussed above. SETB EA ; Enable Interrupts SETB ET0 ; Enable Timer 0 Interrupt SETB TR0 ; Start Timer RET

Interrupt Service Routine CODE TIMER_0_INTERRUPT JB F0, HIGH_DONE LOW_DONE SETB F0 SETB PWMPIN MOV TH0, R7 CLR TF0 RETI HIGH_DONE CLR CLR MOV CLR F0 PWMPIN A, #0FFH C

; If F0 flag is set then we just finished ; the high section of the ; cycle so Jump to HIGH_DONE ; Make F0=1 to indicate start of high section ; Make PWM output pin High ; Load high byte of timer with R7 ; (pulse width control value) ; Clear the Timer 0 interrupt flag ; Return from Interrupt to where ; the program came from

SUBB A, R7 MOV TH0, A CLR TF0 RETI

; Make F0=0 to indicate start of low section ; Make PWM output pin low ; Move FFH (255) to A ; Clear C (the carry bit) so it does ; not affect the subtraction ; Subtract R7 from A. A = 255 - R7. ; so the value loaded into TH0 + R7 = 255 ; Clear the Timer 0 interrupt flag ; Return from Interrupt to where ; the program came from

In your main program you need to call this PWM_SETUP routine and your controller

will have a PWM output. Timer Interrupt service routine will take care of PWM i n the background. The width of PWM can be changed by changing the value of R7 re gister. In above example I am using 160, you can choose any value from 0 to 255. R7 = 0 will give you op 0V approx and R7 = 255 will give you 5V approx. You can also make use of Timer1 if you want. And the output pin can be changed t o whatever pin you want. C Code Example Timer setup for PWM in C CODE Global variables and definition #define PWMPIN P1_0 unsigned char pwm_width; bit pwm_flag = 0; void pwm_setup(){ TMOD = 0; pwm_width = 160; EA = 1; ET0 = 1; TR0 = 1; }

Interrupt Service Routine CODE void timer0() interrupt 1 { if(!pwm_flag) { Start of High level pwm_flag = 1; Set flag PWMPIN = 1; Set PWM op pin TH0 = pwm_width; Load timer TF0 = 0; Clear interrupt flag return; Return } else { Start of Low level pwm_flag = 0; Clear flag PWMPIN = 0; Clear PWM op pin TH0 = 255 - pwm_width; Load timer TF0 = 0; Clear Interrupt flag return; return } }

Now your normal 8051 is capable of PWM output.