Software PWM on AVR using delay

2.5k views Asked by At

I am trying to accomplish a simple PWM generation using delays on an AVR ATMega16

What i am trying to do is simply fade a led from 100% to 0% duty cycle, and later i will expand it to control two colors of a bicolor led to have a nice effect.

I have done this in mikroC with PICs before, but somehow it's not as easy in avr-gcc, or maybe i am missing something.

My problem here is that i want the led to fade completely in 3 seconds, but i feel its fading faster. I also think that it's spending more time on high duty cycles than on low ones. I mean that i see the led bright for a bit, then it fades, but when it becomes dim it moves to different duty cycles very fast or so i think..

Any ideas you might have on what i am missing ?

Code is available here : http://ideone.com/lUP5f

Thanks

2

There are 2 answers

3
user1176976 On BEST ANSWER

It may be a problem with the fuse settings. The clock is usually controlled by fuses not by the define. However the delay function uses the #define F_CPU. Can you post your fuse settings?

Is there a specific reason that you want to use delay instead of a timer to generate the PWM? In case you want to have a look at timers I can recommend these Tutorials to you:1)Timer Tutorial 2)PWM

Edit: btw

 uint8_t b = 1000;

uint8_t allows values from 0 to 255 the compiler usually generates a warning for this:

../test.c:16: warning: large integer implicitly truncated to unsigned type

1
Philipp On

The problem is, that LEDs are not linear. So it doesn't work to turn them on for example with 50% to reduce their brightness to 50%..

You can use a predefinied table (for example here: http://www.mikrocontroller.net/articles/LED-Fading#Das_Demoprogramm)

You don't need to be able to read german. Just study this piece of code.. There are some tables for example for 16 bit PWM (pwmtable_16[]).

So you can write:

delay_us(pwmtable_16[a]);

instead of

delay_us(a);