Subversion Repositories Projects

Rev

Rev 53 | Rev 55 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
28 walter 1
//############################################################################
51 walter 2
// - PWM CTRL 
3
// - Main
28 walter 4
// - ATMEGA8 mit 8MHz
5
// - Nur für den privaten Gebrauch
6
// - Keine Garantie auf Fehlerfreiheit
7
// - Kommerzielle Nutzung nur mit meiner Zustimmung
8
// - walter Meyer @ www.freakware.de
9
// - 11.12.2007
10
// - Make sure Fuses are programmed for internal 8 MHz RC Oscilator
11
//############################################################################*/
12
 
13
#include "main.h"
14
#include "uart.h"
15
#include "twislave.h"
16
 
17
volatile unsigned int ppm_signal = 1500;
18
volatile unsigned char ppm_new = 0;
19
volatile unsigned char TMR1OvF = 0;
51 walter 20
volatile unsigned int  TMR1MS;
28 walter 21
volatile unsigned char ch0;
22
volatile unsigned char ch1;
23
volatile unsigned char ch2;
24
volatile unsigned char ch3;
25
volatile unsigned char ch4;
26
volatile unsigned char ch5;
52 walter 27
volatile unsigned char ch0_tmp;
28
volatile unsigned char ch1_tmp;
29
volatile unsigned char ch2_tmp;
30
volatile unsigned char ch3_tmp;
31
volatile unsigned char ch4_tmp;
32
volatile unsigned char ch5_tmp;
33
 
34
 
51 walter 35
unsigned int timer;
28 walter 36
 
37
SIGNAL(SIG_OVERFLOW1)
38
{
39
        TMR1OvF++;
40
}
41
 
42
 
43
SIGNAL(SIG_INPUT_CAPTURE1)
44
{
45
        static unsigned int pos_ICR;
46
        static unsigned int ppm;
47
 
48
        if ((TCCR1B & (1<<ICES1)) != 0)                                         //rising edge
49
        {
50
                TCCR1B &= ~(1<<ICES1);                                                          //set falling egde
51
                TMR1OvF = 0;
52
                pos_ICR = ICR1;
53
        }
54
        else                                                                                    //falling edge
55
        {
56
                TCCR1B |= (1<<ICES1);                                                           //set rising egde
57
                ppm = (ICR1 - pos_ICR + (int) TMR1OvF * 65536);
58
                if ((ppm > 600) && (ppm < 2400))
59
                {
60
                        if (ppm > 2100) ppm = 2100;
61
                        if (ppm < 900) ppm = 900;
54 walter 62
                        ppm = (ppm_signal * 3 + ppm) / 4;
28 walter 63
                        ppm_signal = ppm;
54 walter 64
                        if (ppm_new < 50) ppm_new++;
28 walter 65
                }
66
 
67
        }
68
 
69
}
70
 
71
 
72
 
73
 
74
 
75
SIGNAL(SIG_OVERFLOW0)
76
{
52 walter 77
        // this function is called every 32us,
78
        // it is very important that it's execution time is as short as possible
79
        // currently it's about 20us
80
 
81
        static unsigned char counter = 254;
82
        static unsigned char ms1 = 0;
28 walter 83
        unsigned char PORTB_BAK;
84
        unsigned char PORTD_BAK;       
85
 
86
        PORTB_BAK = PORTB;
87
        PORTD_BAK = PORTD;
88
 
51 walter 89
        if (counter++ == 254)
28 walter 90
        {
51 walter 91
                PORTB_BAK LEDON (CH0_B | CH1_B | CH2_B);
92
                PORTD_BAK LEDON (CH3_D | CH4_D | CH5_D);       
52 walter 93
                ch0_tmp = ch0;
94
                ch1_tmp = ch1;
95
                ch2_tmp = ch2;
96
                ch3_tmp = ch3;
97
                ch4_tmp = ch4;
98
                ch5_tmp = ch5;         
51 walter 99
                counter = 0;
28 walter 100
        }
101
 
52 walter 102
        if (ch0_tmp == counter) PORTB_BAK LEDOFF CH0_B;
103
        if (ch1_tmp == counter) PORTB_BAK LEDOFF CH1_B;
104
        if (ch2_tmp == counter) PORTB_BAK LEDOFF CH2_B;
105
        if (ch3_tmp == counter) PORTD_BAK LEDOFF CH3_D;
106
        if (ch4_tmp == counter) PORTD_BAK LEDOFF CH4_D;
107
        if (ch5_tmp == counter) PORTD_BAK LEDOFF CH5_D;
51 walter 108
 
109
        PORTB = PORTB_BAK;
110
        PORTD = PORTD_BAK;
28 walter 111
 
54 walter 112
 
51 walter 113
        if (ms1++ == 32)
28 walter 114
        {
51 walter 115
                ms1=0;
116
                TMR1MS++;
28 walter 117
        }
51 walter 118
 
28 walter 119
 
120
 
121
 
51 walter 122
}
28 walter 123
 
