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?
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.
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