Rev 51 |
Rev 53 |
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 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)
{
//printf("%d ",ppm_signal);
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));
}
}
/*
170 00fa 1F92 push __zero_reg__
171 00fc 0F92 push __tmp_reg__
172 00fe 0FB6 in __tmp_reg__,__SREG__
173 0100 0F92 push __tmp_reg__
174 0102 1124 clr __zero_reg__
175 0104 2F93 push r18
176 0106 3F93 push r19
177 0108 8F93 push r24
178 010a 9F93 push r25
181 010c 38B3 in r19,56-0x20
184 010e 22B3 in r18,50-0x20
187 0110 8091 0000 lds r24,counter.1797
188 0114 8F5F subi r24,lo8(-(1))
189 0116 8093 0000 sts counter.1797,r24
190 011a 8F3F cpi r24,lo8(-1)
191 011c 01F4 brne .L15
193 011e 3E60 ori r19,lo8(14)
195 0120 2863 ori r18,lo8(56)
197 0122 8091 0000 lds r24,ch0
198 0126 8093 0000 sts ch0_tmp,r24
200 012a 8091 0000 lds r24,ch1
201 012e 8093 0000 sts ch1_tmp,r24
203 0132 8091 0000 lds r24,ch2
204 0136 8093 0000 sts ch2_tmp,r24
206 013a 8091 0000 lds r24,ch3
207 013e 8093 0000 sts ch3_tmp,r24
209 0142 8091 0000 lds r24,ch4
210 0146 8093 0000 sts ch4_tmp,r24
212 014a 8091 0000 lds r24,ch5
213 014e 8093 0000 sts ch5_tmp,r24
215 0152 1092 0000 sts counter.1797,__zero_reg__
218 0156 8091 0000 lds r24,ch0_tmp
219 015a 9091 0000 lds r25,counter.1797
220 015e 8917 cp r24,r25
221 0160 01F4 brne .L17
222 0162 377F andi r19,lo8(-9)
225 0164 8091 0000 lds r24,ch1_tmp
226 0168 8917 cp r24,r25
227 016a 01F4 brne .L19
228 016c 3B7F andi r19,lo8(-5)
231 016e 8091 0000 lds r24,ch2_tmp
232 0172 8917 cp r24,r25
233 0174 01F4 brne .L21
234 0176 3D7F andi r19,lo8(-3)
237 0178 8091 0000 lds r24,ch3_tmp
238 017c 8917 cp r24,r25
239 017e 01F4 brne .L23
240 0180 277F andi r18,lo8(-9)
243 0182 8091 0000 lds r24,ch4_tmp
244 0186 8917 cp r24,r25
245 0188 01F4 brne .L25
246 018a 2F7E andi r18,lo8(-17)
249 018c 8091 0000 lds r24,ch5_tmp
250 0190 8917 cp r24,r25
251 0192 01F4 brne .L27
252 0194 2F7D andi r18,lo8(-33)
255 0196 38BB out 56-0x20,r19
257 0198 22BB out 50-0x20,r18
259 019a 8091 0000 lds r24,ms1.1798
260 019e 8F5F subi r24,lo8(-(1))
261 01a0 8093 0000 sts ms1.1798,r24
262 01a4 8132 cpi r24,lo8(33)
263 01a6 01F4 brne .L31
265 01a8 1092 0000 sts ms1.1798,__zero_reg__
267 01ac 8091 0000 lds r24,TMR1MS
268 01b0 9091 0000 lds r25,(TMR1MS)+1
269 01b4 0196 adiw r24,1
270 01b6 9093 0000 sts (TMR1MS)+1,r25
271 01ba 8093 0000 sts TMR1MS,r24
274 01be 9F91 pop r25
275 01c0 8F91 pop r24
276 01c2 3F91 pop r19
277 01c4 2F91 pop r18
278 01c6 0F90 pop __tmp_reg__
279 01c8 0FBE out __SREG__,__tmp_reg__
280 01ca 0F90 pop __tmp_reg__
281 01cc 1F90 pop __zero_reg__
282 01ce 1895 reti
*/