0

I am using an Attiny 9. enter image description here

I connected a LED to PB1. I wrote following code and upload it to the Attiny 9.

#define F_CPU 800000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/power.h>

#define D0 PB1

int main(void)
{
  power_adc_disable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  TCCR0A |= (1<<WGM00)|(1<<WGM01)|(1<<COM0B1);
  TCCR0B |= (1<<WGM03)|(1<<WGM02)|(1<<CS00);

  DDRB |= 1<<D0;

  PORTB |= 1<<D0;
  _delay_ms(3000);
  PORTB &= ~(1<<D0);

  for (uint8_t i = 255; 247 < i; --i)
  {
    OCR0B = i;
    _delay_ms(70);
  }

  for (uint8_t i= 247; -1 < i; --i)
  {
    OCR0B = i;
    _delay_ms(4);
  }

  while(1){
    sleep_enable();
    sleep_cpu();
  }

  return 0;
}

I want the LED to be lighten and darken. But after I uploaded the code, the LED illuminates continuously. I also read a datasheet of Attiny 9. I followed how to use PWM. But it's not working.

What's wrong?

neosarchizo
  • 648
  • 1
  • 7
  • 16

1 Answers1

3

There are a number of issues with that code.

  1. You're putting the processor in to power down mode, which according to the datasheet, disables the clocks and only asynchronous events can take place.
  2. You're setting it to use fast PWM mode with OCR0A as your top, but you aren't setting OCR0A anywhere. You won't generate any compare matches if you your timer can't count high enough. It would appear from your loops that you are expecting the timer to count to 255.
  3. You only change the duty cycle of the PWM before your while loop, so even if your PWM gets set up correctly, you won't ever be able to see your LED pulse like you want.

Here's a link giving an example of how to set up a PWM and change its duty cycles: http://allaboutavr.com/index.php/2017/05/13/chapter-5-timers-and-pwm-pulse-width-modulation/

Ty something like this:

#include <avr/io.h>
#include <util/delay.h>

#define D0 PB1

int main(void)
{
    DDRB |= 1<<D0;

    TCCR0A |= (1<<WGM00)|(1<<COM0B1);
    TCCR0B |= (1<<WGM02)|(1<<CS00);

    while (1) {
        for (uint8_t i = 0; i < 255; i++) {
            OCR0B = i;
            _delay_ms(4);
        }

        for (uint8_t i = 255; i >= 0; i--) {
            OCR0B = i;
            _delay_ms(4);
        }
    }
}
  • It works!! I put the processor in power down mode, because I wanted it to be sleep mode. I wanted it to be sleep mode after blinking. – neosarchizo May 27 '17 at 11:51
  • I see. I'm glad it worked for you. The link I posted in my original reply has a bunch of tutorials on there for how to set up different features of an AVR. Hopefully that can be a good resource for you. – rlphillipsiii May 27 '17 at 15:37
  • allaboutavr.com is down :( – needfulthing Jul 02 '19 at 11:52
  • @needfulthing I might have some of the tutorials laying around somewhere. If I can find them, I'll update the link. – rlphillipsiii Jul 11 '19 at 00:54