Rev 53 |
Rev 55 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
//############################################################################
// - PWM CTRL
// - Main
// - ATMEGA8 mit 8MHz
// - Nur für den privaten Gebrauch
// - Keine Garantie auf Fehlerfreiheit
// - Kommerzielle Nutzung nur mit meiner Zustimmung
// - walter Meyer @ www.freakware.de
// - 11.12.2007
// - Make sure Fuses are programmed for internal 8 MHz RC Oscilator
//############################################################################*/
#include "main.h"
#include "uart.h"
#include "twislave.h"
volatile unsigned int ppm_signal
= 1500;
volatile unsigned char ppm_new
= 0;
volatile unsigned char TMR1OvF
= 0;
volatile unsigned int TMR1MS
;
volatile unsigned char ch0
;
volatile unsigned char ch1
;
volatile unsigned char ch2
;
volatile unsigned char ch3
;
volatile unsigned char ch4
;
volatile unsigned char ch5
;
volatile unsigned char ch0_tmp
;
volatile unsigned char ch1_tmp
;
volatile unsigned char ch2_tmp
;
volatile unsigned char ch3_tmp
;
volatile unsigned char ch4_tmp
;
volatile unsigned char ch5_tmp
;
unsigned int timer
;
SIGNAL
(SIG_OVERFLOW1
)
{
TMR1OvF
++;
}
SIGNAL
(SIG_INPUT_CAPTURE1
)
{
static unsigned int pos_ICR
;
static unsigned int ppm
;
if ((TCCR1B
& (1<<ICES1
)) != 0) //rising edge
{
TCCR1B
&= ~
(1<<ICES1
); //set falling egde
TMR1OvF
= 0;
pos_ICR
= ICR1
;
}
else //falling edge
{
TCCR1B
|= (1<<ICES1
); //set rising egde
ppm
= (ICR1
- pos_ICR
+ (int) TMR1OvF
* 65536);
if ((ppm
> 600) && (ppm
< 2400))
{
if (ppm
> 2100) ppm
= 2100;
if (ppm
< 900) ppm
= 900;
ppm
= (ppm_signal
* 3 + ppm
) / 4;
ppm_signal
= ppm
;
if (ppm_new
< 50) ppm_new
++;
}
}
}
SIGNAL
(SIG_OVERFLOW0
)
{
// this function is called every 32us,
// it is very important that it's execution time is as short as possible
// currently it's about 20us
static unsigned char counter
= 254;
static unsigned char ms1
= 0;
unsigned char PORTB_BAK
;
unsigned char PORTD_BAK
;
PORTB_BAK
= PORTB
;
PORTD_BAK
= PORTD
;
if (counter
++ == 254)
{
PORTB_BAK LEDON
(CH0_B
| CH1_B
| CH2_B
);
PORTD_BAK LEDON
(CH3_D
| CH4_D
| CH5_D
);
ch0_tmp
= ch0
;
ch1_tmp
= ch1
;
ch2_tmp
= ch2
;
ch3_tmp
= ch3
;
ch4_tmp
= ch4
;
ch5_tmp
= ch5
;
counter
= 0;
}
if (ch0_tmp
== counter
) PORTB_BAK LEDOFF CH0_B
;
if (ch1_tmp
== counter
) PORTB_BAK LEDOFF CH1_B
;
if (ch2_tmp
== counter
) PORTB_BAK LEDOFF CH2_B
;
if (ch3_tmp
== counter
) PORTD_BAK LEDOFF CH3_D
;
if (ch4_tmp
== counter
) PORTD_BAK LEDOFF CH4_D
;
if (ch5_tmp
== counter
) PORTD_BAK LEDOFF CH5_D
;
PORTB
= PORTB_BAK
;
PORTD
= PORTD_BAK
;
if (ms1
++ == 32)
{
ms1
=0;
TMR1MS
++;
}
}
unsigned int SetDelay
(unsigned int t
)
{
unsigned char temp_hi
;
unsigned char temp_lo
;
temp_hi
= (TMR1MS
>> 8);
temp_lo
= (TMR1MS
& 0xff);
if (temp_hi
!= (TMR1MS
>> 8)) temp_hi
= (TMR1MS
>> 8);
return(((temp_hi
<< 8) | temp_lo
) + t
+ 1);
}
char CheckDelay
(unsigned int t
)
{
unsigned char temp_hi
;
unsigned char temp_lo
;
temp_hi
= (TMR1MS
>> 8);
temp_lo
= (TMR1MS
& 0xff);
if (temp_hi
!= (TMR1MS
>> 8)) temp_hi
= (TMR1MS
>> 8);
return(((t
- ((temp_hi
<< 8) | temp_lo
)) & 0x8000) >> 9);
}
/*##############################################################################*/
void StartPWM
(void)
{
//Timer 0 Config for getting right timing for IR Pattern
TCCR0
= (0<<CS02
)|(0<<CS01
)|(1<<CS00
); // (@8MHz) = 1/8us Clk = 256/8 = 32us overflow
TIMSK setbit
(1<<TOIE0
); // enable Int
}
/*##############################################################################*/
void StartPPM
(void)
{
//global timer1 Config
TCCR1A
= (0<<COM1A1
)|(0<<COM1A0
)|(0<<COM1B1
)|(0<<COM1B0
)|
(0<<FOC1A
) |(0<<FOC1B
) |(0<<WGM10
) |(0<<WGM11
);
TCCR1B
= (1<<ICNC1
)|(1<<ICES1
)|(0<<WGM13
)|
(0<<WGM12
)|(0<<CS12
)|(1<<CS11
)|(0<<CS10
); //ICP_POS_FLANKE
// interrupts
TIMSK
|= (1<<TICIE1
)|(1<<TOIE1
); //ICP_INT_ENABLE and TIMER1_INT_ENABLE
}
/*##############################################################################*/
unsigned int GetPPM
(void)
{
//this routines seems to be nesseccary, as reading a 16 bit value
//on a 8 bit machine is not atomic, so if an interrupt apears between reading
//low and high byte of the 16 bit value a wrong result is possible
unsigned char temp_hi
;
unsigned char temp_lo
;
temp_hi
= (ppm_signal
>> 8);
temp_lo
= (ppm_signal
& 0xff);
if (temp_hi
!= (ppm_signal
>> 8)) temp_hi
= (ppm_signal
>> 8);
return( (temp_hi
<< 8) | temp_lo
);
}
/*##############################################################################*/
// MAIN
/*##############################################################################*/
int main
(void)
{
#define step 128
#define mul 2
#define sigeepadr 0x00
#define mineepadr 0x20
#define maxeepadr 0x22
#define eepsig 0x55aa
unsigned int ppm
;
unsigned int setupdly
;
unsigned int ppmtodly
;
unsigned int lmax
;
unsigned int lmin
;
unsigned int max
;
unsigned int min
;
unsigned int sig
;
unsigned char setup
;
DDRB
= (CH0_B
|CH1_B
|CH2_B
);
PORTB
= 0x00;
DDRC
= (ledred
);
PORTC
= 0x00;
DDRD
= (ledgreen
|CH3_D
|CH4_D
|CH5_D
);
PORTD
= 0x00;
ch0
= 0;
ch1
= 0;
ch2
= 0;
ch3
= 0;
ch4
= 0;
ch5
= 0;
lmax
= 0x0000;
lmin
= 0xffff;
StartUART
();
StartPPM
();
//StartI2C();
StartPWM
();
sei
();
min
= 1100;
max
= 1900;
if (eeprom_read_word
(sigeepadr
) != eepsig
)
{
eeprom_write_word
(mineepadr
, min
);
eeprom_write_word
(maxeepadr
, max
);
eeprom_write_word
(sigeepadr
, eepsig
);
}
else
{
min
= eeprom_read_word
(mineepadr
);
max
= eeprom_read_word
(maxeepadr
);
}
printf("ppm: %d / min: %d / max: %d\n",ppm
,min
,max
);
setup
= 0;
setupdly
= SetDelay
(3000);
ppmtodly
= SetDelay
(5000);
while (1)
{
if (ppm_new
> 20)
{
PORTC clrbit ledred
;
ppm
= GetPPM
();
ppmtodly
= SetDelay
(500);
if (lmax
< ppm
) lmax
=ppm
;
if (lmin
> ppm
) lmin
=ppm
;
}
else
{
PORTC setbit ledred
;
ppm
= min
;
}
if (CheckDelay
(ppmtodly
))
{
ppmtodly
= SetDelay
(5000);
ppm_new
= 0;
}
if ((ppm
> 1600) && ((setup
&1)==0)) setup
++;
if ((ppm
< 1400) && ((setup
&1)==1)) setup
++;
if (setup
== 6)
{
PORTD setbit ledgreen
;
eeprom_write_word
(mineepadr
, lmin
);
eeprom_write_word
(maxeepadr
, lmax
);
min
= lmin
;
max
= lmax
;
setupdly
= SetDelay
(2000);
}
if (CheckDelay
(setupdly
))
{
setup
= 0;
PORTD clrbit ledgreen
;
}
//printf("ppm: %d / min: %d / max: %d\n",ppm,lmin,lmax);
/*
// Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb >
if ((ppm >= (step * 0)) && (ppm < (step * 1)))
{
ch0 = mul * ((ppm - (step * 0))); //fade in red > red (red only)
ch1 = 0;
ch2 = 0;
}
if ((ppm >= (step * 1)) && (ppm < (step * 2)))
{
ch0 = ((step-1) * mul);
ch2 = mul * ((ppm - (step * 1))); //fade in blue > purple (red + blue)
ch1 = 0;
}
if ((ppm >= (step * 2)) && (ppm < (step * 3)))
{
ch0 = mul * ((step - 1) - (ppm - (step * 2))); //fade out red > blue (blue only)
ch2 = ((step-1) * mul);
ch1 = 0;
}
if ((ppm >= (step * 3)) && (ppm < (step * 4)))
{
ch0 = 0;
ch2 = ((step-1) * mul);
ch1 = mul * ((ppm - (step * 3))); //fade in green > tuerkis (blue + green)
}
if ((ppm >= (step * 4)) && (ppm < (step * 5)))
{
ch0 = 0;
ch2 = mul * ((step - 1) - (ppm - (step * 4))); //fade out blue > green (green only)
ch1 = ((step-1) * mul);
}
if ((ppm >= (step * 5)) && (ppm < (step * 6)))
{
ch0 = mul * ((ppm - (step * 5))); //fade in red > yellow (green + red)
ch2 = 0;
ch1 = ((step-1) * mul);
}
if ((ppm >= (step * 6)) && (ppm < (step * 7)))
{
ch0 = ((step-1) * mul);
ch2 = 0;
ch1 = mul * ((step - 1) - (ppm - (step * 6))); //fade out green > red (red only)
}
if ((ppm >= (step * 7)) )
{
ch0 = ((step-1) * mul);
ch2 = 0;
ch1 = 9;
}
*/
}
}