ATMEGA 168 - PWM not working?

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've gone through the data sheet and a few tutorials/example and I can't figure out why this is not working. can anyone help?

I have an led connected to PD6 / Pin12. I'd like to change the brightness. This should make the led go from off to full brightness and then repeat right?

The LED on PINB2 does work.

#define F_CPU 16000000UL


#include 
#include 

int main(void)
{
	
	DDRB |= (1 << PINB1) | (1 << PINB2);	// Set PB1 & PB2 as outputs
		
	TCCR0A |= (1 << COM0A1) | (1 << COM0A0); // Set OCR0A on TOP, Clear on BOTTOM
	
	DDRD |= (1 << PIND6);	// Set PD6 as output
	
	TCCR0A |= (1 << WGM00);
	TCCR0B |= (1 << WGM02) | (1<< CS00);	// set timer 0 for PWM, Phase correct, no prescaling

		
    while(1)
    {

	
		
		for(uint8_t i; i <= 255; i++){
			OCR0A = i;
			_delay_ms(100);
		}
		
		PORTB ^=  (1 << PINB2); // flash LED to make sure chip is working and code was uploaded
		_delay_ms(1000);
	
		
    }
}
Last Edited: Sat. Apr 13, 2013 - 09:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
      if (i = 255) i = 0; 

Make that

      if (i == 255) i = 0; 

to start with.

[EDIT]Oh!, and

   for(uint8_t i; i = 0; i++){

should probably be

   for(uint8_t i; i == 0; i++){

Also, you do not initialize i, and since it is an automatic variable it will take whatever value is at that memory location when you get to the loop.

Your loop seems a bit strange, if you ask me. If you actually had

   for(uint8_t i; i == 0; i++){
      OCR0A = i;
      _delay_ms(100);
         
      if (i == 255) i = 0;
   } 

then, you'd fall out as soon as i was not zero.

If you simply want to go from 0 to 255 then just

for (int i = 0; i < 255; i++)
{
   // ...whatever...
}

Newcomer to C, perhaps?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes new to C but found and fixed the above. I'll post the update code to my first post to keep the thread clean.

Edit: now the PWM led it lit, the brightness does not vary, and the led on PB2 is not working.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Edit: now the PWM led it lit, the brightness does not vary, and the led on PB2 is not working.


Well, we can only imagine what the code actually looks like now...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've update the code in my first post to reflect the changes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

and the led on PB2 is not working.

That is because you now have constructed another for-loop that you can not exit from.

Read my post again. Observe the details. If you don't actually read what I post then I will stop.

Hint: When will an uint8_t not be <= 255?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry i missed that, but wouldn't i = 256 at one point, exiting the loop? why does i < 255 work but not i <= 255?

my blinky led works again, but PWM does not

updated code:

#define F_CPU 16000000UL


#include 
#include 
#include 

int main(void)
{
	
	DDRB |= (1 << PINB1) | (1 << PINB2);	// Set PB1 & PB2 as outputs
		
	TCCR0A |= (1 << COM0A1) | (1 << COM0A0); // Set OCR0A on TOP, Clear on BOTTOM
	
	DDRD |= (1 << PIND6);	// Set PD6 as output
	
	TCCR0A |= (1 << WGM00);
	TCCR0B |= (1 << WGM02) | (1<< CS00);	// set timer 0 for PWM, Phase correct, no prescaling

		
    while(1)
    {

		
		
		for(uint8_t i; i < 255; i++){
			OCR0A = i;
			_delay_ms(100);
		}
		
		
		PORTB ^=  (1 << PINB2); // flash LED to make sure chip is working and code was uploaded
		_delay_ms(1000);
	
		
    }
}

Edit: wrong code

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Sorry i missed that, but wouldn't i = 256 at one point

No. You have i as an uint8_t. Value range for an unsigned eight-bit variable is 0..255 .

Quote:

my blinky led works again

Good. Now you are at least not trapped inside an eternal for-loop
Quote:
my blinky led works again, but PWM does not

Now make sure the loop actually works (i.e. you are not falling out directly). How?, you ask. Answer: Don't bother with the PWM yet. Just blink your LED on PB2, just as you do outside the loop. But make the delay somewhat longer than 100 ms, which might be a tad too fast for you to perceive as blinking. 200 ms, perhaps, so that you can see thte difference between that and the 1 second delay after your for-loop.

When you are sure your loop works as you want, then you focus on the PWM mode of the timer. All fault seeking should ideally be done in small steps, varying and solving one thing at a time. As you're a beginner juggler, it makes no sense to start with more than one ball. :D

Double check every bit you set against the data sheet. Double-check that you are using the mode you intend, and that that mode does what you want.

Also:Double-check that you have the LED connected correctly.

Quote:
I've update the code in my first post to reflect the changes.

Don't do that. It will make future readers of this thread very confused.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hahaha I figured it out XD. if OCRnx is set as TOP (PWM mode 5) then you loose that PWM channel, that's why it wasn't working.

I set the timer to use mode 1 (top is 0xFF) and it works now.

why would you want to set

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I figured it out

Also, you still have not addressed giving your loop counter(s) an initial value. Perhaps no problem THIS time...
Quote:

for(uint8_t i; i < 255; i++){

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.