2024-03-06 19:33:30 +00:00
//#pragma GCC push_options
//#pragma GCC optimize ("O0")
# define F_CPU 8000000UL
2024-03-03 19:04:23 +00:00
# include <util/delay.h>
# include <avr/io.h>
2024-03-05 17:19:42 +00:00
# include <avr/interrupt.h>
2024-03-06 19:33:30 +00:00
# include <avr/power.h>
2024-03-03 19:04:23 +00:00
# define PATTERN_COUNT 4
2024-03-06 11:28:34 +00:00
# define attiny45
2024-03-14 21:37:51 +00:00
2024-03-03 19:04:23 +00:00
typedef struct
{
unsigned char r ;
unsigned char g ;
unsigned char b ;
int time_hold ;
} rgbval ;
2024-03-14 21:37:51 +00:00
2024-03-05 17:19:42 +00:00
volatile uint16_t ms ;
2024-03-14 21:37:51 +00:00
volatile uint16_t counts ;
2024-03-05 17:19:42 +00:00
2024-03-06 19:33:30 +00:00
void InitTimer0 ( void ) ;
void InitTimer1 ( void ) ;
void setrgb ( unsigned int r , unsigned int g , unsigned int b ) ;
void InitInterrupts ( void ) ;
2024-03-06 11:28:34 +00:00
2024-03-05 17:19:42 +00:00
void count ( void )
{
//counts=0;//0..65535
counts + + ;
2024-03-06 19:33:30 +00:00
if ( counts > 3 ) //1m //1ms
2024-03-05 17:19:42 +00:00
{
counts = 0 ;
if ( ms < 60000 ) //1 minute
{
ms + + ;
}
else
{
ms = 0 ;
}
}
}
2024-03-06 11:28:34 +00:00
ISR ( TIMER0_OVF_vect )
{
count ( ) ;
}
2024-03-14 21:37:51 +00:00
int main ( void )
{
rgbval pattern [ 6 ] [ PATTERN_COUNT ] = { { { 0 , 0 , 0 , 100 } , { 0 , 0 , 0 , 100 } , { 0 , 0 , 0 , 100 } , { 0 , 0 , 0 , 100 } } ,
2024-03-05 17:19:42 +00:00
{ { 1 , 1 , 1 , 10 } , { 1 , 1 , 153 , 20 } , { 200 , 50 , 39 , 10 } , { 204 , 255 , 153 , 20 } } ,
2024-03-14 21:37:51 +00:00
{ { 1 , 50 , 50 , 10 } , { 10 , 255 , 0 , 10 } , { 80 , 200 , 0 , 20 } , { 200 , 200 , 1 , 20 } } ,
{ { 1 , 1 , 5 , 10 } , { 1 , 1 , 255 , 10 } , { 1 , 1 , 5 , 10 } , { 1 , 1 , 255 , 10 } } ,
2024-03-05 17:19:42 +00:00
{ { 252 , 102 , 3 , 10 } , { 161 , 67 , 47 , 10 } , { 118 , 120 , 74 , 10 } , { 83 , 120 , 74 , 20 } } ,
2024-03-14 21:37:51 +00:00
{ { 87 , 119 , 122 , 10 } , { 95 , 87 , 122 , 10 } , { 52 , 69 , 56 , 10 } , { 83 , 84 , 72 , 10 } } } ;
int i = 0 , i2 = 0 , i3 = 0 ;
int r , g , b = 0 ;
int set = 0 ;
int input = 0 ;
uint16_t pre_delay = 0 ;
ms = 0 ;
counts = 0 ;
2024-03-05 17:19:42 +00:00
//disable prescaler
2024-03-06 19:33:30 +00:00
// CLKPR = (1<<CLKPR); maybe optimization removes this
// CLKPR = 0x00;
2024-03-14 21:37:51 +00:00
clock_prescale_set ( clock_div_1 ) ; //replaces above 2 lines
2024-03-03 19:04:23 +00:00
//#######OC0A auf ausgang
2024-03-14 21:37:51 +00:00
DDRB = ( 1 < < PB0 ) | ( 1 < < PB1 ) | ( 1 < < PB4 ) ; //data directions - output
PORTB | = ( 1 < < PB2 ) ; //pullups
cli ( ) ; //DISABLE Global Interrupts
InitTimer0 ( ) ;
InitTimer1 ( ) ;
InitInterrupts ( ) ;
sei ( ) ; //ENABLE Global Interrupts
while ( 1 )
{
for ( i = 0 ; i < PATTERN_COUNT ; i + + )
{
r = pattern [ i2 ] [ i ] . r ;
g = pattern [ i2 ] [ i ] . g ;
b = pattern [ i2 ] [ i ] . b ;
if ( i = = ( PATTERN_COUNT - 1 ) ) { i = 0 ; }
while ( 1 )
2024-03-06 19:33:30 +00:00
{
2024-03-14 21:37:51 +00:00
input = PINB ;
if ( ( ( input & ( 1 < < PB2 ) ) = = 0 & & set = = 0 ) )
{
set = 1 ;
i = 0 ;
i2 + + ;
if ( i2 = = 6 )
{
i2 = 0 ;
}
//Visual feedback "mode change"
for ( i3 = 0 ; i3 < i2 ; i3 + + )
{
setrgb ( 0 , 0 , 0 ) ;
pre_delay = ms ;
while ( ( ms - pre_delay ) < 200 ) ;
setrgb ( 0 , 200 , 0 ) ;
pre_delay = ms ;
while ( ( ms - pre_delay ) < 200 ) { } ;
}
}
else if ( ( ( input & ( 1 < < PB2 ) ) ! = 0 ) )
{
set = 0 ;
}
//iterate throught pattern to the next ones
if ( r < pattern [ i2 ] [ i + 1 ] . r ) { r + + ; }
if ( r > pattern [ i2 ] [ i + 1 ] . r ) { r - - ; }
if ( g < pattern [ i2 ] [ i + 1 ] . g ) { g + + ; }
if ( g > pattern [ i2 ] [ i + 1 ] . g ) { g - - ; }
if ( b < pattern [ i2 ] [ i + 1 ] . b ) { b + + ; }
if ( b > pattern [ i2 ] [ i + 1 ] . b ) { b - - ; }
setrgb ( r , g , b ) ;
//read timer evaluate time since read in 1ms steps
//pre_delay = ms;
//while((ms-pre_delay) <1000);
_delay_ms ( 30 ) ;
if ( r = = pattern [ i2 ] [ i + 1 ] . r & & g = = pattern [ i2 ] [ i + 1 ] . g & & b = = pattern [ i2 ] [ i + 1 ] . b ) break ;
2024-03-04 21:20:45 +00:00
}
2024-03-05 17:19:42 +00:00
}
2024-03-14 21:37:51 +00:00
}
return 0 ;
2024-03-03 19:04:23 +00:00
}
2024-03-06 19:33:30 +00:00
void InitTimer0 ( void )
{
//#######Timer0-setup##### |Phase correct pwm
TCCR0A = ( 2 < < COM0A0 ) | ( 2 < < COM0B0 ) | ( 1 < < WGM00 ) | ( 1 < < WGM01 ) ; //mode fast pwm (1/Fcpu)*prescaler*(max+1) =
//prescaler /64 gives 0...255 0.002048s = 2.0ms 1mhz-> /8
TCCR0B = ( 1 < < CS01 ) ; //|(1<<CS01)/256;
}
void InitTimer1 ( void )
{
//######Timer1-setup
PLLCSR & = ~ ( 1 < < PCKE ) ;
2024-03-14 21:37:51 +00:00
TCCR1 = ( 1 < < COM1A0 ) | ( 1 < < COM1A1 ) | ( 1 < < CS12 ) | ( 1 < < CS10 ) | ( 1 < < CS11 ) ; //(1<<CS10)|(1<<CS12);//|(1<<CS13); //frequencyi //inverting PWM because 0 dtc not possible
2024-03-06 19:33:30 +00:00
GTCCR = ( 1 < < PWM1B ) | ( 1 < < COM1B1 ) ; //mode + overrun clear, Set on compare match
OCR1C = 255 ; // clear timer at 255
}
void setrgb ( unsigned int r , unsigned int g , unsigned int b )
{
2024-03-14 21:37:51 +00:00
//depends on timer0
2024-03-06 19:33:30 +00:00
OCR0A = g ; //green
OCR0B = r ; //red
2024-03-14 21:37:51 +00:00
//depends on Timer1
2024-03-06 19:33:30 +00:00
OCR1B = b ; //blue
}
void InitInterrupts ( void )
{
TIMSK | = ( 1 < < TOIE0 ) ; //interrupt on overflow = one timer cycle
TIFR | = ( 1 < < TOV0 ) ;
TCNT0 = 0 ;
}
//#pragma GCC pop_options