124
 
125
 
51 walter 126
unsigned int SetDelay (unsigned int t)
127
{
128
        unsigned char temp_hi;
129
        unsigned char temp_lo;  
28 walter 130
 
51 walter 131
        temp_hi = (TMR1MS >> 8);
132
        temp_lo = (TMR1MS & 0xff);
133
        if (temp_hi != (TMR1MS >> 8)) temp_hi = (TMR1MS >> 8);
28 walter 134
 
51 walter 135
        return(((temp_hi << 8) | temp_lo)  + t + 1);                                            
28 walter 136
 
51 walter 137
}
28 walter 138
 
139
 
54 walter 140
 
51 walter 141
char CheckDelay(unsigned int t)
142
{
143
        unsigned char temp_hi;
144
        unsigned char temp_lo;  
145
 
146
        temp_hi = (TMR1MS >> 8);
147
        temp_lo = (TMR1MS & 0xff);
148
        if (temp_hi != (TMR1MS >> 8)) temp_hi = (TMR1MS >> 8);
149
 
150
        return(((t - ((temp_hi << 8) | temp_lo)) & 0x8000) >> 9);
151
 
28 walter 152
}
153
 
154
 
155
 
156
 
157
/*##############################################################################*/
51 walter 158
void StartPWM(void)
28 walter 159
{
160
        //Timer 0 Config for getting right timing for IR Pattern
161
        TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00);          // (@8MHz) =  1/8us Clk = 256/8 = 32us overflow
162
        TIMSK setbit (1<<TOIE0);                                                // enable Int
163
 
164
}
165
 
166
 
167
 
