106 lines
2.1 KiB
C
106 lines
2.1 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <avr/io.h>
|
|
#include <util/delay.h>
|
|
#include "ledpwmcurve.h"
|
|
|
|
|
|
#define PWMMin 128
|
|
#define PWMMax 1024
|
|
#define PWMRange (PWMMax - PWMMin)
|
|
|
|
#define PWMRandomValue() ((random() % PWMRange) + PWMMin)
|
|
|
|
#define DelayMin 5
|
|
#define DelayMax 50
|
|
#define DelayChange 1
|
|
#define DelayChangeSteps ((DelayMax - DelayMin) / DelayChange)
|
|
|
|
|
|
void var_delay_ms(int n);
|
|
|
|
|
|
|
|
int main()
|
|
{
|
|
uint16_t currentValue = PWMRandomValue();
|
|
uint16_t targetValue = currentValue;
|
|
uint16_t startValue = currentValue;
|
|
|
|
uint16_t speedUpUntil = currentValue;
|
|
uint16_t slowDownFrom = currentValue;
|
|
|
|
uint8_t delay = DelayMax;
|
|
|
|
#define goingUp (targetValue > currentValue)
|
|
|
|
|
|
// -- Set up PWM
|
|
// Set all ports as output (leave none as floating input)
|
|
DDRB = 0b11111111;
|
|
|
|
// Set Timer 0 to internal clock, no prescaling.
|
|
// See chapter 11.9 of the ATTiny85 datasheet
|
|
TCCR0B |= (1 << CS00);
|
|
|
|
// Set to 'Fast PWM' mode
|
|
TCCR0A |= (1 << WGM01) | (1 << WGM00);
|
|
|
|
// Clear OC0B output on compare match, upwards counting
|
|
TCCR0A |= (1 << COM0B1);
|
|
|
|
|
|
while (1)
|
|
{
|
|
if (targetValue == currentValue)
|
|
{
|
|
do
|
|
{
|
|
targetValue = PWMRandomValue();
|
|
} while (targetValue == currentValue);
|
|
|
|
startValue = currentValue;
|
|
speedUpUntil = goingUp ? startValue + DelayChangeSteps : startValue - DelayChangeSteps;
|
|
slowDownFrom = goingUp ? targetValue - DelayChangeSteps : targetValue + DelayChangeSteps;
|
|
}
|
|
|
|
|
|
if (goingUp)
|
|
{
|
|
currentValue++;
|
|
|
|
if (currentValue < speedUpUntil)
|
|
delay -= DelayChange;
|
|
else if (currentValue > slowDownFrom)
|
|
delay += DelayChange;
|
|
else
|
|
delay = DelayMin;
|
|
}
|
|
else
|
|
{
|
|
currentValue--;
|
|
|
|
if (currentValue > speedUpUntil)
|
|
delay -= DelayChange;
|
|
else if (currentValue < slowDownFrom)
|
|
delay += DelayChange;
|
|
else
|
|
delay = DelayMin;
|
|
}
|
|
|
|
|
|
// Update PWM value
|
|
OCR0B = antilog(currentValue);
|
|
var_delay_ms(delay);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Source: http://www.avrfreaks.net/forum/how-use-delay-variable
|
|
void var_delay_ms(int n)
|
|
{
|
|
while(n--)
|
|
_delay_ms(1);
|
|
} |