I'm doing a Photovoltaic(PV) Data Logger project in this, a power MOSFET(IRFZ34N) can be used as load.So i want to vary the gate voltage using a PWM signal(0-5v range) of MCU & i need at least 2o varying points. so i am confusing at writing a 'C' code to generate PWM signal. like 1. what should be the time period of PWM? 2. how can i vary pwm duty cycle in different steps? and etc..

And please help me, if anything else that i have to do to make my project success full. I would be very thank full, if some body help me with answer.


2 Answers 2


You can do this in software and keep track of all the required timing yourself, but most microcontrollers have hardware that can generate PWM autonomous after you initialize it. The basic things are a timer/counter and an Output Compare Register (OCR):

enter image description here

The counter continuously increments, represented by the slope, and is compared with the OCR. The PWM output goes low when the counter exceeds the OCR, and goes high again when it resets. The 5 % resolution you need (20 steps) is not a problem; a 16 bit timer can generate PWM with a better than 0.002 % resolution, and even an 8 bit timer can do 0.4 %.

All you have to do is program a new value in the OCR. The lower the value, the smaller the pulse width. The following animation is from this site:

enter image description here

Further reading
Using the AVR’s High-speed PWM, an Atmel application note.
ATMega32 datasheet describes on page 69 ff. how to use Timer0 for PWM operation.

  • 3
    \$\begingroup\$ Moving pictures, on the internet? That counts for at least 10,000 pretty votes. \$\endgroup\$
    – Kortuk
    Jun 23, 2012 at 13:51
  • 2
    \$\begingroup\$ @Kortuk - 10,000 per still, I hope! :-) I hear there's a completely new invention where you can make even faster moving pictures, I think they call it cinematography, or something like that. I don't know if there's also sound, maybe in the future. ;-) \$\endgroup\$
    – stevenvh
    Jun 23, 2012 at 13:58

Assuming your microcontroller has a PWM module, then it's quite simple. You need to read the datasheet and set up your module accordingly, then load the appropriate values into the duty cycle (usually "compare") register. Here's a rough example: You set up a timer for your desired (fixed) PWM frequency, then alter a register to change the ON/OFF time in this period.
Say you have a 10-bit PWM module. 10 bits = 2^10 = 1024. So for 50% duty cycle you need to load 512 into the register, for 25% 256 and so on (the specific operation of your PWM module may be a bit different)
Then you add a low pass filter (simple RC filter usually will suffice) in front of the PWM to average out the PWM and produce a varying DC voltage:

PWM filter

RC Filter

For the filter you need to make sure the PWM frequency is attenuated greatly, leaving the lower frequencies - since you say all you need is DC, then something like R = 10k C = 0.1uF will do. This will create a cut off of 1 / (2pi * 10k * 0.1uF) = 159Hz. Pick a PWM frequency well above this (e.g. 10kHz)

I noticed the AVR tag - I don't use AVR (so I cannot vouch personally for the below information) but I googled and found a couple of pretty good tutorials:
Aquaticus PWM guide
AVR Freaks PWM guide
PWM sine wave example

In case you don't want to use the PWM module (or need PWM on a specific pin) here's some "soft" PWM code:

 // The following two ISRs are doing "poor man's PWM" 
//  but this allows it to be on a pin of my choice 
ISR(TIMER0_COMP_vect) { 
        // clear the output pin on OCR0 match 
   PORTC &= ~(1<<PC0); 
ISR(TIMER0_OVF_vect) { 
        // set the output pin at timer overflow 
   PORTC |= (1<<PC0); 

int main(void) { 

   // going to use PORTC.0 to PWM the contrast voltage 
   DDRC = (1<<DDC0); 
   TIMSK |= ((1<<OCIE0) | (1<<TOIE0)); // use both interrupts
   OCR0 = 10; // 10 out of 256 means very short on period (low voltage) 
   TCCR0 = (1<<CS00); // timer on - nice high PWM frequency 

   // Might later consider PWMing the backlight voltage too 
   // so it would also be adjustable ... 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.