Search code examples
cmicrocontrolleravravr-gccattiny

_delay_ms seems not to work when using pwm


I'm relatively new to programming microcontrollers, so I started experimenting on an ATtiny85.

First program was simply turning on an LED and off with a little delay (classic blinky program).

Now I wanted to slowly increase the brightness of the LED. Here is the code:

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

#define LED PB0

void setup(void);
void loop(void);
void analogOutput(int8_t brightness);

int main(void)
{
    setup();
    while (1)
    {
        loop();
    }

    return 0;
}

void setup()
{
    TCCR0A = (1 << WGM00) | (1 << WGM01);
    TCCR0B = (1 << CS00) | (1 << CS01);
    DDRB = (1 << LED);
    PORTB = 0;
}

void loop()
{
    int8_t brightness = 0;
    analogOutput(brightness);
    _delay_ms(500);
    for (brightness = 0; brightness < 256; ++brightness)
    {
        analogOutput(brightness);
        _delay_ms(10);
    }
}

void analogOutput(int8_t brightness)
{
    if (brightness == 0)
    {
        // digital output LOW
        TCCR0A &= ~(1 << COM0A1);
        PORTB &= ~(1 << LED);
    }
    else if (brightness == 255)
    {
        // digital output HIGH
        TCCR0A &= ~(1 << COM0A1);
        PORTB |= (1 << LED);
    }
    else
    {
        PORTB &= ~(1 << LED);
        // analog output
        TCCR0A |= (1 << COM0A1);
        OCR0A = brightness;
    }
}

I expected the LED to be turned off for half a second and then increase the brightness. But if i run the code the LED simply becomes more bright, as if the _delay_ms(500) was ignored.

The analogOutput function is inspired by the function of the Arduino library.

What is wrong here? Why does the delay not work as expected?

EDIT

I changed my loop function, new content:

void loop()
{
    analogOutput(127);
    _delay_ms(500);
    analogOutput(255);
    _delay_ms(500);
}

This works, I now have a LED that constantly switches from dimmed to fully on and back.


Solution

  • I feel stupid.. It was just an overflow error, since I used uint8_t and set < 256 in the for loop, the condition was always true (255 + 1 = 0).

    My solution was to use uint16_t for the loop