Rev 52 |
Rev 54 |
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 * 7 + ppm) / 8;
ppm_signal = ppm;
ppm_new = 1;
}
}
}
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
}
/*##############################################################################*/
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 intmask;
unsigned int ppm_temp;
intmask = TIMSK; //backup interupt enable bits
TIMSK &= ~(1<<TICIE1); //disable ppm interrupt
ppm_temp = ppm_signal;
TIMSK = intmask; //restore interupt enable bits
return(ppm_temp); //return ppm_signal
}
/*##############################################################################*/
// MAIN
/*##############################################################################*/
int main (void)
{
unsigned int i;
unsigned int ppm;
unsigned char colorState;
unsigned char nextcolorState=0;
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;
//StartUART();
StartPPM();
//StartI2C();
StartPWM();
sei();
// Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb >
colorState = 0;
while (1)
{
/*
#define step 128
#define mul 2
if ((ppm >= (step * 0) && (ppm < (step * 1))) ch0 = mul * ((ppm - (step * 0)));
if ((ppm >= (step * 1)) && (ppm < (step * 2))) ch1 = mul * ((ppm - (step * 1)));
if ((ppm >= (step * 2)) && (ppm < (step * 3))) ch0 = mul * ((step - 1) - (ppm - (step * 2)));
if ((ppm >= (step * 3)) && (ppm < (step * 4))) ch2 = mul * ((ppm - (step * 3)));
if ((ppm >= (step * 4)) && (ppm < (step * 5))) ch1 = mul * ((step - 1) - (ppm - (step * 4)));
if ((ppm >= (step * 5)) && (ppm < (step * 6))) ch0 = mul * ((ppm - (step * 5)));
if ((ppm >= (step * 6)) && (ppm < (step * 7))) ch2 = mul * ((step - 1) - (ppm - (step * 6)));
//printf("%d ",ppm);
*/
for (i=0; i<=255; i++)
{
switch(colorState)
{
case 0:
ch0 = i; //fade in (ch0) red
nextcolorState = 2;
break;
case 2:
ch1 = i; //fade in (ch1) blue to get pure purple (red + blue)
nextcolorState = 4;
break;
case 4:
ch0 = 255 - i; //fade out (ch0) red to get pure blue
nextcolorState = 6;
break;
case 6:
ch2 = i; //fade in (ch2) green to get pure cyan (blue + green)
nextcolorState = 8;
break;
case 8:
ch1 = 255 - i; //fade out (ch1) blue to get pure green
nextcolorState = 10;
break;
case 10:
ch0 = i; //fade in (ch0) red to get yellow pure (green + red)
nextcolorState = 12;
break;
case 12:
ch2 = 255 - i; //fade out (ch2) green to get pure red
nextcolorState = 0;
break;
}
timer = SetDelay(5); //wait 10ms
while (!CheckDelay(timer));
}
colorState = nextcolorState;
timer = SetDelay(3); //hold pure colors for additional 3ms
while (!CheckDelay(timer));
}
}