168
/*##############################################################################*/
169
void StartPPM(void)
170
{
171
 
172
        //global timer1 Config
173
        TCCR1A =        (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|
174
                                (0<<FOC1A) |(0<<FOC1B) |(0<<WGM10) |(0<<WGM11);                
175
    TCCR1B =    (1<<ICNC1)|(1<<ICES1)|(0<<WGM13)|
176
                                (0<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);                               //ICP_POS_FLANKE
177
 
178
        // interrupts
179
        TIMSK |=        (1<<TICIE1)|(1<<TOIE1);                                                                 //ICP_INT_ENABLE and TIMER1_INT_ENABLE
180
 
181
}
182
 
183
 
184
 
52 walter 185
/*##############################################################################*/
54 walter 186
unsigned int GetPPM(void)
28 walter 187
{
188
        //this routines seems to be nesseccary, as reading a 16 bit value
189
        //on a 8 bit machine is not atomic, so if an interrupt apears between reading
190
        //low and high byte of the 16 bit value a wrong result is possible
191
 
54 walter 192
        unsigned char temp_hi;
193
        unsigned char temp_lo;  
28 walter 194
 
54 walter 195
        temp_hi = (ppm_signal >> 8);
196
        temp_lo = (ppm_signal & 0xff);
197
        if (temp_hi != (ppm_signal >> 8)) temp_hi = (ppm_signal >> 8);
198
        return( (temp_hi << 8) | temp_lo);                                            
28 walter 199
 
200
}
201
 
202
 
203
/*##############################################################################*/
204
// MAIN
205
/*##############################################################################*/
206
int main (void)
207
{
54 walter 208
 
209
        #define step    128
210
        #define mul             2
211
 
212
        #define sigeepadr       0x00
213
        #define mineepadr       0x20
214
        #define maxeepadr       0x22
215
        #define eepsig          0x55aa
216
 
217
 
218
 
53 walter 219
        unsigned int    ppm;
54 walter 220
        unsigned int    setupdly;
221
        unsigned int    ppmtodly;      
222
        unsigned int    lmax;
223
        unsigned int    lmin;
224
        unsigned int    max;
225
        unsigned int    min;
226
        unsigned int    sig;
227
        unsigned char   setup;
28 walter 228
 
54 walter 229
 
51 walter 230
    DDRB  = (CH0_B|CH1_B|CH2_B);
231
    PORTB = 0x00;
232
 
233
    DDRC  = (ledred);
28 walter 234
    PORTC = 0x00;
51 walter 235
 
236
    DDRD  = (ledgreen|CH3_D|CH4_D|CH5_D);
28 walter 237
    PORTD = 0x00;
238
 
239
        ch0 = 0;
240
        ch1 = 0;
241
        ch2 = 0;
242
        ch3 = 0;
243
        ch4 = 0;
244
        ch5 = 0;       
245
 
54 walter 246
        lmax = 0x0000;
247
        lmin = 0xffff;
248
 
249
        StartUART();
28 walter 250
        StartPPM();
51 walter 251
        //StartI2C();
28 walter 252
        StartPWM();
253
        sei();
254
 
51 walter 255
 
54 walter 256
        min = 1100;
257
        max = 1900;
51 walter 258
 
54 walter 259
        if (eeprom_read_word(sigeepadr) != eepsig)
260
        {
261
                eeprom_write_word(mineepadr, min);
262
                eeprom_write_word(maxeepadr, max);
263
                eeprom_write_word(sigeepadr, eepsig);
264
        }
265
        else
266
        {
267
                min = eeprom_read_word(mineepadr);  
268
                max = eeprom_read_word(maxeepadr);  
269
        }
51 walter 270
 
54 walter 271
        printf("ppm: %d / min: %d / max: %d\n",ppm,min,max);                   
272
 
273
 
274
        setup = 0;
275
        setupdly = SetDelay(3000);
276
        ppmtodly = SetDelay(5000);     
28 walter 277
 
278
    while (1)
279
        {
51 walter 280
 
54 walter 281
                if (ppm_new > 20)
282
                {
283
                        PORTC clrbit ledred;
284
                        ppm = GetPPM();
285
                        ppmtodly = SetDelay(500);                      
286
                        if (lmax < ppm) lmax=ppm;
287
                        if (lmin > ppm) lmin=ppm;              
288
                }
289
                else
290
                {
291
                        PORTC setbit ledred;
292
                        ppm = min;     
293
                }
294
 
295
                if (CheckDelay(ppmtodly))
296
                {
297
                        ppmtodly = SetDelay(5000);                     
298
                        ppm_new = 0;
299
                }
28 walter 300
 
54 walter 301
                if ((ppm > 1600) && ((setup&1)==0)) setup++;
302
                if ((ppm < 1400) && ((setup&1)==1)) setup++;
303
                if (setup == 6)
304
                {
305
                        PORTD setbit ledgreen;
306
                        eeprom_write_word(mineepadr, lmin);
307
                        eeprom_write_word(maxeepadr, lmax);
308
                        min = lmin;
309
                        max = lmax;
310
                        setupdly = SetDelay(2000);
311
                }
312
                if (CheckDelay(setupdly))
313
                {
314
                        setup = 0;
315
                        PORTD clrbit ledgreen;
316
                }
53 walter 317
 
54 walter 318
                //printf("ppm: %d / min: %d / max: %d\n",ppm,lmin,lmax);                        
319
 
320
 
321
/*             
322
                // Farbablauf: rot > Violett > blau > tuerkis > gruen > gelb >
323
                if ((ppm >= (step * 0)) && (ppm < (step * 1)))
51 walter 324
                {
54 walter 325
                        ch0 = mul * ((ppm - (step * 0)));                                       //fade in red > red (red only)
326
                        ch1 = 0;
327
                        ch2 = 0;
328
                }
329
                if ((ppm >= (step * 1)) && (ppm < (step * 2)))
330
                {
331
                        ch0 = ((step-1) * mul);
332
                        ch2 = mul * ((ppm - (step * 1)));                                       //fade in blue > purple (red + blue)
333
                        ch1 = 0;
334
                }
335
                if ((ppm >= (step * 2)) && (ppm < (step * 3)))
336
                {
337
                        ch0 = mul * ((step - 1) - (ppm - (step * 2)));  //fade out red > blue (blue only)
338
                        ch2 = ((step-1) * mul);
339
                        ch1 = 0;
340
                }
341
                if ((ppm >= (step * 3)) && (ppm < (step * 4)))
342
                {
343
                        ch0 = 0;
344
                        ch2 = ((step-1) * mul);
345
                        ch1 = mul * ((ppm - (step * 3)));                                       //fade in green > tuerkis (blue + green)
346
                }
347
                if ((ppm >= (step * 4)) && (ppm < (step * 5)))
348
                {
349
                        ch0 = 0;
350
                        ch2 = mul * ((step - 1) - (ppm - (step * 4)));  //fade out blue > green (green only)
351
                        ch1 = ((step-1) * mul);
352
                }
353
                if ((ppm >= (step * 5)) && (ppm < (step * 6)))
354
                {
355
                        ch0 = mul * ((ppm - (step * 5)));                                       //fade in red > yellow (green + red)
356
                        ch2 = 0;
357
                        ch1 = ((step-1) * mul);
358
                }
359
                if ((ppm >= (step * 6)) && (ppm < (step * 7)))
360
                {
361
                        ch0 = ((step-1) * mul);
362
                        ch2 = 0;
363
                        ch1 = mul * ((step - 1) - (ppm - (step * 6)));  //fade out green > red (red only)
364
                }
365
                if ((ppm >= (step * 7)) )
366
                {
367
                        ch0 = ((step-1) * mul);
368
                        ch2 = 0;
369
                        ch1 = 9;                                                                                       
370
                }
371
*/             
28 walter 372
 
54 walter 373
 
374
 
51 walter 375
 
376
 
377
 
28 walter 378
        }
379
 
380
 
381
}
52 walter 382